[Solved]OnCollisionStay stops as soon as Co-Routine finishes.

Hello Devs,

Scenario:
Game : Top-Down View.
I have a player and an object. When the player collides with the object. The object disables the controls for ‘n’ seconds. For ‘m’ seconds, there is no interaction after ‘m’ seconds, the objects pushes the player (rigidbody) using addforce.

Problem :
The Monobehaviour functions I use are OnCollisionEnter,Exit & Stay. Plus I also use a co-routine which waits for ‘m’ seconds. After ‘m’ seconds I change a boolean value which in turn activate the force on the rigidbody on the OnCollisionStay function. Now, what happens is - sometimes OnCollisionStay does not work as soon as the boolean changes. I just do not know why. My player has for joints and all those joints do not have collider. I have attached the script.

CODE:

using UnityEngine;
using System.Collections;

public class nestDock : MonoBehaviour 
{
	CompletePl playerRoutine;
	float choice;
	bool EVADE;
	Vector3 hitdir;
	// Use this for initialization
	void Start ()
	{
		playerRoutine = (CompletePl)GameObject.FindGameObjectWithTag("Player").GetComponent<CompletePl>();
		choice = (int)Random.Range(1,5);
		EVADE = false;
		switch((int)choice)
		{
			case 1:
				hitdir = new Vector3(Random.Range(5f,10f),Random.Range(0f,20f),Random.Range(5f,10f));
				break;
			case 2:
				hitdir = new Vector3(Random.Range(-5f,-10f),Random.Range(0f,20f),Random.Range(5f,10f));
				break;
			case 3:
				hitdir = new Vector3(Random.Range(5f,10f),Random.Range(0f,20f),Random.Range(-5f,-10f));
				break;
			case 4:
				hitdir = new Vector3(Random.Range( -5f,-10f),Random.Range(0f,20f),Random.Range(-5f,-10f));
				break;
			default:
				hitdir = new Vector3(Random.Range(5f,10f),Random.Range(0f,20f),Random.Range(5f,10f));
				break;			
		}
		choice = Random.Range(3f,5f);	
	}
	
	void OnCollisionEnter(Collision hit)
	{
		if (hit.collider.tag == "Player")	
		{
			playerRoutine.StartCoroutine(playerRoutine.NullAccel(choice));
			StartCoroutine(escapeSeq(choice--));
			playerRoutine.AUTONULL = true;
		}
	}
	
	void OnCollisionStay(Collision hit)
	{
		Vector3 dir;
		dir = new Vector3(hitdir.x,0,hitdir.z);
		if (hit.collider.tag == "Player")
		{
			Debug.Log("Leaf is here & EVADE = "+ EVADE);	
			if(EVADE)
			{
				StopCoroutine("escapeSeq");
				hit.rigidbody.AddForce(Time.deltaTime*400*dir,ForceMode.Acceleration);
				Debug.LogWarning("hitdir = "+hitdir);
			}
		}
	}
	
	public IEnumerator escapeSeq(float waitTime)
	{
		yield return new WaitForSeconds(waitTime);
		EVADE = true;
Debug.Log(EVADE);

	}
	
	void OnCollisionExit(Collision hit)
	{
		if (hit.collider.tag == "Player")
		{
			if(EVADE)
				EVADE = false;	
			playerRoutine.AUTONULL = false;
			Debug.LogError("Exit");
		}
	}
	
	void OnGUI()
	{
		GUI.Label(new Rect(10, 10, 100, 50), EVADE.ToString());
		//GUI.Label(new Rect(10, 50, 100, 50), playerRoutine.rigidbody.velocity.ToString());
	}
}

Please look into it, and help if you could. If I am not audible in the way I explain, I would be glad to explain a bit more.

Your help is much appreciated.

ScreenShot :
alt text

Thank you,

regards,

Karsnen.

Kars, there does seem to be something wrong … what you are doing should be incredibly simple, something has gone wrong

One issue did you check out unityGEMS.com for an explanation of using the very simple timers in Unity, Invoke and InvokeRepeating

Regarding the concept TURN OFF THE CONTROLS FOR A FEW SECONDS

it should be no harder than this …

controlsNotAvailable = true;
Invoke( "turnControlsOn", 3.50 );

function turnControlsOn() { controlsNotAvailable = false; }

so that’s done. never use “waitforseconds” or whatever it is far too complex

Regarding the concept “apply force for a few seconds”.

I would consider doing it the simplest way humanly possible. As you know force is applied in FixedUpdate(). So to do this most easily and reliably…

FixedUpdate()
{
if ( applyThatForceAtTheMoment )  ForceAdd .. blah
}

and then exactly like above

applyThatForceAtTheMoment = true;
Invoke( "forceOff", 3.50 );

function forceOff() { applyThatForceAtTheMoment = false; }

it’s a case of KISS to the max. hope it helps!

you MUST unit test each separate concept