using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
{
///
/// Component that spawns a PlayerAvatar's Avatar. It does this in two places:
/// 1) either inside OnNetworkSpawn() or
/// 2) inside NetworkAnimator's OnSynchronize method.
/// The latter is necessary for clients receiving initial synchronizing data, where the Animator needs to be present
/// and bound (Animator.Bind()) *before* the incoming animation data is applied.
///
public class ClientPlayerAvatarNetworkAnimator : NetworkAnimator
{
[SerializeField]
NetworkAvatarGuidState m_NetworkAvatarGuidState;
bool m_AvatarInstantiated;
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (!IsClient || m_AvatarInstantiated)
{
return;
}
InstantiateAvatar();
}
public override void OnNetworkDespawn()
{
base.OnNetworkDespawn();
m_AvatarInstantiated = false;
var avatarGraphics = Animator.transform.GetChild(0);
if (avatarGraphics != null)
{
Destroy(avatarGraphics.gameObject);
}
}
protected override void OnSynchronize(ref BufferSerializer serializer)
{
if (NetworkManager.Singleton.IsClient && !m_AvatarInstantiated)
{
InstantiateAvatar();
}
base.OnSynchronize(ref serializer);
}
void InstantiateAvatar()
{
if (Animator.transform.childCount > 0)
{
// we may receive a NetworkVariable's OnValueChanged callback more than once as a client
// this makes sure we don't spawn a duplicate graphics GameObject
return;
}
// spawn avatar graphics GameObject
Instantiate(m_NetworkAvatarGuidState.RegisteredAvatar.Graphics, Animator.transform);
Animator.Rebind();
m_AvatarInstantiated = true;
}
}
}