Skip to content

Spawn and immediate re-parent of owner auth local space NetworkTransform always results in incorrect world position #3645

@zachstronaut

Description

@zachstronaut

Description

Spawn and immediate re-parent of owner auth local space NetworkTransform always results in incorrect world position unless you get lucky with (0,0,0) world position prefab or new parent.

Host Harry with one additional Client Charlie.

Charlie avatar prefab NetworkObject settings:
SyncOwnerTransformWhenParented = false
AllowOwnerToParent = true

Charlie avatar prefab NetworkTransform settings:
Authority Mode = Owner
Switch Transform Space When Parented = true
In Local Space = true

Host spawns Charlie avatar NetworkObject prefab that has a NetworkTransform using SpawnWithOwnership() and setting the owner to the Charlie client. The initial position of Charlie is not world 0,0,0 but some other world position e.g. (500, 0, 70)

Host immediately re-parents the Charlie avatar from initial null parent to a valid NetworkObject parent, and that new parent is not at (0,0,0), it is at some other position e.g. (100, 0, 0)

then ApplyAuthoritativeState() runs on Host and this else case executes:


if (PositionInLocalSpace)
{
    // This handles the edge case of transitioning from local to world space where applying a local
    // space value to a non-parented transform will be applied in world space. Since parenting is not
    // tick synchronized, there can be one or two ticks between a state update with the InLocalSpace
    // state update which can cause the body to seemingly "teleport" when it is just applying a local
    // space value relative to world space 0,0,0.
    if (SwitchTransformSpaceWhenParented && m_IsFirstNetworkTransform && Interpolate && m_PreviousNetworkObjectParent != null
        && transform.parent == null)
    {
        m_InternalCurrentPosition = m_PreviousNetworkObjectParent.transform.TransformPoint(m_InternalCurrentPosition);
        transform.position = m_InternalCurrentPosition;
    }
    else // this executes!
    {
        transform.localPosition = m_InternalCurrentPosition;
    }
}

But m_InternalCurrentPosition was still (500, 0, 70) and so now Charlie's world position is (600, 0, 70) which is incorrect.

This value will stay incorrect until the Charlie client sends new authoritative position data, and with enough lag and/or packet loss this incorrect position will be perceived by the Host, potentially for awhile.

It seems that on the host neither InternalOnNetworkObjectParentChanged() nor AdjustForChangeInTransformSpace() makes any changes to m_InternalCurrentPosition, and I wonder if they should be?

Or does there need to be an additional else if case in ApplyAuthoritativeState() for this?

Environment

OS: Windows 11
Unity Version: 6000.1.3f1
Netcode Version: 2.4.2
Netcode Topology: Client-Server

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions