Ползунок Unity, управляющий анимацией

Я хотел бы создать ползунок, который отображает текущий кадр анимации в пределах единства, и когда вы перемещаете ползунок, он обновляет текущий кадр в анимации.

Пока у меня есть (отредактированный код)

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class NewAnimController : MonoBehaviour {


public Slider sliderScrubber;
public Animator animator;


void Start()
{
    float t = animator
    .GetCurrentAnimatorStateInfo(0)
    .normalizedTime;


    //animator.speed = 0.0001f;
    //slider.onValueChanged.AddListener(OnValueChanged);
}

public void Update()
{
    float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
    Debug.Log("animationTime (normalized) is " + animationTime);
    sliderScrubber.value = animationTime;
}

public void OnValueChanged(float changedValue)
{
    animator.speed = 0.0001f;
    animator.Play("Take 001", -1, sliderScrubber.normalizedValue);
}
}

На данный момент это изменяет текущий кадр в анимации, когда вы настраиваете ползунок, но когда анимация воспроизводится, ползунок не обновляется.

Как я могу заставить это работать в обоих направлениях?

Большое спасибо


person Tim Hanson    schedule 01.02.2016    source источник


Ответы (3)


Сначала обязательно удалите все строки кода

animation.speed = 0.0001f

которые кажутся остатками учебника или отладки.


Как насчет

public void Update()
 {
 float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
 // in case of a looping anime, animationTime = animationTime %1f;

 Debug.Log("animationTime is " + animationTime);
 // of course remove that in production

 slider.value = animationTime;
 }

Обратите внимание, конечно, установите ползунок min / max на 0f, 1f в редакторе.

Обратите внимание, вы можете предпочесть сделать «скруббер» для положения сустава; тоже хорошо работает.

Обратите внимание, тонкая проблема: опытные программисты могут предпочесть установить скорость анимации на ноль, пока палец пользователя удерживает ползунок; наверное нормально без этого.


ПРИМЕЧАНИЕ: удалите все ссылки на animation.speed. Похоже, это переход из неправильного учебника.

person Fattie    schedule 01.02.2016
comment
Это правильно, затем я установил ползунок от 0 до 1 и заставил slider.value = animationTime; работать нормально, мне просто нужно было обновить скорость воспроизведения анимации, иначе она воспроизводилась слишком медленно. Я собираюсь написать в него ползунок, который может изменять скорость воспроизведения, но для исходного кода animation.speed = 0.0001f был слишком медленным, чтобы увидеть, работает ли он вообще. Я получил это исходное значение из кода, который я нашел в первую очередь. - person Tim Hanson; 02.02.2016
comment
Аааа! хорошо, просто удалите эту строку полностью animation.speed = 0.0001f, это глупо! - person Fattie; 02.02.2016
comment
Да, теперь все работает отлично, спасибо за вашу помощь. - person Tim Hanson; 04.02.2016
comment
Я только отмечал ответ, который сразу отвечал на вопрос, на тот случай, если у кого-то была такая же проблема, чтобы они могли заставить все работать как можно быстрее. - person Tim Hanson; 04.02.2016

Хорошо, после долгого разбрасывания вещей, чтобы посмотреть, что прилипнет, это дает мне результат, который мне нужен.

Я хотел бы поблагодарить @JoeBlow за его помощь.

Кто-нибудь угостит того парня выпить.

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class NewAnimController : MonoBehaviour {

public Slider sliderScrubber;
public Animator animator;   

public void Update()
{
    float animationTime = animator.GetCurrentAnimatorStateInfo(0).normalizedTime;
    Debug.Log("animationTime (normalized) is " + animationTime);
    sliderScrubber.value = animationTime;
}

public void OnValueChanged(float changedValue)
{
    animator.Play("Take 001", -1, sliderScrubber.normalizedValue);
}
}

Я обновлю это снова, когда у меня будет работать кнопка паузы воспроизведения и ползунок, который может изменять скорость воспроизведения.

person Tim Hanson    schedule 02.02.2016

Думаю, вы почти получили это просто вместо того, чтобы присвоить значение непосредственно в функции обновления:

sliderScrubber.value = animationTime;

Использовать это:

sliderScrubber.Set(animationTime, false);

параметр false - вызвать функцию OnValueChange () в вашем случае, если вы этого не хотите.

Дополнительно вы можете проверить, воспроизводится ли анимация, чтобы избежать ненужных вызовов функции Set:

http://answers.unity3d.com/questions/362629/how-can-i-check-if-an-animation-is-being-played-or.html

и проверьте свой slider.maxValue, чтобы настроить его на длину анимации.

person Myke Dev    schedule 02.02.2016