【问题标题】:Return Object to pool将对象返回池
【发布时间】:2015-07-02 01:29:09
【问题描述】:

我正在制作无限公路游戏。我正在将对象池用于道路和敌方对象。道路运行良好,但我遇到了敌人的问题,我可以从池中添加敌人,但我不能将敌人的物体返回到池中。

public void CreateEnemy( EnemyPool pool, int roadLenght, Vector3 startPos , int numberOfEnemies, int enemyType )
    {
        enemy = new Transform[numberOfEnemies];
        enemyIndex = new int[numberOfEnemies];

        currentRoadLenght = roadLenght;
        //I add enemies along the length of the path. Path Lenght is randomly generated.
        currentEnemyNumber = numberOfEnemies;

        int arrayedEnemyObject = 0;

        for( int i = 0; i < roadLenght; i++ )
        {
            Vector3 pos = startPos + new Vector3(0, 1, i * 15);

            for( int j = 0; j < numberOfEnemies; j++ )
            {
                Transform obj = pool.PullEnemyFromPool(enemyType);
                obj.position = pos;
                obj.gameObject.SetActive(true);

                enemy[j] = obj;
                enemyIndex[j] = enemyType;
                Debug.Log(j);

                pos.z += 3;
                arrayedEnemyObject++;
            }

            if( arrayedEnemyObject == numberOfEnemies )
            {
                arrayedEnemyObject = 0;
                i += enemyObjectDistance;
            }
        }
    }

    public void DestroyEnemy( EnemyPool objectPooler )
    {   
        if (enemy != null) 
        {
            int destroyedObj = 0;

            for( int i = 0; i < currentRoadLenght; i++ )
            {
                for( int j = 0; j < currentEnemyNumber; j++ )
                {
                    Transform obj = enemy[j];
                    obj.gameObject.SetActive( false );
                    objectPooler.AddEnemyToPool( enemyIndex[j], obj );

                    destroyedObj++;
                }

                if( destroyedObj == currentEnemyNumber )
                {
                    destroyedObj = 0;
                    i += enemyObjectDistance;
                }
            }

            enemy = null;
        }
    }

我的敌人池脚本

public class EnemyPool : MonoBehaviour 
{
    private GameObject[] enemyObjects;
    private List<Transform>[] enemyObjectsPool;

    public void FillPool( GameObject[] enemyObjects , int size )
    {
        this.enemyObjects = enemyObjects;

        Vector3 pos = Vector3.zero;
        Quaternion tilt = Quaternion.identity;
        GameObject obj;

        enemyObjectsPool = new List<Transform>[enemyObjects.Length];

        for ( int i = 0; i < enemyObjects.Length; i++ ) 
        {
            enemyObjectsPool[i] = new List<Transform>();

            for( int j = 0; j < size; j++ )
            {
                obj = Instantiate( enemyObjects[i], pos, tilt ) as GameObject;
                obj.SetActive( false );
                enemyObjectsPool[i].Add( obj.transform );
            }
        }
    }

    public void AddEnemyToPool( int index, Transform obj )
    {
        enemyObjectsPool[index].Add (obj);
    }

    public Transform PullEnemyFromPool( int index )
    {
        Transform obj;

        if( enemyObjectsPool[index].Count <= 0 )
        {
            obj = ( Instantiate( enemyObjects[index], Vector3.zero, Quaternion.identity ) as GameObject ).transform;
        }
        else
        {
            obj = enemyObjectsPool[index][0];
            enemyObjectsPool[index].RemoveAt (0);
        }

        return obj;
    }

}

【问题讨论】:

  • 有什么问题?你有例外吗?
  • 不,不能销毁对象。

标签: c# unity3d object-pooling


【解决方案1】:

您为什么要在添加和删除时迭代道路长度。这可能就是你的问题所在。您在数组中多次设置相同的项目。您正在为每条道路从池中拉出一个项目,并将其放在同一个插槽中。

for (int i = 0; i < roadCount; i++)
    enemy[j] = pullObject;

外部循环可能是罪魁祸首。

此外,在您的池中,使用队列而不是列表可能会有所帮助。 queues专门用于从前面移除item,会比RemoveAt(0)效率更高

编辑:

好吧......这有点难以解释,但你的外循环可能没有做你认为它正在做的事情。你所有的外循环正在做的是确保你重复你的内循环 roudcount 次数。假设你的道路长度为 3,敌人数量为 2。

这就是你的程序正在做的事情:

pos = startPos + new Vector3(0,1,0);
obj.position = pos;
enemy[0] = obj;
pos.z += 3;
arrayedEnemeyObject++;
obj.position = pos;
enemy[1] = obj;
pos.z += 3;
arrayedEnemeyObject++;
arrayedEnemeyObject = 0;
i += enemyObjectDistance;
pos = startPos + new Vector3(0,1,15);
obj.position = pos;
enemy[0] = obj;
pos.z += 3;
arrayedEnemeyObject++;
obj.position = pos;
enemy[1] = obj;
pos.z += 3;

注意enemy[0] 是如何被设置两次的。我仍然不知道 roaddistance 是什么意思,因为你的外环没有做任何事情。我……猜,这就是你想要的……但我真的不知道

enemy[,] = new Transform[roadCount, numberOfEnemies];
enemyIndex[,] = new int[roadCount, numberOfEnemies];

然后在你的内部循环中:

enemy[i,j] = obj;

【讨论】:

  • 新错误,所有对象都在破坏。我想在我经过的路上消灭敌人。
  • 似乎没有任何逻辑将对象与道路相关联。您可能需要一个二维数组。敌人[i,j] 可能更有意义。目前,您只是在每条道路上迭代和设置/删除相同的敌人一次。我也不确定i += enemyObjectDistance; 应该做什么,但看起来很危险。
  • 您对i += enemyObjectDistance; 有其他想法吗?
  • i 目前没有用于任何用途。我也不知道enemyobjectdistance 应该是什么...不
  • 你真棒!!! [i , j] 索引是个好主意,它很有效,非常感谢。
猜你喜欢
  • 1970-01-01
  • 2019-11-11
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多