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

时间:2016-08-30 13:22:14

标签: c# unity3d network-programming unity5

我希望在整个网络中同步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`1   GameManager :: listRoomPlayerInfo]不能有通用参数。   UnityEngine.Debug:LogError(Object)Unity.UNetWeaver.Log:错误(字符串)   (在   C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:20)   Unity.UNetWeaver.NetworkBehaviourProcessor:ProcessSyncVars()(at   C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetBehaviourProcessor.cs:1838)   Unity.UNetWeaver.NetworkBehaviourProcessor:Process()(at   C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetBehaviourProcessor.cs:53)   Unity.UNetWeaver.Weaver:ProcessNetworkBehaviourType(类型定义)   (在   C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1064)   Unity.UNetWeaver.Weaver:CheckNetworkBehaviour(TypeDefinition)(at   C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1549)   Unity.UNetWeaver.Weaver:Weave(String,IEnumerable`1,   IAssemblyResolver,String,String,String)(at   C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1658)   Unity.UNetWeaver.Weaver:WeaveAssemblies(IEnumerable`1,IEnumerable`1,   IAssemblyResolver,String,String,String)(at   C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1748)   Unity.UNetWeaver.Program:Process(String,String,String,String [],   String [],IAssemblyResolver,Action`1,Action`1)(at   C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:34)   UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(字符串,   String,String,String,Boolean)

     

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

     

Error3:MissingReferenceException:类型&#39;对象&#39;具有   被摧毁但你还在试图访问它。你的脚本   应该检查它是否为空或你不应该销毁   宾语。 UnityEditor.Editor.IsEnabled()(at   C:/buildslave/unity/build/Editor/Mono/Inspector/Editor.cs:589)   UnityEditor.InspectorWindow.DrawEditor(UnityEditor.Editor编辑器,   Int32 editorIndex,Boolean rebuildOptimizedGUIBlock,System.Boolean&amp;   showImportedObjectBarNext,UnityEngine.Rect&amp; 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)   UnityEditor.InspectorWindow.OnGUI()(at   C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:352)   System.Reflection.MonoMethod.Invoke(System.Object obj,BindingFlags   invokeAttr,System.Reflection.Binder binder,System.Object []   参数,System.Globalization.CultureInfo文化)(at   /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222)

1 个答案:

答案 0 :(得分:2)

查看documentation for SyncVar,这一行似乎很相关:

  

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

因此,通用List无法标记为SyncVar,因为它不包含在Unity程序集中。但是,还有其他选项 - Unity包括several collection types,可用于在网络中进行同步。

在您的情况下,听起来您需要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;
    }
}

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