Reputation: 926
I am making infinity road game. I am using object pooling for roads and enemy objects. roads is working well but I have problem with enemy objects, I can add enemy from pool but I cant return back enemy objects to pool.
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;
}
}
My EnemyPoolScript
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;
}
}
Upvotes: 1
Views: 647
Reputation: 376
Why are you itterating over road length in your adds and deletes. that's probably where your problem lies. you're setting the same item in your array multiple times. you are pulling an item out of your pool for every road, and putting it in the same slot.
for (int i = 0; i < roadCount; i++)
enemy[j] = pullObject;
the outer loop is probably the culprit.
Also, in your pool, it might help to use a queue instead of a list. queues are specifically used for removing items from the front, which will be more efficient than RemoveAt(0)
Edit:
okay... it's a bit hard to explain, but your outerloop probably isn't doing what you think it's doing. all your outer loop is doing is making sure you repeat your inner loop roudcount number of times. lets pretend you have a road length of 3, and a number of enemies of 2.
This is what your program is doing:
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;
Notice how enemy[0] gets set twice. i still don't know what roaddistance is meant to do, because your outerloop isn't doing anything. i'm... guessing, this is what you want... but i really don't know
enemy[,] = new Transform[roadCount, numberOfEnemies];
enemyIndex[,] = new int[roadCount, numberOfEnemies];
then in your inner loop:
enemy[i,j] = obj;
Upvotes: 3