0

Hello I am new to c# and unity anyone know how to make the AI return to the pre-define waypoint after the player trigger the ai chase player code ? because i've been using this new code and try using agent.setdestination but it keeps giving me index out of range exception. Anyone know how to fix this.

public NavMeshAgent agent;

public Transform player;

public LayerMask whatIsGround, whatIsPlayer;

//Attacking
public float timeBetweenAttacks;
bool alreadyAttacked;

//States
public float sightRange, attackRange;
public bool playerInSightRange, playerInAttackRange;

public float MovementSpeed = 3f;
public float TurningSpeed = 3f;

Vector3 dist;
bool WpReached;
GameObject StartingPoint;
string TargetWpToGo;
private int CurrentWpNumber;
Rigidbody rb;
public Transform[] waypoints;
public int speed;

private int waypointIndex = 0;
}
public GameObject FindClosestWaypoint()
{
    GameObject[] gos;
    gos = GameObject.FindGameObjectsWithTag("Waypoint");
    GameObject closest = null;
    float distance = Mathf.Infinity;
    Vector3 position = transform.position;
    foreach (GameObject go in gos)
    {
        Vector3 diff = go.transform.position - position;
        float curDistance = diff.sqrMagnitude;
        if (curDistance < distance)
        {
            closest = go;
            distance = curDistance;
        }
    }
    return closest;
}
private void SearchWalkPoint()
{
    //Calculate random point in range
    float randomZ = Random.Range(-walkPointRange, walkPointRange);
    float randomX = Random.Range(-walkPointRange, walkPointRange);

    walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ);

    if (Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround))
        walkPointSet = true;
}

private void ChasePlayer()
{
    //patrol = false;
    agent.SetDestination(player.position);
}

private void AttackPlayer()
{
    //Make sure enemy doesn't move
    agent.SetDestination(transform.position);

    transform.LookAt(player);

    if (!alreadyAttacked)
    {
        ///Attack code here
        

        ///End of attack code

        alreadyAttacked = true;
        Invoke(nameof(ResetAttack), timeBetweenAttacks);
    }
}
private void ResetAttack()
{
    alreadyAttacked = false;
}

private void OnDrawGizmosSelected()
{
    Gizmos.color = Color.red;
    Gizmos.DrawWireSphere(transform.position, attackRange);
    Gizmos.color = Color.yellow;
    Gizmos.DrawWireSphere(transform.position, sightRange);
}
private void OnTriggerEnter(Collider other)
{
    if (other.tag == "Waypoint" && !WpReached)
    {
        WpReached = true;
        if (GameObject.Find("wp-" + (CurrentWpNumber + 1)) != null)
            CurrentWpNumber += 1;
        else
            CurrentWpNumber = 0;
    }
    Debug.Log("Current Wp Target : " + CurrentWpNumber);
}

private void OnTriggerExit(Collider other)
{
    if (other.tag == "Waypoint" && WpReached)
    {
        WpReached = false;
    }
}

}

and here is the code i added to make the ai return back to waypoint if the player out of range.I put the code in the private voide lateup();

transform.LookAt(waypoints[CurrentWpNumber].position);
agent.SetDestination(waypoints[CurrentWpNumber].position);

and here is the error that happens the error that happens

Thank you for taking your time reading this.

Progman
  • 16,827
  • 6
  • 33
  • 48

1 Answers1

0

Common way to achieve this with simple A.I is to implement finite-state machine (FSM) where each behaviour is divided in to states. There are plenty of tutorials out there that can teach you how to make one.

With it you could have ReturnToClosestWaypoint state which would find the closest Waypoint, move towards it and when close enough set the state back to something like IdleState or PatrolState.

Your exception is generic array/list exception which is basically telling you that you're trying to get item from the array/list with index that doesn't exists.

Check that CurrentWpNumber is not less than zero and is less than the lenght/size of the waypoints array/list. It's also possible that your waypoints array/list is empty so you could also check if the lenght/size of the array is greater than zero before trying to access it.

if(waypoints == null || waypoints.Length == 0){
    Debug.Log("waypoints array is empty!");
    return;
}

if(CurrentWpNumber < 0 || CurrentWpNumber >= waypoints.Length){
    Debug.Log("No waypoint with index " + CurrentWpNumber);
    return;
}
Pasi Österman
  • 2,002
  • 1
  • 6
  • 13