最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

godot4 - How To Make Animations Play Based on Movement Direction In Godot - Stack Overflow

programmeradmin2浏览0评论

So I've got some code in Godot that allows for 8-directional movement for a top-down game in Godot, it works fine, exactly as intended. The part that keeps tripping me up is trying to figure out how to make specific movement animations play depending on the direction the player is moving.

For reference, here is the movement code:

extends CharacterBody2D

var speed = 100

func _physics_process(delta):
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    velocity = direction * speed

    move_and_slide()

I tried to make the animations play depending on which inputs are being pressed (i.e: if Up and Right are being pressed the animation will be the Up Diagonal animation facing to the right), but with 8 different animations to play it became such a large slab of code that seemed to be not very efficient and that while it technically functioned, it looked very janky and stuttered a lot when in use.

So I've got some code in Godot that allows for 8-directional movement for a top-down game in Godot, it works fine, exactly as intended. The part that keeps tripping me up is trying to figure out how to make specific movement animations play depending on the direction the player is moving.

For reference, here is the movement code:

extends CharacterBody2D

var speed = 100

func _physics_process(delta):
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    velocity = direction * speed

    move_and_slide()

I tried to make the animations play depending on which inputs are being pressed (i.e: if Up and Right are being pressed the animation will be the Up Diagonal animation facing to the right), but with 8 different animations to play it became such a large slab of code that seemed to be not very efficient and that while it technically functioned, it looked very janky and stuttered a lot when in use.

Share Improve this question asked Mar 17 at 8:05 Rebecca MarshallRebecca Marshall 256 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

KidsCanCode's recipe "8-Directional Movement/Animation" is what you're looking for, using keyboard input instead of the mouse.

First, you get the angle of the current movement direction (in radians):

if not direction.is_zero_approx():
    var angle = direction.angle()

Then, you divide it by π/4 to transform the angles into offsets in the [-3, 4] interval:

var offset = angle / (PI/4)

Next, you wrap the offset to be in the [0, 7] interval:

var index = wrapi(int(offset), 0, 8)

The index is a numerical equivalent of cardinal directions, and you can use it to access the appropriate animation, by means of a name suffix:

var anim_name = "Idle"
if not direction.is_zero_approx():
    ...
    anim_name = "Run"
# Works with both AnimatedSprite2D and AnimationPlayer
$Animation.play(anim_name + str(index))  # "Idle0"/"Run0, "Idle1"/"Run1"...

If you don't like numerical suffixes, replace them with cardinal directions:

const idx_to_dir: Array[String] = ["E", "SE", "S", "SW", "W", "NW", "N", "NE"]
$Animation.play(anim_name + idx_to_dir[index])  # "IdleE"/"RunE", "IdleSE"/"RunSE"...

Here's the complete code snippet using numerical indices (adapted from your code and the original source), tweak it as you need:

extends CharacterBody2D

var speed = 100

func _physics_process(delta):
    var anim_name = "Idle"
    var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
    if not direction.is_zero_approx():
        var angle = direction.angle()
        var offset = angle / (PI/4)
        var index = wrapi(int(offset), 0, 8)
        anim_name = "Run"
    velocity = direction * speed
    move_and_slide()
    $Animation.play(anim_name + str(index))

And here's a handy conversion table for reference:

Angle 0 45° 90° 135° 180° 225° 270° 315°
Offset -3 -2 -1 0 1 2 3 4
Index 0 1 2 3 4 5 6 7
Direction E SE S SW W NW N NE
发布评论

评论列表(0)

  1. 暂无评论