I’m having a problem with updating my list when an enemy dies. Unity gives me the error “Argument is out of range” when line 67 is called. ie, when i try to remove the enemy i just killed. Is this the proper way to do this?
some info: using a trigger to add to the list, and KillTargetInList is called when the enemy dies.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Gouloriginal : MonoBehaviour {
public Enemy2D enemy2D;
public Transform target;
public Transform player;
public int moveSpeed;
private Transform goul;
public int idleDistance = 1;
public int enemyMaxDistance = 20;
public int enemyMinDistance = 2;
//attack vars
public float attackRange = 2;
float attackRate = 1f;
float coolDown = 1;
public int goulDamage = 10;
public List<Transform> myList;
public bool enemyDied;
//12+ hours on this fucking script...
void Awake(){
goul = transform;
}
void Start () {
myList = new List<Transform> ();
GameObject po = GameObject.FindGameObjectWithTag("Player");
player = po.transform;
}
void Update (){
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
void FixedUpdate () {
if( target != null Vector3.Distance (goul.position, target.position) < attackRange){
target = myList [0];
if (Time.time >= coolDown){
GoulAttack();
coolDown = Time.time + attackRate;
}
}
if (target == null || Vector3.Distance (goul.position, target.position) > enemyMaxDistance){
if (Vector3.Distance (goul.position, player.position) > idleDistance) {
if (player.position.x < goul.position.x) {
goul.position -= goul.right * moveSpeed * Time.deltaTime; // player is left of goul, move left
} else if (player.position.x > goul.position.x) {
goul.position += goul.right * moveSpeed * Time.deltaTime; // player is right of goul, move right
}
}
}
else if (target != null) {
if (Vector3.Distance (player.position, target.position) < enemyMaxDistance Vector3.Distance (goul.position, target.position) > enemyMinDistance) {
if (target.position.x < goul.position.x) {
goul.position -= goul.right * moveSpeed * Time.deltaTime; // target is left of goul, move left
} else if (target.position.x > goul.position.x) {
goul.position += goul.right * moveSpeed * Time.deltaTime; // target is right of goul, move right
}
}
}
Debug.DrawLine(player.position, goul.position, Color.yellow);
if (target != null) {
Debug.DrawLine (target.position, goul.position, Color.green);
}
}
public void KillTargetInList(){
myList.RemoveAt (0);
Debug.Log ("enemy dead");
}
void OnTriggerEnter (Collider tripwire){
if (tripwire.tag == "Enemy") {
myList.Add (tripwire.transform);
target = myList [0];
}
}
private void GoulAttack(){
//find target with tag
if (target != null target.gameObject.tag == "Enemy") {
//send damage call to enemy script
target.gameObject.SendMessage ("EnemyDamaged", goulDamage, SendMessageOptions.DontRequireReceiver);
}
}
}
I’m going to post all the corresponding scripts so you can get the full picture.
player pushes the “F” key to spawn a goul.
how the goul spawns isn’t important.
Goul spawns:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Gouloriginal : MonoBehaviour {
public Enemy2D enemy2D;
public EnemyManager enemyManager;
public Transform target;
public Transform player;
public int moveSpeed;
private Transform goul;
public int idleDistance = 1;
public int enemyMaxDistance = 20;
public int enemyMinDistance = 2;
//attack vars
public float attackRange = 2;
float attackRate = 1f;
float coolDown = 1;
public int goulDamage = 10;
public bool enemyDied;
//12+ hours on this fucking script...
void Awake(){
goul = transform;
}
void Start () {
GameObject po = GameObject.FindGameObjectWithTag("Player");
player = po.transform;
}
void Update (){
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
void FixedUpdate () {
if( target != null Vector3.Distance (goul.position, target.position) < attackRange){
if (Time.time >= coolDown){
GoulAttack();
coolDown = Time.time + attackRate;
}
}
if (target == null || Vector3.Distance (goul.position, target.position) > enemyMaxDistance){
if (Vector3.Distance (goul.position, player.position) > idleDistance) {
if (player.position.x < goul.position.x) {
goul.position -= goul.right * moveSpeed * Time.deltaTime; // player is left of goul, move left
} else if (player.position.x > goul.position.x) {
goul.position += goul.right * moveSpeed * Time.deltaTime; // player is right of goul, move right
}
}
}
else if (target != null) {
if (Vector3.Distance (player.position, target.position) < enemyMaxDistance Vector3.Distance (goul.position, target.position) > enemyMinDistance) {
if (target.position.x < goul.position.x) {
goul.position -= goul.right * moveSpeed * Time.deltaTime; // target is left of goul, move left
} else if (target.position.x > goul.position.x) {
goul.position += goul.right * moveSpeed * Time.deltaTime; // target is right of goul, move right
}
}
}
Debug.DrawLine(player.position, goul.position, Color.yellow);
if (target != null) {
Debug.DrawLine (target.position, goul.position, Color.green);
}
}
public void KillTargetInList(){
if (enemy2D.enemyDead == true) {
Debug.Log (enemyManager.myList.Count);
//myList.RemoveAt(0);
//target = myList [1];
target = null;
}
else
Debug.Log("nothing in list");
}
private void GoulAttack(){
//find target with tag
if (target != null target.gameObject.tag == "Enemy") {
//send damage call to enemy script
target.gameObject.SendMessage ("EnemyDamaged", goulDamage, SendMessageOptions.DontRequireReceiver);
}
}
}
when an enemy trips the trigger collider, player passes the transform to the enemy manager:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerPetTarget : MonoBehaviour {
public Gouloriginal goul;
public EnemyManager enemyManager;
void OnTriggerEnter (Collider tripwire){
if (tripwire.tag == "Enemy") {
enemyManager.myList.Add (tripwire.transform);
goul.target = enemyManager.myList [0];
Debug.Log (enemyManager.myList.Count);
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class EnemyManager : MonoBehaviour {
public List<Transform> myList;
// Use this for initialization
void Start () {
myList = new List<Transform> ();
}
// Update is called once per frame
void Update () {
}
}
BUT when the enemy enters the trigger i get a “Object reference not set to instance of an object” error.