Unity3D Mecanim在某个状态下动画重新播放

最近,公司想把旧的动画系统转到使用Mecanim来实现,让我来做技术预演。之前学习Unity3D的时候有接触过Mecanim,不过都忘了,所以又重新学了一遍。重新看了官网的Mecanim视频教程,凭我这半吊子英语水平也只是一知半解,所以又找了个视频看看,中国人的Mecanim教程。经过近1个半小时的努力,总算是实现了用Mecanim来控制各个动画的播放。可以做到Idle、Run、Attack、Hit和Die这五个状态的转换。当验收时主管提出但人物处于Hit状态时,再次受到Hit时动画要重头播放,故要重新返工。先是自己摸索一下Animator类是否支持动画重新播放,查看了文档,无奈官方文档 没有详细介绍Animator类,中文文档根本就没有介绍Animator类。现在就只能靠猜了,看来看去也就Animator下的StartPlayback()这个方法比较靠谱。可是试来试去还是不得法,最后就只能靠搜索引擎了。在这我不得不吐槽一下,做技术的还是用谷歌吧,百度搜不到的东西谷歌也许就能搜到。好吧,我就是用谷歌搜到了,网址在这,我会跟你说这是日本网站么。

这里说明一下,StartRecording()不是只回放一个状态的动画,而是可以记录n个状态的动画。如果要用这个来重播动作,需要自己用代码来控制,使其只播放要重播的状态的动画。如果要把这个状态的动画从最开始播放,那么前一个状态到要重播动画的状态的过渡动画就不要了,这个要在Animator Controller中进行设置,否则不可能做到从该状态的最开始重播动画(这个下面的代码没有实现)。

好吧,自己也实现了一把,送给有缘看到这篇博客的人,免去了找资料的痛苦。简化了Mecanim的状态,只有Idle和Hit两个状态。

后来发现这个方法不太好,哪里不好就不说了。说说新的方法:使用Animator.Play(state, layer, normalizedTime)这个方法,当normalizedTime为零时就可以做到重播的效果。

using UnityEngine;
using System.Collections;

public class SimpleExample : MonoBehaviour {

	Animator anim = null;
	AnimatorStateInfo currentBaseStage;
	int idle = Animator.StringToHash("Base Layer.Idle");
	int hit = Animator.StringToHash("Base Layer.Hit");
	bool isHit = false;//在播放受击动画时是否再次受击 true: 受击
	bool isPlayBack = false;//是否重播  true: 重播

	// Use this for initialization
	void Start () {
		anim = GetComponent<Animator>();
	}
	
	// Update is called once per frame
	void Update () {
		currentBaseStage = anim.GetCurrentAnimatorStateInfo(0);
		if (currentBaseStage.nameHash == idle && !anim.IsInTransition(0))
		{
			anim.SetBool("hit", false);
			isHit = false;
		}
		//hit
		if (!isHit && Input.GetKey(KeyCode.H) && !anim.IsInTransition(0) && currentBaseStage.nameHash == idle)
		{
			anim.SetBool("hit", true);
			anim.StartRecording(0);//frameCount为记录的帧数,0表示用StopRecording()来停止记录
			isHit = true;
		}
		if (isHit && Input.GetKey(KeyCode.H) && currentBaseStage.nameHash == hit)
		{
			//二次受击
			isPlayBack = true;
			anim.StopRecording();//停止记录重播
			anim.StartPlayback();//开始重播
			anim.playbackTime = 0f;//从0s开始重播
		}

		//设置现在重播时播放的时间
		if (isPlayBack)
		{
			float newPlaybackTime = anim.playbackTime + Time.deltaTime;
			if (newPlaybackTime > anim.recorderStopTime) {
				newPlaybackTime = 0;
				anim.StopPlayback();
				isPlayBack = false;
			}
			anim.playbackTime = newPlaybackTime;
		}
	}
}



  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值