I'm trying to make a bubble/balloon popper style game and have a Spawner script (Spawner.cs) which holds a pool of objects (bubbles), this Spawner script then selects, at random, one of the objects that's in the pool.
From here another script (Bubble.cs), which is attached to all of the bubbles in the pool, is supposed to check the Spawner script to see which bubble from the pool is currently selected as the safeBubble. If this bubble matches the current safeBubble then the bubble should change it's tag to "Safe", if it doesn't match the safeBubble then it's tag should be "Bad".
It seems that the Bubble.cs does check and set initially (when I first hit play) but only then, they don't de-set/ re-check after that first safeBubble is chosen, like it should.
The idea being that the safeBubble changes at random intervals and thus the tags on the active/spawned bubbles should change to reflect whether they are "Safe" or "Bad".
Here are my scripts, the only script not provided is the GM.cs but that's just the score manager.
Bubble.cs
public class Bubble : MonoBehaviour{
public Spawner spawner;
public float popPoint = 10f;
public float spinSpeed;
public float riseSpeed;
public AudioSource popAudio;
public bool safe;
void Start(){
transform.name = transform.name.Replace("(Clone)","").Trim();
riseSpeed= Random.Range(0.05f, 0.1f);
spinSpeed= Random.Range(0.1f, 0.5f);
if (this.gameObject == spawner.safeBubble) {
this.tag ="Safe";
} else{
this.tag ="Bad";
}
}
void Update(){
if ( this.gameObject == spawner.safeBubble ){
this.tag ="Safe";
} else {
this.tag ="Bad";
}
transform.Translate (Vector3.up * riseSpeed, Space.World);
transform.Rotate (Vector3.right * 2* Time.deltaTime);
transform.Rotate (Vector3.up * spinSpeed* Time.deltaTime);
if(gameObject.transform.position.y >= popPoint ){
gameObject.SetActive(false);
}
}
}
Spawner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Spawner : MonoBehaviour{
public int index;
public int randomIndex;
public List<GameObject>[] pool;
public GameObject[] bubbles;
public GameObject greenBubble;
public GameObject orangeBubble;
public GameObject pinkBubble;
public GameObject purpleBubble;
public GameObject redBubble;
public GameObject blueBubble;
public GameObject safeBubble;
public float timeBetweenSpawns;
public float speed = 1.0f;
public float swapTime;
public Transform spawnLoc;
public Vector3 Position1;
public Vector3 Position2;
public Image BubbleToPopImg;
public Sprite green;
public Sprite orange;
public Sprite pink;
public Sprite purple;
public Sprite red;
public Sprite blue;
public bool willGrow = true;
void Awake(){
bubbles = new GameObject[6];
bubbles [0] = greenBubble;
bubbles [1] = orangeBubble;
bubbles [2] = pinkBubble;
bubbles [3] = purpleBubble;
bubbles [4] = redBubble;
bubbles [5] = blueBubble;
safeBubble = bubbles[Random.Range(0, 5)];
swapTime = Random.Range (2f,3f);
// Randomiser ();
timeBetweenSpawns = Random.Range (0.6f,1.2f);
InvokeRepeating ("Spawn", 1f, timeBetweenSpawns);
pool = new List<GameObject>[bubbles.Length];
for (int i = 0; i < bubbles.Length; i++){
pool[i] = new List<GameObject>();
}
// Debug.Log("Safe Bubble is " + safeBubble);
}
public GameObject GetPooledObject(){
randomIndex = Random.Range(0, pool.Length);
for (int i = 0; i < pool[randomIndex].Count; i++){
GameObject go = pool[randomIndex][i];
if (!go.activeInHierarchy){
return go;
}
}
if (willGrow){
GameObject obj = (GameObject)Instantiate(bubbles[randomIndex]);
pool[randomIndex].Add(obj);
return obj;
}
return null;
}
public void Spawn(){
GameObject bubbles = GetPooledObject ();
if(bubbles != null){
bubbles.transform.position = spawnLoc.transform.position;
bubbles.transform.rotation = spawnLoc.transform.rotation;
bubbles.SetActive(true);
}
}
void Update(){
transform.position = Vector3.Lerp (Position1, Position2, Mathf.PingPong(Time.time*speed, 1.0f));
timeBetweenSpawns -= Time.deltaTime;
swapTime -= Time.deltaTime;
if(timeBetweenSpawns<=0){
timeBetweenSpawns = Random.Range (0.6f,1.1f);
}
if(swapTime <= 0){
Randomiser ();
swapTime = Random.Range (3f,6f);
}
switch(index){
case 5: BubbleToPopImg.sprite = blue; break;
case 4: BubbleToPopImg.sprite = red; break;
case 3: BubbleToPopImg.sprite = purple; break;
case 2: BubbleToPopImg.sprite = pink; break;
case 1: BubbleToPopImg.sprite = orange; break;
case 0: BubbleToPopImg.sprite = green; break;
}
}
public void Randomiser(){
index = randomIndex;
safeBubble = bubbles[index];
// Debug.Log("Safe Bubble is " + safeBubble);
}
}
Popper.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Popper : MonoBehaviour{
public GM gm;
void Update(){
if (Input.GetMouseButtonDown(0)) {
Shoot();
}
}
void Shoot(){
RaycastHit hit;
Ray ray = GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit)) {
if(hit.collider.tag == "Bad"){
Debug.Log("Ouch");
}
if(hit.collider.tag == "Safe"){
Debug.Log("Nice");
}
}
}
}
I though that a simple if
statement to set and check the tag in both the Start and Update functions of the Bubble.cs would work but it doesn't and I'm just not managing to figure it out.
I've also tried using a switch
, but it has the same result.
Any Help is greatly appreciated.
Thanks in advance.
In
this.gameObject == spawner.safeBubble
you check if an existing object is equal to your Prefab.
This will of course Never be true!
Instead simply set the tag on the prefab as soon as you selected it
// Note that here was another mistake: The maxValue is EXCLUSIVE
// so Random.Range(0,5) returns the values 0 to 4!
// rather simply use the length of the array
safeBubble = bubbles[Random.Range(0, bubbles.Length)];
foreach(var bubble in bubbles)
{
bubble.tag = bubble == safeBubble ? "Safe" : "Bad";
}
This way everytime you Instantiate
according prefabs the tag is already set correctly and there is no need to do this later from the bubble itself.