如何在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)
查看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;
}
}
希望这对你有帮助!如果您有任何问题,请告诉我。