简体   繁体   English

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

[英]How can I synchronize a List like a SyncVar in Unity?

I want to synchronize a List across the network like when using the SyncVar attribute in Unity. SyncVar在Unity中使用SyncVar属性一样在网络上同步List Is that possible to do? 那有可能吗?

When we write a class that extends NetworkBehaviour it allows us to use SyncVar on variables: 当我们编写扩展NetworkBehaviour的类时,它允许我们对变量使用SyncVar

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

In same way is it possible to do something similar with a List ? 用同样的方式可以对List做类似的事情吗? This doesn't work: 这不起作用:

[SyncVar(hook = "TimeDiff")]
public List<RoomPlayerInfo> listRoomPlayerInfo = new List<RoomPlayerInfo> ();

I tried that line of code but it showed me the following error in console: 我尝试了该行代码,但在控制台中向我显示了以下错误:

Error 1: UNetWeaver error: SyncVar [System.Collections.Generic.List`1 GameManager::listRoomPlayerInfo] cannot have generic parameters. 错误1:UNetWeaver错误:SyncVar [System.Collections.Generic.List`1 GameManager :: listRoomPlayerInfo]不能具有通用参数。 UnityEngine.Debug:LogError(Object) Unity.UNetWeaver.Log:Error(String) (at 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(TypeDefinition) (at 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, St UnityEngine.Debug:LogError(Object)Unity.UNetWeaver.Log:Error(String)(在C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:20)Unity.UNetWeaver.NetworkBehaviourProcessor:ProcessSyncVars() (在C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetBehaviourProcessor.cs:1838)Unity.UNetWeaver.NetworkBehaviourProcessor:Process()(在C:/ buildslave / unity / build / Extensions / Networking / Weaver / UNetBehaviourProcessor .cs:53)Unity.UNetWeaver.Weaver:ProcessNetworkBehaviourType(TypeDefinition)(在C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1064)Unity.UNetWeaver.Weaver:CheckNetworkBehaviour(TypeDefinition)(在C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1549)Unity.UNetWeaver.Weaver:Weave(String,IEnumerable`1,IAssemblyResolver,String,String,String)(在C:/ buildslave / unity / build / Extensions / Networking / Weaver / UNetWeaver.cs:1658)Unity.UNetWeaver.Weaver:WeaveAssemblies(IEnumerable`1,IEnumerable`1,IAssemblyResolver,String,St ring, 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, String, Boolean) 环形字符串)(位于C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1748)Unity.UNetWeaver.Program:Process(String,String,String,String [],String [],IAssemblyResolver ,动作1,动作1)(位于C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:34)UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(String,String,String,String,布尔)

Error2: Failure generating network code. 错误2:生成网络代码失败。 UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(String, String, String, String, Boolean) UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(String,String,String,String,Boolean)

Error3: MissingReferenceException: The object of type 'Object' has been destroyed but you are still trying to access it. 错误3:MissingReferenceException:类型为“对象”的对象已被破坏,但您仍在尝试访问它。 Your script should either check if it is null or you should not destroy the object. 您的脚本应检查其是否为null或不破坏该对象。 UnityEditor.Editor.IsEnabled () (at C:/buildslave/unity/build/Editor/Mono/Inspector/Editor.cs:589) UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1151) UnityEditor.InspectorWindow.DrawEditors (UnityEditor.Editor[] editors) (at 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[] parameters, System.Globalization.CultureInfo culture) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222) UnityEditor.Editor.IsEnabled()(在C:/buildslave/unity/build/Editor/Mono/Inspector/Editor.cs:589)UnityEditor.InspectorWindow.DrawEditor(UnityEditor.Editor编辑器,Int32 editorIndex,布尔值rebuildOptimizedGUIBlock,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)UnityEditor.InspectorWindow.OnGUI()(在C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:352)System.Reflection。 MonoMethod.Invoke(System.Object obj,BindingFlags invokeAttr,System.Reflection.Binder绑定器,System.Object []参数,System.Globalization.CultureInfo文化)(在/ Users / builduser / buildslave / mono / build / mcs / class / corlib /的System.Reflection / MonoMethod.cs:222)

Looking at the documentation for SyncVar , this line seems quite relevant: 查看SyncVar文档 ,这一行似乎很相关:

Only simple values can be marked as [SyncVars]. 只能将简单值标记为[SyncVars]。 The type of the SyncVar variable cannot be from an external DLL or assembly. SyncVar变量的类型不能来自外部DLL或程序集。

As such, a generic List can't be marked as a SyncVar , because it's not contained within the Unity assembly. 因此,通用List不能标记为SyncVar ,因为它不包含在Unity程序SyncVar However, there are other options - Unity includes several collection types that can be used for synchronizing across the network. 但是,还有其他选项-Unity包含几种可用于跨网络同步的集合类型

In your case, it sounds like you need the SyncListStruct collection, which allows you to synchronize a list of user-defined struct instances. 在您的情况下,听起来好像需要SyncListStruct集合,该集合可让您同步用户定义的struct实例的列表。 (Of course, that means RoomPlayerInfo needs to be a struct , which may entail a bit of code rewrite.) (当然,这意味着RoomPlayerInfo需要是一个struct ,这可能需要重写一些代码。)

For example, your code might look like: 例如,您的代码可能如下所示:

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

Hope this helps! 希望这可以帮助! Let me know if you have any questions. 如果您有任何疑问,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM