Unity 让物体同时播放两种动画

        在用Unity开发工程中,会遇到需要让一个物体同时播放两种动画的情况,举个简单的例子: 一只小鸟,这只小鸟会拍翅膀,这只小鸟也会按一定的轨迹飞行。   实现这个需求有几种思路:

1. 用动画控制器控制小鸟拍翅膀的动画,编写脚本控制小鸟的飞行轨迹;

2. 在一个动画中同时K上 拍翅膀相关的帧 和 运动轨迹相关的帧;

3. 给这只小鸟加一个父节点,小鸟自身的控制器会控制鸟拍翅膀的动画,其父节点上挂一个控制器,用来控制器运动轨迹;

4. 采用动画混合层的方式,由小鸟自身的动画控制器 直接控制 小鸟拍翅膀及其运动轨迹的动画。 

本文将会对第 4 种思路进行简要介绍。

1)新建一个Unity工程,导入相关资源,图中的“Bird”已经挂好动画控制器,并且其“BaseLayer” (第0层)中新建一个 拍翅膀动画 => “Fly”动画。此时,小鸟已经具备拍翅膀的表现了。 

接着,我们需要新建一个动画层,来实现其飞行轨迹动画的叠加:

2). 点击下图中左上角的 “ + ”号,下方便会出现一个新的层 “New Layer ” 也就是动画层1了(BaseLayer 是动画层0),此时可以对这个层重命名。



3) 在新建的层中点击右上角的设置按钮 ,打开该层的设置面板,在设置面板中把 weight 的值 设置成1 (当weight 为0 时,该层的动画不起作用,随着weight的值增大,动画权重增大(类似于动画速度增加),当weight为1时,表示该层中的动画均为正常速度播放)。

4)在该层中K上控制小鸟移动的动画 =>  “Move"。



此时,基本功能已经实现,启动Unity 你便会发现,物体已经具备两种动画表现。


在这里可以扩展一些知识, 如何单独停止第一层(即新建层)动画,并在一定时候后继续该层在停止时刻的动画? ----有两种方法可以供大家参考。

第一种方法也是常用的方法是 用代码设置该层的权重 weight =0 。新建一个脚本“Bird” ,挂载到小鸟物体上,加入如下代码:

当按下键盘上按键”Q“时,新建层的动画会停止,只保留”BaseLayer“层的动画。

这种方向可以有效地停止掉骨骼动画。 像CS类射击游戏中,通过混合动画,Base层中主要控制角色手部开枪射击等动画,在新建的混合层中控制脚步移动的动画,这种情况可以用上述的方法停止掉新建的混合动画层。   然而,对”移动旋转缩放 “ 类动画不能用这种方法!

本文需求中小鸟的这种  ”拍翅膀“ + ”拍翅膀“ 组合而成的动画,不能用设置权重weight的方式去停止动画 , 这是因为当你把新建的混合层动画权重设置成0时,物体会回到移动动画第一帧的位置,并不是在原点待命!


对于”骨骼动画“ + ”移动动画“ 这类的,我们可以这样解决:

1)在新建的混合层中添加一个空的动画State ,命名可随意为,并把write defaults 这个选项勾去掉;


2)在常用于播放动画的 animator.Play() 方法中有5个重载,其中有一个重载方法是可以自行决定动画从哪里开始播放的,调用此方法我们需要知道两个关键的数值:

stateNameHash 和 normalizedTime。

3)在停止动画前 先获取 ”Move“ 动画当前已经播放了多少(该值为0 到1 ,1 为100%,0.1为10%),即“normalizedTime”。获取代码如下,相关解释已经备注在代码里:


4)获取混合层中当前动画的 名字所对应的哈希值 => nameHash. 



5)此时准备工作已经完成,下面贴出全部代码。小鸟飞行过程中按下 键盘”W“键,小鸟会保持“拍翅膀”状态 原地停止3秒,3秒后继续飞行。

 

其实在物体有固定移动路线时,给物体添加一个父节点,物体自身K骨骼动画,父节点K带动物体移动的动画也是可行的,停掉移动动画只需要禁用父节点的动画控制器即可,再次启动也就是把父节点的控制器再次启动,动画也能继承停止时刻的状态继续播放,在逻辑控制上简单很多,但是随意给物体添加一个父节点有时有打乱物体之间的结构规律,所以并不推荐这样做。 

到此,功能已基本实现。

(有什么错误的地方也请各位大大不吝指出~~~)


  • 32
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity中实现物体移动动画的代码可以使用以下两种方式: 1. 使用Animator组件 Animator组件是Unity中用于创建动画的主要组件之一。您可以使用它来创建基于时间线的动画和脚本驱动的动画。您可以将动画片段添加到Animator组件中,并使用Animator组件的API在代码中控制动画。以下是一个简单的示例,演示如何使用Animator组件在代码中控制物体的移动动画: ```csharp using UnityEngine; public class MoveAnimation : MonoBehaviour { Animator animator; void Start() { animator = GetComponent<Animator>(); } void Update() { if (Input.GetKey(KeyCode.W)) { animator.SetBool("IsMoving", true); transform.Translate(Vector3.forward * Time.deltaTime); } else { animator.SetBool("IsMoving", false); } } } ``` 在这个示例中,我们使用Animator组件来控制物体的移动动画。我们将动画片段添加到Animator组件中,并使用`animator.SetBool()`方法来启动或停止动画。在Update()方法中,我们检查输入是否为W键,如果是,则启动动画,否则停止动画。在启动动画时,我们还使用`transform.Translate()`方法来移动物体。请注意,这是一个非常简单的示例,但您可以使用更复杂的动画片段来实现更复杂的动画效果。 2. 使用Animation组件 Animation组件是Unity中用于创建基于时间线的动画的另一种组件。您可以使用它来创建关键帧动画,以及在代码中控制动画。以下是一个简单的示例,演示如何使用Animation组件在代码中控制物体的移动动画: ```csharp using UnityEngine; public class MoveAnimation : MonoBehaviour { Animation animation; void Start() { animation = GetComponent<Animation>(); } void Update() { if (Input.GetKey(KeyCode.W)) { animation.Play("Move"); transform.Translate(Vector3.forward * Time.deltaTime); } else { animation.Stop("Move"); } } } ``` 在这个示例中,我们使用Animation组件来控制物体的移动动画。我们创建了一个名为“Move”的动画片段,并将其添加到Animation组件中。在Update()方法中,我们检查输入是否为W键,如果是,则播放名为“Move”的动画片段,并使用`transform.Translate()`方法来移动物体。如果输入不是W键,则停止播放动画。请注意,这是一个非常简单的示例,但您可以使用更复杂的动画片段来实现更复杂的动画效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值