Unity3D получит аниматор контроллера текущего времени анимации - PullRequest
0 голосов
/ 09 октября 2018

Привет. Все, что я пытался создать приложение и пытаться делать что-то на свитке.

У меня есть 3 разных слоя в Контроллере Аниматора Единства весь вес 1. В первом слое, имеющеманимация при загрузке и в слое 2, имеющем анимацию при прокрутке, которую необходимо воспроизвести поверх анимации слоя 1. Вместе с ней.

Итак, чтобы вызвать анимацию при прокрутке, я написал программу, котораявызов анимации в основах прокрутки, чтобы анимация на слое 2 «take001» воспроизводилась на прокрутке, зависит от того, сколько прокрутки произошло.

Теперь я хочу получить текущее время анимации слоя 2.

Найдите приведенный ниже код и снимок экрана слоев, которые я создал в Unity:

[Refer Img]: https://imgur.com/j4Up4OE

using UnityEngine;
using System.Collections;
public class MouseMovementScript : MonoBehaviour {
Animator anim;
AnimatorStateInfo stateInfo;
AnimatorClipInfo[] myAnimatorClip;
double speedBase = 1;
void Start () {
     anim = GetComponent<Animator>();
     stateInfo = anim.GetCurrentAnimatorStateInfo(1);
    //Output the name of the starting clip

}

// Update is called once per frame
void Update () {

    var d = Input.GetAxis("Mouse ScrollWheel");

    if (d > 0f)
    {

        Time.timeScale = 1;
        anim.SetFloat("Direction", 1.0f);
        anim.Play("take001");
        StartCoroutine(TestCoroutine(d));

        anim.Play("BoxAnimation001");
    }
    else if (d < 0f)
    {
        Time.timeScale = 1;
        anim.SetFloat("Direction", -1.0f);
    }

     // Cursor
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;

    if(Physics.Raycast (ray, out hit))
    {
        if (Input.GetMouseButtonDown(0)){
            if(hit.transform.tag == "Popup_1")
            {
                Application.ExternalCall("OpenPopup", 0);
            } 
            else if(hit.transform.tag == "Popup_2")
            {
                Application.ExternalCall("OpenPopup", 1);
            } 
            else if(hit.transform.tag == "Popup_3")
            {
                Application.ExternalCall("OpenPopup", 2);
            } 
            else if(hit.transform.tag == "Popup_4")
            {
                Application.ExternalCall("OpenPopup", 3);
            } 
        }
    }
}


IEnumerator TestCoroutine(float d){
 yield return new WaitForSeconds(d);
 Time.timeScale = 0; } }

1 Ответ

0 голосов
/ 09 октября 2018

Самый простой способ - разделить текущее нормализованное время анимации на 1 и вернуть остаток от деления.

public float GetCurrentAnimatorTime(Animator targetAnim, int layer = 0)
{
    AnimatorStateInfo animState = targetAnim.GetCurrentAnimatorStateInfo(layer);
    float currentTime = animState.normalizedTime % 1;
    return currentTime;
}

Это работает большую часть времени, но я видел места, где этоне работает должным образом


Правильный способ сделать это немного сложнее, потому что Unity не дает вам доступа к AnimationClip, используемому Animator, и вам нужен AnimationClipчтобы получить текущее время, умножив AnimationClip.length на AnimationState.normalizedTime;.

Для этого вам нужно сохранить ссылку на AnimationClip, который вы использовали в публичной переменной.Создайте словарь, который использует Animator.StringToHash в качестве ключа и соответствующий AnimationClip в качестве значения.Чтобы получить текущий AnimationClip, передайте Animator.GetCurrentAnimatorStateInfo.fullPathHash в словарь, и он даст вам AnimationClip.Этот клип можно использовать для получения текущего времени путем умножения его длины на AnimationState.normalizedTime.


Ваши AnimationClip ссылки:

public AnimationClip jumpClip;
public AnimationClip moveClip;
public AnimationClip lookClip;

Получите хэш состояния анимации для каждогоСостояние анимации:

const string animBaseLayer = "Base Layer";
int jumpAnimHash = Animator.StringToHash(animBaseLayer + ".Jump");
int moveAnimHash = Animator.StringToHash(animBaseLayer + ".Move");
int lookAnimHash = Animator.StringToHash(animBaseLayer + ".Look");

Словарь для связывания каждого хэша состояния анимации с их анимационным клипом:

Dictionary<int, AnimationClip> hashToClip = new Dictionary<int, AnimationClip>();

Инициализация Dictionary в функции Awake:

void Awake()
{
    hashToClip.Add(jumpAnimHash, jumpClip);
    hashToClip.Add(moveAnimHash, moveClip);
    hashToClip.Add(lookAnimHash, lookClip);
}

Функция для получения AnimationClip из хэша состояния анимации:

AnimationClip GetClipFromHash(int hash)
{
    AnimationClip clip;
    if (hashToClip.TryGetValue(hash, out clip))
        return clip;
    else
        return null;
}

Наконец, функция для получения текущего времени аниматора:

public float GetCurrentAnimatorTime(Animator targetAnim, int layer = 0)
{
    AnimatorStateInfo animState = targetAnim.GetCurrentAnimatorStateInfo(layer);
    //Get the current animation hash
    int currentAnimHash = animState.fullPathHash;

    //Convert the animation hash to animation clip
    AnimationClip clip = GetClipFromHash(currentAnimHash);

    //Get the current time
    float currentTime = clip.length * animState.normalizedTime;
    return currentTime;
}

Использование :

public Animator anim;

void Update()
{
    float time = GetCurrentAnimatorTime(anim, 0);
    Debug.Log(time);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...