快速提问。我正在开发一个自上而下的2d平台游戏,在地图中有很多敌人(每个级别的开始至少有一百个生成)。每个敌人使用AI在地图上搜索具有指定标记的对象,根据距离将每个对象分类到一个列表中,然后对最接近它们的对象作出反应。
我的代码有效,但问题是,如果我的游戏运行的机器很慢,那么我的游戏就会滞后。我希望能够将我的游戏移植到具有低端规格的Android和iOS。
为了减少对CPU的压力,有没有更好的方法来编写我的AI?
这是我的代码:
void Start () {
FoodTargets = new List<Transform>(); // my list
SelectedTarget = null; // the target the enemy reacts to
myTransform = transform;
AddAllFood ();
}
public void AddAllFood()
{
GameObject[] Foods = GameObject.FindGameObjectsWithTag("Object");
foreach (GameObject enemy in Foods)
AddTarget (enemy.transform);
}
public void AddTarget(Transform enemy)
{
if (enemy.GetComponent<ClassRatingScript>().classrating != 1) { // classrating is an attribute each enemy has that determines their identity (like if they are a plant, a herbivore or a carnivore)
FoodTargets.Add (enemy); // adds the object to the list
}
}
private void SortTargetsByDistance() // this is how I sort according to distance, is this the fastest and most efficient way to do this?
{
FoodTargets.Sort (delegate(Transform t1, Transform t2) {
return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
});
}
private void TargetEnemy() // this is called every 4 frames
{
if (SelectedTarget == null) {
SortTargetsByDistance ();
SelectedTarget = FoodTargets [1];
}
else {
SortTargetsByDistance ();
SelectedTarget = FoodTargets [1];
}
}
if (optimizer <= 2) { // this is a variable that increments every frame and resets to 0 on the 3rd frame. Only every 3rd frame is the target enemy method is called.
optimizer++;
} else {
TargetEnemy ();
// the rest are attributes that the AI considers when reacting to their target
targetmass = SelectedTarget.GetComponent<MassScript> ().mass;
targetclass = SelectedTarget.GetComponent<ClassRatingScript> ().classrating;
mass = this.GetComponent<MassScript> ().mass;
classrating = this.GetComponent<ClassRatingScript> ().classrating;
distance = Vector3.Distance (transform.position, SelectedTarget.transform.position);
optimizer = 0;
}
有更优化的方法吗?非常感谢您的帮助。提前谢谢!
答案 0 :(得分:1)
我对C#或Unity并不十分熟悉,但我会仔细研究你的排序方法正在使用的排序算法。如果你想要的只是最接近的游戏对象,那么排序是不必要的。
最快的排序算法,例如Quicksort,是O(n*log(n))
。也就是说,对n
个对象进行排序所需的时间受n*log(n)
的一些常数倍的限制。如果您只想要k
最近的对象,k << n
,那么您可以执行Bubble Sort algorithm的k
次迭代。这将具有时间复杂度O(k*n)
,这比以前好多了。
但是,如果您只需要最近的单个对象,那么只需找到最近的对象而不进行排序(伪代码):
float smallestDistance = Inf;
object closestObject = null;
foreach object in objectsWithTag {
float d = distance(object, enemy);
if (d < smallestDistance) {
smallestDistance = d;
closestObject = object;
}
}
这种极其简单的算法具有时间复杂度O(n)
。