大家好,我试图构建一个应用程序,并尝试在滚动中执行操作。
我在Unity的Animator控制器中具有3个不同的层,权重均为1。在具有加载动画的第一层和具有滚动动画的第2层中,需要在该层的顶部播放1个动画以及它。
因此,要调用滚动动画,我编写了一个程序,该程序在滚动的基础上调用了动画,因此第2层“ take001”上的动画要在滚动上播放,这取决于发生了多少滚动。
现在我要获取第2层动画的当前时间。
找到以下代码以及我在Unity中创建的图层的屏幕截图:
[参考图片]: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; } }
答案 0 :(得分:2)
最简单的方法是用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
传递给Dictionary,它将为您提供适当的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");
字典,将每个动画状态哈希值与其AnimationClip链接起来:
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;
}
最后,一个获取当前Animator时间的函数:
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);
}