Obstacle Avoidance in Unity, using raycasts. C#

I am using some rudimentary obstacle avoidance algorithm to avoid obstacles, however i am having issues with the right and left sensors. When both are active. they will cancel their rotations and not rotate at all. Also having a bit of trouble figuring out hit.normals via the front sensor.

 ray = new Ray(transform.position + Vector3.up, transform.forward);
 Vector3 posInicial = transform.position;
 float speed = 10f;
     if (Physics.Raycast(ray, out hit, 55f)) // Front sensor
     {
         if (hit.collider.tag == ("Pick Up")) // If robot detects pick up, it goes towards it
         {
             Debug.DrawLine(ray.origin, hit.point, Color.red);
             transform.position = Vector3.MoveTowards(transform.position, hit.point, Time.deltaTime * speed);
         }
         else
         {
             transform.Rotate(0, -80 * Time.deltaTime, 0); // Rotate if front sensor doesn't detect pick up
             Debug.DrawLine(ray.origin, hit.point, Color.blue);
         }
     }
     else
     {
         transform.position += transform.forward * speed * Time.deltaTime; // Go forward
         Debug.DrawLine(ray.origin, hit.point, Color.white);
     }
     if (Physics.Raycast(posInicial, Quaternion.AngleAxis(45f, transform.up) * transform.forward, out hit2, 20f))
     {
         transform.Rotate(0, -80 * Time.deltaTime, 0); // Rotate left if right detected
         Debug.DrawLine(posInicial, hit2.point, Color.yellow);
     }
     if (Physics.Raycast(posInicial, Quaternion.AngleAxis(-45f, transform.up) * transform.forward, out hit3, 20f))
     {
         transform.Rotate(0, 80 * Time.deltaTime, 0); // rotate right if detected left
         Debug.DrawLine(posInicial, hit3.point, Color.cyan);
     }
 }

Not rotating when there is an obstacle both left and right seems correct to me, otherwise you would turn towards one of them… :slight_smile:

I think the solution is to restructure the logic and put the thinking on a higher level. That is, first gather all the information, then decide what to do. For example, you could first do all 3 raycasts, then decide using the results of all what to do.

Using pseudo-code:

raycast front, left, and right
if (pickup in front) { move forward }
else if (something in front) {
    if (obstacle to left) { turn right }
    else if (obstacle to right) { turn left }
    else { /* it's a wall - turn around? */ }
}
else { // nothing in front - check for side obstacles
    if (obstacle to left AND obstacle to right) { /* it's a funnel - turn around? */ }
    else if (obstacle to left) { turn right }
    else { turn left }
}

Note that because we first always check obstacle to left, the algorithm will tend to steer right. You could randomise which one is checked first to keep it more balanced.

Also, the cases for when there is an obstacle in to left and/or right don’t seem to depend on if there is an obstacle in front, so they could probably be merged (refactored).