Skip to content

Network Transform synchronized wrong position when WorldPositionStays is false #2888

Closed
@AsmPrgmC3

Description

@AsmPrgmC3

Description

When a client joins a server the initial synchronized positions of Network Transforms are wrong, if

  • "In Local Space" of the Network Transform is off,
  • The Network Transform has a parent without Network Object, and
  • The parent has a non-zero position.

The problematic code path I was able to determine:

  1. The Network Object sets m_CachedWorldPositionStays to false because it has a parent without Network Object:
    if (transform.parent != null && !removeParent && !m_LatestParent.HasValue && isInScenePlaced)
    {
    var parentNetworkObject = transform.parent.GetComponent<NetworkObject>();
    // If parentNetworkObject is null then the parent is a GameObject without a NetworkObject component
    // attached. Under this case, we preserve the hierarchy but we don't keep track of the parenting.
    // Note: We only start tracking parenting if the user removes the child from the standard GameObject
    // parent and then re-parents the child under a GameObject with a NetworkObject component attached.
    if (parentNetworkObject == null)
    {
    // If we are parented under a GameObject, go ahead and mark the world position stays as false
    // so clients synchronize their transform in local space. (only for in-scene placed NetworkObjects)
    m_CachedWorldPositionStays = false;
  2. When joining the server side Network Transform synchronizes the local position based on that (but doesn't set networkState.InLocalSpace):
    if (isSynchronization)
    {
    if (NetworkObject.WorldPositionStays())
    {
    position = transformToUse.position;
    }
    else
    {
    position = transformToUse.localPosition;
    }
    }
  3. The client Network Transform applies the transmitted position based on newState.InLocalSpace (which is false):
    if (newState.InLocalSpace)
    {
    transform.localPosition = currentPosition;
    }
    else
    {
    transform.position = currentPosition;
    }

Reproduce Steps

  1. Create an empty called "parent"
  2. Set the local position of "parent" to [1, 1, 1]
  3. Add a cube as a child of "parent"
  4. Add Network Object and Network Transform Scripts to the cube
  5. Start the server and have a client join it (joining a host also works, but the issue doesn't happen on the host itself)

Actual Outcome

The cube on the client spawns at the origin (local position [-1, -1, -1])

Expected Outcome

The cube on the client spawns at the server position of [1, 1, 1] (local position [0, 0, 0])

Environment

  • OS: Windows 10 (22H2)
  • Unity Version: 2022.3.7f1
  • Netcode Version: 1.9.0 (also happens on lastest release 1.8.1)
  • Netcode Commit: d97d968

Metadata

Metadata

Labels

priority:highThis issue has high priority and we are focusing to resolve itstat:importedStatus - Issue is tracked internally at Unitytype:bugBug Report

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions