简体   繁体   中英

Unity3D - Changing animation states based on movement

I'm trying to make a simple AI (a simple ellipse), which switches between a walking animation and a standing animation, depending on whether or not it is moving.

I already have the AI set to follow and turn to the player, however I am having trouble finding out how to switch between animation states.

I have a Boolean parameter in the animator, " isWalking ", which is set to switch to the walk animation if true , and switch to the standing animation if false .

My problem is how to 'check if the object is moving'. I essentially want to write some code that does something like this:

If(object is moving) 
{
    isWalking == true;
}
else 
{
    isWalking == false;
}

I've searched on the web, but I've yet to find a solution. I considered using rigidbody.IsSleeping() to see if the object is asleep, but I couldn't find any examples of how to use it.

I'm a complete newbie to both Unity and programming.

Thanks in advance. :)

在此输入图像描述

The object, as shown in the inspector window

Edit: I have tried this code, but there's probably something wrong with it. :/

using UnityEngine;
using System.Collections;

public class aiscript : MonoBehaviour {

    NavMeshAgent agent;
    public Transform target;
    public Animator anim;
    Vector3 pos;
    public GameObject monmon;

    void Start () 
    {
        pos = monmon.transform.position;
        anim = GetComponent<Animator> ();
        agent = GetComponent<NavMeshAgent> ();
    }


    void Update () 
    {   
        pos = monmon.transform.position;
        Vector3 originalPosition = pos;
        agent.SetDestination(target.position);
        Vector3 difference = originalPosition - pos;
        anim.SetBool("isWalking", difference.magnitude > 0.5f);
    }

}

From the Animator class, you can do that with the GetBool function and also set change the animation state with the SetBool function.

Animator myAnim;

.....

myAnim = GameObject.Find("ObjectAnimatorIsAttachedTo").GetComponent<Animator>();

.....

if (myAnim.GetBool("isWalking") == true)
{
    //Is walking.....
}
else
{
    //Is not walking
}

You can even change the state of isWalking later on with

myAnim.SetBool("isWalking", false);
myAnim.SetBool("isWalking", true);

I will suppose your object has a Rigidbody attached to it to move, and the Animator.

If so, you just check the velocity vector in the rigidbody, and check it's magnitude to a specific threshold.

Suppose you have a threshold of 0.5f, This will mean that, if the object is moving in any direction at more than 0.5 unit/second, it's considered running, otherwise, it's standing.

Animator myAnimator;
Rigidbody myRigidbody;

void Awake() {
    this.myAnimator = GetComponent<Animator>();
    this.myRigidbody = GetComponent<Rigidbody>();
}

void Update() {
    myAnimator.SetBool("isWalking", myRigidbody.velocity.magnitude > 0.5f);
}

EDIT:

To optimize it, you can save the hash of the boolean parameter of the animator

int isWalkingAnimationId = Animator.StringToHash("isWalking");

and then use that instead of the string.

myAnimator.SetBool(isWalkingAnimationId , myRigidbody.velocity.magnitude > 0.5f);

UPDATE:

It seems you Rigidbody is kinematic, velocity will always be (0,0,0). I guess you are changing the transform.position manually to move the object. If so:

Vector3 originalPosition = transform.position;
// Your manual changes on transform.position
Vector3 difference = originalPosition - transform.position;
myAnimator.SetBool("isWalking", difference.magnitude > 0.5f);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM