問題提起
NetworkTransform は NetworkVariable を用いて Transform の同期を行っています. ここで思い出して頂きたいのですが,NGO 版から NetworkVariable の値設定は Server の権限でしかできなくなったため, 例えば Client 側の Input で NetworkObject の Transform を更新しようとして, これまでの MLAPI と同様に,NetworkTransform をアタッチしても Transform の同期はできなくなりました. というより,移動自体ができません(移動しようとしても瞬時にスポーン時の Transform に戻る)
ClientNetworkTransform
とはいえ,NetworkTransform
のコードを読んでみると,以下の記載があります.
/// <summary> /// Tries updating the server authoritative transform, only if allowed. /// If this called server side, this will commit directly. /// If no update is needed, nothing will be sent. This method should still be called every update, it'll self manage when it should and shouldn't send /// </summary> /// <param name="transformToCommit"></param> /// <param name="dirtyTime"></param> protected void TryCommitTransformToServer(Transform transformToCommit, double dirtyTime) { var isDirty = ApplyTransformToNetworkState(ref m_LocalAuthoritativeNetworkState, dirtyTime, transformToCommit); TryCommit(isDirty); }
つまり,NetworkTransform
を基底とし,Client 側で Transform
の更新が行えるような拡張クラスを作ればよさそうです.
実は Package Manager に載っているサンプルで ClientNetworkTransform
があるんですよね.
using Unity.Netcode.Components; using UnityEngine; namespace Unity.Netcode.Samples { /// <summary> /// Used for syncing a transform with client side changes. This includes host. Pure server as owner isn't supported by this. Please use NetworkTransform /// for transforms that'll always be owned by the server. /// </summary> [DisallowMultipleComponent] public class ClientNetworkTransform : NetworkTransform { /// <summary> /// Used to determine who can write to this transform. Owner client only. /// Changing this value alone will not allow you to create a NetworkTransform which can be written to by clients. /// We're using RPCs to send updated values from client to server. Netcode doesn't support client side network variable writing. /// This imposes state to the server. This is putting trust on your clients. Make sure no security-sensitive features use this transform. /// </summary> // This is public to make sure that users don't depend on this IsClient && IsOwner check in their code. If this logic changes in the future, we can make it invisible here public override void OnNetworkSpawn() { base.OnNetworkSpawn(); CanCommitToTransform = IsOwner; } protected override void Update() { base.Update(); if (NetworkManager.Singleton != null && (NetworkManager.Singleton.IsConnectedClient || NetworkManager.Singleton.IsListening)) { if (CanCommitToTransform) { TryCommitTransformToServer(transform, NetworkManager.LocalTime.Time); } } } } }
Client 側で NetworkObject の Transform を更新したい場合は ClientNetworkTransform を利用しましょう.
終わりに
Inspector 側で CanCommitToTransform が露出されていますが, Unity Editor でここはチェックを入れないようにしてください. 現時点ではバグって永久にワーニングのログが出るようになってしまいます.