Saj*_*ake 3 c# unity-game-engine unityscript gameobject
从这两种方法中获得最接近目标的最有效和最便宜的方法是什么?
使用LINQ
GameObject FindClosestTarget(string trgt)
{
GameObject[] closestGameObject = GameObject.FindGameObjectsWithTag(trgt)
.OrderBy(go => Vector3.Distance(go.transform.position, transform.position)
.FirstOrDefault();
return closestGameObject ;
}
Run Code Online (Sandbox Code Playgroud)
或这个
GameObject FindClosestTarget(string trgt)
{
GameObject[] gos= GameObject.FindGameObjectsWithTag(trgt);
GameObject closest=null;
float distance = Mathf.Infinity;
Vector3 position = transform.position;
foreach (GameObject go in gos) {
Vector3 diff = go.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance < distance) {
closest = go;
distance = curDistance;
}
}
return closest;
}
Run Code Online (Sandbox Code Playgroud)
第一个示例使用Vector3.Distance
需要非常昂贵的Sqrt
操作,而第二个使用代码我更喜欢抛出更简单的LINQ形式.
以下是Unity Scripting API文档的摘录sqrMagnitude
:
矢量v的大小计算为
Mathf.Sqrt(Vector3.Dot(v, v))
.但是,Sqrt
计算非常复杂,执行时间比正常的算术运算要长.计算平方幅度而不是使用幅度属性要快得多 - 只有没有慢速Sqrt
调用,计算基本相同.如果您仅使用幅度来比较距离,那么您也可以将平方幅度与距离的平方进行比较,因为比较将给出相同的结果.
因此,您的场景基本上就是他们创建sqrMagnitude
属性的原因...因为Sqrt
如果您只是想知道距离的顺序而不需要以后使用的实际距离,则您不需要这种昂贵的操作.
我个人更喜欢这个作为第三种选择:
GameObject FindClosestTarget(string trgt)
{
Vector3 position = transform.position;
return GameObject.FindGameObjectsWithTag(trgt)
.OrderBy(o => (o.transform.position - position).sqrMagnitude)
.FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
两个世界中最好的...... LINQ的简单性(以及非常有效的实现)没有多余的Sqrt
操作来减慢你的速度.
但与往常一样,当您对代码的实际性能有疑问时,您应该对每种方法进行一些仔细的分析,以确定哪种方法实际上表现更好.有时优化器会抛出一个曲线球并将可怕的C#代码转换为非常有效的输出.
顺便提一下,如果你想将你的范围限制在一个特定的最大距离,将该距离平方并将其与之比较sqrMaginitude
以避免邪恶Sqrt
.
归档时间: |
|
查看次数: |
5798 次 |
最近记录: |