- Home /
Coroutine "While" Setup
Hello,
I have a character that running speed is battery powered. When the battery runs down the player slows down. If he gets a battery booster power up he runs fast. I originally had this code as "if" statements in update but don't want the overhead of having to check every frame. I have capped my game to run at 30 fps for mobile purposes and have set this coroutine to run every 2 frames. When my player's battery power runs below 50 his speed slows down. This part works. The problem is when his battery charges back up to above 50 the script does not loop back up to the first "while" statment to make him run at normal speed. How can I get a corouting to loop back up to the first part of the code. If I delete the brackets after the yield statements all the checks run every 2 seconds and the code works but I was hopeing to have only one part of the code run at a time while True. If not true jump to the second and then the third part and if not True back to the top for a full loop.
Here is my Code:
void Start(){
StartCoroutine(BatteryStatus());
}
IEnumerator BatteryStatus() {
while (playerBattery > 50){ // if playerBattery is above minimum power than run at regular speed.
maxSpeed = batteryChargedSpeed;
accel = batteryChargedAccelSpeed;
print("ChargedSpeed50");
yield return new WaitForSeconds(2f);
}
print("2"); while (playerBattery < 50){ //// if playerBattery is too low the animation speed of the player will slow down.
maxSpeed=batteryLowSpeed;
accel = batteryLowAccelSpeed;
print("LowSpeed");
yield return new WaitForSeconds(2f);
}
print("3"); while (playerBattery > 600){ //// if playerBattery has Mega Battery Power than increase to extra fast speed
maxSpeed = 15;
accel = 95;
print("MaxSpeed" + maxSpeed);
yield return new WaitForSeconds(2f);
}
}
}
I am not running coroutine at framerate. Is coroutine in my example more of a load even if I am only running it every 2 frames? I may increase this to every 4 frames and see how it plays out. Checking only every 2 frames saves checking the same code in Update 60 times per 2 frames(my game is locked in at 30 fps for mobile). I have read that one should be careful at how much code you put in update because it does run every frame.
Thanks in advance for your help.
Except that you are paying a penalty for the context switch to run the co-routine at all.
And if all you are doing is checking one value in an if, thats basically no work at all.
Finally if you complicate your code in ANY way as result then you've already wasted more then you are buying.
Donald $$anonymous$$nuth said "premature optimization is the root of all evil". This is definitely one of those times. $$anonymous$$icro-optimizations seldom help. Write your code to be clear and clean, then if you have performance issues once it is written, profile it and optimize it.
All you are doing with this right now is wasting cycles... both of the CPU and of yourself.
P.S. This is one of my areas of particualr specialization. I was the co-author of this best selling book: http://www.amazon.com/Java%C2%BF-Platform-Performance-Strategies-Tactics/dp/0201709694
The principles are the same be it Java, C# or C++.
Thank you for your reply. Your thoughts are very appreciated. I really wanted to learn how to do coroutines and this part seemed like a good place to implement it. I will ultimately probably place it back into update as you seem to know your stuff.
Even though I finally have it working as a coroutine you still recomend putting it back under Update?
Not unless you have performance issues and the profiler identifies it as a key hotspot.
Again, premature optimization is bad. If you have it working don't mess with it for now.
Answer by FrostyNomad · Nov 18, 2014 at 09:12 PM
You could do some conditional testing using if else if inside of a while to get what you're looking for:
while (true) {
if (playerBattery > 600) {
maxSpeed = 15;
accel = 95;
} else if (playerBattery > 50) {
maxSpeed = batteryChargedSpeed;
accel = batteryChargedAccelSpeed;
} else { // playerBattery <= 50
maxSpeed=batteryLowSpeed;
accel = batteryLowAccelSpeed;
}
yield return new WaitForSeconds(2f);
}
Notice: The tests of playerBattery are in a descending value order to make sure each condition is tested for the correct value.
Frosty Nomad’s solution worked great as far as I can tell so far. Thanks Frosty for your well written code. I still am interested in getting feedback on Jeff $$anonymous$$esselman's comments about performance efficiency between my corrected(Frosty's Version)coroutine scenario running at every 2 frames vs. the same code in update.
Your answer
Follow this Question
Related Questions
start coroutine everytime 2 Answers
Coroutoutine doesnt work properly. 3 Answers
Coroutines /WaitForSecond ain't working 2 Answers
Coroutine loop not working 1 Answer
Index out of range in while statement but I can't figure out how. 1 Answer