如何在Unity中同步一个像SyncVar一样的列表?

本文关键字:SyncVar 一样 列表 Unity 同步 一个 | 更新日期: 2023-09-27 18:04:38

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

当我们写一个扩展NetworkBehaviour的类时,它允许我们在变量上使用SyncVar:

[SyncVar(hook = "OnHealthChange")]
public int currentHealth = maxHealth;

以同样的方式是否有可能与List做类似的事情?这行不通:

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

错误1:UNetWeaver错误:SyncVar[System.Collections.Generic.List ' 1GameManager::listRoomPlayerInfo]不能有通用参数。UnityEngine.Debug: LogError(对象)Unity.UNetWeaver.Log:错误(字符串)(在C:/buildslave/团结/构建/扩展/网络/编织/Program.cs: 20)(在Unity.UNetWeaver.NetworkBehaviourProcessor: ProcessSyncVars ()C:/buildslave/团结/构建/扩展/网络/编织/UNetBehaviourProcessor.cs: 1838)(在Unity.UNetWeaver.NetworkBehaviourProcessor:过程()C:/buildslave/团结/构建/扩展/网络/编织/UNetBehaviourProcessor.cs: 53)Unity.UNetWeaver.Weaver: ProcessNetworkBehaviourType (TypeDefinition)(在C:/buildslave/团结/构建/扩展/网络/编织/UNetWeaver.cs: 1064)Unity.UNetWeaver.Weaver: CheckNetworkBehaviour (TypeDefinition) (C:/buildslave/团结/构建/扩展/网络/编织/UNetWeaver.cs: 1549)Unity.UNetWeaver。韦弗:编织(字符串,IEnumerable"1,IAssemblyResolver, String, String, StringC:/buildslave/团结/构建/扩展/网络/编织/UNetWeaver.cs: 1658)Unity.UNetWeaver。韦弗:WeaveAssemblies (IEnumerable 1 IEnumerable 1,IAssemblyResolver, String, String, StringC:/buildslave/团结/构建/扩展/网络/编织/UNetWeaver.cs: 1748)Unity.UNetWeaver。程序:进程(字符串,字符串,字符串,字符串[],字符串[],IAssemblyResolver,动作' 1,动作' 1)(atC:/buildslave/团结/构建/扩展/网络/编织/Program.cs: 34)UnityEditor.Scripting.Serialization.Weaver: WeaveUnetFromEditor(字符串,String, String, String, Boolean)

Error2: failed generated network code。UnityEditor.Scripting.Serialization.Weaver: WeaveUnetFromEditor(字符串,String, String, String, Boolean)

Error3: MissingReferenceException: object类型的对象有已经被摧毁了,但你还在试图访问它。你的脚本是否应该检查它是否为空,或者不应该销毁对象。unityeeditor . editor . isenabled (C:/buildslave/团结/构建/编辑/Mono/检查/Editor.cs: 589)UnityEditor.InspectorWindow.DrawEditor (UnityEditor。编辑器编辑,Int32 editorIndex, Boolean, rebuildOptimizedGUIBlock, system .Boolean& &;showImportedObjectBarNext UnityEngine.Rect&importedObjectBarRect)(在C:/buildslave/团结/构建/编辑/Mono/检查/InspectorWindow.cs: 1151)UnityEditor.InspectorWindow.DrawEditors (UnityEditor。编辑器[]编辑)(在C:/buildslave/团结/构建/编辑/Mono/检查/InspectorWindow.cs: 1028)unityeitor . inspectorwindow . ongui (C:/buildslave/团结/构建/编辑/Mono/检查/InspectorWindow.cs: 352)System.Reflection.MonoMethod.Invoke(系统。对象obj,绑定标志绑定器,绑定器,系统。对象[]参数,System.Globalization.CultureInfo/用户/builduser/buildslave/mono/构建/mcs/类/corlib/System.Reflection/MonoMethod.cs: 222)

如何在Unity中同步一个像SyncVar一样的列表?

查看SyncVar的文档,这一行似乎非常相关:

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

因此,一个通用的List不能被标记为SyncVar,因为它不包含在Unity程序集中。然而,还有其他的选择——Unity包含了几种可以用于跨网络同步的集合类型。

在您的示例中,听起来您需要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;
    }
}

希望这对你有帮助!如果您有任何问题,请告诉我。