- Home /
Yield doesn't work (he doesn't count) after I hit a powerup
using UnityEngine;
using System.Collections;
using System;
using System.Timers;
public class BoosterJump : MonoBehaviour
{
GameObject whatIHit;
public bool jumpHigh;
void Update()
{
}
void Start()
{
jumpHigh = false;
StartCoroutine(ResetJumpForce(0f));
}
void OnTriggerEnter2D(Collider2D other)
{
jumpHigh = true;
StartCoroutine(ResetJumpForce(2f));
whatIHit = other.gameObject;
// Destroy the booster
Destroy(gameObject);
}
IEnumerator ResetJumpForce(float time)
{
// infinity loop
while (true)
{
while (jumpHigh == false)
{
yield return null;
}
Debug.Log("boosterjump become 1500f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1500f);
Debug.Log(time);
yield return new WaitForSeconds(time); // wacht 15 seconden
Debug.Log("test yield" + time);
if (time <= 0)
{
Debug.Log("Time is longer than 0 sec");
jumpHigh = false;
Debug.Log("boosterjump became 1000f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1000f);
Debug.Log("boosterjump is 1000f");
}
}
}
}
Isn't there a problem in the OnTriggerEnter2D function, in that a coroutine is started and then the gameobject it's running on is destroyed, killing the coroutine?
Answer by Nymisu · Mar 19, 2015 at 01:14 PM
Vast majority of us can't read dutch. Please comment your code in english in the future :)
Also, try not to use while(true), it's exceptionally bad practice, and leads to numerous curious errors. A coroutine doesn't need to, and should be in a loop unless it's necessary, for starters.
The reason it can't yield, is because you tell it to return null, therefore terminating the coroutine.
Also, if you're making a simple delay, there's no need to use a couroutine for that. Try the following:
float delay = 15f;
float highjumped = -15f; //you can do this in start with "highjump = -delay;"
void Update()
{
if(jumpbuttonwaspressed)
{
//if time of jump + delay is less than the time now...
if(highjumped + delay < Time.time)
{
jump();
highjumped = Time.time; //Save the time of the jump.
}
}
}
The only things that are in dutch are my Debug.Log.. And I'm sorry but your piece of code doesn't work.
public bool jumpHigh;
float delay = 15f;
float highjumped = -15f;
//you can do this in start with "highjump = -delay;"
void Update()
{
if (jumpHigh)
{
//if time of jump + delay is less than the time now...
if (highjumped + delay < Time.time)
{
Jump();
highjumped = Time.time; //Save the time of the jump.
}
}
}
void Jump()
{
GameObject.FindGameObjectWithTag("Player2").Send$$anonymous$$essage("BoosterJump", 2000f);
}
#endregion
#region onTriggerEnter2D
void OnTriggerEnter2D(Collider2D other)
{
jumpHigh = true;
whatIHit = other.gameObject;
// Vernietig de booster.
Destroy(gameObject);
}
endregion
It still doesn't work
public bool jumpHigh;
float delay = 15f;
float highjumped = -15f; //you can do this in start with "highjump = -delay;"
void Update()
{
if (jumpHigh)
{
//if time of jump + delay is less than the time now...
if (highjumped + delay < Time.time)
{
Jump();
highjumped = Time.time; //Save the time of the jump.
}
}
}
void Jump()
{
GameObject.FindGameObjectWithTag("Player2").Send$$anonymous$$essage("BoosterJump", 2000f);
}
yield return null;
This stops the coroutine at this step, and will continue on the start of the next frame, while
yield break;
would be what is used to exit the coroutine.
I personally just tested the code and it works fine on my end. Are you sure jumpHigh is set as true properly? if(highjumped + delay < Time.time) fires just as expected aswell.
Try debug logging like so:
public bool jumpHigh;
float delay = 15f;
float highjumped = -15f; //you can do this in start with "highjump = -delay;"
void Update()
{
if (jumpHigh)
{
Debug.Log("jumpHigh fired\n Compare: " + (highjumped+delay) + " vs. " Time.time );
//if time of jump + delay is less than the time now...
if (highjumped + delay < Time.time)
{
Jump();
Debug.Log("last jump was at: " + highjumped + " new one set at: " + Time.time);
highjumped = Time.time; //Save the time of the jump.
}
}
}
void Jump()
{
Debug.Log("Jumping");
GameObject.FindGameObjectWithTag("Player2").Send$$anonymous$$essage("BoosterJump", 2000f);
}
Answer by Bieere · Mar 19, 2015 at 02:05 PM
I would recommend not calling the coroutine multiple times, as that will cause it to create multiple couroutines, keep time external to the coroutine if you wish to use it as an infinite loop, that way within the coroutine check to see if time is equal to zero, if not wait, and if you can choose to skip and wait for a wait time greater than zero, or continue through without waiting.
float time = 0f;
IEnumerator ResetJumpForce()
{
// infinity loop
while (true)
{
while (jumpHigh == false)
{
yield return null;
}
Debug.Log("boosterjump become 1500f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1500f);
Debug.Log(time);
if(time != 0f)
{
yield return new WaitForSeconds(time); // wacht 15 seconden
Debug.Log("test yield" + time);
time = 0f;
}
Debug.Log("Time is longer than 0 sec");
jumpHigh = false;
Debug.Log("boosterjump became 1000f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1000f);
Debug.Log("boosterjump is 1000f");
}
}
though the way i would recommend you do it to avoid sending multiple messages at a time during the frame, return null if time is equal to zero, and only use it when its requiring a wait time.
float time = 0f;
IEnumerator ResetJumpForce()
{
Debug.Log("boosterjump became 1000f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1000f);
Debug.Log("boosterjump is 1000f");
// infinity loop
while (true)
{
while (jumpHigh == false)
{
yield return null;
}
Debug.Log("boosterjump become 1500f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1500f);
Debug.Log(time);
if(time != 0f)
{
yield return new WaitForSeconds(time); // wacht 15 seconden
Debug.Log("test yield" + time);
time = 0f;
Debug.Log("Time is longer than 0 sec");
jumpHigh = false;
Debug.Log("boosterjump became 1000f");
GameObject.FindGameObjectWithTag("Player2").SendMessage("BoosterJump", 1000f);
Debug.Log("boosterjump is 1000f");
}
else
{
yield return null;
}
}
}
And that way you call it the StartCoroutine() once at the start, and can change the time as required.
Your answer
Follow this Question
Related Questions
My speed Powerup doesnt decrease after a duration 1 Answer
IEnumerable in Unity 1 Answer
problems with damage over time script 2 Answers
WaitForSeconds not working C# 2 Answers