using Unity.Netcode; using UnityEngine; using UnityEngine.XR.Content.Interaction; namespace XRMultiplayer { /// /// Represents a networked XR knob interactable. /// [RequireComponent(typeof(XRKnob))] public class NetworkXRKnob : NetworkBehaviour { /// /// The networked knob value. /// NetworkVariable m_NetworkedKnobValue = new NetworkVariable(0f, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server); /// /// The XR knob component. /// XRKnob m_XRKnob; /// public void Awake() { // Get associated components if (!TryGetComponent(out m_XRKnob)) { Utils.Log("Missing Components! Disabling Now.", 2); enabled = false; return; } } /// public override void OnNetworkSpawn() { base.OnNetworkSpawn(); m_XRKnob.onValueChange.AddListener(KnobChanged); if (IsServer) { m_NetworkedKnobValue.Value = m_XRKnob.value; } else { m_XRKnob.value = m_NetworkedKnobValue.Value; } } public override void OnNetworkDespawn() { base.OnNetworkDespawn(); m_XRKnob.onValueChange.RemoveListener(KnobChanged); } /// /// Called when the knob value is changed. /// /// The new value of the knob. private void KnobChanged(float newValue) { KnobChangedServerRpc(newValue, NetworkManager.Singleton.LocalClientId); } /// /// Server RPC called when the knob value is changed. /// /// The new value of the knob. /// The client ID of the player who changed the knob value. [ServerRpc(RequireOwnership = false)] void KnobChangedServerRpc(float newValue, ulong clientId) { m_NetworkedKnobValue.Value = newValue; KnobChangedClientRpc(newValue, clientId); } /// /// Client RPC called when the knob value is changed. /// /// The new value of the knob. /// The client ID of the player who changed the knob value. [ClientRpc] void KnobChangedClientRpc(float newValue, ulong clientId) { if (clientId != NetworkManager.Singleton.LocalClientId) { m_XRKnob.onValueChange.RemoveListener(KnobChanged); m_XRKnob.value = newValue; m_XRKnob.onValueChange.AddListener(KnobChanged); } } } }