Yet again another entry for animated sprites, this time to make an attack action.
We'll be working upon the previous part 1 and part 2. Assuming you have your attack action key framed already, we can go and start creating the state machine and set up the states.
- To do this, we need to create a few more variables in our script:
```
extends KinematicBody2D
const ACCELERATION = 500
const MAX_SPEED = 80
const FRICTION = 500
enum {
MOVE,
ROLL,
ATTACK
}
var state = MOVE
var velocity = Vector2.ZERO
onready var animationPlayer = $AnimationPlayer
onready var animationTree = $AnimationTree
onready var animationState = animationTree.get("parameters/playback")
```
- With them, we can update our functions to select the state it's in each time. Now we update the rest of the code
```
func _ready():
animationTree.active = true
func _physics_process(delta):
match state:
MOVE:
move_state(delta)
ROLL:
pass
ATTACK:
attack_state(delta)
func move_state(delta):
var input_vector = Vector2.ZERO
input_vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
input_vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
input_vector = input_vector.normalized()
if input_vector != Vector2.ZERO:
animationTree.set("parameters/Idle/blend_position", input_vector)
animationTree.set("parameters/Run/blend_position", input_vector)
animationState.travel("Run")
velocity = velocity.move_toward(input_vector * MAX_SPEED, ACCELERATION * delta)
else:
animationState.travel("Idle")
velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
velocity = move_and_slide(velocity)
if Input.is_action_just_pressed("attack"):
state = ATTACK
func attack_state(delta):
animationPlayer.play("AttackDown")
```
- However we don't have our BlendingSpace state and the attack goes in loop. So, it's time to add a new blendSpace2D:
- Set transitions from/to Idle, and add your vertex for the attack node
- Now, it gets to do one attack and gets blocked because it doesn't know what to do next. To fix that, we are going to add
add a track (a function) in our animationPlayer for each attack, we'll do one attack here as example
- Select "call method track", and select your player node in the pop-up
- Create a function for the attack finishing in your player script:
```
func attack_animation_finished():
state = MOVE
```
- Go back to your animation animationPlayer and add an animation key in the newly appeared track.
- You want to select your created function `attack_animation_finished`
- Do the same for all your attack animations. Before running the game, your code for the player script should currently look like this:
```
extends KinematicBody2D
const ACCELERATION = 500
const MAX_SPEED = 80
const FRICTION = 500
enum {
MOVE,
ROLL,
ATTACK
}
var state = MOVE
var velocity = Vector2.ZERO
onready var animationPlayer = $AnimationPlayer
onready var animationTree = $AnimationTree
onready var animationState = animationTree.get("parameters/playback")
func _ready():
animationTree.active = true
func _physics_process(delta):
match state:
MOVE:
move_state(delta)
ROLL:
pass
ATTACK:
attack_state(delta)
func move_state(delta):
var input_vector = Vector2.ZERO
input_vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
input_vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
input_vector = input_vector.normalized()
if input_vector != Vector2.ZERO:
animationTree.set("parameters/Idle/blend_position", input_vector)
animationTree.set("parameters/Run/blend_position", input_vector)
animationTree.set("parameters/Attack/blend_position", input_vector)
animationState.travel("Run")
velocity = velocity.move_toward(input_vector * MAX_SPEED, ACCELERATION * delta)
else:
animationState.travel("Idle")
velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
velocity = move_and_slide(velocity)
if Input.is_action_just_pressed("attack"):
state = ATTACK
func attack_state(delta):
animationState.travel("Attack")
func attack_animation_finished():
state = MOVE
```
If you followed this entry carefully, your character should have animations for moving around and attacking.
The next step should be adding hitboxes and hurtboxes, however, since this has become a bit of a big entry, will do those in the next entry. (Meanwhile, you can add a roll action following the attack example)
We'll be working upon the previous part 1 and part 2. Assuming you have your attack action key framed already, we can go and start creating the state machine and set up the states.
- To do this, we need to create a few more variables in our script:
```
extends KinematicBody2D
const ACCELERATION = 500
const MAX_SPEED = 80
const FRICTION = 500
enum {
MOVE,
ROLL,
ATTACK
}
var state = MOVE
var velocity = Vector2.ZERO
onready var animationPlayer = $AnimationPlayer
onready var animationTree = $AnimationTree
onready var animationState = animationTree.get("parameters/playback")
```
- With them, we can update our functions to select the state it's in each time. Now we update the rest of the code
```
func _ready():
animationTree.active = true
func _physics_process(delta):
match state:
MOVE:
move_state(delta)
ROLL:
pass
ATTACK:
attack_state(delta)
func move_state(delta):
var input_vector = Vector2.ZERO
input_vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
input_vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
input_vector = input_vector.normalized()
if input_vector != Vector2.ZERO:
animationTree.set("parameters/Idle/blend_position", input_vector)
animationTree.set("parameters/Run/blend_position", input_vector)
animationState.travel("Run")
velocity = velocity.move_toward(input_vector * MAX_SPEED, ACCELERATION * delta)
else:
animationState.travel("Idle")
velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
velocity = move_and_slide(velocity)
if Input.is_action_just_pressed("attack"):
state = ATTACK
func attack_state(delta):
animationPlayer.play("AttackDown")
```
- However we don't have our BlendingSpace state and the attack goes in loop. So, it's time to add a new blendSpace2D:
- Set transitions from/to Idle, and add your vertex for the attack node
- Now, it gets to do one attack and gets blocked because it doesn't know what to do next. To fix that, we are going to add
add a track (a function) in our animationPlayer for each attack, we'll do one attack here as example
- Select "call method track", and select your player node in the pop-up
- Create a function for the attack finishing in your player script:
```
func attack_animation_finished():
state = MOVE
```
- Go back to your animation animationPlayer and add an animation key in the newly appeared track.
- You want to select your created function `attack_animation_finished`
- Do the same for all your attack animations. Before running the game, your code for the player script should currently look like this:
```
extends KinematicBody2D
const ACCELERATION = 500
const MAX_SPEED = 80
const FRICTION = 500
enum {
MOVE,
ROLL,
ATTACK
}
var state = MOVE
var velocity = Vector2.ZERO
onready var animationPlayer = $AnimationPlayer
onready var animationTree = $AnimationTree
onready var animationState = animationTree.get("parameters/playback")
func _ready():
animationTree.active = true
func _physics_process(delta):
match state:
MOVE:
move_state(delta)
ROLL:
pass
ATTACK:
attack_state(delta)
func move_state(delta):
var input_vector = Vector2.ZERO
input_vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left")
input_vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up")
input_vector = input_vector.normalized()
if input_vector != Vector2.ZERO:
animationTree.set("parameters/Idle/blend_position", input_vector)
animationTree.set("parameters/Run/blend_position", input_vector)
animationTree.set("parameters/Attack/blend_position", input_vector)
animationState.travel("Run")
velocity = velocity.move_toward(input_vector * MAX_SPEED, ACCELERATION * delta)
else:
animationState.travel("Idle")
velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
velocity = move_and_slide(velocity)
if Input.is_action_just_pressed("attack"):
state = ATTACK
func attack_state(delta):
animationState.travel("Attack")
func attack_animation_finished():
state = MOVE
```
If you followed this entry carefully, your character should have animations for moving around and attacking.
The next step should be adding hitboxes and hurtboxes, however, since this has become a bit of a big entry, will do those in the next entry. (Meanwhile, you can add a roll action following the attack example)
No comments:
Post a Comment