If the player collides with 2 triggers, their effects get mixed up

The player is moving, and if they collide with trigger A, they will stop moving for 1 second, and then start moving. If the player collides with trigger B, they will stop moving for 2 seconds. However, the speeds get mixed up if the player collides with A and then quickly collides with B, so the player will start moving even though they should be still.

It’s difficult to explain, basically if player collides with A, then collides with B straight after, I would like the effect of A to be cancelled, and the effect of B to start. Here is the code for them

 if (col.gameObject.tag == "trigA")
	{
		
		
			speed = 0f;
			yield return new WaitForSeconds(1);
		speed = 21f;
		
	}

	if (col.gameObject.tag == "trigB")
	{
	
			speed = 0f;
			yield return new WaitForSeconds(2);
			speed = 21f;
		
		}

}

Thanks

“Hello guys” probably won’t get you a quicker answer in the future.

You need add another statement to your IF’s. What the new If statement is saying is that if trigA is true and trigB is not true then proceed with the if statement, but if trigB becomes true then the statement will become false so your IF with trigB alone should take priority.

if (col.gameObject.tag == "trigA" && col.gameObject.tag != "trigB")
     {
         
         
5.             speed = 0f;
             yield return new WaitForSeconds(1);
         speed = 21f;
         
     }
10.
     if (col.gameObject.tag == "trigB")
     {
     
             speed = 0f;
15.             yield return new WaitForSeconds(2);
             speed = 21f;
         
         }


}

I hope this helps.

It’s obvious why because of the way you have written the code, the situation will occur if the player hits both triggers together. The yield functions allow both triggers to run on a double hit.

Sequence on a double hit

trigA sets the speed to zero then yields

trigB sets the speed to zero (the yield of trigA allows another entry)

trigA comes back from yielding and sets speed to 21. <==== WRONG

trigB comes back from yielding and sets speed to 21 but player is already moving

The triggers are both hit … yielding will allow two calls on top of each other … that is the error

Welcome to multitask programming :slight_smile:

Two simple solutions

  1. write a non yielding delay
  2. use private bools and track the trigger states

Option 2 looks like this

// place these at top of class
   private bool trigA = false;
   private bool trigB = false;</code>
</pre>
<pre>`// now fix your code sample 
        if  (col.gameObject.tag == "trigA") {
            trigA = true;                             // set trigA bool
            speed = 0f;
            yield return new WaitForSeconds(1);
            trigA = false;                           // clear trigA bool
            if (!trigB) speed = 21f;                 // if trigB isn't active release
        }
        if (col.gameObject.tag == "trigB") {
            trigB = true;                            // set trigB bool
            speed = 0f;
            yield return new WaitForSeconds(2);
            trigB = false;                           // release trig B bool
            if (!trigA) speed = 21f;                 // if trigA isn't active release 
         }

`

None of those code will work I guarantee because noone has understood the problem at all.

The problem is the wait inside a function with yield … be clear that is the problem.

When the object hits both triggers together, the nightmare case let me describe it in detail

trigA is calculated to be hit by the unity engine and it passes out the call and you set speed to 0.

we get half way thru that call and then yield FOR A HUGE 1 SECOND

trigB will be calculated by the unity engine and it will pass out the call and you will set speed to 0

we get half way thru that call and then yield FOR A HUGE 2 SECOND

zzzzzzz … sometime later by the original 1 second yield

trigA call comes back out and sets the speed back to 21f

zzzzzzz … sometime later by the trigB 2 second yield

trigB call comes back out and sets the speed back to 21f

Now walk thru all of the code provided above and confirm it does not fix the problem !!!

You aren’t supposed to wait in calls, Do something intelligent like set a timer and do the setting of the speed back when the timer zeros etc.

If you really are going to wait in a call that can go re-enterant, you have to deal with re-enterant which none of the code above does.

There is nothing wrong with either code but they won’t fix this problem which is about wait and reentrancy