|
|
|
|
Reply From: |
rk3Omega |
You could store the animation paths to an array, then use the angle of move_direction to get the index to have your animation player play. And I added a facing value to store which direction you were last facing, otherwise it always turns right when idle.
var directions = ["right", "down_right", "down", "down_left", "left", "up_left", "up", "up_right"]
var facing = Vector2()
func _physics_process(delta):
var move_direction = Vector2()
var LEFT = Input.is_action_pressed("ui_left")
var RIGHT = Input.is_action_pressed("ui_right")
var UP = Input.is_action_pressed("ui_up")
var DOWN = Input.is_action_pressed("ui_down")
move_direction.x = int(RIGHT) - int(LEFT)
move_direction.y = int(DOWN) - int(UP)
if LEFT || RIGHT || UP || DOWN:
facing = move_direction
var animation = direction2str(facing)
if $AnimationPlayer.assigned_animation != animation:
$AnimationPlayer.play(animation)
func direction2str(direction):
var angle = direction.angle()
if angle < 0:
angle += 2 * PI
var index = round(angle / PI * 4)
return directions[index]
thanks you for your teaching, i try out your code and it work, and it look simply elegant but i have no idea how PI work and make wonder how to apply idle/facing. because my old code switch between str(“idle”) and str(“move”) as you can see. my animation mostly loop.
for some reason when i paste my code here not all in gray
extends KinematicBody2D
const move_speed = 100
var move_direction = dir.center
var sprite_direction = "_Down"
func _physics_process(delta):
control_loop()
move_loop()
sprite_loop()
if move_direction != dir.center:
animation_play("Fmove")
else:
animation_play("Fidle")
pass
func control_loop():#control key
var RIGHT = Input.is_action_pressed("ui_right")
var LEFT = Input.is_action_pressed("ui_left")
var DOWN = Input.is_action_pressed("ui_down")
var UP = Input.is_action_pressed("ui_up")
############Walking##################
move_direction.x = int(RIGHT) -int(LEFT)
move_direction.y = int(DOWN) -int(UP)
func move_loop():
var motion = move_direction.normalized() * move_speed
move_and_slide(motion, dir.center)
func sprite_loop():
match move_direction:
dir.right:
sprite_direction ="_Right"
dir.left:
sprite_direction = "_Left"
dir.up:
sprite_direction = "_Up"
dir.down:
sprite_direction = "_Down"
func animation_play(animation):# to atcive animation_switch
var New_anim = str(animation,sprite_direction)
if $anim.current_animation != New_anim:
$anim.play(New_anim)
potatobanana | 2018-08-06 16:13
Howdy. Sorry just now seen you replied. I probably should’ve commented my code explaining it. Basically what the direction2str method does is get the angle you’re moving. It’s in radians, which is based on PI. So instead of -180 to 180 (degrees), it’s -PI to PI (3.14 etc). 0 is right, negative is counter-clockwise to right and positive is clockwise to right.
To make things simple we want to make angle positive, so if it’s less than 0, we add 2 * PI to it. So now angle is a value between 0 and 2 * PI. We can then divide it by PI * 4 and round it to get a value between 0 and 7, which correlates to the direction you’re facing. 0 being right going clockwise. You then use that value to determine which string in the array you need to use.
As for “idle” and “move”, I would have them named like “idle_right” and “move_right” etc. So that you can determine if you’re idling or moving, then do something along the lines of:
var suffix = "idle_"
var direction = direction2str(facing)
var animation = suffix + direction # idle_right
rk3Omega | 2018-08-24 14:19
I know I’m quite late to the party, but in my code I found some bugs where (angle / 4PI) was getting me 8, which is out of the bounds of the array. To solve this I returned
directions[int(index) % 8]
instead of just
directions[index]
in the direction2str function. This prevents any out-of-bounds by just making the index a ring of sorts.