Unity Animation -- 使用Animator控制动画

这篇具有很好参考价值的文章主要介绍了Unity Animation -- 使用Animator控制动画。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        在很多实际场景中,我们经常需要根据特定的事件(比如玩家输入,敌人受到攻击等)来播放不同的动画。这需要我们了解一下Animator,Animator Controller和基础的动画状态机。

创建一个开门的动画

        首先我们来创建一个简单的开门动画,示例中的门的模型来自官方教程。其实我们也可以用一个简单的Cube调整一下做成门的形状来做。无论是哪种方式,我们首先需要检查一下这个游戏物体的pivot point。一个pivot point是物体进行移动的基准点。对于门来说,这个点非常重要。如果pivot点设置不对,则开门动画会看起来非常奇怪(比如门沿着自身中轴线旋转,当然,如果你是要制作旋转门动画就另说,示例中是一个普通的门)。

        1. 首先,选中门对应的游戏物体。此时Unity编辑器中会出现移动widget,如果这个widget的位置处于游戏物体正中心,如下图:

Unity Animation -- 使用Animator控制动画

         2. 我们点击Toggle Tool Handle Position按钮(上图左上角红框处),将它从Center改为Pivot

Unity Animation -- 使用Animator控制动画

         3. 在Animation编辑器中,点击Create按钮,创建一个新的动画片段,我们将其命名为Door_Open并保存

Unity Animation -- 使用Animator控制动画

         4. 在Animation编辑器中,点击Record,然后点击Add Property,添加Transform -> Rotation属性

Unity Animation -- 使用Animator控制动画

         5. 将Playhead移动到1:00处(第二个关键帧),然后调整一下门的旋转角度,将门的Inspector里的Transform -> Rotation里的Y改成90

Unity Animation -- 使用Animator控制动画

         6. 预览一下开门动画,没问题后再次点击Record退出Recording模式。

         7.  在工程文件窗口中,找到刚刚创建的Door_Open动画文件,点击后,在Inspector窗口中,禁用掉Loop Time。禁用这个选项后动画只会播放一次,而不是无限循环。

Unity Animation -- 使用Animator控制动画

 Animator Controller

        再次选择Door游戏物体,在Inspector中我们可以看到出现了一个新的Animator组件。对于一个选中的游戏物体,当我们第一次为其创建动画片段时,Unity会自动为它创建一个Animator组件。

Unity Animation -- 使用Animator控制动画

         Animator负责为游戏物体分配动画。但它并不控制实际的动画片段,这个任务交给了Animator Controller,这个也是在第一个动画片段创建时自动创建的。在Animator组件中的Controller这一栏中,可以看到有一个名为Door的Animator Controller(在保存动画的目录中,一般为Animations目录,下面也有一个同样名字的Door文件)。

        1. 在工程文件窗口中,选中Door这个文件,将其重命名为Door_Controller

Unity Animation -- 使用Animator控制动画

         2. 双击这个文件,打开Animator窗口

Unity Animation -- 使用Animator控制动画

         3. 为了方便演示,将Animator窗口拖动到工程窗口处

Unity Animation -- 使用Animator控制动画

         4. 在场景中选中Door游戏物体,然后点击Play进入游戏模式

Unity Animation -- 使用Animator控制动画

         当场景进入Play模式后,可以看到门被打开了,同时,我们会看到Animator窗口中的Door_Open动画下方有一个蓝色的进度条开始慢慢填满,这表示Door_Open动画片段的播放过程。Animator窗口中会实时地显示当前正在播放的动画片段以及动画片段播放进度。

动画状态机

        Animation Controller运行在一种叫做状态机(State Machine)的特殊系统上。状态机会跟踪一个物体所能执行的所有可能的动作,并且根据当前的情况(状态,state)选择合适的动作。对于当前状态的控制逻辑,一般是通过脚本来控制。状态机处理的从一个动作转到另一个动作的过程,叫做转换(Transition)。

        为了更好地理解状态机是如何工作的,我们以案例里的门为例子,它可以执行的动作有开门和关门两种。

        因此门可能处于的状态有:

  •         正在开门过程中(Currently Opening)
  •         正在关门过程中(Currently Closing)
  •         打开状态(Currently Open)
  •         关闭状态(Currently Close)

        接下来我们画出这些状态之间的关系:

