using UnityEngine; using System; namespace Unity.Netcode { /// /// A variable that can be synchronized over the network. /// /// the unmanaged type for [Serializable] public class NetworkVariable : NetworkVariableBase { /// /// Delegate type for value changed event /// /// The value before the change /// The new value public delegate void OnValueChangedDelegate(T previousValue, T newValue); /// /// The callback to be invoked when the value gets changed /// public OnValueChangedDelegate OnValueChanged; /// /// Constructor for /// /// initial value set that is of type T /// the for this /// the for this public NetworkVariable(T value = default, NetworkVariableReadPermission readPerm = DefaultReadPerm, NetworkVariableWritePermission writePerm = DefaultWritePerm) : base(readPerm, writePerm) { m_InternalValue = value; } /// /// The internal value of the NetworkVariable /// [SerializeField] private protected T m_InternalValue; /// /// The value of the NetworkVariable container /// public virtual T Value { get => m_InternalValue; set { // Compare bitwise if (NetworkVariableSerialization.AreEqual(ref m_InternalValue, ref value)) { return; } if (m_NetworkBehaviour && !CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId)) { throw new InvalidOperationException("Client is not allowed to write to this NetworkVariable"); } Set(value); } } /// /// Sets the , marks the dirty, and invokes the callback /// if there are subscribers to that event. /// /// the new value of type `T` to be set/> private protected void Set(T value) { SetDirty(true); T previousValue = m_InternalValue; m_InternalValue = value; OnValueChanged?.Invoke(previousValue, m_InternalValue); } /// /// Writes the variable to the writer /// /// The stream to write the value to public override void WriteDelta(FastBufferWriter writer) { WriteField(writer); } /// /// Reads value from the reader and applies it /// /// The stream to read the value from /// Whether or not the container should keep the dirty delta, or mark the delta as consumed public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta) { // todo: // keepDirtyDelta marks a variable received as dirty and causes the server to send the value to clients // In a prefect world, whether a variable was A) modified locally or B) received and needs retransmit // would be stored in different fields T previousValue = m_InternalValue; NetworkVariableSerialization.Read(reader, ref m_InternalValue); if (keepDirtyDelta) { SetDirty(true); } OnValueChanged?.Invoke(previousValue, m_InternalValue); } /// public override void ReadField(FastBufferReader reader) { NetworkVariableSerialization.Read(reader, ref m_InternalValue); } /// public override void WriteField(FastBufferWriter writer) { NetworkVariableSerialization.Write(writer, ref m_InternalValue); } } }