I am working on a project, and would really appreciate an answer as to why this throws an error at runtime. It’s the part below the comment: //Either way i.transform is added to the list if the enemy is on the enemy list.
Any assistance is much appreciated!
using UnityEngine;
using System.Collections;
public class NPCAI : MonoBehaviour {
public Transform player;
public Transform myTransform;
void Awake(){
myTransform = transform;
player = GameObject.FindGameObjectWithTag("Player").transform;
}
public enum State{
wander,
panic,
attackMob,
followPlayer,
}
private State npcState;
public Transform[] enemyList = new Transform[1];
public Transform badGuy = null;
public bool Alive = false;
public bool fightsMobs = false;
public bool followingPlayer = false;
public Transform[] nearbyEnemyList = new Transform[1];
public float localScaleDivisor = 2;
public Transform mobTarget;
public bool chasing = false;
//Finite state machine to control the NPC
public IEnumerator FSM(){
while(Alive){
decideState();
switch(npcState){
case State.wander:
wander();
break;
case State.panic:
panic();
break;
case State.attackMob:
attackMob();
break;
case State.followPlayer:
followPlayer();
break;
}
yield return null;
}
}
//Move at random
public void wander(){
}
//Run away from the mob
public void panic(){
}
//Follow and attack the bad guy
public void attackMob(){
mobTarget = badGuy;
chasing = true;
}
//Follow the player
public void followPlayer(){
mobTarget = player;
chasing = true;
}
//Searches for a bad guy
void OnTriggerEnter(Collider other){
foreach(Transform i in enemyList){
//If the entering object is on the enemy list.....
if(other.gameObject.name == i.gameObject.name){
//Check the indexes to see if there's an empty one, rather than making a special new box for a new enemy
bool foundEmptyIndex = false;
for(int iii = 0; iii < nearbyEnemyList.Length; iii++){
if(nearbyEnemyList[iii] == null) nearbyEnemyList[iii] = i.transform;
foundEmptyIndex = true;
}
//Either way i.transform is added to the list if the enemy is on the enemy list
if(!foundEmptyIndex){
System.Array.Resize(ref nearbyEnemyList, nearbyEnemyList.Length + 1);
Debug.Log(nearbyEnemyList.Length);
nearbyEnemyList[nearbyEnemyList.Length] = i;
}
foundEmptyIndex = false;
}
}
//Gets the enemy with the least distance and sets it as the most threatening
int ii = nearbyEnemyList.Length;
while(ii > 0){
float currentGreatestDistance = 0;
float distance = Vector3.Distance(myTransform.position, nearbyEnemyList[ii].position);
if(distance > currentGreatestDistance) badGuy = nearbyEnemyList[ii];
ii--;
}
}
void OnTriggerExit(Collider other){
int x = nearbyEnemyList.Length;
//Removes the leaving entity from the list of entities in the sphere
while(x > 0){
if(other.transform.position == nearbyEnemyList[x].position) nearbyEnemyList[x] = null;
x--;
}
//Basically checks if the targetted bad guy is the one that left the area
if(other.transform.position == badGuy.position){
int ii = nearbyEnemyList.Length;
//If so, it checks to see for the next most threatening enemy
while(ii > 0){
float currentGreatestDistance = 0;
float distance = Vector3.Distance(myTransform.position, nearbyEnemyList[ii].position);
if(distance > currentGreatestDistance) badGuy = nearbyEnemyList[ii];
ii--;
}
}
}
//Decides the state this NPC is in
public void decideState(){
if(badGuy){
if(fightsMobs) npcState = State.attackMob;
else npcState = State.panic;
}
if(!badGuy){
int ii = nearbyEnemyList.Length;
//Gets the enemy with the least distance and sets it as the most threatening
while(ii > 0){
float currentGreatestDistance = 0;
float distance = Vector3.Distance(myTransform.position, nearbyEnemyList[ii].position);
if(distance > currentGreatestDistance) badGuy = nearbyEnemyList[ii];
ii--;
}
}
if(followingPlayer) npcState = State.followPlayer;
if(!badGuy & !followingPlayer) npcState = State.wander;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
FSM();
if(chasing && mobTarget){
//Grab the distance between the enemy's position and the player's position.
float distance = Vector3.Distance(myTransform.position, mobTarget.position);
float turnSpeed = 10.0f;
//Grab the x angle of the player
float playerXAngle = myTransform.rotation.x;
float playerZAngle = myTransform.rotation.z;
//Rotate the enemy to point towards the player.
myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(mobTarget.position - myTransform.position), turnSpeed * Time.deltaTime);
//Set the angle of the enemy to the original x position.
myTransform.rotation = new Quaternion(playerXAngle,myTransform.rotation.y,playerZAngle,myTransform.rotation.w);
//Grab the y position of the terrain the enemy is at.
float ypos = Terrain.activeTerrain.SampleHeight(myTransform.position);
//Shift the enemy up based of the size of the enemy.
float localScaleModifier = transform.localScale.y / localScaleDivisor;
//Reposition the enemy to the proper y position based off the terrain, and then move the enemy forward if the distance
//between the player and the enemy is greater than 0.8
myTransform.position = new Vector3(myTransform.position.x, ypos + localScaleModifier,myTransform.position.z);
if(distance > 0.8) myTransform.position += myTransform.forward * Time.deltaTime;
}
}
}