Kinda lost here

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?

1 Like

Sorry for being vague. what happens is that when I take and end a turn i get this error

. Me enemy doesnt move and the count of issues keep rising.
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

1 Like

Privacy & Terms