2016-08-30 2 views
1

Я хочу синхронизировать List по сети, например, при использовании атрибута SyncVar в Unity. Можно ли это сделать?Как синхронизировать список как SyncVar в Unity?

Когда мы пишем класс, который расширяет NetworkBehaviour это позволяет использовать SyncVar по переменным:

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

В этом же образом можно сделать что-то подобное с List? Это не работает:

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

Я попробовал эту строку кода, но он показал мне следующую ошибку в консоли:

Error 1: UNetWeaver error: SyncVar [System.Collections.Generic.List`1 GameManager::listRoomPlayerInfo] cannot have generic parameters. 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, 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, String, Boolean)

Error2: Failure generating network code. 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. Your script should either check if it is null or you should not destroy the object. 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)

ответ

1

Глядя на documentation for SyncVar, эта линия кажется вполне уместным:

Only simple values can be marked as [SyncVars]. The type of the SyncVar variable cannot be from an external DLL or assembly.

Как таковой, общий 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; 
    } 
} 

Надеется, что это помогает! Дайте знать, если у вас появятся вопросы.

Смежные вопросы