Unity Animation -- 使用Animator控制动画

         门的默认状态处于关闭状态。当玩家足够靠近门时,状态机会切换到正在开门的状态,然后会切换到打开状态。在玩家离开之前,门会一直处于打开状态。玩家离开后,门会进入正在关闭状态,然后切换到关闭状态。此时状态机又回到了初始状态。

        基于此,我们可以看到有两种转换(transitions)需要一些逻辑输入(检测玩家靠近和远离门),有两种状态会自动转换到下一个状态(正在开门转换到开门,正在关门转换到关门)。

创建默认动画状态

        前面小节中,我们创建的Door_Open动画,只要场景开始运行就会自动播放。这不是我们想要的效果,造成这个问题的原因是,当前只有这个动画和门关联,在添加这个动画时,Unity的Animation Controller自动将其设置为了默认状态。接下来我们来解决一下这个问题。

        1. 在Animator的工作区中(背景是网格,包含了各种状态的区域),点击右键并选择Create State -> Empty,创建一个空状态

        2. 选择新创建的节点,在Inspector面板中,将它的名字从New State改为Closed

        3. 右键点击Closed状态,然后选择“Set as Layer Default State”

Unity Animation -- 使用Animator控制动画

         我们可以看到,现在Closed状态变成了橙色,并且Entry节点指向了它。Entry节点和Closed节点之间的橙色线表示了一个转换(transition)。Entry节点是状态机开始运行时所处的第一个节点,在场景开始运行的时候会自动运行Entry节点。

        4. 再次点击运行按钮,看看门的行为有什么差异。

实现开门状态转换

        下一步,我们来实现检测玩家并切换到开门动画的功能。要检测玩家是否靠近到门,通常的逻辑是通过一个Trigger碰撞器加上脚本来实现。我们先完成状态机部分的设置,增加脚本要使用的引用变量即可。

        1. 右键点击Closed节点,选择Make Transition。此时有一个白色的箭头会出现在光标处。

        2. 选择Door_Open节点,让这个箭头和它连接起来。

Unity Animation -- 使用Animator控制动画

        3. 点击运行按钮测试一下效果。

                运行过程中,我们可以看到,在Animation Controller中,首先会经过Closed节点。当Closed节点完成后,会立即调到Door_Oepn动画,随后停在了开门动画上。为了避免Closed节点直接调到开门动画节点,我们要在转换条件上附加一些逻辑来做控制。要实现这个控制,我们需要使用状态机参数(Parameters)参数是Animator内部创建的变量,可以在Animator编辑器的左边找到Parameters标签页。

        4. 选择Parameters标签页,在Parameteres列表的顶部,点击“+”并且选择Trigger(触发器)

Unity Animation -- 使用Animator控制动画

             Trigger参数会在它被脚本所修改时立即变化。

        5. 将Trigger变量的名字设置为PlayerProximity,注意后面在脚本里引用这个变量时,名字一定不要搞错了。

        6. 选中Closed和Door_Open节点中间的带白色箭头线。然后在其Inspector中找到Conditions。

        7. 在Condiditons列表底部,选择“+”。由于目前只有一个参数,PlayerProximity会自动加到列表中。

Unity Animation -- 使用Animator控制动画

        8. 点击运行按钮,运行场景。

        9. 在参数列表中,点击PlayerProximity参数旁边的单选按钮,手动触发这个变量。

Unity Animation -- 使用Animator控制动画

        我们可以看到,当PlayerProximity被修改后,状态切换到了Door_Open并开始播放开门动画。

实现关门状态转换

        接下来我们用类似的方法实现关门状态。

        1. 在Animator里选中Door_Open节点,然后按Ctrl/Command + d复制一份这个节点。

        2. 在Inspector中,将复制的节点的名字修改为Door_Close,并且将它的Speed参数设置为-1,这样会让动画的帧反向播放。 

        3. 右键点击Door_Open节点,选择Make Transition,然后将Door_Open和Door_Close节点连接起来。

