C# 如何像Unity中的SyncVar一样同步列表?

C# 如何像Unity中的SyncVar一样同步列表?,c#,unity3d,network-programming,unity5,C#,Unity3d,Network Programming,Unity5,我想在网络上同步列表,就像在Unity中使用SyncVar属性一样。这可能吗 当我们编写一个扩展networkbehavior的类时,它允许我们对变量使用SyncVar: [SyncVar(hook = "OnHealthChange")] public int currentHealth = maxHealth; 同样,是否可以对列表执行类似操作?这不起作用: [SyncVar(hook = "TimeDiff")] public List<RoomPlayerInfo> lis

我想在网络上同步
列表
,就像在Unity中使用
SyncVar
属性一样。这可能吗

当我们编写一个扩展
networkbehavior
的类时,它允许我们对变量使用
SyncVar

[SyncVar(hook = "OnHealthChange")]
public int currentHealth = maxHealth;
同样,是否可以对
列表执行类似操作?这不起作用:

[SyncVar(hook = "TimeDiff")]
public List<RoomPlayerInfo> listRoomPlayerInfo = new List<RoomPlayerInfo> ();
[SyncVar(hook=“TimeDiff”)]
public List listroomplayerfo=新列表();
我尝试了那行代码,但在控制台中显示了以下错误:

错误1:UNetWeaver错误:SyncVar [System.Collections.Generic.List`1 GameManager::listRoomPlayerInfo]不能具有常规参数。 调试:LogError(对象)Unity.UNetWeaver.Log:Error(字符串) (在 C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:20) Unity.UNetWeaver.NetworkBehavior处理器:ProcessSyncVars()(位于 C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetBehaviourProcessor.cs:1838) Unity.UNetWeaver.NetworkBehavior处理器:进程()(位于 C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetBehaviourProcessor.cs:53) Unity.UNetWeaver.Weaver:ProcessNetworkBehavior类型(类型定义) (在 C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1064) Unity.UNetWeaver.Weaver:CheckNetworkBehavior(类型定义)(at C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1549) 统一。不可分割。编织者:编织(弦,IEnumerable`1, IAssemblyResolver,String,String,String)(在 C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1658) 统一。不可分割。编织者:编织组件(IEnumerable`1,IEnumerable`1, IAssemblyResolver,String,String,String)(在 C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1748) Unity.UNetWeaver.Program:Process(字符串,字符串,字符串,字符串[], 字符串[],IAssemblyResolver,操作'1,操作'1)(位于 C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:34) UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(字符串, 字符串,字符串,字符串,布尔值)

错误2:生成网络代码失败。 UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(字符串, 字符串,字符串,字符串,布尔值)

错误3:MissingReferenceException:类型为“object”的对象已被删除 已被销毁,但您仍在尝试访问它。你的剧本 应该检查它是否为null,或者不应该销毁 对象UnityEditor.Editor.IsEnabled()(位于 C:/buildslave/unity/build/Editor/Mono/Inspector/Editor.cs:589) UnityEditor.InspectorWindow.DrawEditor(UnityEditor.Editor编辑器, Int32 editorIndex,布尔重建优化UIBlock,System.Boolean& showImportedObjectBarNext、UnityEngine.Rect和importedObjectBarRect) (在 C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1151) UnityEditor.InspectorWindow.DrawEditors(UnityEditor.Editor[]编辑器) (在 C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1028) UnityEdit.InspectorWindow.OnGUI()(位于 C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:352) System.Reflection.MonMethod.Invoke(System.Object对象,BindingFlags invokeAttr,System.Reflection.Binder活页夹,System.Object[] 参数,System.Globalization.CultureInfo文化)(位于 /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)

从总体上看,这一行似乎非常相关:

只有简单值才能标记为[SyncVars]。SyncVar变量的类型不能来自外部DLL或程序集

因此,通用
列表
不能标记为
SyncVar
,因为它不包含在Unity程序集中。但是,还有其他选项—Unity includes可用于跨网络同步

在您的例子中,听起来您需要
SyncListStruct
集合,它允许您同步用户定义的
struct
实例列表。(当然,这意味着
RoomPlayerInfo
需要是一个
struct
,这可能需要一些代码重写。)

例如,您的代码可能如下所示:

// Define a new class which inherits from the generic SyncListStruct
public class RoomPlayerInfoList : SyncListStruct<RoomPlayerInfo> {}

// [...]

public class PlayerNetworkingScript : NetworkBehaviour
{
    public RoomPlayerInfoList listRoomPlayerInfo = new RoomPlayerInfoList();

    // If necessary, define and attach a callback to the collection for when it changes
    private void RoomPlayerInfoListChanged(Operation op, int itemIndex) {
    }

    void Start() {
        listRoomPlayerInfo.Callback = RoomPlayerInfoListChanged;
    }
}
//定义从通用SyncListStruct继承的新类
公共类RoomPlayerFolist:SyncListStruct{}
// [...]
公共类PlayerNetworkScript:网络行为
{
public RoomPlayerFolist listRoomPlayerInfo=新RoomPlayerFolist();
//如有必要,在集合发生更改时,定义并向集合附加回调
私有void RoomPlayerInfoListChanged(操作op,int itemIndex){
}
void Start(){
listRoomPlayerInfo.Callback=RoomPlayerFolistChanged;
}
}
希望这有帮助!如果你有任何问题,请告诉我