[英]Efficient For Loops Unity C#
我正在统一运行机器人模拟,其中 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)?
一般来说,不是每个机器人 36 次投射,你不能只使用Physics.OverlapSphere
可能已经减少了很多,因为重叠球体很容易为物理引擎计算( if(distance < sphereRadius)
)
然后,在您的情况下会花费很多性能的一件事可能是Contains
on a List
。 在那里你应该使用HashSet
。 请参阅Performance List vs HashSet了解您的 300 个可能值得的对象。
或者对我来说,听起来你想知道哪些其他机器人靠近那个......你可以在某个层上给每个机器人一个SphereCollider
,这样它们只会相互碰撞,让它成为触发器并将它们存储在OnTriggerEnter
并在OnTriggerExit
中删除它们。
有没有办法在不访问其组件的情况下访问 GameObject 特定数据(如 ID)?
好吧,是的,您可以访问GameObject
特定数据,例如.name
。 但是该ID
显然不是特定于GameObject
的东西,而是在您的RobotControl
class 中,所以,不,没有真正的解决方法GetComponent
。
然而,在较新的 Unity 版本中, GetComponent
不再那么昂贵,因为引用在编辑时被散列和序列化。
问题是你真的需要那个 ID 列表还是仅仅保存对撞机/游戏对象引用并仅在真正需要时访问特定组件就足够了?
在您的特定情况下, Debug.DrawRay
也是非常昂贵的东西,您不应该经常这样做并且可能300 * 299
次;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.