# Unity State machine for beginner - how to shoot state AND jump state

This topic is 460 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi all,

My first post. I am not very skilled yet in programming though have a good idea of the ideas behind how a lot of it works. I've done codecademy courses on Javascript, GIT and am working through their Python course now. I am using Godot as my preferred engine, due to this I've put Python as the topic prefix as it's the closest I could find.

The above is to give an idea of where I'm at.

I've in time found that If Then Else is a bad idea for controlling a character due to the complexity that comes from such a structure and the code turns spaghetti. So I've been researching and have come to state machines. I love the idea of them, but I can't get my head around this issue below. (remember I'm a newb)

[attachment=33096:FSM-export01.png]

If you look at the image attached I have various states and I think I know how to move between them in theory. My issue though is the shooting state. You see I can shoot and idle, shoot and jump, shoot and fly, shoot and run. As it's a state machine and I can only have one state at a time, does that mean I need 4 new states for those combinations? It's a shame if so due to the duplication of so much code. So I thought I'd check here first and see what the community thinks.

Thanks so much and I'm glad to have found this place.

Rob

Edited by Robster

##### Share on other sites
Generally you only want to use a state machine when it contains mutually exclusive states. If you ever have two or more things that you can combine at the same time (like shooting and any movement state), either split them in two different state machines, or use something else instead of a state machine.

Sometimes you don't need a state machine at all and can do everything in a single Update function that gets called once a frame.

such as:

If health is <= 0 and dying animation not playing, play it and return.
If dying animation is done, do game over and return.

Check arrow keys, update velocity.
Check whether the player is touching the ground, if so reset the jumping flag.
If jumping flag is false and jump key is pressed, set jump flag and add lots of upward velocity.
If jumping flag is set and jump key is released quickly, subtract a bit of upward velocity to let the player perform a smaller jump.  Potentially add another flag to prevent the user from repeating this multiple times in the same jump.
If player is capable of flight, holding the jump key while jumping adds a little bit of upward velocity.

If fire key is down, and firing is possible now, then fire.

Apply velocity to position.

If in air, use jumping/flying animation.
Else If on ground and speed > large threshold, use running animation.
Else If on ground and speed > small threshold, use walking animation.
Else if on ground use idle animation.

Edited by Nypyren

##### Share on other sites

For typical player operations, state machine's are really the right tool.  Being an early game you're making, you should really be doing something simple.  For example, assume you're characters have apdate() method called once a frame, for your player character, you'd do something like this:

