Hello everyone,
This is my first post so I’ll take the chance to introduce myself. My name is Pere and I am a programmer in a small indie game developer called StrangeLightGames. Pleased to meet you!
I’ve encountered a weird problem with yields. I’ve been able to fix it with a dirty trick, but I would like to know if someone has some experience with this issue or knows where the mistake might come from.
We are developing a 2.5 platformer with simple FSM and coroutines. Testing wall jumps we realized it sometimes responded in a different way when you tried to make a wall jump in the same wall. It works fine when the second wall jump makes contact on the wall below the first jump position. The problem comes after we execute a movement called “dash” before the first wall jump. In that case, the second wall jump makes contact on the wall a few points over the first wall jump location.
We use a simple swapping method for our states:
private void SwapHorizontal( StateHorizontal newState ) {
switch( _currentHorizontal ) {
// Finalitzem estats en cas de ser trencats de cop
case StateHorizontal.Idle:
break;
case StateHorizontal.Inertia:
break;
case StateHorizontal.Run:
break;
case StateHorizontal.Crouch:
IncreaseController();
break;
case StateHorizontal.Dash:
StartCoroutine( ResetDash() );
IncreaseController();
break;
case StateHorizontal.Slide:
break;
case StateHorizontal.TripOver:
break;
}
switch( newState ) {
// Inicialitzem el nou estat
case StateHorizontal.Idle:
StartCoroutine( "Idle" );
break;
case StateHorizontal.Inertia:
StartCoroutine ( "Inertia" );
break;
case StateHorizontal.Run:
StartCoroutine( "Run" );
break;
case StateHorizontal.Crouch:
DecreaseController ();
StartCoroutine ("Crouch");
break;
case StateHorizontal.Dash:
StartCoroutine( "Dash" );
break;
case StateHorizontal.Slide:
StopCoroutine(_currentHorizontal.ToString());
StartCoroutine ("Slide");
break;
case StateHorizontal.TripOver:
StopCoroutine(_currentHorizontal.ToString());
StartCoroutine ("TripOver");
break;
}
_currentHorizontal = newState;
}
We then use coroutines for each state, Dash’s one is:
/**
* Coroutina per al dash
*/
private IEnumerator Dash() {
DecreaseController();
bool run = false;
_canDash = false;
movementProps.speed = MovementProperties.DASH_SPEED;
Debug.Log ( "[MainCharControl::smile:ash] pre-yield 0.2f" );
float time = Time.time;
while ( time + 0.2f > Time.time ) {
yield return null;
}
// yield return new WaitForSeconds( 0.2f );
Debug.Log ( "[MainCharControl::smile:ash] post-yield 0.2f" );
// Testegem si es pot aixecar
RaycastHit hit;
bool hitting; // Per saber si ens podem aixecar
float marginTop = 0.3f; // Per saber si ens podem aixecar amb una mica de marge
hitting = Physics.SphereCast( transform.position + _controller.center, _controller.height / 4, transform.up, out hit, _controller.height / 2 + marginTop );
while( hitting ) {
// Debug.Log ("[MainCharControl::smile:ash] Running");
hitting = Physics.SphereCast(transform.position + _controller.center, _controller.height / 2, transform.up, out hit, _controller.height / 2 + marginTop );
// jumpProperties.canJump = !hitting;
yield return null;
}
run = ( _input.xAxis == movementProps.runDirection ); // Si no es la mateixa direccio, fem inertia
StartCoroutine( ResetDash() );
// Swap State
if( run ) {
SwapHorizontal( StateHorizontal.Run );
} else {
SwapHorizontal( StateHorizontal.Inertia );
}
}
I have realized the problem is a yield in the code yield return new WaitForSeconds( 0.2f );
Changing the code for:
while ( time + 0.2f > Time.time ) {
yield return null;
}
the issue seems to disappear.
Anyone knows why this might be happening? Its not a big pain but it makes no sense to me and I would like to know if there is something I’m missing about WaitForSeconds().
Thank you all!