Help fixing Object Pooling platforms in Doodle Jump clone.

Updated on March 18, 2018 in [A] Unity Scripting
Share on Facebook0Tweet about this on TwitterShare on Google+0Share on Reddit0
5 on March 6, 2018

So I was making the Doodle Jump clone by following Brackey’s video. And to create the platforms I followed his Object Pooling video rather than instantiating as he did in his live video.
But the thing is, those platforms just traverse to the top too fast. I mean they all move/translate to top together and not one by one. 
How do I make them stop, so the player can jump on those and then reuse the older platforms at right time one by one? Instead of making an Interface, I am calling the ‘SpawnFromPool’ method directly in the Update method of the Spawner. I even tried creating Interface and all as he did still didn’t fix my issue.
What I tried doing then was to check if the time has passed a certain limit then I call the ‘SpawnFromPool’ but the problem with this is platforms are spawned too slow that I reach at the last platform on the top and have to wait for a platform to spawn.
Kindly help me.
[EDIT1-Added link]
PS:Here’s the GitHub link to my project: Link

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlatformSpawner : MonoBehaviour {
 public float xRange;
 public float yMin = 0.01f;
 public float yMax=1f;
 public float xPos,yPos;
 public float TimeToReuse=2f;
 public float time;
 PlatformPooler p;
 void Start () {
 p = PlatformPooler.Instance;
 }
 void Update () {
 time += Time.deltaTime;
 if (time > TimeToReuse) {
 xPos = Random.Range (-xRange, xRange);
 yPos += Random.Range (yMin, yMax);
 Vector2 position = new Vector2 (xPos, yPos);
 p.SpawnFromPool ("Normal",position);
 time = 0;
 }
 }
}

  • Liked by
Reply
2 on March 7, 2018

By the code you provided I can’t really guess much, but what about creating your n number of platform prefabs, each one with his own monobehaviour to act like you want it to, and storing them inside an array or something? then you could pool from there with a random index

 

on March 7, 2018

Yeah, this is the code just on the platform. Rest is same according to Brackey’s video about Object Pooling. I have even posted the GitHub link to my project where each file is available.
Rest, I’ll try using array as you mentioned.

on March 7, 2018

So, I implemented using just array and the issue now is same as mentioned in original post that I reach the last platform and it takes time for the platform to spawn.

public class PlatformSpawner : MonoBehaviour {
public float xRange;
 public float yMin = 0.01f;
 public float yMax=1f;
 public float xPos,yPos;
public GameObject prefab;
 private GameObject[] plats;
 public int arraySize;
 private int currentPlat;
public float TimeToReuse=2f;
 public float time;
Platform p;
 void Start () {
 p = Platform.instance;
 plats= new GameObject[arraySize];
 time = 0;
 currentPlat = 0;
 for (int i = 0; i < arraySize; i++) {
 xPos = Random.Range (-xRange, xRange);
 yPos += Random.Range (yMin, yMax);
 Vector2 pos = new Vector2 (xPos, yPos);
 plats [i] = (GameObject)Instantiate (prefab, pos, Quaternion.identity);
 }
 }
void Update () {
 time += Time.deltaTime;
// Debug.Log (p.invisible);
 if (time>=TimeToReuse) {
 time = 0;
 xPos = Random.Range (-xRange, xRange);
 yPos += Random.Range (yMin, yMax);
 plats [currentPlat].transform.position = new Vector2 (xPos, yPos);
 currentPlat += 1;
 if (currentPlat >= arraySize) {
 currentPlat = 0;
 }
 }
 }

So rather than waiting for time I thought of spawning a platform whenever a previous platform is not visible any more but gives Null Reference Exception something.

PLATFORM SPAWNER

public class PlatformSpawner : MonoBehaviour {
public float xRange;
 public float yMin = 0.01f;
 public float yMax=1f;
 public float xPos,yPos;
public GameObject prefab;
 private GameObject[] plats;
 public int arraySize;
 private int currentPlat;
public float TimeToReuse=2f;
 public float time;
Platform p;
 void Start () {
 p = Platform.instance;
 plats= new GameObject[arraySize];
 time = 0;
 currentPlat = 0;
 for (int i = 0; i < arraySize; i++) {
 xPos = Random.Range (-xRange, xRange);
 yPos += Random.Range (yMin, yMax);
 Vector2 pos = new Vector2 (xPos, yPos);
 plats [i] = (GameObject)Instantiate (prefab, pos, Quaternion.identity);
 }
 }
void Update () {
 time += Time.deltaTime;
// Debug.Log (p.invisible);
 if (time>=TimeToReuse || p.invisible) {
 time = 0;
 p.invisible = false;
 xPos = Random.Range (-xRange, xRange);
 yPos += Random.Range (yMin, yMax);
 plats [currentPlat].transform.position = new Vector2 (xPos, yPos);
 currentPlat += 1;
 if (currentPlat >= arraySize) {
 currentPlat = 0;
 }
 }
 }

Script attached to PLATFORM Prefab

public class Platform : MonoBehaviour {
public float jumpForce;
 public bool invisible=false;
public static Platform instance;
 void OnAwake()
 {
 instance=this;
 }
void OnBecameInvisible()
 {
 invisible = true;
 }
void OnCollisionEnter2D(Collision2D col)
 {
 if (col.relativeVelocity.y <= 0)
 {
 Rigidbody2D rb = col.collider.GetComponent<Rigidbody2D>();
 if (rb != null)
 {
 rb.velocity = new Vector2(rb.velocity.x, jumpForce);
 }
 }
 }
}

 

Show more replies
  • Liked by
Reply
Cancel
1 on March 7, 2018

I don’t think it’s a good practice to have a static Platform instance if you’re gonna have more than one of those monobehaviour… Think about it: if you instantiate a platform, its monoBehaviour is gonna set the public static Platform instance to itself, but on the next platform you instantiate, the instance is gonna be overwritten. I don’t know but that could cause u problems

on March 18, 2018

I tried again, different from earlier approaches but for some reason it is showing that the list has only 1 element in it, although in the hierarchy it does create clones which are not active. But debugging it shows only one element which thereby, returns null when called by Spawner class.

Pooler Class

public class ObjectPooler : MonoBehaviour {
public GameObject prefab;
 public int size;
 List<GameObject> plat;
void Start () {
 plat = new List<GameObject> ();
 for (int i = 0; i < size; i++) {
 GameObject o = (GameObject)Instantiate(prefab);
 o.SetActive (false);
 plat.Add (o);
 print (plat.Count);
 }
 }
public GameObject GetPlatform() {
 print (plat.Count);
 if(plat.Count>0)
 {
 GameObject temp= plat[0];
 plat.RemoveAt(0);
 print ("GetPlatform called");
// temp.SetActive(true);
 return temp;
 }
 return null;
 }
public void DestroyPlatform(GameObject obj)
 {
 plat.Add (obj);
 obj.SetActive (false);
 }
}

 

Spawner Class

public class Spawner : MonoBehaviour {
 public GameObject op;
 ObjectPooler poolerScript2;
float xPos,yPos;
 public float xRange=2;
 public float yMin=0.01f;
 public float yMax= 1;
void Start () {
 poolerScript2 = op.GetComponent<ObjectPooler> ();
 }
 // Update is called once per frame
 void Update () {
 xPos = Random.Range (-xRange, xRange);
 yPos += Random.Range (yMin, yMax);
 GameObject platforms = poolerScript2.GetPlatform ();
 platforms.transform.position = new Vector2 (xPos, yPos);
 platforms.SetActive (true);
 }
}

Show more replies
  • Liked by
Reply
Cancel