Hello,
I’m working on a small game and I wrote a script which this script job is to wait for amount of time, But for some reason nothing happened and there is no error showing to me…!
Here is the script:
void OnTriggerEnter2D (Collider2D other)
{
if ((other.tag == “Player” ) && (!taken) && (other.gameObject.GetComponent().playerCanMove))
{
turnTime = true;
charc.moveSpeed += amountOfSpeed;
taken=true;
if (explosion)
{
Instantiate(explosion,transform.position,transform.rotation);
}
DestroyObject(this.gameObject);
}
}
void Update()
{
if (turnTime == true)
{
StartCoroutine (“time”);
}
}
IEnumerator time()
{
yield return new WaitForSeconds (1f);
charc.moveSpeed = 3f;
turnTime = false;
print (“Time”);
}
I will appreciate any help…
Thanks.
Hey there and welcome to the Unity forums!
Firstly, you should always put code in code tags using the “Code” button on the post toolbar. So your code looks like this to start:
void OnTriggerEnter2D(Collider2D other)
{
if ((other.tag == "Player") && (!taken) && (other.gameObject.GetComponent<CharacterController2D>().playerCanMove))
{
turnTime = true;
charc.moveSpeed += amountOfSpeed;
taken = true;
if (explosion)
{
Instantiate(explosion, transform.position, transform.rotation);
}
DestroyObject(this.gameObject);
}
}
void Update()
{
if (turnTime == true)
{
StartCoroutine("time");
}
}
IEnumerator time()
{
yield return new WaitForSeconds(1f);
charc.moveSpeed = 3f;
turnTime = false;
print("Time");
}
Just going off of what I see here there don’t seem to be any errors in the code. Have you verified that the “if” statement you have at the top is actually returning true? Try putting in a Debug.Log(“something happened”); line in there just to verify that all of those conditions are actually being met.
I almost never put a StartCoroutine call in an update, it just makes me too nervious. if you accidentally forget to make TurnTime false then you’ll be starting a new coroutine every frame.
Actually… that’s exactly what’s happening. you’re starting a coroutine via a string “time” which means there can only be one coroutine instance in that script at a time. you start the coroutine and then the very next frame you’re restarting the coroutine again, stopping the previous one. thing is you don’t set turntime false until after the coroutine runs for a full second (which it can’t cause your restarting it every frame).
in fact why not just have the startCoroutine in the OnTrigger where you’re setting the turnTime to true, and just ditch that variable (unless its needed elsewhere)
1 Like
JoshuaMcKenzie:
I almost never put a StartCoroutine call in an update, it just makes me too nervious. if you accidentally forget to make TurnTime false then you’ll be starting a new coroutine every frame.
Actually… that’s exactly what’s happening. you’re starting a coroutine via a string “time” which means there can only be one coroutine instance in that script at a time. you start the coroutine and then the very next frame you’re restarting the coroutine again, stopping the previous one. thing is you don’t set turntime false until after the coroutine runs for a full second (which it can’t cause your restarting it every frame).
in fact why not just have the startCoroutine in the OnTrigger where you’re setting the turnTime to true, and just ditch that variable (unless its needed elsewhere)
This guys got it down for you. Try using Invoke instead, your code should look like this afterwards.
void Update()
{
if (turnTime == true)
{
Invoke ("time", 1f);
}
}
void time()
{
charc.moveSpeed = 3f;
turnTime = false;
print("Time");
}
1 Like
phaem
May 4, 2016, 9:36am
5
How do you expect the “time” coroutine to run when the game object is destroyed?
void OnTriggerEnter2D (Collider2D other)
{
turnTime = true;
DestroyObject(this.gameObject);
}
void Update()
{
if (turnTime == true)
{
StartCoroutine ("time");
}
}
Also for constructions like this one must use trigger and not just a flag:
void OnTriggerEnter2D (Collider2D other)
{
if(!turnTime)
{
turnTimeTrigger = true;
turnTime = true;
DestroyObject(this.gameObject);
}
}
void Update()
{
if (turnTimeTrigger == true)
{
turnTimeTrigger = false;
StartCoroutine ("time");
}
}
That’s why state machines are cool. Don’t need flags and triggers, still concrete solid.
1 Like
As phaem already mentioned: If you Destory a gameObject, all coroutines created with it are destroyed also.
That’s why behaviour trees are even cooler. Don’t need states and explicit transitions, still concrete solid and simple.
1 Like
McMayhem:
Hey there and welcome to the Unity forums!
Firstly, you should always put code in code tags using the “Code” button on the post toolbar. So your code looks like this to start:
void OnTriggerEnter2D(Collider2D other)
{
if ((other.tag == "Player") && (!taken) && (other.gameObject.GetComponent<CharacterController2D>().playerCanMove))
{
turnTime = true;
charc.moveSpeed += amountOfSpeed;
taken = true;
if (explosion)
{
Instantiate(explosion, transform.position, transform.rotation);
}
DestroyObject(this.gameObject);
}
}
void Update()
{
if (turnTime == true)
{
StartCoroutine("time");
}
}
IEnumerator time()
{
yield return new WaitForSeconds(1f);
charc.moveSpeed = 3f;
turnTime = false;
print("Time");
}
Just going off of what I see here there don’t seem to be any errors in the code. Have you verified that the “if” statement you have at the top is actually returning true? Try putting in a Debug.Log(“something happened”); line in there just to verify that all of those conditions are actually being met.
Yes I’m sure that the if statement is working.
I have tried to put StartCoroutine in the OnTriggerEnter function but the same thing happen the waiting does’t start!
JoshuaMcKenzie:
I almost never put a StartCoroutine call in an update, it just makes me too nervious. if you accidentally forget to make TurnTime false then you’ll be starting a new coroutine every frame.
Actually… that’s exactly what’s happening. you’re starting a coroutine via a string “time” which means there can only be one coroutine instance in that script at a time. you start the coroutine and then the very next frame you’re restarting the coroutine again, stopping the previous one. thing is you don’t set turntime false until after the coroutine runs for a full second (which it can’t cause your restarting it every frame).
in fact why not just have the startCoroutine in the OnTrigger where you’re setting the turnTime to true, and just ditch that variable (unless its needed elsewhere)
Actually sir I tried to put the StartCoroutine in the OnTrigger function, But nothing happening also…
phaem:
How do you expect the “time” coroutine to run when the game object is destroyed?
void OnTriggerEnter2D (Collider2D other)
{
turnTime = true;
DestroyObject(this.gameObject);
}
void Update()
{
if (turnTime == true)
{
StartCoroutine ("time");
}
}
Also for constructions like this one must use trigger and not just a flag:
void OnTriggerEnter2D (Collider2D other)
{
if(!turnTime)
{
turnTimeTrigger = true;
turnTime = true;
DestroyObject(this.gameObject);
}
}
void Update()
{
if (turnTimeTrigger == true)
{
turnTimeTrigger = false;
StartCoroutine ("time");
}
}
That’s why state machines are cool. Don’t need flags and triggers, still concrete solid.
Yes that’s it…!
Thank you very much sir