-
Notifications
You must be signed in to change notification settings - Fork 459
Description
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