【问题标题】:Efficient For Loops Unity C#高效的 For 循环 Unity C#
【发布时间】:2020-12-20 14:43:00
【问题描述】:

我正在统一运行机器人模拟,其中 300 个机器人中的每一个都运行相同的脚本,并且我使用 RayCast 进行机器人之间的通信。每个机器人每 0.02 秒以 10 度增量投射 36 条光线,覆盖所有 360 度。这是使用RaycastCommand 完成的,因此它是并行完成的,不会导致任何性能问题。尝试处理 RayCast 数据时会出现问题。

我需要遍历每个结果并比较每个机器人脚本中的标签和 ID:

for(int k =0; k< results.Length; k++) // For every result
{
    if(results[k].collider !=null) // Check if RayCast collision happened
    {

        if(results[k].collider.tag == "Robot") // Check that collision is with robot 
        {
            var ID = results[k].collider.GetComponent<RobotControl>().ID;  // Get The robot ID  
            if(!listID.Contains(ID))   // Check that it hasnt comunicated with that robot yet 
            {
                listID.Add(ID);
                Debug.DrawRay(origin + (0.55f* Directions[k]), Directions[k] * results[k].distance , new Color(Directions[k].x, Directions[k].y, Directions[k].z, 1));
                // Grab important info here 
            }
        }
    }
}

主要问题是我无法使用IJobParallelFor,因为我正在访问对撞机并尝试读取标签,这是代码中降低我性能的部分,因为其他所有操作都是使用并行作业完成的。真正的问题是访问组件的成本很高。

关于如何使其更高效或以某种方式并行化的任何想法?

有没有办法访问GameObject 特定数据,例如 ID,而不访问它们的组件?

【问题讨论】:

    标签: c# for-loop unity3d parallel-processing simulation


    【解决方案1】:

    一般来说,不是每个机器人 36 次投射,你不能只使用 Physics.OverlapSphere 可能已经减少了很多,因为重叠球体很容易为物理引擎计算 (if(distance &lt; sphereRadius))


    那么,在您的情况下,会耗费大量性能的一件事可能是 ContainsList 上。在那里你应该使用HashSet。请参阅 Performance List vs HashSet 了解您的 300 件可能值得的物品。


    或者对我来说,听起来你想知道哪些其他机器人与那个机器人很接近......你可以在某个层上给每个机器人一个SphereCollider,这样它们只会相互碰撞,让它成为触发器并将它们存储在OnTriggerEnter 并在OnTriggerExit 中删除它们。


    有没有办法在不访问其组件的情况下访问 GameObject 的特定数据(例如 ID)?

    嗯,是的,您可以访问 GameObject 特定数据,例如.name。但是 ID 显然不是 GameObject 特定的东西,而是在你的 RobotControl 类中,所以,不,没有办法绕过 GetComponent

    但是,在较新的 Unity 版本中,GetComponent 不再那么昂贵,因为引用在编辑时被散列和序列化。

    问题是你真的需要那个 ID 列表,还是仅仅保存对撞机/游戏对象引用并仅在真正需要时访问特定组件就足够了?


    在你的具体情况下,Debug.DrawRay 也是非常昂贵的东西,你不应该经常这样做,并且可能会在300 * 299 次;)

    【讨论】:

    • 我试图模仿真实机器人中的红外传感器,至于为什么RayCast。我还使用RayCast 来避开墙壁和其他机器人并检查物体,所以我可能会保持这种方式以实现真实感。我将尝试使用HashSetSphereCollider 进行通信,就像以前一样,我没有框架问题。我也在没有Debug.DrawRay() 的情况下进行了测试,但仍然很糟糕。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 2019-05-14
    • 2012-04-12
    • 2022-11-10
    • 2013-02-16
    • 2021-01-10
    • 2022-01-26
    相关资源
    最近更新 更多