用Timeline实现动画特写(下)

用Timeline实现动画特写(下)

https://www.bilibili.com/read/cv4145535?from=articleDetail

大渣好。说书人放了无穷久的鸽子之后又回来了。 空中三百六十度回旋磕头以表歉意 书接上一回,上一篇介绍了Timeline的部分基础知识,并实现了主角的动画播放,本篇将接着把剩余的功能实现。本篇主要介绍实现的方法,具体的手感参数还需小伙伴们根据自己的动画慢慢调哦(体力活)。与格挡结合后效果图如下: 本篇实现功能: 1.Timeline控制角色位移 2.切换特写镜头 3.触发镜头抖动和播放粒子特效 4.子弹时间 5.动态绑定轨道对象(Binding) 本文不包含格挡与切割内容,有兴趣的小伙伴自行参考底部链接。 一、Timeline Signals Unity 2019.1版本推出了Timeline Signals功能,具有“广播”特点,帮助发送事件。接下来将通过实现部分功能来熟悉Timeline Signals。 概念速览: 1.Signal Emitter(信号发射器) 信号发射器会放在Timeline上,它包含对信号资源的引用。如果当前播放时间点比发射器所在的时间点后,发射器会把信号资源发送到信号接收器。 (1)添加:对应Track右键 -> Add Signal Emitter (2)Signal Emitter面板简介 Retroactive: 开始播放时的进度位置在发射器后也能回溯触发。 Emit Once:循环播放时只触发一次。 Create Signal:新建信号资源。 Add Signal Receiver:添加信号接收器。 2.Signal Asset(信号资源) 信号资源是发射器和接收器之间的联系。通常信号资源会用作标识符。 已有Signal信号资源时,新建或切换Signal如下图: 3.Signal Receiver(信号接收器) 当接收器知道信号已被触发时,它会激活关联到对应信号资源的反应。Signal Receiver会自动添加到绑定对象(轨道左侧)上。添加信号反应操作如下图: 大概逻辑:播放到信号发射器处 -> 发射信号 -> 对应信号的接收器激活反应 此外,还可以通过编写Marker脚本自定义标记,有兴趣的小伙伴自行了解。 二、设置被击退位移 上一篇结尾“组合”出敌人被击退的动画,现在开始通过Transform Tween Track和Signals设置击退的位移。(也可以通过点击小红点录制实现位移) Ps:本文命名只是为了增加辨识度,无其他特殊含义。 1.添加Transform Tween Track (1)添加Track:Timeline编辑器空白处右键 > Transform Tween Track,命名为ETransformTrack。(Inspector窗口可重命名) (2)添加Clip:右键该Track > Add Transform Tween Clip,命名为BackTransClip。 (3)用Track Group(空白处右键)把主角和敌人的轨道分别装起来,便于整理。 (4)Transform Tween Clip部分属性简介: Tween Positon:是否转换Position。 Tween Rotation:是否转换Rotation。 Twee Type(转换类型):Linear线性匀速、Deceleration减速、Harmonic(中间最快)、Custiom自定义。 Start Location:Clip起始的Transform。 End Location:Clip结束的Transform。 (5)给所有轨道左侧绑定框拖进对应的对象。 2.设置Transform Tween Track 在敌人被攻击的时候,通过给Start Location和End Location赋值来实现击退位移动。 (1)方法一(速览即可):脚本中通过层层遍历找到Location,然后为其赋值,有兴趣的小伙伴自行研究。 大概思路如下: (2)方法二(本文粗暴做法): ①在主角里新建一个空的GameObject,命名为KickEndTrans,作为敌人被击退位移结束的Transform参考。 ②另外在Hierarchy再建一个空的GameObject,命名为TempKickEndTrans,拖进BackTransClip的End Location。 ③播放BackTransClip(Transform Tween Clip)前通过Signal调用方法,把TempKickEndTrans置到KickEndTrans的方位上,达到设置End Location的效果。(Start Location也如此设置) 代码如下: /// /// 设置敌人被击退后的Transform /// public void OnSignal_SetKickEndTrans() { //开始时敌人Transform tempTargetTrans.position = cPlayer.targetTrans.position;// cPlayer.targetTrans为当前敌人Transform tempTargetTrans.rotation = cPlayer.targetTrans.rotation; //结束时敌人Transform tempKickEndTrans.rotation = kickEndTrans.rotation; tempKickEndTrans.position = kickEndTrans.position; } ④使用Signal调用方法: 新建一个Signal Track,在开始击退前的位置添加Signal Emitter,添加信号,命名为Kick。 Hierarchy中新建一个空对象,命名为SignalFunctions,拖进Signal Track左侧绑定框,在SignalFunctions的Inspector窗口可以看到自动添加的Signal Receiver。 在Signal Receiver中选择对应信号,点击“+”添加反应,然后把方法所在对象拖进Reaction里,最后选择需要调用的方法。操作如图: 位移效果: 以上便是用Signal和Transform Tween Track 设置位移的粗暴做法,其他位移也可以如此设置,参数还需小伙伴们根据自己的动画具体情况具体分析。 三、镜头切换 镜头的切换主要是通过Cinemachine Track与Cinemachine配合完成的。 (1)基本概念 Cinemachine核心组件包括Brain和Virtual Camera(虚拟相机): Brain:负责相机的切换。 Virtual Camera(虚拟相机):负责拍摄。 Cinemachine提供了一些预设好行为方案,方便我们实现游戏中的功能。这次工程轨道中主要使用了Target Group Camera 和普通的Virtrual Camera,另外Timeline播放前人物用的是Free Look Camera(非本文主要介绍范围)。 Target Group Camera:可以在多个拍摄目标之间设置焦点,通过权重调节焦点偏移。 Virtrual Camera:普通的相机。 Free Look Camera:允许玩家控制并围绕目标旋转的相机,可以用作第三人称相机。 (2)设置Target Group Camera 脚踢敌人过程中使用的是Target Group Camera ,以主角和敌人综合得出拍摄焦点。 ①添加Target Group Camera后,Hierarchy窗口会出现一个CM vcam和一个对应的TargetGroup。关系如下图: ②调节TargetGroup 拍摄焦点通过目标、对应的权重以及半径综合得出。 Target:拍摄目标,本工程把玩家身上的摄像参考点拖进第一个参数框,通过脚本把敌人的Transform放进第二个参数框。 Weight:权重,用于调节焦点的偏移。 Radius:半径,用于调节相机距离。 在脚本中把敌人的Transform赋值给Target属性第二个参数框,代码如下(在播Timeline前调用),需要using Cinemachine; using Cinemachine; //... /// /// Timeline开始前设置Trans /// public void SetTransBeforeTL() { if (cPlayer.targetTrans) { //把敌人Trans赋值到Target Group组件里Target的第二个参数 targetGroup.m_Targets[1].target = cPlayer.targetTrans; //... } } (3)设置Cinemachine Track ①添加Track:Timeline编辑窗口空白处 > 右键 > Cinemachine Track。 ②把Main Camera拖进左侧绑定框。 ③添加Clip:把所需的cinemachine拖进轨道,按需排序和混合即可,播放时会随着进度自动切换,重叠处会自动过渡。 本工程的切换顺序(仅供参考):Free Look Camera(起始过渡) > Target Group Camera (脚踢过程)> Virtrual Camera(跳劈时在头顶) > Free Look Camera 四、触发镜头抖动与播放粒子特效 1.屏幕抖动 (1)需要用到的组件: ①Cinemachine Impulse Source:发出抖动信号。 ②Cinemachine Impulse Listener:收到信号,则镜头抖动。 (2)在Main Camera中添加Cinemachine Impulse Source组件:Inspector > Add Component > Cinemachine Impulse Source。 部分属性: Raw Signal:原始信号,可理解为抖动类型。使用Unity提供的信号类型:右侧齿轮 > Persets > 选择需要类型。 Amplitude Gain:振幅增益。 Frequency Gain:频率增益。 Impact Radius:影响半径。 (3)在需要抖动的Virtual Camera中添加Cinemachine Impulse Listener: Inspector > Cinemachine 组件(底部)> Add Extension > CinemachineImpulseListener。 2.粒子特效播放方法 在命中敌人的位置添加粒子特效,然后脚本中获取粒子特效,最后在方法中调用Play()播放。 public ParticleSystem hitRed_Kick; /// /// Kick特效 /// public void OnSignal_SetKickEffect() { hitRed_Kick.Play(); } 3.在攻击命中敌人的时候,通过Signal Receiver来触发镜头抖动和调用特效播放方法。 发出信号方法:CinemachineImpulseSource.GenerateImpulse(); 五、子弹时间 本次是通过调节时间的缩放来实现子弹时间。 1.添加Time Dilation Track。 2.添加Time Dilation Clip。部分属性: Time Scale:时间缩放比例,1为正常时间,0为静止。 Blend Curves:混合曲线。 3.调节思路 (1)创建两个Time Dilation Clip:一个Time Scale为0,另一个Time Scale为1。(参数自行调节) (2)把连个Clip重叠起来,通过调节Clip重叠长度和混合曲线,达到自己想要的效果。 六、动态绑定轨道对象 终结不同的敌人代表着动画的执行角色不同,因此需要在脚本中为轨道更换绑定的目标。 1.添加事件 (1)相关变量: using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.Playables;using UnityEngine.Timeline; public class PAnimation : MonoBehaviour{ CPlayer cPlayer; PSlicer pSlicer; //切割脚本 Animator animator; Animator targetAnimator; RuntimeAnimatorController player_AC; //记录玩家AnimatorController RuntimeAnimatorController target_AC; //记录目标AnimatorController public PlayableDirector playableDirector; //TimelineDirector; public TimelineAsset tL_StrikeBack; //反击的TimelineAsset //信号相关 SignalFunctions signalFunctions; //信号方法脚本 Dictionary bindingDict; //存储 //...} (2)事件 ①PlayableDirector.played:在PlayableDirector 开始播放时调用。 ②PlayableDirector.stopped:在PlayableDirector停止播放时调用。 void Start() { // ... //添加事件 playableDirector.played += OnPlayableDirectorStart; //开播时执行 playableDirector.stopped += OnPlayableDirectorStopped; //停播时执行 } 2.释放技能时: (1)指定播放片段(TimelineAsset)。 public void PlayTimeline() { //指定TimelineAsset(播放片段) playableDirector.playableAsset = tL_StrikeBack; //储存Binding SaveBindings(); playableDirector.Play(); } (2)用字典储存每个轨道:PlayableBinding.streamName 获取轨道名字,作为字典的Key。 代码如下(需要using UnityEngine.Playables;和using UnityEngine.Timeline;): using UnityEngine.Playables;using UnityEngine.Timeline;//... //储存绑定的Track左侧,换新TimelineAsset时调用 public void SaveBindings() { foreach (PlayableBinding binding in playableDirector.playableAsset.outputs) { if (!bindingDict.ContainsKey(binding.streamName)) { bindingDict.Add(binding.streamName, binding); } } } 3.Timeline播放前 (1)置空AnimatorController避免播放TimeLine过程中执行其他状态。(也可在动画状态机中添加表示正在播放Timeline的状态来解决) (2)通过检索字典给轨道绑定对象: 绑定轨道左侧对象:PlayableDirector.GetGenericBinding(Object key, Object value);。 Key:可用PlayableBinding.sourceObject获取。 Value:需要绑定的对象。 代码如下(含注释): /// /// 播放前执行 /// /// void OnPlayableDirectorStart(PlayableDirector aDirector) { cPlayer.characterController.enabled = false; //关闭CharacterController,不然有冲突 animator.applyRootMotion = true; //应用RootMotion //暂存AnimatorController player_AC = animator.runtimeAnimatorController; //把AnimatorController暂时置空,避免播Timeline时动画状态机还在执行其他状态。 animator.runtimeAnimatorController = null; //敌人AnimatorController暂时置空,播完置回去。 targetAnimator = cPlayer.targetTrans.GetComponent(); target_AC = targetAnimator.runtimeAnimatorController; targetAnimator.runtimeAnimatorController = null; //把玩家Animator绑进轨道 playableDirector.SetGenericBinding(bindingDict["PlayerAniTrack"].sourceObject, animator); playableDirector.SetGenericBinding(bindingDict["PTransformTrack"].sourceObject, animator.transform); //把敌人Animator绑进轨道 playableDirector.SetGenericBinding(bindingDict["EnemyAniTrack"].sourceObject, cPlayer.targetTrans.GetComponent()); playableDirector.SetGenericBinding(bindingDict["ETransformTrack"].sourceObject, cPlayer.targetTrans); //Clip 参考Trans设置 signalFunctions.SetTransBeforeTL(); } 4.动画播放完后,用PlayableDirector.Evaluate()估算Timeline中各对象,否则会回到开播的位置,然后把播放的TimelineAsset置为null。代码如下(含注释): /// /// 播放完执行 /// /// void OnPlayableDirectorStopped(PlayableDirector aDirector) { playableDirector.Evaluate(); //评估对象所在位置,否则回到播放前位置 playableDirector.playableAsset = null; //playableDirector里的TimlineAsset置Null //重置玩家播放Timeline前的状态 cPlayer.characterController.enabled = true; cPlayer.isStrikingBack = false; animator.applyRootMotion = false; animator.runtimeAnimatorController = player_AC; //重置敌人播放Timeline前的状态 if (targetAnimator) { targetAnimator.runtimeAnimatorController = target_AC; //... } } 5.踩过的坑 (1)角色身上CharacterController在激活状态,播放Timeline时角色会不能位移。 (2)结束播放时,没有执行PlayableDirector.Evaluate(),角色回到开始播放位置。 (3)播放结束,没有把PlayableDirector.playableAsset置空,非Apply Root Motion时角色不能移动。 结语:本文结合了Timeline Signals和各种Track实现了一系列的功能,虽然已花了较长时间查询资料,但是仍存在很多不完善的地方,时间关系只好先介绍到这里(自己开的坑,头发掉满地也只能含泪勉强填完)。希望对大家初步了解Timeline有所启发,如有问题欢迎讨论。 相关资料 1.Timeline Signals:https://connect.unity.com/p/shi-yong-unity-2019-1zhong-de-timeline-signals 2.Timeline动态赋值:https://zhuanlan.zhihu.com/p/29585350 3.Ezy-Slice切割教程:https://www.bilibili.com/video/av65373505 4.从SkinnedMeshRenderer获取正确显示的普通Mesh:https://blog.csdn.net/Traip/article/details/88095446 5.格挡:https://zhuanlan.zhihu.com/p/83607025 链接:https://pan.baidu.com/share/init?surl=K1RX_qmmPfcjQazJHpNBJA 提取码:stll 咱们的游戏开发交流群也欢迎强势插入:869551769 希望参与线下游戏开发学习的,欢~~~~~~迎访问:http://www.levelpp.com/

