最近工程升级到Netcode For Gameobject 1.2.0版本
运行会出现部分报错,查看原因后发现是网络变量模块构造方法出现的问题
【1.1.0+版本 标记以下类为过时】
【1.0.2-版本 以下类可用】
///
/// 网络变量 - 基类【重写】
///
///
///
///
/// - 加入构造函数,可以new新元素加入链表
/// - 网络变量可以用作静态字段,但是RPC不可以
///
///
[Serializable]
public class NetVar<T> : NetworkVariable<T> where T : unmanaged
{
public NetVar(T value = default,
NetworkVariableReadPermission readPerm = DefaultReadPerm,
NetworkVariableWritePermission writePerm = DefaultWritePerm) :
base(value, readPerm, writePerm)
{
Value = value;
}
}
[Obsolete("1.0.2-版本可用,1.1+版本使用-NetworkVariable")]
[Serializable] public class NetVar_Int : NetVar<int>
{
public NetVar_Int(int value = 0,
NetworkVariableReadPermission readPerm = DefaultReadPerm,
NetworkVariableWritePermission writePerm = DefaultWritePerm) : base(value, readPerm, writePerm)
{
Value = value;
}
}
1 自己定义的类继承网络变量【NetworkVariable】
1.1使用自定义的类,构造时会直接报错,新版本的网络变量内部有改动
NetVar<int> nv_hp = new NetVar<int>(); **[1.0版本以前可用]**
NetworkVariable<int> nv_hp = new NetworkVariable<int>(); [1.1、1.2版本可用]
显著的变化在T Value赋值的过程,和对T的限定,变得更加安全
比较值得方法不一样,但是均在值比较之后发生变化才赋值,无变化不触发。
using System;
using System.Runtime.CompilerServices;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
namespace Unity.Netcode
{
[Serializable]
public class NetworkVariable<T> : NetworkVariableBase where T : unmanaged
{
public delegate void OnValueChangedDelegate(T previousValue, T newValue);
public OnValueChangedDelegate OnValueChanged;
[SerializeField]
private protected T m_InternalValue;
public virtual T Value
{
get
{
return m_InternalValue;
}
set
{
if (!ValueEquals(ref m_InternalValue, ref value))
{
if ((bool)m_NetworkBehaviour && !CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId))
{
throw new InvalidOperationException("Client is not allowed to write to this NetworkVariable");
}
Set(value);
}
}
}
public NetworkVariable(T value = default(T), NetworkVariableReadPermission readPerm = NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission writePerm = NetworkVariableWritePermission.Server)
: base(readPerm, writePerm)
{
m_InternalValue = value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static bool ValueEquals(ref T a, ref T b)
{
void* ptr = UnsafeUtility.AddressOf(ref a);
void* ptr2 = UnsafeUtility.AddressOf(ref b);
return UnsafeUtility.MemCmp(ptr, ptr2, sizeof(T)) == 0;
}
private protected void Set(T value)
{
SetDirty(isDirty: true);
T internalValue = m_InternalValue;
m_InternalValue = value;
OnValueChanged?.Invoke(internalValue, m_InternalValue);
}
public override void WriteDelta(FastBufferWriter writer)
{
WriteField(writer);
}
public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
{
T internalValue = m_InternalValue;
NetworkVariableSerialization<T>.Read(reader, out m_InternalValue);
if (keepDirtyDelta)
{
SetDirty(isDirty: true);
}
OnValueChanged?.Invoke(internalValue, m_InternalValue);
}
public override void ReadField(FastBufferReader reader)
{
NetworkVariableSerialization<T>.Read(reader, out m_InternalValue);
}
public override void WriteField(FastBufferWriter writer)
{
NetworkVariableSerialization<T>.Write(writer, ref m_InternalValue);
}
}
}
using System;
using UnityEngine;
namespace Unity.Netcode
{
[Serializable]
public class NetworkVariable<T> : NetworkVariableBase
{
public delegate void OnValueChangedDelegate(T previousValue, T newValue);
public OnValueChangedDelegate OnValueChanged;
[SerializeField]
private protected T m_InternalValue;
public virtual T Value
{
get
{
return m_InternalValue;
}
set
{
if (!NetworkVariableSerialization<T>.AreEqual(ref m_InternalValue, ref value))
{
if ((bool)m_NetworkBehaviour && !CanClientWrite(m_NetworkBehaviour.NetworkManager.LocalClientId))
{
throw new InvalidOperationException("Client is not allowed to write to this NetworkVariable");
}
Set(value);
}
}
}
public NetworkVariable(T value = default(T), NetworkVariableReadPermission readPerm = NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission writePerm = NetworkVariableWritePermission.Server)
: base(readPerm, writePerm)
{
m_InternalValue = value;
}
private protected void Set(T value)
{
SetDirty(isDirty: true);
T internalValue = m_InternalValue;
m_InternalValue = value;
OnValueChanged?.Invoke(internalValue, m_InternalValue);
}
public override void WriteDelta(FastBufferWriter writer)
{
WriteField(writer);
}
public override void ReadDelta(FastBufferReader reader, bool keepDirtyDelta)
{
T internalValue = m_InternalValue;
NetworkVariableSerialization<T>.Read(reader, ref m_InternalValue);
if (keepDirtyDelta)
{
SetDirty(isDirty: true);
}
OnValueChanged?.Invoke(internalValue, m_InternalValue);
}
public override void ReadField(FastBufferReader reader)
{
NetworkVariableSerialization<T>.Read(reader, ref m_InternalValue);
}
public override void WriteField(FastBufferWriter writer)
{
NetworkVariableSerialization<T>.Write(writer, ref m_InternalValue);
}
}
}