我希望在整个网络中同步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)
答案 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;
}
}
希望这有帮助!如果您有任何问题,请告诉我。