NavMesh in State Machines class does not work

I want to use state machines to improve my code and make it easier to change anything from it withouth having much dependance on everything, the problem is that I don’t know how to apply the state machines with for example Navegation so that the enemies follow the player.
Unity tells me that only Monobehaviour can Get a Component and I need that it gets it from the exact prefab so that I can create copies of the same and that it does not apply everything to the others.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy1SateManager : MonoBehaviour
{
    Enemy1BaseState currentState;
    public Enemy1MovementState MovementState = new Enemy1MovementState();
    public Enemy1AttackState AttackState = new Enemy1AttackState();
    public Enemy1DeathState DeathState = new Enemy1DeathState();

    void Start()
    {
        currentState = MovementState;
        //"this" is a reference to the Enemy1 context
        currentState.EnterState(this);
    }

    void Update()
    {
        currentState.UpdateState(this);
    }  

    public void SwitchState(Enemy1BaseState state)
    {
        currentState = state;
        state.EnterState(this);
    }
}
using UnityEngine;
using UnityEngine.AI;

public class Enemy1MovementState : Enemy1BaseState
{
    NavMeshAgent navEnemy;
    Transform target;

    public override void EnterState(Enemy1SateManager enemy1)
    {
        navEnemy = GetComponent<NavMeshAgent>();
        target = PlayerManager.instance.player.transform;
    }

    public override void UpdateState(Enemy1SateManager enemy1)
    {
        navEnemy.SetDestination(target.position);
    }
   
    public override void OnCollisionState(Enemy1SateManager enemy1)
    {

    }
}

Can you not just pass any components you need through a constructor?

FSM finite state machines:

This is my position on finite state machines (FSMs):

I’m kind of more of a “get it working first” guy.

Your mileage may vary.

Well, more accurately, you need a reference to either a component or a gameobject to get its components.

When working inside of a monobehaviour derived class, as it is derived from component, you can write just straight GetComponent<T>.

Obviously a plain class is neither of these things, you need a reference to a specific gameobject/component to get its components.

So you can do this in lieu of line 11 of your second script:

navEnemy = enemy1.GetComponent<NavMeshAgent>(); //you have a reference to a component so you get get its sister components

But what @RadRedPanda said is better advice. You should be sending through all required fields in the constructor of a state. This could just be the parent game object of which you find all needed components from.

1 Like