First off, I just want to thank all of you in this community for answering my questions and helping me out. I am trying to learn C# and I have plans about joining real life courses to become a better programmer. I have already learned a lot thanks to all of you.
Now on to my question of the hour
I am having troubles making this script work. What I want to happen is this:
When a bullet from my gun hits an object with the tag, I want the gameObject to be de-activated and wait 5 seconds. After the 5 seconds I want the mesh renderer of that object to blink for a second or two and then re-enable the game object. Here’s what I’ve got:
using UnityEngine;
using System.Collections;
public class RemovableObject : MonoBehaviour {
IEnumerator OnCollisionEnter (Collision col)
{
if(col.gameObject.tag == "RemovableObject")
{
col.gameObject.SetActive (false);
yield return new WaitForSeconds (5);
yield return StartCoroutine(DoBlinks(2f, 0.2f));
col.gameObject.SetActive (true);
}
}
IEnumerator DoBlinks(float duration, float blinkTime)
{
while (duration > 0f)
{
duration -= Time.deltaTime;
//toggle renderer
GetComponent<Renderer>().enabled = !GetComponent<Renderer>().enabled;
//wait for a bit
yield return new WaitForSeconds(blinkTime);
}
//make sure renderer is enabled when we exit
GetComponent<Renderer>().enabled = true;
}
}
This script is attached to my bullet prefab. The removable objects are tagged “RemovableObject”.
What happens right now is that the object gets de-activated and waits for 5 seconds but then the BULLET starts blinking and not the Object thats been hit. after the bullet is done blinking, the object is activated again.
So how can I make the object blink and not the bullet? I tried putting col.GetComponent<Renderer>().enabled = !GetComponent<Renderer>().enabled; on line 22, but that returned an error…
It’s because on line 22 you call ‘GetComponent()’.
When you do this, really you’re calling a instance method on ‘this’ scoped to where the function is.
Because this script is on the Bullet, it’s getting the Renderer on the Bullet.
What you should be doing is passing the GameObject from the Collision into the ‘DoBlinks’ routine and calling ‘GetComponent’ on that:
using UnityEngine;
using System.Collections;
public class RemovableObject : MonoBehaviour {
IEnumerator OnCollisionEnter (Collision col)
{
if(col.gameObject.tag == "RemovableObject")
{
col.gameObject.SetActive (false);
yield return new WaitForSeconds (5);
var rend = col.gameObject.GetComponent<Renderer>();
if(rend != null)
{
yield return StartCoroutine(DoBlinks(rend, 2f, 0.2f));
}
col.gameObject.SetActive (true);
}
}
IEnumerator DoBlinks(Renderer rend, float duration, float blinkTime)
{
while (duration > 0f)
{
duration -= Time.deltaTime;
//toggle renderer
rend.enabled = !GetComponent<Renderer>().enabled;
//wait for a bit
yield return new WaitForSeconds(blinkTime);
}
//make sure renderer is enabled when we exit
rend.enabled = true;
}
}
Although I see a critical problem here… the target has been deactivated. So the renderer isn’t even rendering. Probably want to SetActive(true) before calling DoBlinks.
I think disabling GameObject stops the ticking of coroutines. After “this.gameObject.SetActive(false)” the method will never execute pass the “yield return”.