I’m working on a 2D, top-down RPG and I’m trying to use the animator to change animations based on movement… I can’t figure out how to change the character to the “idle” animation when I release the movement keys…
public class player_movement : MonoBehaviour
{
public float default_speed = 1.0f;
public Animator anim;
void Start(){
anim = GetComponent<Animator>();
}
void Update () {
Vector2 pos = transform.position;
if (Input.GetKey ("w")) {
anim.SetBool("walk_n", true);
pos.y += default_speed * Time.deltaTime;
if (Input.GetKeyUp("w"))
{
anim.SetBool("walk_n", false);
}
}
if (Input.GetKey ("s")) {
anim.SetBool("walk_s", true);
pos.y -= default_speed * Time.deltaTime;
}
if (Input.GetKey ("d")) {
anim.SetBool("walk_e", true);
pos.x += default_speed * Time.deltaTime;
}
if (Input.GetKey ("a")) {
anim.SetBool("walk_w", true);
pos.x -= default_speed * Time.deltaTime;
}
transform.position = pos;
}
}
I’ve tried to solve this (GetKeyUp?). When the bool is set to false, it should transition to the “idle_north” animation… What would be a way to accomplish this properly? Thank you.
Oh, just noticed that you have separate Idle for each direction.
But as you set that in code if animator is good it should work. Post screenshot of animator?
You should use Any State as root for that animator. From Any State you have transition to w walk (for example) with anim.SetTrigger(“trig_walk_n”) and from that to w idle with condition anim.SetTrigger(“trig_idle_w”);
No back transitions. Idle animations are loop and so are walk. That way player stays in idle, displays walk on keypress.
I guess that you want player character to stay in idle that corespondents to last walk direction?
for every walk_w add transition to idle_w with trigger “trig_idle_w”
Any State transitions only to walk animations.
Walk animations only transition to corespondent idle animations.
That way character enters idle on start of scene. From that animation with code you provided should go to walk depending on button pressed, and from that to its idle. From that one goes to next walk depending on next button press.
awesome, thank you so much for the help. it is almost there. it is moving in each direction, and it is reaching the idle states properly…however, when it does the “walk” direction, it seems to get stuck on the first frame, and it doesn’t play it out…any idea why?
It does that because Update checks every frame what is, in this case, pressed and on every frame that the button is pressed there is trigger and plays animation according to AnyState transition. Now, this can be solved in more than one way. For instance use, yeah I know, Bool on transition to walk:
if (Input.GetKeyDown ("s")&anim.GetBool("walk_s", false))
{
anim.SetBool("walk_s", true)
pos.y -= default_speed * Time.deltaTime;
}
if (Input.GetKeyUp("s"))
{
anim.SetBool("walk_s", false)
anim.SetTrigger("idle_s");
}
Now, from AnyState transition to walk with Bool walk_s as true. From walk to idle on trigger idle_s.
Maybe, for idle to work you will have to transition to idle from AnyState directly with trigger “idle_s” in this example.
Then, maybe, you need to use Bool for idle also like this:
I’m sorry for bringing this back up, but I’ve been trying and trying different things, but this is about as close as I can get. How can I program this without the Update method resetting the animation to the first frame, making it look like it’s frozen when I hold the key down? I tried setting a private bool, etc. I’ve done a lot of research, and apparently there was something called “can transition to self” that seems like it may resolve this issue, but it doesn’t seem to be in newer versions of Unity… Any thoughts here?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class player_movement : MonoBehaviour
{
public float default_speed = 2.0f;
public Animator anim;
void Start(){
anim = GetComponent<Animator>();
}
void Update () {
Vector2 pos = transform.position;
if (Input.GetKeyUp("w"))
{
anim.SetBool("walk_n", false);
}
if (Input.GetKeyUp("a"))
{
anim.SetBool("walk_w", false);
}
if (Input.GetKeyUp("s"))
{
anim.SetBool("walk_s", false);
}
if (Input.GetKeyUp("d"))
{
anim.SetBool("walk_e", false);
}
if (Input.GetKey("w")){
anim.SetBool("walk_n", true);
pos.y += default_speed * Time.deltaTime;
}
if (Input.GetKey("s")){
anim.SetBool("walk_s", true);
pos.y -= default_speed * Time.deltaTime;
}
if (Input.GetKey("d")) {
anim.SetBool("walk_e", true);
pos.x += default_speed * Time.deltaTime;
}
if (Input.GetKey("a")) {
anim.SetBool("walk_w", true);
pos.x -= default_speed * Time.deltaTime;
}
transform.position = pos;
}
}