0 votes

hey im trying to make simple character controller but i'm having problems with the transitions between animations here's my code:

var previous_dir
if _direction == Vector2(1,0):
    previous_dir = Vector2(1,0)
    if Input.is_action_pressed("interract"):
elif _direction == Vector2(-1,0):
    previous_dir = Vector2(-1,0)
    if Input.is_action_pressed("interract"):
elif _direction.y == 1:
    previous_dir = Vector2(0,1)
    if Input.is_action_pressed("interract"):
elif _direction.y == -1:
    previous_dir = Vector2(0,-1)
    if Input.is_action_pressed("interract"):
elif _direction == Vector2(0,0):
    if previous_dir == Vector2(1,0):
    elif previous_dir == Vector2(-1,0):
    elif previous_dir == Vector2(0,1):
    elif previous_dir == Vector2(0,-1):

it plays the walking and interacting animations fine but for some reason it doesn't play the idle

also isn't there an easier way to write all of this
thanks for taking a look at my post :)

asked Jun 9 in Projects by ROBOTOO007 (108 points)

1 Answer

+1 vote
Best answer

Very untested Code:

extends Node2D # Change this!

# Never write 2 times the same node with $
# If you rename a Node, you need to search every line with the name
# So it is only one line
onready var anim : AnimationPlayer = $Animation

# Looking right into your face by default
var previous_dir : Vector2 = Vector2.DOWN

# Set some strings to put them together
const STR_DIR : Dictionary = {  Vector2.UP: "up",
                                Vector2.DOWN: "down",
                                Vector2.LEFT: "left",
                                Vector2.RIGHT: "right"}
const STR_IDLE : String = "Idle_" # should be lowercase
const STR_WALK : String = "walk_"
const STR_ACT : String = "interract_" # typo!

# BTW: Static Typing FTW!

func _ready() -> void:
    # Examples: (check the debug output!)
    animate(Vector2.UP, false)
    animate(Vector2.UP, false)
    animate(Vector2.UP, true)
    animate(Vector2.RIGHT, true)
    animate(Vector2.RIGHT, false)
    animate(Vector2.ZERO, false)
    animate(Vector2.ZERO, true)

    # You might want to use it like this:
    # animate(dir, Input.is_action_pressed("interract"))

# Lets make a funny method!
func animate(_direction : Vector2, _interact : bool = false) -> void:
    match _direction:
        Vector2.UP, Vector2.DOWN, Vector2.LEFT, Vector2.RIGHT:
            previous_dir = _direction # Set this if movment

            pass # keep if no movement

        _: # cry if something is fishy
            assert(false, "Not a straight direction: " + str(_direction))

    var animation : String = STR_DIR[previous_dir]

    # --- The next part might need to be modified. Depends on your needs! ---
    if _interact: # I think you want interaction as priority. I might be wrong!
        animation = STR_ACT + animation
        if _direction != Vector2.ZERO: 
            animation = STR_WALK + animation # Walk, if movement ...
            animation = STR_IDLE + animation # ... and idle if not
    # -----------------------------------------------------------------------

    # Sweet debug output
    print_debug("Animation: ", animation)

It should be pretty self-explanatory with the comments.
You might need to change "Idle" to "Idle_down"

Thats how i would do it.
Feel free to ask, if something is unclear. And please tell me, if it works!

oh, the problem with your code was probably, that previous_dir was not 'global'. If this is in your function/method, it will be reseted everytime it is declared.

answered Jun 9 by whiteshampoo (978 points)
selected Jun 10 by ROBOTOO007

Wow! thanks for this answer and for taking the time to make this function! i could've asked for a better response

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.