文章目录
- 前言
- NetworkAnimation
- 服务端权威
- 客户端权威
前言
这次的动画同步与位置同步,可以说实现思路是一样的,代码相似度也非常高
NetworkAnimation
如果直接挂载这个脚本只有Host(服务端)才可以同步,Client是没有权限同步的。
服务端权威
直接修改之前的PlayerSync.cs
脚本。
using Unity.Netcode;
using UnityEngine;
public class PlayerSync : NetworkBehaviour
{
private NetworkVariable<Vector3> _syncPos = new();
private NetworkVariable<Quaternion> _syncRota = new();
private Transform _syncTransform;
private NetworkVariable<bool> _syncisIdle = new();
private NetworkVariable<bool> _syncisRun = new();
private Animator _syncAnimator;
public void SetTarget(Transform player)
{
_syncTransform = player;
_syncAnimator = player.GetComponent<Animator>();
}
private void Update()
{
if (IsLocalPlayer)
{
UploadTransform();
UploadAnimation();
}
}
private void FixedUpdate()
{
if (!IsLocalPlayer)
{
SyncTransform();
SyncAnimation();
}
}
private void SyncTransform()
{
_syncTransform.position = _syncPos.Value;
_syncTransform.rotation = _syncRota.Value;
}
private void SyncAnimation()
{
_syncAnimator.SetBool("isIdle", _syncisIdle.Value);
_syncAnimator.SetBool("isRun", _syncisRun.Value);
}
private void UploadTransform()
{
if (IsServer)
{
_syncPos.Value = _syncTransform.position;
_syncRota.Value = _syncTransform.rotation;
}
else
{
UploadTransformServerRpc(_syncTransform.position, _syncTransform.rotation);
}
}
[ServerRpc]
private void UploadTransformServerRpc(Vector3 position, Quaternion rotation)
{
_syncPos.Value = position;
_syncRota.Value = rotation;
}
private void UploadAnimation()
{
if (IsServer)
{
_syncisIdle.Value = _syncAnimator.GetBool("isIdle");
_syncisRun.Value = _syncAnimator.GetBool("isRun");
}
else
{
UploadAnimationServerRpc();
}
}
[ServerRpc]
private void UploadAnimationServerRpc()
{
_syncisIdle.Value = _syncAnimator.GetBool("isIdle");
_syncisRun.Value = _syncAnimator.GetBool("isRun");
}
}
客户端权威
写个OwnerNetworkAnimator.cs
挂载到角色身上即可
using Unity.Netcode.Components;
public class OwnerNetworkAnimator : NetworkAnimator
{
protected override bool OnIsServerAuthoritative()
{
return false;
}
}
脚本的Animator
直接把角色拖进去即可读取。