I’m trying to create a game AI where it uses a tier-based system (that uses an array of lists of transforms) to support a pathfinding algorithm. Thus far, I’m around 99% the logic for the pathfinding algorithm works, though I’ve yet to test it because I get an NRE error when I test my pathfinding target acquisition. The error seems to occur in line 185 of the code (where it says drawnPath.Add(target.transform); in the Patrol function) no matter what I do. The debugs never occur and I am extremely frustrated because as far as I’m concerned, I have everything else assigned, not to mention the fact that I have an if target == null statement right in the Patrol function! Can anyone help?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class AIHovercraft : MonoBehaviour {
public float hoverHeight;
public float hoverForce;
private float hoverStandard;
public float speed;
private Rigidbody rb;
private bool onGround;
private bool falling;
[SerializeField]
private NavMeshAgent enemy;
public HoverVehicle player;
public GameObject[] hovercraft;
private int tier;
private float altitude;
private WaitForSeconds altCheckDelay = new WaitForSeconds(0.06f);
private bool canCheck;
public enum State
{
EVADE,
CHASE,
PATROL
}
public State state;
private bool alive;
public GameManagement gManager;
#region EVADE
private int wIndex;
private Vector3 eDirect;
private int eModifier;
private WaitForSeconds waitForDamage = new WaitForSeconds(2f);
private bool hasTakenDamage;
#endregion
#region CHASE
private GameObject target;
#endregion
#region PATROL
List<Transform>[] allWaypoints;
List<Transform> drawnPath = new List<Transform>();
private int pWIndex;
public float maxDistance;
public float threatDistance;
public float nearestDistance;
private float nearestStaticDistance;
private bool isMarked;
#endregion
private void Awake()
{
allWaypoints = new List<Transform>[gManager.tiers];
int i = 0;
foreach (List<Transform> tier in allWaypoints)
{
allWaypoints *= new List<Transform>();*
i++;
}
}
private void Start()
{
rb = GetComponent();
enemy = GetComponent();
enemy.updatePosition = true;
enemy.updateRotation = false;
state = State.PATROL;
alive = true;
hasTakenDamage = false;
canCheck = true;
nearestStaticDistance = nearestDistance;
//Start FSM
StartCoroutine(“FSM”);
}
private void Update()
{
CheckTier();
}
int CheckTier()
{
int i = 1;
foreach (int height in gManager.tierThresholds)
{
if (transform.localPosition.y > height)
{
tier = i;
}
i++;
}
StartCoroutine(“TierDelay”);
return tier;
}
IEnumerator FSM()
{
while (alive)
{
switch (state)
{
case State.PATROL:
Patrol();
break;
case State.CHASE:
Chase();
break;
case State.EVADE:
Evade();
break;
}
yield return null;
}
}
IEnumerator TierDelay()
{
yield return altCheckDelay;
}
void Patrol()
{
foreach (GameObject hc in hovercraft)
{
float targetDistance = Vector3.Distance(hc.transform.position, transform.position);
float targetAngle = Vector3.Angle(transform.position, hc.transform.position);
var direction = hc.transform.position - transform.position;
if (targetDistance <= maxDistance && targetAngle <= 90 && targetDistance < threatDistance)
{
Ray ray = new Ray(transform.position, direction);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.CompareTag(“Hovercraft”))
{
threatDistance = targetDistance;
target = hc;
state = State.CHASE;
return;
}
}
}
}
nearestDistance = nearestStaticDistance;
if (target == null)
{
pWIndex = 0;
foreach (Transform point in allWaypoints[0])
{
float targetDistance = Vector3.Distance(point.transform.position, transform.position);
float targetAngle = Vector3.Angle(transform.position, point.transform.position);
var direction = point.transform.position - transform.position;
if (targetDistance <= maxDistance && targetAngle <= 90 && targetDistance < nearestDistance)
{
nearestDistance = targetDistance;
target = point.gameObject;
}
}
drawnPath.Add(target.transform);
isMarked = false;
DrawPath();
foreach (Transform waypoint in drawnPath)
{
Debug.Log(waypoint);
}
}
}
private void DrawPath()
{
for (int i = 0; i < 4; i++)
{
Vector3 originPosition = drawnPath*.position;*
RaycastHit hit;
while (!isMarked)
{
eModifier = UnityEngine.Random.Range(-1, 2);
if (eModifier == -1)
{
Physics.Raycast(originPosition, -transform.right, out hit);
if (hit.collider.gameObject.layer == tier + 7)
{
target = hit.collider.gameObject;
}
}
else if (eModifier == 0)
{
Physics.Raycast(originPosition, transform.forward, out hit);
if (hit.collider.gameObject.layer == tier + 7)
{
target = hit.collider.gameObject;
}
}
else if (eModifier == -1)
{
Physics.Raycast(originPosition, transform.right, out hit);
if (hit.collider.gameObject.layer == tier + 7)
{
target = hit.collider.gameObject;
}
}
else if (eModifier == 2)
{
Physics.Raycast(originPosition, transform.forward, out hit);
if (hit.collider.gameObject.layer == tier + 7)
{
target = hit.collider.gameObject;
}
}
if (target != null)
{
isMarked = true;
}
}
drawnPath.Add(target.transform);
isMarked = false;
}
}
void Chase()
{
Debug.Log("Chasing " + target.name);
}
void Evade()
{
}
public void AccountWaypoints(Transform[] waypoints)
{
foreach (Transform waypoint in waypoints)
{
allWaypoints[waypoint.gameObject.layer - 8].Add(waypoint);
}
}
private void FixedUpdate()
{
Hover();
}
private void Hover()
{
RaycastHit hit;
Ray ray = new Ray(transform.position, -transform.up);
if (Physics.Raycast(ray, out hit, hoverHeight))
{
float proportionalHeight = (hoverHeight - hit.distance) / hoverHeight;
Vector3 appliedHoverForce = transform.up * proportionalHeight * hoverForce;
//ForceMode.Acceleration helps smooth out the hovering.
rb.AddForce(appliedHoverForce, ForceMode.Acceleration);
onGround = true;
falling = false;
}
else if (!Physics.Raycast(ray, out hit, hoverHeight + 1f))
{
onGround = false;
falling = true;
}
}
}