-1
\$\begingroup\$

I have an enemy that is supposed to go in one direction and after hitting the wall or if a certain amount of time passes, it should turn around and go back. After hitting another wall, it should turn around again and keep doing this in a loop.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Want to show us your code so we can help you build on it? \$\endgroup\$
    – DMGregory
    Commented Feb 3, 2021 at 1:27
  • \$\begingroup\$ i dont have any code at all i tried a few things but they didnt do much so i just asked if theres code that can do that cuz i was tired of doing google searches i was using transform.position that was the only one that moved the object and this is a 2D game \$\endgroup\$ Commented Feb 3, 2021 at 1:48
  • 2
    \$\begingroup\$ We don't even know if you're working in 2D or 3D, using Rigidbodies or navmesh or transform.position, so we need a lot more specifics to be able to help you with this. \$\endgroup\$
    – DMGregory
    Commented Feb 3, 2021 at 1:52
  • \$\begingroup\$ 2D and transform \$\endgroup\$ Commented Feb 3, 2021 at 1:54
  • 1
    \$\begingroup\$ @D.Kallan that looks like about the best advice we can offer this user, given the dearth of information they've given us to work with. Want to post it as an answer below? \$\endgroup\$
    – DMGregory
    Commented Feb 3, 2021 at 13:12

2 Answers 2

1
\$\begingroup\$

As mentioned in my comment, I would look at what exactly you need and make steps that you can work on.

"An enemy has to move in a direction until conditions are met, then turn around."

So you can start by looking up how to move an object (either by transform.position or by physics with rigidbodies, etc.). Instead of going to position x or y, you can let it move indefinitly.

You can add a boolean somewhere in that movement, if it is changed, the direction it moves in inverts. When your conditions are met again, the boolean flips back to it's initial state, turning the character back around to the original direction, etc.

Then have checks to change that bool. Certain amount of time: make a timer and when it elapses, change the bool. For hitting a wall: search for object collision with walls (maybe a trigger on the enemy and collider on the wall, so when the wall enters the trigger, the bool is flipped)?

These are just some pointers to go on, there are multiple ways to approach it, but this should get you something workable and steps to lookup / learn.

\$\endgroup\$
1
\$\begingroup\$

Build a Finite State Machine

Finite State Machines (FSM) are a simple but effective programming pattern which is very useful for implementing the behavior of AI enemies.

FSM's in a nutshell:

  • An enemy can be in different states
  • Its current behavior depends on what state they are currently in
  • Certain conditions might cause them to switch to a different state, thus changing their behavior

In this case, the state machine which describes the behavior of your enemy has only two states:

  1. MOVE_LEFT state:
    • Move to the left.
    • When a certain amount of time passed, reset that timer and change to the MOVE_RIGHT state.
    • When there is a wall to the left, reset the timer and transit to the MOVE_RIGHT state.
  2. MOVE_RIGHT state:
    • Move to the right
    • When a certain amount of time passed, reset that timer and change to the MOVE_LEFT state
    • When there is a wall to the right, reset the timer and transit to the MOVE_LEFT state.

So how would a basic implementation of this pattern look in Unity?

First you need to define the states and a variable to store the current state. You only have two states right now, so a bool currentState variable could do the job. But you might want to add more than those two states later, so I would recommend to use an enum instead:

private enum States {
    MOVE_RIGHT,
    MOVE_LEFT
}
private State currentState;

Then your Update() method could use a switch(currentState) to execute different code depending on the current state: Moving left it's in the MOVE_LEFT state and move right when it's in the MOVE_RIGHT state. That code should also include the code to check if the condition for switching the state is met, and when that's the case change currentState to the respective other state.

How would a more advanced implementation look?

When you have an enemy with a lot of states and when those states get pretty complex regarding their behavior and transition logic, then it can be useful to not just create an enumeration and a large switch statement, but to create a separate C# class for every possible state. All these classes which represent states for the same type of entity should implement the same interface (or alternatively: extend the same abstract base-class). When I implement the FSM state pattern this way, then my IState interface usually has these methods

  • Enter which gets called when transitioning to this state.
  • Update which gets called each frame while the FSM is in this state.
  • Leave which gets called when transitioning out of this state.

The actual MonoBehaviour which implements the FSM itself then looks something like this:

public class GoombaAI : MonoBehaviour {
    
    public IState<GoombaAI> moveLeftState;
    public IState<GoombaAI> moveRightState;

    Start() {
        moveLeftState = new GoombaMoveLeftState(this);
        moveRightState = new GoombaMoveRightState(this);
        currentState = moveLeftState;
    }

    Update() {
        currentState.Update();
    }

    public void SwitchState(IState<GoombaAI> newState) {
        currentState.Leave();
        newState.Enter();
        currentState = newState;
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .