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);
}
}
}