using System; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; public sealed class NetworkButtonInteractable : NetworkInteractable { [SerializeField] private UnityEvent pressed = new(); [SerializeField] private UnityEvent buttonStateChanged; private readonly NetworkVariable isPressed = new( false, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); private readonly NetworkVariable pressSequence = new( 0, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); public bool IsPressed => isPressed.Value; public uint PressSequence => pressSequence.Value; public event Action Pressed; public event Action StateChanged; public override void OnNetworkSpawn() { isPressed.OnValueChanged += HandleStateChanged; pressSequence.OnValueChanged += HandlePressSequenceChanged; ApplyState(isPressed.Value); } public override void OnNetworkDespawn() { isPressed.OnValueChanged -= HandleStateChanged; pressSequence.OnValueChanged -= HandlePressSequenceChanged; } protected override bool CanInteractOnServer(ulong senderClientId) => true; protected override void InteractOnServer(ulong senderClientId, NetworkObject playerObject) { isPressed.Value = !isPressed.Value; pressSequence.Value++; } private void HandleStateChanged(bool _, bool currentValue) => ApplyState(currentValue); private void HandlePressSequenceChanged(uint previous, uint current) { if (current == previous) return; Pressed?.Invoke(); pressed?.Invoke(); } private void ApplyState(bool currentValue) { StateChanged?.Invoke(currentValue); buttonStateChanged?.Invoke(currentValue); } }