void Player::Update()
{
if (Input.KeyPressed(LEFT_KEY)) {
Velocity.X = -5; // move left
}
else if (Input.KeyPressed(RIGHT_KEY)) {
Velocity.X = 5; // move right
}

if (IsOnGround) {
if (Input.KeyPressed(JUMP_KEY)) {
Velocity.Y = -30; // set player velocity negative to jump, we'll slow down each frame
IsOnGround = false;
}
else {
// we're in the air, decrease Y velocity each frame to simulate gravity
Velocity.Y += 2;
}

if (Weapon.RefireTimer < GetCurrentTime() && Input.KeyPressed(FIRE_KEY)) {
// shoot a bullet and set refire timer to however long the current weapon's refire time is
Weapon.RefireTimer = GetCurrentTime() + Weapon.RefirePeriod;
}
// store old location, and move player in each axis
// If we're colliding with something, set the velocity to 0 in that direction and reset player's position in that axis
Vector2d OldPosition = Position;
Position.X += Velocity.X;
if (CheckCollision(Position)) {
Position.X = OldPosition.X;
Velocity.X = 0;
}
Position.Y += Velocity.Y;
if (CheckCollision(Position)) {
// if we hit the ground, set onGround
IsOnGround = CheckHitGround(Position);
Position.Y = OldPosition.Y;
Velocity.Y = 0;
}


##### Share on other sites

I love the idea of them, but I can't get my head around this issue below.

State machines are standard everywhere in games. Learn to love them.

I put together this article where I used state machines in several different ways in some simple little prototypes.

You see I can shoot and idle, shoot and jump, shoot and fly, shoot and run

As Nypyren points out, usually they are best when used as discrete things. That is, you are in A, then B, then C.  You can also do work in the transition between A and B, do work in the transition between B and C.

That doesn't mean you can't make it work.  Depending on the animation system you are using, you might be able to control the shooting arm separately from the rest of the body. You'll have one set of body actions that control most things, and another set of arm actions for your shooting.

Some systems will allow more complex animation blending to make it work.  Others will use inverse kinematics (IK) which is a fancy way to say you tell the system where the hand goes and where the shoulder goes and it uses physics to figure out how all the joints fit together. These take a bit of work to put together and thankfully most professional-grade engines have them implemented already.

##### Share on other sites

For typical player operations, state machine's are really the right tool.  Being an early game you're making, you should really be doing something simple.  For example, assume you're characters have apdate() method called once a frame, for your player character, you'd do something like this:

void Player::Update()
{
if (Input.KeyPressed(LEFT_KEY)) {
Velocity.X = -5; // move left
}
else if (Input.KeyPressed(RIGHT_KEY)) {
Velocity.X = 5; // move right
}

if (IsOnGround) {
if (Input.KeyPressed(JUMP_KEY)) {
Velocity.Y = -30; // set player velocity negative to jump, we'll slow down each frame
IsOnGround = false;
}
else {
// we're in the air, decrease Y velocity each frame to simulate gravity
Velocity.Y += 2;
}

if (Weapon.RefireTimer < GetCurrentTime() && Input.KeyPressed(FIRE_KEY)) {
// shoot a bullet and set refire timer to however long the current weapon's refire time is
Weapon.RefireTimer = GetCurrentTime() + Weapon.RefirePeriod;
}
// store old location, and move player in each axis
// If we're colliding with something, set the velocity to 0 in that direction and reset player's position in that axis
Vector2d OldPosition = Position;
Position.X += Velocity.X;
if (CheckCollision(Position)) {
Position.X = OldPosition.X;
Velocity.X = 0;
}
Position.Y += Velocity.Y;
if (CheckCollision(Position)) {
// if we hit the ground, set onGround
IsOnGround = CheckHitGround(Position);
Position.Y = OldPosition.Y;
Velocity.Y = 0;
}


Thank you for the large effort above.  What I found though, having already tried a bunch of if / else type of logic that in time it gets very hard to keep track of and a bit sphagetti, hence my looking into state machines.  I'll definitely have a look over your code though and see what I can learn from it.   I've decided to hold off a week or more whilst I do some more Python lessons to make better use of the available then come back to this thread.  Thanks again.

I love the idea of them, but I can't get my head around this issue below.

State machines are standard everywhere in games. Learn to love them.

I put together this article where I used state machines in several different ways in some simple little prototypes.

You see I can shoot and idle, shoot and jump, shoot and fly, shoot and run

As Nypyren points out, usually they are best when used as discrete things. That is, you are in A, then B, then C.  You can also do work in the transition between A and B, do work in the transition between B and C.

That doesn't mean you can't make it work.  Depending on the animation system you are using, you might be able to control the shooting arm separately from the rest of the body. You'll have one set of body actions that control most things, and another set of arm actions for your shooting.

Some systems will allow more complex animation blending to make it work.  Others will use inverse kinematics (IK) which is a fancy way to say you tell the system where the hand goes and where the shoulder goes and it uses physics to figure out how all the joints fit together. These take a bit of work to put together and thankfully most professional-grade engines have them implemented already.

Thank you for the well written answer.  I used to be a full time animator so am quite aware of IK etc.  It's made me think that maybe I need to look at a modular approach to the character if that's what you're referring to?  I'll do some research in Godot and see if I can force an animation of one body part over the rest.  Still, what I also told the other commentor, I'm going to wait a week or more until I learn more Python.  I just want to get some more fundamentals down so I have the tools to tackle this.  I think I understand it from a conceptual perspective. I just need some actual tool knowlege (the language).  Once I have more of that I'll come back to this thread.  I just wanted to say thank you for now until I come back here.  I realised I was jumping the gun a little.  Thanks again

##### Share on other sites

If you look at the image attached I have various states and I think I know how to move between them in theory. My issue though is the shooting state. You see I can shoot and idle, shoot and jump, shoot and fly, shoot and run. As it's a state machine and I can only have one state at a time, does that mean I need 4 new states for those combinations? It's a shame if so due to the duplication of so much code. So I thought I'd check here first and see what the community thinks.

Shoot and Idle, Shoot and jump, could be two separate states, or it could be three possible states with two OR-ed together.  This obviously really depend on the game you are making and the kind of logic you are aiming for.  Most of the time, if you are looking at a 2D game (I'm assuming so since you mentioned Godot), it's safer to keep them separate.

I also prefer to present my states in a table rather diagrams.  List your states on the Y axis, and the conditions on the X axis, then the values is what happens when condition is met.  For example:

+-----------------+------------------+-------------------+
| State\Condition | BTN_FIRE_PRESSED | BTN_FIRE_RELEASED |
+-----------------+------------------+-------------------+
| STATE_IDLE      | STATE_IDLE_FIRE  |  -                |
| STATE_IDLE_FIRE | -                | STATE_IDLE        |
| STATE_JUMP      | STATE_JUMP_FIRE  | -                 |
| STATE_JUMP_FIRE | -                | STATE_JUMP        |
+-----------------+------------------+-------------------+


Column are the conditions, and each row represent that state you are in, and what state is next if the condition is met.  You can organize this into a two-dimensional array (or one-dimensional if you are old-school), then switching from one state to another is a matter of assigning your current state to the value in the table.

nextState = STATE_TABLE[currentState][condition]
if (nextState != null) {
currentState = nextState
}

Edited by alnite

##### Share on other sites

Your state machine chart looks good. All the states are mutually exclusive, but shooting is something that can be done in all of them except death. Therefore, call your shooting code in addition to updating the state machine. Perhaps with a check to make sure you're not dead (which I would call a special case). Or if you end up needing multiple states where you can't shoot, then instead of special casing each one, you could add a bool canShoot to your data table of stuff related to each state (or create a table if you don't have one already).

Choosing which animation to display can also be done by a table lookup, where you have two animations for each state (one shooting and one not).

##### Share on other sites

This topic is 460 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628740
• Total Posts
2984470
• ### Similar Content

• I need a Unity Developer for a game I've been working on for the past months.
It's a 2D dungeonCrawler with a typing mechanic along with Item specific attacks and Procedule Generated levels.
The development is planned to be 4 months long(up to 8 months maximum).
Although this is a hobby project the person who apply to work on this project will be paid once we(the team) find investors for the game.
Anyone interested Send an Email to netinhocrisosto@gmail.com with your portifolio or just talk about your expereince with Unity.

• THE PROJECT

INT is a 3D Sci-fi RPG with a strong emphasis on story, role playing, and innovative RPG features such as randomized companions. The focus is on the journey through a war-torn world with fast-paced combat against hordes of enemies. The player must accomplish quests like a traditional RPG, complete objectives, and meet lively crew members who will aid in the player's survival. Throughout the game you can side and complete missions through criminal cartels, and the two major combatants, the UCE and ACP, of the Interstellar Civil War.
Please note that all of our current positions are remote work. You will not be required to travel.
Talent Needed

Unity Engine Programmer
3D Animator
We have made great strides in the year 2017! INT has received a comprehensive face-lift compared to the start of the year. We look forward to a productive, fruitful year 2018!
Revenue-Share
This is the perfect opportunity to get into the game development industry. Being an Indie team we do not have the creative restrictions often imposed by publishers or other third parties. We are extremely conscientious of our work and continuously uphold a high level of quality throughout our project.
We are unable to offer wages or per-item payments at this time. However revenue-sharing from crowd-funding is offered to team members who contribute 15-20 hours per week to company projects, as well as maintain constant communication and adhere to deadlines. Currently the crowd-funding campaign is scheduled for the year 2018. Your understanding is dearly appreciated.

Thank you for your time! We look forward to hearing from you!

John Shen