Hello, Im starting a Rpg and im using an animated sprite for my main player since all his movements are too big to fit on one sprite sheet. I saw videos on YouTube and they all use animation player with an animation tree. In the end i was able to show the up, down, left, right movement and idle animations but cant figure out the diagonals.
Animated Sprite 8 directional
You probably want to do something using the input_vector
code below at line 32 instead of checking each individual input, as this will allow you to do some processing to more easily detect diagonal movement. It will require some adjusting for idle animations though, but if you store the last non zero value of input_vector
then you can use it for telling which idle animation to choose.
There are many ways to do this. The easiest way is to do some conditions to tell if movement is diagonal or not, and then which direction. I have not tested it, but something like this should work:
onready var _animated_sprite = $AnimatedSprite
var last_direction = Vector2.ZERO
func _physics_process(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 we are moving...
if input_vector.length_squared() > 0:
# Store the direction for use later when needing
# to choose the idle animation
last_direction = input_vector
# Diagonal movement
if input_vector.x != 0 and input_vector.y != 0:
# going down?
if input_vector.y > 0:
if input_vector.x > 0:
_animated_sprite.play(“run_down_right”)
else:
_animated_sprite.play(“run_down_left”)
else:
if input_vector.x > 0:
_animated_sprite.play(“run_up_right”)
else:
_animated_sprite.play(“run_up_left”)
# Otherwise we are moving either horizontal or vertical, so its just a
# matter of finding out which.
# horizontal movement
elif input_vector.x != 0:
if input_vector.x > 0:
_animated_sprite.play(“run_left”)
else:
_animated_sprite.play(“run_right”)
# vertical movement
else:
if input_vector.y > 0:
_animated_sprite.play(“run_down”)
else:
_animated_sprite.play(“run_up”)
# if we are not moving, use the last known movement
else:
# Diagonal movement
if last_direction.x != 0 and last_direction.y != 0:
# going down?
if last_direction.y > 0:
if last_direction.x > 0:
_animated_sprite.play(“idle_down_right”)
else:
_animated_sprite.play(“idle_down_left”)
else:
if last_direction.x > 0:
_animated_sprite.play(“idle_up_right”)
else:
_animated_sprite.play(“idle_up_left”)
# Otherwise we are moving either horizontal or vertical, so its just a
# matter of finding out which.
# horizontal movement
elif last_direction.x != 0:
if last_direction.x > 0:
_animated_sprite.play(“idle_left”)
else:
_animated_sprite.play(“idle_right”)
# vertical movement
else:
if last_direction.y > 0:
_animated_sprite.play(“idle_down”)
else:
_animated_sprite.play(“idle_up”)
Hopefully this helps a bit :smile:
Thank you it worked perfectly! I came across another dilemma, eventually i would like to add a Roll, Damage, Death and Power change animation. Would i have to make a enum for those states I want the player to be in along with his movement and idle animations?
@LegendarySaintLos said: Thank you it worked perfectly! I came across another dilemma, eventually i would like to add a Roll, Damage, Death and Power change animation. Would i have to make a enum for those states I want the player to be in along with his movement and idle animations?
Awesome, I’m glad it worked.
For the different stuff, it really depends on how you want to do it. I would personally suggest using a state machine, or something similar, to handle this kind of thing as I find it a flexible solution for adding different states and animations. However, the best advice I can give is to go with whatever you think will work and/or what you are comfortable with, as that will be the best solution for your project :smile:
- Edited
For future readers: You can make it by using an angle from Vector2. First (for educational purposes) create input Vector2:
inputVector.y = Input.GetActionStrength("Move_down") - Input.GetActionStrength("Move_up");
inputVector.x = Input.GetActionStrength("Move_right") - Input.GetActionStrength("Move_left");
Then calculate angle (0-360) from it:
yourAngle = Mathf.Rad2Deg(inputVector.AngleTo(Vector2.Down)); // For me Vector down as zero
yourAngle = yourAngle < 0 ? yourAngle + 360f : yourAngle; // change -180 <-> +180 to 0 <-> 360
yourAngle = Mathf.Stepify(yourAngle, 45); // Step it for 8 directions (360/8 = 45)
yourAngle = yourAngle == 360f ? 0f : yourAngle; //360 and 0 are the same
Then if you have animations organised in angles like me:
CurrentAnimation = "Run_" + yourAngle;
(Fixed code formatting)