- Home /
The question is answered, right answer was accepted
Problem destroying cloned prefabs
I instantiate a lot bat prefab from within a coroutine. Each prefab has a touch detection which should destroy the clone on touch.
My problem now, is that all clones a destroyed at once, if I touch a prefab. And not only the one that got touched.
this is the script which generates the bat prefabs:
public class BatGenerator : MonoBehaviour {
public GameObject Bat;
public GameObject CountDown;
private GameObject Main;
private int CountDownTimer;
private bool GameDone;
private bool BatGeneratorRunning;
private int BatCounter;
// Use this for initialization
void Start () {
GameDone = false;
Main = GameObject.Find("Main");
BatGeneratorRunning = false;
BatCounter = 1;
}
void Update()
{
CountDownTimer = Convert.ToInt32(CountDown.GetComponent<Text>().text);
if (Main.GetComponent<SchreiGameEvents>().GameRunning && !BatGeneratorRunning)
{
BatGeneratorRunning = true;
Debug.Log("Start Coroutine");
StartCoroutine("GenerateBat");
}
if (GameDone)
{
Application.LoadLevel("GameScene");
}
}
IEnumerator GenerateBat()
{
CountDownTimer = Convert.ToInt32(CountDown.GetComponent<Text>().text);
while (CountDownTimer > 0)
{
CountDownTimer = Convert.ToInt32(CountDown.GetComponent<Text>().text);
Vector3 BatPos = new Vector3(UnityEngine.Random.Range(-6f, 6f), UnityEngine.Random.Range(-0.7f, 3.36f), 0);
GameObject clone = (GameObject)Instantiate(Bat, BatPos, Quaternion.identity);
clone.name = "Bat_" + BatCounter;
Animator BatAnimator = clone.GetComponent<Animator>();
BatAnimator.Play("BatFly");
yield return new WaitForSeconds(0.6f);
BatCounter++;
}
GameDone = true;
yield return null;
}
}
And this is my AI script on each prefab to detect the touch event and destroy the clone:
public class BatAI : MonoBehaviour
{
private GameObject BatHitCounter;
private int killedBats;
private bool alreadyHit;
private Vector3 lastScale;
public Animator BatAnimator;
public AudioClip BatSwatter;
private GameObject Main;
private bool BatAnimationRunning;
private RuntimePlatform platform;
void Start()
{
BatHitCounter = GameObject.Find("batHitCounter");
Main = GameObject.Find("Main");
BatAnimationRunning = false;
platform = Application.platform;
alreadyHit = false;
}
// Update is called once per frame
void Update () {
if (Main.GetComponent<SchreiGameEvents>().GameRunning && !BatAnimationRunning)
{
BatAnimationRunning = true;
this.BatAnimator.Play("BatFly");
}
if (Main.GetComponent<SchreiGameEvents>().GameRunning)
{
if (this.transform.localScale.x >= 0.59f && !alreadyHit)
{
BatAnimator.SetTrigger("MaxSizeReached");
Destroy(this.gameObject);
}
}
if (platform == RuntimePlatform.Android || platform == RuntimePlatform.IPhonePlayer)
{
if (Input.touchCount > 0)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
checkTouch(Input.GetTouch(0).position);
}
}
}
else if (platform == RuntimePlatform.WindowsEditor)
{
if (Input.GetMouseButtonDown(0))
{
checkTouch(Input.mousePosition);
}
}
}
private void checkTouch(Vector3 pos)
{
Vector3 wp = Camera.main.ScreenToWorldPoint(pos);
Vector2 touchPos = new Vector2(wp.x, wp.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if(hit)
{
Debug.Log(hit.transform.gameObject.name);
//hit.transform.gameObject.SendMessage('Clicked',0,SendMessageOptions.DontRequireReceiver);
lastScale = this.transform.localScale;
alreadyHit = true;
Debug.Log("Hit");
BatAnimator.SetTrigger("Hit");
this.transform.localScale = lastScale;
StartCoroutine(DestroyBat(hit));
}
}
IEnumerator DestroyBat(Collider2D hit)
{
SoundManager.instance.PlaySingle(BatSwatter);
killedBats = Convert.ToInt32(BatHitCounter.GetComponent<Text>().text);
BatHitCounter.GetComponent<Text>().text = (killedBats+1).ToString();
yield return new WaitForSeconds(0.4f);
BatAnimator.SetTrigger("Dead");
Destroy(this.gameObject);
}
}
I hope you can help me with that problem.
Thanks in advance Frank
Answer by HarshadK · Apr 14, 2015 at 08:50 AM
Inside your
private void checkTouch(Vector3 pos)
along with if(hit) you should also check if the hit is registered on that prefab only otherwise every prefab will note that a hit was made and irrespective on which prefab it was registered they will destroy themselves. You can change your if(hit) to something like:
if(hit && hit == gameObject.GetComponent<Collider2D>())
{
// Your other stuff
}
Follow this Question
Related Questions
How to refer to a collision between clones of the same prefab? C# 1 Answer
Destroy an instance of a prefab 1 Answer
How to destroy a game object within an instance of prefab 1 Answer
Instantiated object is destroyed in scene, but still logs as existing in console. 1 Answer
How do I instantiate a prefab B in same place prefab A? 1 Answer