using Unity.Multiplayer.Samples.BossRoom.Shared.Infrastructure;
using Unity.Multiplayer.Samples.Utilities;
using Unity.Netcode;
using UnityEngine;
using VContainer;
namespace Unity.Multiplayer.Samples.BossRoom.Client
{
///
/// Represents a door in the client. The visuals of the door animate as
/// "opening" and "closing", but for physics purposes this is an illusion:
/// whenever the door is open on the server, the door's physics are disabled,
/// and vice versa.
///
[RequireComponent(typeof(NetworkDoorState))]
[RequireComponent(typeof(NetcodeHooks))]
public class ClientDoorVisualization : MonoBehaviour
{
[SerializeField]
[Tooltip("This physics and navmesh obstacle is enabled when the door is closed.")]
GameObject m_PhysicsObject;
[SerializeField]
NetworkDoorState m_DoorState;
NetcodeHooks m_Hooks;
[Inject]
IPublisher m_Publisher;
void Awake()
{
m_Hooks = GetComponent();
m_Hooks.OnNetworkSpawnHook += OnSpawn;
m_Hooks.OnNetworkDespawnHook += OnDespawn;
}
void OnSpawn()
{
if (!NetworkManager.Singleton.IsClient)
{
enabled = false;
}
else
{
m_DoorState.IsOpen.OnValueChanged += OnDoorStateChanged;
// initialize visuals based on current server state (or else we default to "closed")
m_PhysicsObject.SetActive(!m_DoorState.IsOpen.Value);
var gameState = FindObjectOfType();
if (gameState != null)
{
gameState.Container.Inject(this);
}
}
}
void OnDespawn()
{
if (m_DoorState)
{
m_DoorState.IsOpen.OnValueChanged -= OnDoorStateChanged;
}
}
public void OnDestroy()
{
m_Hooks.OnNetworkSpawnHook -= OnSpawn;
m_Hooks.OnNetworkDespawnHook -= OnDespawn;
}
void OnDoorStateChanged(bool wasDoorOpen, bool isDoorOpen)
{
m_PhysicsObject.SetActive(!isDoorOpen);
m_Publisher?.Publish(new DoorStateChangedEventMessage() { IsDoorOpen = isDoorOpen });
}
}
}