C# 优化GameObject唯一ID赋值器统一性

C# 优化GameObject唯一ID赋值器统一性,c#,algorithm,unity3d,optimization,C#,Algorithm,Unity3d,Optimization,最近我正在为我的多人游戏开发门系统,我的门ID(指定与哪个门交互)有问题。我想避免手动分配ID,因为我的游戏有很多门,所以我找到了一个解决方案-而不是不可靠的FindObjectsOfType,我构建了以下场景循环器: void迭代场景(场景场景) { SortedList sortedObjects=新SortedList(); //List audioListeners=新列表(); foreach(场景中的GameObject场景对象。GetRootGameObjects()) { for

最近我正在为我的多人游戏开发门系统,我的门ID(指定与哪个门交互)有问题。我想避免手动分配ID,因为我的游戏有很多门,所以我找到了一个解决方案-而不是不可靠的FindObjectsOfType,我构建了以下场景循环器:

void迭代场景(场景场景)
{
SortedList sortedObjects=新SortedList();
//List audioListeners=新列表();
foreach(场景中的GameObject场景对象。GetRootGameObjects())
{
foreach(场景对象GetComponentsInChildren()中的NetworkedObject netObj)
{
Vector3位置=netObj.transform.position;
字符串transformHash=position.x.ToString(“0.00”)+position.y.ToString(“0.00”)+position.z.ToString(“0.00”);
transformHash=Hashing.MD5(transformHash);
sortedObjects.Add(transformHash,netObj);
//CrossSceneAudioSyncListener audioListener=netObj.GetComponent();
//if(audioListener!=null)audioListener.Add(audioListener);
}
}
//加载对象(音频监听器);
Dictionary preparedObjects=新字典();
ushort lastId=_id[scene.name];
foreach(分拣对象中的var部分)
{
NetworkedObject preparedObject=part.Value;
preparedObject.GetObjectData().id=lastId;
preparedObjects[lastId]=preparedObject;
lastId++;
}
_id[scene.name]=lastId;
_registeredObjects[scene.name]=准备对象;
}
我在这里一步一步地列出了此方法的作用:

  • SortedList被实例化以保存对象
  • 2个foreach正在获取场景中的所有对象
    • 在这里,脚本生成位置的MD5并将其添加到SortedList
  • 然后,创建Dictionary实例来保存最终数据
  • 下一步foreach完成后,循环浏览SortedList并以可靠的方式分配NetworkedObject ID
这在中小型场景中做得很好,但我开始在大型场景中遇到严重问题-我有一台很好的电脑&它需要12秒,我的游戏目标是中型电脑


那么,您知道如何优化此算法吗?

由于我不知道
FindObjectsOfType
的内部结构,因此很难将此方法与您的代码片段进行比较。但是,您确实提到了顺序问题,并且由于
FindObjectsOfType
不能保证以任何特定顺序返回对象,因此它不适用于您的用例

要优化代码段,您需要以某种方式删减搜索。当您查看所有根游戏对象时,您可以用每个根对象作为子对象的门数来标记每个根对象,并为每个根对象保留一个计数器。这样,一旦您达到从子对象发送的所需数量,它就可以停止搜索该根对象


但是,由于您似乎只想将有序ID指定给场景中的对象以供参考,因此我建议使用编辑器工具来处理指定。代码几乎相同,但优点是不需要考虑运行时的开销,因为它是在游戏之外计算的。在使用任何修改场景的编辑器工具时,请确保Unity会保存更改。

您能否不标记所有门并使用它们。我不知道内部
FindObjectsOfType
是如何工作的,因此我无法比较此代码的有效性。我能想象的唯一能让搜索更有效的地方就是修剪。在场景中循环遍历每个对象,然后获取每个具有组件的子对象。您可以使doors将所有根父级标记为具有一个doors,以便于查找。FindObjectOfType不是一种可靠的方法。它可能会以不同的顺序返回对象,这是不可接受的,有时我没有选择&需要使用child对象,或者不要在大海捞针,而是告诉别人让针告诉你它自己。您可以让门获取门管理器的引用,然后让门管理器在调用函数时分配ID,或者使用静态实例实现。它不保存值是什么意思?你很可能不是。如果您确实需要在运行时执行此操作,请创建一个异步加载屏幕,并在需要时将其抛出。我建议你把它扔掉,让编辑器工具工作起来。@teebkne感谢MarkSceneDirty!现在编辑器脚本按预期工作!这个算法现在是无用的。