Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.1k stars 430 forks source link

Re-parenting of "In Local Space" client-authoritative NetworkTransform results in large interpolation #2843

Open zachstronaut opened 3 months ago

zachstronaut commented 3 months ago

Re-parenting of "In Local Space" client-authoritative NetworkTransform results in large interpolation on non-owning client.

If a non-host client owns a GameObject with a client/owner authoritative NetworkTransform that is "In Local Space" and that object is re-parented by the server, the server/host will see the object interpolated across the difference in the before & after local position even though the world position has not changed.

zachstronaut commented 3 months ago

I thought maybe I could solve this as a general case in NetworkTransform.cs in either ApplyTransformToNetworkStateWithInfo on the authoritative side or in ApplyUpdatedState on the non-authoritative side by checking if transform.parent != previousParent and setting IsTeleportingNextFrame = true but I'm seeing mixed results with that approach in terms of how much it mitigates the big unwanted interpolation.

I also explored not making edits to NetworkTransform.cs and trying to fix this interpolation issue with normally available methods:

public void ClientAuthoritativeReparent(Transform _newParent)
{
    if (!IsOwner) return;
    ReparentRpc(_newParent.gameObject);
    GetComponent<Unity.Netcode.Components.NetworkTransform>().Teleport(transform.localPosition, transform.localRotation, transform.localScale);
}

[Rpc(SendTo.Everyone)]
void ReparentRpc(NetworkObjectReference _newParent)
{
    NetworkObject newParent = _newParent;
    this.NetworkObject.AutoObjectParentSync = false;
    this.transform.parent = newParent.transform;
    this.NetworkObject.AutoObjectParentSync = true;
}

This seems to almost work, but there's still a small noticeable visual hiccup. I'm not sure if this is a result of interrupted interpolation or not, but that's my suspicion.

NoelStephensUnity commented 2 months ago

@zachstronaut You might take a gander at the develop-2.0.0 branch (all still experimental and no full documentation out on it yet)...or if you update to Unity 6 you can add the experimental package by using the com.unity.netcode.gameobjects name and 2.0.0-exp.2 as the version...or edit your manifest (for Unity 6) to use the 2.0.0-exp.2 version.

Running in distributed authority mode everything can be handled on the client side. For your example above, you would just parent the NetworkObject on the owning client side (i.e. it avoids the RTT latency by having the server handling the parenting).

v2.0,0 will require using Unity 6 (currently 6000.0.0b13), but you will notice several of the issues you have been experiencing similar to this can be avoided using the distributed authority mode where clients can spawn their own NetworkObjects locally and have full authority over the NetworkObjects they own.

zachstronaut commented 2 months ago

v2.0,0 will require using Unity 6 (currently 6000.0.0b13),

@NoelStephensUnity Wait... like, 2.x will only ever work on Unity 6? You're not supporting LTS?