0
\$\begingroup\$

I am new to Game Development and Unity. I have written a component for Jumping and Running, CharacterJumpAbility.cs and CharacterRunAbility.cs.

I would like the Character to be able to Jump only if the Character is not moving. I came across a State Pattern but I can't understand how to apply it. For example if I want to Jump, first I must check if the Character is Running, but I have to do this in the CharacterJumpAbility.cs or in the CharacterController.cs (the component who handles inputs)?

If I define a state for example:

public enum CharacterState {
    Run,
    Jump
}

For example if the player is pressing the space bar, I have to set the Jump state, the code that sets state = CharacterState.Jump should be written in the CharacterJumpAbility.cs or in the component that handles inputs?

And if I want to set a new state for example Jump, while I am running, this is clearly not possible, how to handle situations like these?

\$\endgroup\$
  • \$\begingroup\$ Have you considered making use of the Mecanim animation state machine for managing this type of character state logic? It has a lot of features for building sophisticated state systems, with handling of transitions, conditions, layering, etc. - specifically tailored to working with character movement & ability state management. And you can define custom behaviour scripts to act in particular states \$\endgroup\$ – DMGregory Mar 13 at 0:44
  • \$\begingroup\$ Keep in mind that there is never just one way to do things in software development. You usually have the option to implement a new features in a variety of different components. \$\endgroup\$ – Philipp Sep 4 at 14:10
1
\$\begingroup\$

for working with state pattern, first thing that comes to mind is enum and state. most problem is switch is not OO and most of the time its better to not to use switch-case. and you dont have much freedom to extend. its implemented like below: you can fill cases with any logic you want and you only have to change state variable to change running state.

 enum states {run, jum,shoot,etc }
    states state;
    private void Update()
    {
        switch (state)
        {
            case states.run:
                break;
            case states.jum:
                break;
            case states.shoot:
                break;
            case states.etc:
                break;
            default:
                break;
        }
    }

another approach that is much better is use of delegates like Action. one action runs in all times but you can change assigning function to it. you define it like below: you can change state like what happened in Start callback

  System.Action CurrentState;

    void Shoot() { }
    void Run() { }
    void Jump() { }

    private void Start()
    {
        CurrentState = Run;
    }

    private void Update()
    {
        CurrentState.Invoke();
    }
\$\endgroup\$
1
\$\begingroup\$

It depends on the complexity of your character. Enumerations are fine for simpler characters, but it can become very problematic when character's abilities get expanded.

Virtouso's answer is good, but I'd just like to add how I go about doing state machines a lot of the time.

You can create a base class along these lines:

public abstract class StateBase<T>
{
 public abstract void OnEnter(T owner);
 public abstract void Update(T owner);
 public abstract void OnExit(T owner);
}

Then have a state machine something like this:

public class StateMachine<T>
{
 private T owner;
 private StateBase<T> currentState;

 public void Update()
 {
  currentState.Update(owner);
 }

 public void GoToState(StateBase<T> state)
 {
  //...
 }
}

Obviously, this is very stripped down for an example, but you get the idea. Your running and jumping would inherit from StateBase. This state machine can then easily be re-used across different types.

I'm not a fan of the delegate method because you add a lot of functions, which I don't think is as clear as having classes that are easily found for each state.

I find this eBook very useful: https://gameprogrammingpatterns.com/state.html

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

Here is a good tutorial on the use of the state pattern in your game. If you set your animation controller up right, you can use the OnStateEnter and onStateExit methods of each state to set animator parameters. Hope this helps.

\$\endgroup\$
  • \$\begingroup\$ The text of your answer seems to be at odds with the link you provided. You are talking about using the AnimationController (and i am not so sure if this is a good solution for this situation, by the way), but the link you posted describes a method to create a complete own state machine not based on the Unity animation system. \$\endgroup\$ – Philipp Sep 4 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.