Unity Animation -- 使用Animator控制动画

        4. 选择这个新建的转换(transition),在Condiditons列表中点击“+”。同样,PlayerProximity会自动出现。

        5. 点击运行按钮,运行场景,同样我们使用PlayerProximity旁边的单选按钮,来测试先开门后关门的动作是否正常。

        Animator中的Trigger参数在当前转换(从一个状态切换到下一个状态)完成后,会立即失效。因此我们在开门和关门的时候,可以安全地复用这个参数。后面我们会用脚本来操作这个参数。

复位状态机

        到目前为止,我们以及实现了通过Animator参数来实现开门和关门的动画播放和相关状态。但状态机最后会停留在关门状态,这个过程只会发生一次。为了让动画每次在PlayerProximity发生变化时还能正常表现,当关门动画播放完毕时,我们要将动画状态机复位到初始状态。我们可以通过使用Exit节点来实现这个功能。当状态转换到Exit节点时,状态机会自动地切换到Entry节点。

        1. 右键点击Door_Close节点,选择Make Transition。

        2. 点击Exit节点,连接Door_Close节点和Exit节点。

Unity Animation -- 使用Animator控制动画

        3. 点击运行按钮,运行场景

            现在我们可以看到,当Door_Close播放完成后会自动转换到Exit,然后再回到Closed状态。这里我们还会注意到一点,在我们修改了PlayerProximity的值之后到门被打开之间会有点延迟。这是因为默认情况下,在一个状态节点执行转换之前,要先走完整个动画播放时间(Animator里状态节点的进度条可以直观感受到这个时间)。我们可以选择将禁用这个行为,让切换到Door_Open的转换立即发生。

        4. 选择Closed和Door_Open节点之间的转换(transition),在Inspector中,禁用掉Has Exit Time。

Unity Animation -- 使用Animator控制动画

        6. 重新运行场景,看看现在的效果。

 添加Trigger检测碰撞器,用脚本控制PlayerProximity参数

        前面我们通过手动点击PlayerProximity的方式来做状态机的测试。接下来我们用一个Trigger碰撞器和一个脚本来实现对这个参数的动态控制。关于普通的collider和tirgger collider的区别,本笔记不会讨论,请自行参考网上资料。

        1. 在Hierarchy中,点击右键选择Create Empty创建一个空游戏物体。

        2. 将这个游戏物体命名为Door_Trigger。

        3. 选中Door_Trigger,在Inspector中选择Add Component,添加一个Box Collider。

Unity Animation -- 使用Animator控制动画

        4. 在Box Collider组件中,启用“Is Trigger”。

        5. 调整Box Collider的大小,让其能够覆盖到门前后一片空间。

Unity Animation -- 使用Animator控制动画

        6. 编写DoorTrigger脚本,并且将脚本添加到Door_Trigger游戏物体上。

             DoorTrigger脚本代码如下:

Unity Animation -- 使用Animator控制动画

             代码意思很好懂,OnTriggerEnter/Exit函数中,检测到Player进入/离开Trigger Collider之后,会去修改PlayerProximity参数。 

        7. 在Door_Trigger的Inspector中,将Door游戏物体拖动到Door Trigger脚本里的Anim属性方框中,这能够将Door的animator和脚本里的Anim参数关联到一起(当然,也可以直接在脚本里通过GetComponent方法获取这个Animator)。

Unity Animation -- 使用Animator控制动画

        8. 运行场景,控制Player进入和离开Trigger Collider的区域,观察结果(案例中有一个可用键盘控制的人物模型,我们也可以直接在场景中添加一个小球或立方体来代替,通过在Editor中拖动这个物体来实现Trigger Collider的检测)。文章来源地址https://www.toymoban.com/news/detail-426774.html

