My enemy is in an infinte loop and wont take an action
You will have to give us more than that if you would like us to try and help out. How do you know your enemy is in an infinite loop? Can you show us the infinite loop?
What do you mean by infinite loop? Always moving back and forth between two positions? It’s not doing anything but the enemy turn does not end?
Sorry for being vague. what happens is that when I take and end a turn i get this error
here is my enemyAI Code : using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
private enum State
{
WaitingForEnemyTurn,
TakingTurn,
Busy,
}
private State state;
private float timer;
private void Awake()
{
state = State.WaitingForEnemyTurn;
}
private void Start()
{
TurnSystem.Instance.OnTurnChanged += TurnSystem_OnTurnChanged;
}
private void Update()
{
if (TurnSystem.Instance.IsPlayerTurn())
{
return;
}
switch (state)
{
case State.WaitingForEnemyTurn:
break;
case State.TakingTurn:
timer -= Time.deltaTime;
if (timer <= 0f)
{
if (TryTakeEnemyAIAction(SetStateTakingTurn))
{
state = State.Busy;
} else
{
// No more enemies have actions they can take, end enemy turn
TurnSystem.Instance.NextTurn();
}
}
break;
case State.Busy:
break;
}
}
private void SetStateTakingTurn()
{
timer = 0.5f;
state = State.TakingTurn;
}
private void TurnSystem_OnTurnChanged(object sender, EventArgs e)
{
if (!TurnSystem.Instance.IsPlayerTurn())
{
state = State.TakingTurn;
timer = 2f;
}
}
private bool TryTakeEnemyAIAction(Action onEnemyAIActionComplete)
{
foreach (Unit enemyUnit in UnitManager.Instance.GetEnemyUnitList())
{
if (TryTakeEnemyAIAction(enemyUnit, onEnemyAIActionComplete))
{
return true;
}
}
return false;
}
private bool TryTakeEnemyAIAction(Unit enemyUnit, Action onEnemyAIActionComplete)
{
EnemyAIAction bestEnemyAIAction = null;
BaseAction bestBaseAction = null;
foreach (BaseAction baseAction in enemyUnit.GetBaseActionArray())
{
if (!enemyUnit.CanSpendActionPointsToTakeAction(baseAction))
{
// Enemy cannot afford this action
continue;
}
if (bestEnemyAIAction == null)
{
bestEnemyAIAction = baseAction.GetBestEnemyAIAction();
bestBaseAction = baseAction;
}
else
{
EnemyAIAction testEnemyAIAction = baseAction.GetBestEnemyAIAction();
if (testEnemyAIAction != null && testEnemyAIAction.actionValue > bestEnemyAIAction.actionValue)
{
bestEnemyAIAction = testEnemyAIAction;
bestBaseAction = baseAction;
}
}
}
if (bestEnemyAIAction != null && enemyUnit.TrySpendActionPointsToTakeAction(bestBaseAction))
{
bestBaseAction.TakeAction(bestEnemyAIAction.gridPosition, onEnemyAIActionComplete);
return true;
}
else
{
return false;
}
}
}
From what I can see, it looks like UnitManager.Instance.GetEnemyUnitList()
is returning null. Can you share that method?
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UnitManager : MonoBehaviour
{
public static UnitManager Instance { get; private set; }
private List<Unit> unitList;
private List<Unit> friendlyUnitList;
private List<Unit> enemyUnitList;
private void Awake()
{
if (Instance != null)
{
Debug.LogError("There's more than one UnitManager! " + transform + " - " + Instance);
Destroy(gameObject);
return;
}
Instance = this;
unitList = new List<Unit>();
friendlyUnitList = new List<Unit>();
enemyUnitList = new List<Unit>();
}
private void Start()
{
Unit.OnAnyUnitSpawned += Unit_OnAnyUnitSpawned;
Unit.OnAnyUnitDead += Unit_OnAnyUnitDead;
}
private void Unit_OnAnyUnitSpawned(object sender, EventArgs e)
{
Unit unit = sender as Unit;
unitList.Add(unit);
if (unit.IsEnemy())
{
enemyUnitList.Add(unit);
} else
{
friendlyUnitList.Add(unit);
}
}
private void Unit_OnAnyUnitDead(object sender, EventArgs e)
{
Unit unit = sender as Unit;
unitList.Remove(unit);
if (unit.IsEnemy())
{
enemyUnitList.Remove(unit);
}
else
{
friendlyUnitList.Remove(unit);
}
}
public List<Unit> GetUnitList()
{
return unitList;
}
public List<Unit> GetFriendlyUnitList()
{
return friendlyUnitList;
}
public List<Unit> GetEnemyUnitList()
{
return enemyUnitList;
}
}
OK, that looks fine. Is it possible that UnitManager.Instance
itself is null? Does it exist in the hierarchy? You can put a Debug.Log
in the Awake
or Start
method to see if it runs
I is not in the Hierarchy let me try that
Yeah, it has to be there. MonoBehaviours
don’t run if they are not in the hierarchy
I put it in the hierarchy and im getting the same error. Maybe i don’t have the correct scripts attached.
Fixed thanks
Great! Sorry, I had to go to bed. Enjoy the rest of the course