作者:皮皮关做游戏
https://www.bilibili.com/read/cv4145535?from=articleDetail
出处: bilibili

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity Timeline 是 Unity 引擎中的一个时间轴工具,它用于创建复杂的、多阶段的动画序列。Unity Timeline 不仅可以实现动画混合,而且还提供了强大的工具和功能来实现动画的各种混合方式。 在 Unity Timeline 中,可以通过添加和编辑各种动画轨道来创建动画序列。每个动画轨道可以包含不同的动画剪辑,这些剪辑可以是来自不同的动画片段或者不同的动画控制器。通过将这些动画剪辑串联在一起,就可以实现动画的混合。 Unity Timeline 还支持混合树和混合器,这使得在动画序列中实现复杂的动画混合变得更加容易。混合树可以将多个动画状态和过渡规则组合在一起,使得在不同动作之间平滑过渡变得十分灵活。混合器则提供了一种便捷的方式来控制动画状态之间的混合过渡和权重。 除了基本的动画混合功能外,Unity Timeline 还提供了丰富的转换和修饰器功能,使得动画的混合过程更加精细化和个性化。通过调整过渡曲线、添加淡入淡出效果、调整动画速度等方式,可以实现更加平滑和自然的动画混合效果。 综上所述,Unity Timeline 可以非常方便地实现动画的混合。无论是基本的动画片段串联,还是复杂的动画混合变换,Unity Timeline 都提供了一系列强大的工具和功能来满足开发者的需求。 ### 回答2: Unity Timeline可以实现动画混合。动画混合是指将多个动画片段无缝地连接在一起,以实现更加流畅自然的动画过渡效果。在Unity中,Timeline是一个强大的工具,可以创建和编辑时间轴,控制和混合不同的动画片段。 使用Unity Timeline,我们可以将多个动画状态连接在一起,然后根据指定的规则进行混合。例如,我们可以通过控制时间曲线和变换曲线来制定动画的过渡效果。我们还可以根据需要在时间轴上添加和编辑事件,并进行动画状态之间的补间。 通过Unity Timeline,我们可以实现多种动画混合效果,如淡入淡出、平滑过渡、融合等等。我们可以根据动画状态的优先级、权重、时间曲线等来控制动画的混合效果,实现更加精细的动画控制。 总之,Unity Timeline是一个强大的工具,可以实现动画混合效果。通过使用Timeline,我们可以创建复杂、流畅的动画过渡,并且可以根据需求进行细节调整。无论是游戏开发还是其他领域的动画制作,Unity Timeline都是一个非常有用的工具。 ### 回答3: 是的,Unity Timeline可以实现动画混合。动画混合是指同时播放多个动画,使它们平滑地过渡,并按照一定的权重进行混合。Unity Timeline为开发者提供了一个可视化的时间轴编辑器,可以方便地对动画进行管理和控制。 在Unity Timeline中,我们可以创建多个动画轨道,并在每个轨道上放置不同的动画剪辑。通过设置每个动画剪辑的权重和过渡曲线,可以使动画在时间轴上平滑切换和过渡。开发者可以使用Timeline中的插值器,例如Blend Tree,来控制动画的混合过程,使不同的动画之间实现平滑的过渡效果。 此外,Unity Timeline还提供了灵活的控制选项,比如可以调整动画的播放速度、循环模式、延迟启动等。还可以通过添加事件轨道,在特定的时间点触发脚本事件,实现更高级的交互和逻辑控制。 总的来说,Unity Timeline是一个强大的工具,可以帮助开发者实现复杂的动画混合效果,使游戏或应用程序中的角色和场景动画更加丰富和流畅。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值