Самый простой способ - разделить текущее нормализованное время анимации на 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);
}