Context
Hello, its me again. I have been playing around with "Object Pool" and it is fascinating the amount of CPU performance can save up. However, I have encountered a new "feature" where it scores once for the object being called and going through the pipe.
In my object pool, I have a pipe GameObject where is being Instantiated and set its method Active(false)
until it is spawned. Once spawned, my prefabs will be filled accordingly to the Object Pool's size.
Problem
Once it spawns, it does what it should do, both scoring and the same mechanic as "Flappy Bird". However, once the object gets Active again, it doesn't seem to score anymore because it was passed by a player. What I have done is to have a flag that checks if the player (bird) has passed the pipe or not. However, when I pass through it, it will update it as if it was 6 times (one point per frame). You may ask "have you done another flag for the pipe itself?" then the answer is yes. I tried that way also, but it will only keep the score once and not increase further than 5.
I ran out of ideas with the object pool approach. It seems to work fine if it is WITHOUT object pooling, but the flaw here is that it costs me CPU performance.
It either increases it by just 1, or it increases it by 6 times (because for each frame the object is in the ray, it counts another point).
Attempts
I have browsed on the Unity Learning center to find out how to do the object pooling, and it wasn't too bad as I thought. Later, I found this issue and I thought it was a problem with my logic (which it can be). I have spent several hours already (first mistake) to think it is something easy to fix, but apparently it wasn't due the time I have spent to just figure out why it is not working . I have been fiddling around my RayCastDetection
, SpawnManager
, ObjectPooling
, and PlayerControl
logic that interacts accordingly to the way I want, but nada.
Code
ObjectPooling.cs
public static ObjectPooling sharedInstance;
public List<GameObject> pooledObjects;
public GameObject objectToPool;
private PlayerControl playerControllerScript;
public int amountToPool;
void Awake()
{
sharedInstance = this;
}
void Start()
{
playerControllerScript = GameObject.Find("Player").GetComponent<PlayerControl>();
pooledObjects = new List<GameObject>();
GameObject tmp;
for (int i = 0; i < amountToPool; i++) //Add objects to the pool and turns them invisible (false)
{
tmp = Instantiate(objectToPool);
tmp.SetActive(false);
playerControllerScript.passedBeam = false;
pooledObjects.Add(tmp);
}
}
public GameObject GetPooledObject()
{
for (int i = 0; i < amountToPool; i++)
{
if (!pooledObjects[i].activeInHierarchy)
return pooledObjects[i];
}
return null;
}
RayCastDetection.cs
public class RayCastDetection : MonoBehaviour
{
public UIManager UIManagerScript;
public PlayerControl playerControlScript;
private RaycastHit hit;
public bool passed;
void Start()
{
UIManagerScript = GameObject.Find("UI_Manager").GetComponent<UIManager>(); //Used for scoring
playerControlScript = GameObject.Find("Player").GetComponent<PlayerControl>(); //used for player passing through the pipe
passed = false;
playerControlScript.passedBeam = false;
}
void Update()
{
Vector3 beamDown = transform.TransformDirection(Vector3.down);
Ray ray = new Ray(transform.position, beamDown);
if (!passed)
{
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "Player" && !playerControlScript.passedBeam)
{
playerControlScript.passedBeam = !playerControlScript.passedBeam;
UIManagerScript.score++;
}
Debug.DrawRay(transform.position, hit.point - transform.position);
}
}
else
playerControlScript.passedBeam = false;
}
}
SpawnManager.cs
public class SpawnManager : MonoBehaviour
{
public GameObject[] obstaclesPrefab;
private PlayerControl playerControllerScript;
private float startDelay = 1.69f;
private float repeatRate = 1.1f;
void Start()
{
playerControllerScript = GameObject.Find("Player").GetComponent<PlayerControl>();
InvokeRepeating("SpawnObstacle", startDelay, repeatRate);
}
void Update()
{
}
void SpawnObstacle()
{
// int obstaclesIndex = Random.Range(0, obstaclesPrefab.Length); //This is used only if I don't want to deal with object pooling, but the whole point is to use it. This is just a reference if I want to go back
if (playerControllerScript.gameOver == false)
{
float randomY = Random.Range(-2f, 2f);
Vector3 randomHeight = new Vector3(35, randomY, -7);
GameObject pipe = ObjectPooling.sharedInstance.GetPooledObject();
if (pipe != null)
{
pipe.transform.position = randomHeight;
pipe.SetActive(true);
//My guess is that I want to instantiate the object pipe's beam to false here
}
}
// Instantiate(obstaclesPrefab[obstaclesIndex], randomHeight, obstaclesPrefab[obstaclesIndex].transform.rotation); //This is used only if I don't want to deal with object pooling, but the whole point is to use it. This is just a reference if I want to go back
}
}
Feel free to leave some suggestions in what I have missed out or any questions in regards to fill in. Thank you for your time!