Unity 5 - Object pooling not deactivating objects

833 views Asked by At

I'm working on an endless runner game. I'm very much a beginner to programming, working off this and this tutorial, so I'm not 100% sure how this code works, which makes it difficult to figure out how to fix my problems. The code is supposed to use object pooling to create platforms, then activate them, deactivate them, move them in front of the player and activate them again. (At least, I think) This gives the player endless platforms to run across without having to constantly instantiate new platforms. Here's the code for the Platform Generator:

using UnityEngine;
using System.Collections;

public class PlatformGenerator : MonoBehaviour
{

public GameObject thePlatform;
public Transform generationPoint;
public float distanceBetween;

private float platformWidth;

public float distanceBetweenMin;
public float distanceBetweenMax;

private int platformSelector;
private float[] platformWidths;
//  public GameObject[] thePlatforms;

public ObjectPooler[] theObjectPools;

private float minHeight;
private float maxHeight;
public Transform maxHeightPoint;
public float maxHeightChange;
private float heightChange;

void Start ()
{
//      platformWidth = thePlatform.GetComponent<BoxCollider2D> ().size.x;

    platformWidths = new float[theObjectPools.Length];

    for (int i = 0; i < theObjectPools.Length; i++)
    {
        platformWidths[i] =             theObjectPools[i].pooledObject.GetComponent<BoxCollider2D>().size.x;
    }

    minHeight = transform.position.y;
    maxHeight = maxHeightPoint.position.y;
}

void Update ()
{
    if (transform.position.x < generationPoint.position.x)
    {
        distanceBetween = Random.Range (distanceBetweenMin, distanceBetweenMax);

        platformSelector = Random.Range (0, theObjectPools.Length);

        heightChange = transform.position.y + Random.Range (maxHeightChange, -maxHeightChange);
        //          if you want to have platforms generating outside boundries, comment out this code:
        if (heightChange > maxHeight)
        {
            heightChange = maxHeight;
        }
        else if (heightChange < minHeight)
        {
            heightChange = minHeight;
        }

        transform.position = new Vector3 (transform.position.x + (platformWidths[platformSelector] / 2) + distanceBetween, heightChange, transform.position.z);

 //         Instantiate (/*thePlatform*/ thePlatforms[platformSelector], transform.position, transform.rotation);

        GameObject newPlatform = theObjectPools[platformSelector].GetPooledObject();

        newPlatform.transform.position = transform.position;
        newPlatform.transform.rotation = transform.rotation;
        newPlatform.SetActive (true);

        transform.position = new Vector3 (transform.position.x + (platformWidths[platformSelector] / 2), transform.position.y, transform.position.z);

    }
}
}

And Here's the code for the Object Pooler:

public class ObjectPooler : MonoBehaviour
{
public GameObject pooledObject;
public int pooledAmount;

List<GameObject> pooledObjects;

void Start ()
{
    pooledObjects = new List<GameObject>();

    for (int i = 0; i < pooledAmount; i++)
    {
        GameObject obj = (GameObject) Instantiate (pooledObject);
        obj.SetActive (false);
        pooledObjects.Add (obj);
    }
}

public GameObject GetPooledObject()
{
    for (int i = 0; i < pooledObjects.Count; i++)
    {
        if (!pooledObjects[i].activeInHierarchy)
        {
            return pooledObjects[i];
        }
    }

    GameObject obj = (GameObject) Instantiate (pooledObject);
    obj.SetActive (false);
    pooledObjects.Add (obj);
    return obj;

}
}

The script works fine for a few seconds of play, but soon begins to create new platforms, which is what I'm trying to avoid. I think what's happening is that the platforms aren't being disabled, so the code can't move the platforms and it creates new ones instead. I'm sure it's an easy fix, but I'm not sure what to do. Anybody know how to fix this? Thanks.

2

There are 2 answers

0
chosendeath On

There's no functionality in your code to return objects to the pool as far as I can see. There's a function to get an object from the pool which auto instantiates if needed, otherwise pulling from the pool, and you have in the start method logic to prepool, but you never put objects back. You need to create a function to return objects back to the pool.

1
theawless On

The function

public GameObject GetPooledObject(){...}

returns a poolObject from the pool if the object is disabled in the heirarchy. Otherwise it instantiates a new pool object and return that.

newPlatform.SetActive (true);

In update function you set the poolObject to active but never deactivate it. Hence your pooler keeps generating new objects. You need to deactivate the object using object.setActive(false);

You can do it timely - say every 2 second the object disappears(but for different levels you will need to alter this time) or you can calculate if the object has been crossed and is far behind then you can deactivate it.