Avoid obstacles with nested coroutines

Hi! I’m making the AI for a race game in a pip and i need to know the way of doing something like:

  1. Raycast forward
  2. if tag enemy
  3. if distance < 20 START COROUTINE Avoid()
  4. in Avoid RANDOM turn direction by change the turnSpeed var SMOOTHLY

The systm works with the var turnSpeed. As it increments the ship transform.position vector.

		// DRIVE FORWARD
		Vector3 forward = transform.TransformDirection (Vector3.forward);
		transform.position = transform.position + forward * speed * Time.deltaTime;
		
		// TURN AROUND
		
		Vector3 turn = transform.TransformDirection (Vector3.right);
		transform.position = transform.position + turn * turnSpeed * Time.deltaTime;

The othe part of the script is:

		// AVOID OTHER SHIPS

		Vector3 front = transform.TransformDirection (Vector3.forward);

		RaycastHit frontHit;

		if (Physics.Raycast (transform.position, front, out frontHit)) {

			if (frontHit.collider.tag == "Ship") {

				if (frontHit.distance < 20.0F) {

					StartCoroutine (Avoid ());
				}
			}
		}

ANd the coroutines:

	IEnumerator Avoid () {

		int randomNum = Random.Range (0, 2);

		if (randomNum == 0) {

			yield return StartCoroutine (TurnLeft ());
			yield return StartCoroutine (TurnRight ());
		}

		if (randomNum == 1) {

			yield return StartCoroutine (TurnRight ());
			yield return StartCoroutine (TurnLeft ());
		}
	}

	IEnumerator TurnLeft () {

		turnSpeed -= turnAccel * speed * Time.deltaTime * 0.2F;
		yield return new WaitForSeconds (0.5F);
		turnSpeed = 0.0F;
	}

	IEnumerator TurnRight () {

		turnSpeed += turnAccel * speed * Time.deltaTime * 0.2F;
		yield return new WaitForSeconds (0.5F);
		turnSpeed = 0.0F;
	}

If it can’t be done with coroutines, I would like to know other methods…
Thanks

Note you can define the length of a raycast and skip your manual distance check. You could also use a single “turn” routine which takes a signed integer argument to determine direction. Bit cleaner.

The foremost problem is, you’re invoking this coroutine every frame the ray hits something. So it’s creating a zillion instances of this coroutine and its TurnLeft and TurnRight byproduct coroutines. You need to create a way for the coroutine to know that it’s busy. Often the most expedient way is a boolean like isBusy. Set it to true when you enter the Avoid() routine. Set to to false at the end of your if-random-zero and if-random-one blocks. If it’s busy, don’t invoke it.