rpg enemy target gives null reference
after giving my enemy a target it shows a null reference in the editor, it seems to be in line 90
if (HeroToAttack.GetComponent<HeroSM>() != null)
{
DoDamage();
}
line that i added only to avoid any null reference that will show in line 105
HeroToAttack.GetComponent<HeroSM>().TakeDamage(calcDamage);
the idea is that my enemy gets a random target from the heroes performing list, i do this using state machines.
here is the one of the enemy:
using UnityEngine; using System.Collections; using UnityEngine.UI;
public class EnemySM : MonoBehaviour {
public EnemyStats Enemy;//creamos a enemigo desde la plantilla
private BattleState BS;
public bool actionStarted = false;
public GameObject Description;
private HandleTurn myAttack;
public enum enemyTurn
{
PROCESSING,
CHOOSEACTION,
WAITING,
ACTION,
DEAD
}
public static enemyTurn currentEnemyTurn;
private float curCooldown = 0f;
private float maxCooldown = 8f;
//para cambiar las barras
private float curHealth;
public GameObject HeroToAttack;
// Use this for initialization
void Start()
{
myAttack = new HandleTurn();
currentEnemyTurn = enemyTurn.PROCESSING;
BS = GameObject.Find("BM").GetComponent<BattleState>();
}
// Update is called once per frame
void Update()
{
if (GMScript.InBattle == true)
{
curHealth = Enemy.CurrentHp;
switch (currentEnemyTurn)
{
case (enemyTurn.PROCESSING):
UpgradeBar();
break;
case (enemyTurn.CHOOSEACTION):
//print("enemy chooseaction");
ChooseAction();
currentEnemyTurn = enemyTurn.WAITING;
break;
case (enemyTurn.WAITING):
//idle state
break;
case (enemyTurn.ACTION):
// print("enemy action");
StartCoroutine(TimeForAction());
break;
case (enemyTurn.DEAD):
break;
}
}
}
void ChooseAction()
{
myAttack = new HandleTurn();
myAttack.Attacker = Enemy.baseName;
myAttack.Side = "Enemy";
myAttack.AttackerGO = this.gameObject;
myAttack.TargetGO = BS.HeroInGame[Random.Range(0, BS.HeroInGame.Count)];
HeroToAttack = myAttack.TargetGO;
int num = Random.Range(0, Enemy.Attacks.Count);//se genra un numero aleatorio entre 0 y la cantidad de ataques
myAttack.chooseAttack = Enemy.Attacks[num];//usamos el numero para escoger el ataque
Debug.Log(this.gameObject.name + " has choosen " + myAttack.chooseAttack.attackName + " and did " + myAttack.chooseAttack.attackDamage + " damage!!!");
BS.CollectActions(myAttack);
}
private IEnumerator TimeForAction()//controla variables atraves del tiempo
{
if (actionStarted == true)
{
yield break;
}
actionStarted = true;
//wait
//do damage
if (HeroToAttack.GetComponent<HeroSM>() != null)
{
DoDamage();
}
//remove from bs list
BS.PerformList.RemoveAt(0);//remueve al objeto en 0, el siguiente sube transformando el 1 en 0
//continua removiendo hasta desaparecer todo
//reset bs to wait
BS.battleStates = BattleState.performAction.WAIT;
//al pasar a wait y saltar a takeaction los objetos vuelven a crearse repitiendo el ciclo
//end coroutine
actionStarted = false;
currentEnemyTurn = enemyTurn.PROCESSING;
}
void DoDamage()
{
float calcDamage = Enemy.Fue * BS.PerformList[0].chooseAttack.attackDamage;
print(calcDamage);
HeroToAttack.GetComponent<HeroSM>().TakeDamage(calcDamage);
}
void UpgradeBar()
{
print(curCooldown);
curCooldown = curCooldown + Time.deltaTime;
if(curCooldown >= maxCooldown)
{
currentEnemyTurn = enemyTurn.CHOOSEACTION;
curCooldown = 0f;
}
}
}
kind of a long script, i think the place to check is in the do damage or timeforaction functions but cant seem to find anything.
it works with the help of another state machine wich also handles another herostatemachine but its just so much code for a question plus i doubt the error is there.
but just in case here are two small chunks that may be related to the problem
this is takedamage:
public void TakeDamage(float getDamageAmount)
{
hero.CurrentHp -= getDamageAmount;
if (hero.CurrentHp <= 0)
{
currentHeroTurn = heroTurn.DEAD;
}
}
and this interacts with the lists
if (PerformList[0].Side == "Enemy")
{
EnemyS$$anonymous$$ ES$$anonymous$$ = performer.GetComponent<EnemyS$$anonymous$$>();
ES$$anonymous$$.HeroToAttack = PerformList[0].TargetGO;
EnemyS$$anonymous$$.currentEnemyTurn = EnemyS$$anonymous$$.enemyTurn.ACTION;
}
Your answer