到了这里,关于Unity Animation -- 使用Animator控制动画的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity中,点击按钮Button,控制,动画Animator暂停播放

    在Unity中,你可以使用以下脚本来实现点击按钮时停止动画的功能: using UnityEngine; using UnityEngine.UI; public class StopAnimationOnClick : MonoBehaviour {     public Animator animator;     public Button button;     private bool isAnimationPlaying = true;     private void Start()     {         button.onClick.AddListen

    2024年04月27日
    浏览(49)
  • Unity-Animation&Animator

    Animation窗口 直译就是动画窗口 它主要用于在unity内部创建和修改动画 所有在场最中的对象都可以通过Animation窗口为其制作动画 原理: 制作动画时:记录在固定时间点对象挂载的脚本的变量变化 播放动画时:将制作动画时记录的数据在固定时间点进行改变,产生动画效果 动画时

    2024年03月13日
    浏览(55)
  • Unity获取Animation和Animator的时长

    我们有时候会在协程中等待动画播放完毕,再去执行下一步的操作,但是由于不知道动画的播放时长,每次都要去看动画然后默数秒数(PS:作者以前是这样做的)。终于突发奇想我为什么不能直接获取动画的时长呢? 下面直接上代码

    2024年02月09日
    浏览(43)
  • 在Unity中,Animation和Animator区别

    在Unity中,Animation和Animator都是用于控制动画的组件,但它们的工作方式和应用场景不同。 Animation是一种比较简单的动画系统,它可以让开发者直接对物体的Transform、Rotation、Scale等属性进行关键帧动画编辑。开发者可以通过Animation组件将动画剪辑(Animation Clip)和动画控制器

    2024年02月15日
    浏览(52)
  • Unity 制作动画 - Animation 的使用

    1. unity 顶部导航栏点击 Window  Animation 打开 Animation 窗口 通过这个窗口可以创建、编辑动画,也可以查看导入的动画。Animation 窗口同一时间只能查看、编辑同一段Clip中的动画 2. 选中 Hierarchy 面板中的节点, 也就是要制作动画的物体,该物体上没有动画,可以点击Animation窗口

    2024年02月15日
    浏览(45)
  • [Unity] 播放 Generic Animation 导致无法移动的解决办法:在 Animator 中勾选 Apply Root Motion

    我在使用 Animation Type 为 Humanoid 的 Animation 的时候是一切正常的 但是,自从因为 Humanoid 会导致手腕错误旋转问题,把 Animation Type 改成了 Generic 之后,我的人物就不能动弹了 测试发现,给 CharacterController 的输入是没有问题的,但是 CharacterController 所控制的父级 GameObject,也就是

    2023年04月08日
    浏览(39)
  • Unity animator动画倒放的方法

    在Unity中, 我们有时候不仅需要 animator 正放的效果,也需要倒放的效果。但我们在实际制作动画的时候可以只制作一个正放的动画,然后通过代码控制倒放。 实现方法其实很简单,只需要把 animator 动画的 speed 设置为-1即为倒放, speed 设置为1即为正放: 比如我制作了一个从

    2024年01月23日
    浏览(47)
  • Unity新动画系统之动画状态机Animator Controller

    1、创建动画状态机文件 (1)会在创建动画时自动创建 (2)Create----Animator Controller 2、动画状态机窗口相关 层级:可以在右侧齿轮设置参数大小   3、添加动画 为对象添加动画后会自动添加到状态机中 4、状态切换 动画会在1和2之间不断切换  添加条件 点击转换箭头  在这

    2024年02月05日
    浏览(48)
  • Unity Animator人物模型动画移动偏移

    模型动画出现移动方向偏移 !修改Animation中的Root Transform Rotation(根变换位置)、Root Transform Rotation(x,y,z)(旋转),Bake Info Pose修改为Original。可以解决 !!但是,使用动画移动函数时将无法移动,原因是锁定根变换位置和循环位置 !!!所以只要修改依据为原始或者微调偏离值,

    2024年02月15日
    浏览(43)
  • Unity Animator获取当前播放动画片段

    Animator获取当前播放片段,获取错误,跟当前播放的片段不一致的原因。 一般使用下面API,获取当前动画机播放片段: 这里有一个机制,如果上一句代码是播放一个动画片段,下一句代码立即去获取当前播放片段信息,是获取不到的,需要等待几十ms的延迟,才能正确获取到

    2024年02月12日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包