- Home /
How to change this using a coroutine
Hi, guys. I've never used coroutines before but when i asked for a solution to an event problem, some of you told me that's the best way to deal with events that trigger when some requisites are met.
My scenario is this:
I have a car running along a path (circuit) by placing it into a specific percent of this path (i use awesome tool iTween). Every 10 seconds of game a random event occurs and this event may involve a wheel puncture. When this happens i use a flag (boxes==true) so when the car reaches tue boxes road entrance it will be relocated on this other path (boxes). So i use this code:
if (boxes==true && percent>=boxes_entrance){ // Coroutine needed
if (percentbox>=0.5 && timer<=FixCarTimeLapse) { //It waits for reparation on the box (0.5 is the middle of box lane)
timer+=Time.deltaTime;
wheelsPoints=100;
}
else percentbox=percentbox+Time.deltaTime/Circuit_DriveThrough;
if (percentbox>=0.4f){ //controls lap counter when car passes boxes (Coroutine needed)
totalLaps++;
}
iTween.PutOnPath(gameObject, iTweenPath.GetPath("boxes"), percentbox);
if (percentbox>=1) { //exits boxes road
boxes=false;
percentbox=0;
timer=0;
percent=boxes_exit;
TimePerLap=InitialTimePerLap/3;
}
}
Where:
percent: is the position of the car, a float between 0 and 1 for the function iTween.PutOnPath() which uses percent of the path as its last argument. percentbox: is the position of the car when it's driving along boxes lane. Circuit_DriveThrough: is a constant defined in the circuit and it describes the time lapse for a car to drive the whole boxes lane. boxes_entrance and boxes_exit: are the exact percent of path circuit where it "joins" the start of boxes path and the end of boxes path, respectively. FixTimeCarElapse: is a variable of the mechanic team, it defines the time the team will last fixing the car.
So, the problem in this code is in the lines commented as "coroutine needed". The first line of code is a problem for me when the car breaks after reaching boxes entrance but before it finishes the circuit: the car "jumps" from its position to boxes_entrance point. That jump may be very large. As percent is a float i cant use:
if (boxes==true && percent==boxes_entrance)
because percent will vary from frame to frame so it wont be exactly the same as boxes_entrance. I may use a "distance" here:
if (boxes==true && percent>=boxes_entrance && percent=0.4f)
is the percent of boxes lane that matches a lap (when a car passes boxes lane it counts as a lap). But i cant use the same solution as before because it will count more than 1 lap. I cant calculate the exact time a frame will delay so a solution like:
if (percentbox>=0.4 && percentbox<0.40001)
will mean lots of lap counts.
To post it clearly: I need a way to manage events that happen once and these events are triggered by float variables which grow ratio we dont know. I've been checking coroutines and i understand how they work, but i cant "see" the idea clearly. How would you solve this problem using coroutines? Thank you in advance.
Answer by TheMidn1ght · Dec 02, 2013 at 11:59 PM
I am having a hard time understanding this problem and it seems to be stemming from what the words "boxes road" mean. I think you mean the "pit stop" or "pit area" as I am thinking of it. So what you are trying to do is enter the pit stop whenever your tires pop. If the tires pop after you have passed the entrance to the pit area the car just jumps to the entrance. The only way to solve this is to make the car continue driving around the circuit until it gets to the boxes_entrance again and then make it go in. This isn't necessarily a bad thing. You could make the car go slower while its tired is popped.
The logic would be something like this:
if( carTiresPopped)
{
while(carIsNotAtBoxEntrance())
{
ContinueDriving();
}
SendCarDownBoxPath();
}
That's what i'm trying, and basically i use the same logic but i use if statement ins$$anonymous$$d of while. The tire has already popped in previous code i didnt show and the car actually has a speed reduction. When it gets fixed the speed becomes normal (last line) though i have realised that should happen when it gets fixed and not when it leaves the pit lane. So thank you for that.
The real problem relies on the moment you seek for box entrance, because the position is given by a float value which grows in intervals depending on frame duration so it will change from frame to frame, from one machine to another. I can't compare if position IS EQUAL to box entrance, i must use IS EQUAL OR GREATER THAN because of this. Then if the car has passed the box entrance and it triggers the tire broken event, as position is greater the car will jump back to the entrance.
I see. Sounds like you only want to go into the pit area if the tire popped happens before the entrance. I would change the if to ins$$anonymous$$d check to see if percent>=boxesEntrance - acceptableGap && percent < boxesEntrance. Then you could tweak acceptableGap until the jump isn't too bad. This will basically cause the car to not trigger this code once it has passed the boxesEntrance.
There is also the possibility of putting an artificial time delay on your game, and doing the next frame of movement before it is actually drawn. This would let you check whether it is going to go past the box entrance and if it would have just move it into the box entrance ins$$anonymous$$d.
If i write that code the car will never enter boxes. Imagine the box entrance is at 94.0 percent of the track. In the last frame before entering the car's percent is 93.99872 but the next one is 94.00216. When the script is comparing:
if (percent>=94.0 && percent<94.0) ---> well this will never happen. It will never be greater or equal to 94 AND smaller at the same time. But if i use (i actually had tried it):
if (percent>=94.0 && percent<94.1) it works but still there is a visible jump if the tire pops at 94.05. Believe me, it is visible. Anyway, if you run this method from a slow machine it may happen the last frame is 93 and the next one is 95, so it wont enter either.
I dont understand the delay option you mention. When do i run the delay? I think i have the same problem, and after all every line of code in Update function will run BEFORE the next frame painting.
Well, the goal of this question was how to get this by using courutine but if anybody knows a different way to do it, please help me.
Your answer
Follow this Question
Related Questions
Waiting for and using output of a UnityEvent within coroutines 1 Answer
StartCoroutine by another class (Coroutine inside Coroutine - Instance class) 1 Answer
Rerun a script after it finishes, when it already has multiple Coroutines? 1 Answer
Issue with nested coroutines getting stuck 1 Answer
Question about coroutines 2 Answers