I am building a top down 2D plane game for practice. Here, enemy has an AI script attached. AI script does the following :
- Determine whether the object is spawned to the left or right of screen.
- If spawned to the left, rotate object by -90, move till a certain x position is reached, then turn down.
- If spawned to the right, rotate object by 90, move till a certain x position is reached, then turn down.
This works when I'm using Instantiate - Destroy method. But causes inconsistent behavior when I implement object pooling. Inconsistent behavior as in, 1>Planes are spawned, 2>Instead of moving a certain distance horizontally, they just turn down and move downwards. Sometimes they behave as intended, but other times, inconsistenct behavior.
Here is the AI script:
public class AI : MonoBehaviour
{
float angle;
Vector2 vel, turnVel;
Rigidbody2D rb;
bool leftSpawn, rightSpawn;
void OnEnable ()
{
transform.rotation = Quaternion.Euler (Vector3.zero);
rb = GetComponent<Rigidbody2D> ();
turnVel = new Vector2 (0, -0.5f);
if (transform.position.x < 0) {
leftSpawn = true;
transform.Rotate (0, 0, -90);
vel = new Vector2 (1, 0);
}
if (transform.position.x > 0) {
rightSpawn = true;
transform.Rotate (0, 0, 90);
vel = new Vector2 (-1, 0);
}
}
void Update ()
{
if (leftSpawn && transform.position.x < -0.8f)
rb.velocity = vel;
if (rightSpawn && transform.position.x > 0.8f) {
rb.velocity = vel;
}
if (rightSpawn && transform.position.x <= 0.8f) {
rb.velocity = turnVel;
angle = Mathf.LerpAngle (90, 180, Time.time * 0.9f);
transform.eulerAngles = new Vector3 (0, 0, angle);
}
if (leftSpawn && transform.position.x > -0.8f) {
rb.velocity = turnVel;
angle = Mathf.LerpAngle (-90, -180, Time.time * 0.9f);
transform.eulerAngles = new Vector3 (0, 0, angle);
}
}
}
Here is the spawning script that doesn't use Pooling. This works fine.
public class EnemySpawner : MonoBehaviour
{
int turn = 0;
public GameObject BF, JU, cam, Hawker, Blenheim;
void Start ()
{
InvokeRepeating ("SpawnEnemy", 0, 3);
}
void SpawnEnemy ()
{
turn = Random.Range (1, 5);
if (turn == 1)
SpawnBF ();
else if (turn == 2)
SpawnJU ();
else if (turn == 3)
SpawnHawker ();
else if (turn == 4)
SpawnBlenheim ();
}
void SpawnHawker ()
{
float x = -4.47f, y;
y = cam.transform.position.y + 4.59f;
Vector3 pos = new Vector3 (x, y, 1);
GameObject obj = (GameObject)Instantiate (Hawker, pos, Quaternion.identity);
}
void SpawnBlenheim ()
{
float x = 4.39f, y;
y = cam.transform.position.y + 4.59f;
Vector3 pos = new Vector3 (x, y, 1);
GameObject obj = (GameObject)Instantiate (Blenheim, pos, Quaternion.identity);
}
void SpawnBF ()
{
float x = -4.47f, y;
y = cam.transform.position.y + 4.59f;
Vector3 pos = new Vector3 (x, y, 1);
GameObject obj = (GameObject)Instantiate (BF, pos, Quaternion.identity);
}
void SpawnJU ()
{
float x = 4.39f, y;
y = cam.transform.position.y + 4.59f;
Vector3 pos = new Vector3 (x, y, 1);
GameObject obj = (GameObject)Instantiate (JU, pos, Quaternion.identity);
}
}
This is the script that pools Enemy planes:
public class EnemiesPooler : MonoBehaviour
{
public static EnemiesPooler current;
public GameObject BF, JU, Hawker, Blenheim;
int pooledAmount = 10;
List<GameObject> BFPlane;
List<GameObject> JUPlane;
List<GameObject> HawkerPlane;
List<GameObject> BlenheimPlane;
void Start ()
{
BFPlane = new List<GameObject> ();
JUPlane = new List<GameObject> ();
HawkerPlane = new List<GameObject> ();
BlenheimPlane=new List<GameObject>();
current = this;
for (int i=0; i<pooledAmount; i++) {
GameObject bf = (GameObject)Instantiate (BF,Vector3.zero,Quaternion.identity);
bf.SetActive (false);
BFPlane.Add (bf);
GameObject ju = (GameObject)Instantiate (JU,Vector3.zero,Quaternion.identity);
ju.SetActive (false);
JUPlane.Add (ju);
GameObject hawker = (GameObject)Instantiate (Hawker,Vector3.zero,Quaternion.identity);
hawker.SetActive (false);
HawkerPlane.Add (hawker);
GameObject blenheim = (GameObject)Instantiate (Blenheim,Vector3.zero,Quaternion.identity);
blenheim.SetActive (false);
BlenheimPlane.Add (blenheim);
}
}
public GameObject GetBF ()
{
for (int i=0; i<BFPlane.Count; i++) {
if (!BFPlane [i].activeInHierarchy)
return BFPlane [i];
}
return null;
}
public GameObject GetJU ()
{
for (int i=0; i<JUPlane.Count; i++)
if (!JUPlane [i].activeInHierarchy) {
return JUPlane [i];
}
return null;
}
public GameObject GetHawker ()
{
for (int i=0; i<HawkerPlane.Count; i++)
if (!HawkerPlane [i].activeInHierarchy) {
return HawkerPlane [i];
}
return null;
}
public GameObject GetBlenheim ()
{
for (int i=0; i<BlenheimPlane.Count; i++)
if (!BlenheimPlane [i].activeInHierarchy) {
return BlenheimPlane [i];
}
return null;
}
}
Here is the script that spawns using Object Pooling. This is the one causing inconsistent behavior.
public class PoolTest : MonoBehaviour {
int turn=0;
float left=-4.47f,right=4.39f,yPos=4.59f,zpos=1,y,rotClockwise=270,rotCounterClockwise=-270;
public Transform cam;
// Use this for initialization
void Start () {
InvokeRepeating ("SpawnEnemy",0,3);
}
void SpawnEnemy()
{
turn = Random.Range (1, 5);
if(turn == 1)
SpawnBF ();
else if (turn == 2)
SpawnJU ();
else if (turn == 3)
SpawnHawker ();
else if (turn == 4)
SpawnBlenheim ();
}
void SpawnBF()
{
int spawnSide;
Vector3 pos;
float rot;
y = cam.position.y + yPos;
spawnSide = Random.Range (0,2);
if (spawnSide == 0) {
pos = new Vector3 (left, y, zpos);
}
else {
pos = new Vector3 (right, y, zpos);
}
GameObject obj=EnemiesPooler.current.GetBF();
if (obj == null)
return;
obj.transform.position=pos;
obj.SetActive (true);
}
void SpawnJU()
{
int spawnSide;
Vector3 pos;
spawnSide = Random.Range (0,2);
if (spawnSide == 0)
pos = new Vector3 (left, y, zpos);
else
pos = new Vector3 (right,y,zpos);
GameObject obj=EnemiesPooler.current.GetJU();
if (obj == null)
return;
obj.transform.position=pos;
obj.SetActive (true);
}
void SpawnHawker()
{
int spawnSide;
Vector3 pos;
spawnSide = Random.Range (0,2);
if (spawnSide == 0)
pos = new Vector3 (left, y, zpos);
else
pos = new Vector3 (right,y,zpos);
GameObject obj=EnemiesPooler.current.GetHawker();
if (obj == null)
return;
obj.transform.position=pos;
obj.SetActive (true);
}
void SpawnBlenheim()
{
int spawnSide;
Vector3 pos;
spawnSide = Random.Range (0,2);
if (spawnSide == 0) {
pos = new Vector3 (left, y, zpos);
}
else
pos = new Vector3 (right,y,zpos);
GameObject obj=EnemiesPooler.current.GetBlenheim();
if (obj == null)
return;
obj.transform.position=pos;
obj.SetActive (true);
}
void Update () {
y = cam.position.y + yPos;
}
}
I have spent a lot of time trying to figure out what is causing this inconsistency. But, couldn't find any solution. Please help me. Thanks.