我的目标选择AI是否有效?

时间:2014-06-06 02:53:53

标签: android ios optimization unity3d

快速提问。我正在开发一个自上而下的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;
                }

有更优化的方法吗?非常感谢您的帮助。提前谢谢!

1 个答案:

答案 0 :(得分:1)

我对C#或Unity并不十分熟悉,但我会仔细研究你的排序方法正在使用的排序算法。如果你想要的只是最接近的游戏对象,那么排序是不必要的。

最快的排序算法,例如Quicksort,是O(n*log(n))。也就是说,对n个对象进行排序所需的时间受n*log(n)的一些常数倍的限制。如果您只想要k最近的对象,k << n,那么您可以执行Bubble Sort algorithmk次迭代。这将具有时间复杂度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)