6.4.5 动画层
图6-42显⽰了动画层设置窗⼝。在动画状态机⾥可以添加很多层,层之间可以是覆盖关系也可以是叠加关系,当然也可以随时屏蔽⼀些层、启⽤另⼀些层。
每⼀个动画层可以有单独的设置,其选项解释如下。
①Weight(权重),本层对总体动画效果的影响,取值范围为0~1。0代表没有影响,1代表完全影响。
②Mask(遮罩),每层可以单独设置遮罩,如某些层只负责上肢动画。
③Blending(混合模式),有Override(覆盖)和Additive(叠加)两个选项,是指这⼀层的影响覆盖其他层,还是叠加到已有动画上。
④Sync与Timing,⽤于两个动画层之间的同步。
⑤IK Pass(更新反向动⼒学),如果勾选,则这⼀层动画会触发脚本中的OnAnimatorIK()函数,可以在脚本中进⼀步处理IK。总结来说,动画遮罩和动画层为开发者进⼀步组合多种不同的动
画提供了可能。另外,在游戏项⽬早期或独⽴游戏开发时,美术资源还不够丰富,这套系统可以帮助开发者尽可能组合出多种多样的动作。
6.4.6 动画帧事件
很多时候需要在特定的时机执⾏某种逻辑。例如,当玩家做挥砍动作时,在挥砍的某个时刻开始,需要持续判断是否击中了物体。这个时机要求⽐较精确,因为它和玩家的动作息息相关,不能在⼀开始抽出武器时就进⾏攻击判定,也不能在收招阶段判定。攻击判定的时间段只能是整个攻击动作中的⼀部分。
因此引擎需要提供⼀种机制,在动画的时间轴上做⼀个标记,在动画播放到特定帧的时候触发脚本函数。以挥砍动作为例,可以在挥出武器时执⾏“开启攻击判定”的函数,⽽在攻击收招时执⾏“关闭攻击判定”的函数。
⼩提⽰
帧事件让动画与游戏逻辑耦合由于动画帧事件的标记必须在动画的时间轴上,因此会和动画数据本⾝耦合在⼀起。纯粹从程序逻辑的⾓度看,多种不同系统的耦合并不是好事,但为了增强游戏表现⼒,这么做也有充分的理由。
根⾻骼动画也有同样的特点,根⾻骼动画是将动作与物体运动耦合在了⼀起。也许,正是这种⽆处不在的耦合,才会让游戏开发显得特殊和复杂。
下⾯以落地动作为例,给落地动作添加⼀个动画帧事件。
添加动画帧事件依然是在模型和动画导⼊设置中完成。⾸先找到落地动作,然后在动画状态机中找到Airborne(空中)状态,双击打开融合树。经过分析,融合树中的HumanoidFall动画就是落地动画。单击该动画,Project窗⼝会⾃动跳转到对应的资源⽂件,也就是HumanoidIdleJumpUp。选中该⽂件查看导⼊设置,在Animation标签⻚的下⽅有⼀个Events(事件)选项,动画帧事件就在这⾥添加,如图6-43所⽰。但⼀定要先选中需要修改的动画⽚段,即HumanoidFall,再继续设置。
Events设置中包含⼀个时间轴,时间轴左侧有⼀个添加按钮,⽤于添加新的事件,其步骤如下。
01 单击添加按钮,会在时间轴上多出⼀个标记。
02 将该标记拖到需要触发事件的时刻。注意这⾥的时间轴并不对应动画的真实时间⻓度,⽆论动画本⾝时间⻓或短,都会统⼀为同样的⻓度,在程序中⽤⼀个0~1的值表⽰,这叫作“标准化时间”或“归⼀化时间”
03 将标记拖到合适的位置后,就可以填写事件信息了。Function字段必须填写,它既是事件的名称,也是会⾃动调⽤的函数名。例如,填写MyFall就会调⽤脚本组件中的MyFall函数,且这个函数还可以带多个参数⽅便后续使⽤,包括1个浮点数、1个整数、1个字符串和1个Object类型的引⽤。
进⾏了设置后,编辑器中的信息就准备完毕了,注意要单击Apply按钮让修改⽣效。接下来的⼀步是修改脚本,给脚本添加对应名称的函数。
在例⼦中,玩家⾓⾊已经挂载了ThirdPersonUserControl脚本,为了简单起⻅,直接给ThirdPersonUserControl脚本添加MyFall函数。
void MyFall()
{
Debug.Log(" 触发帧事件,落地");
}
运⾏游戏,按跳跃键进⾏测试。如果设置正确就会在Console窗⼝中显⽰“触发帧事件,落地”的信息。这样帧事件的主要使⽤⽅法就介绍完毕了。但是如果深究,就还有⼀些⼩问题,⾸先是动画系统查找动画帧事件的函数的规则是怎样的?
简单来说,动画会查找当前对应物体的所有脚本,只要有名称和类型符合的函数,都会被调⽤。也就是说,如果玩家⾝上的两个脚本都有名为MyFall的函数(返回值不是void也可以),那么都会被调⽤;如果⼀个函数都没找到,就会产⽣⼀条错误信息。读者可⾃⾏试验。
其次,上⽂的MyFall函数没有参数,实际上可以带⼀个参数,但最多也只能带⼀个参数。参数类型可以是float、int、string或Object其中之⼀,参数的值可以在编辑动画帧事件时指定。
最后,动画帧事件不单是3D动画独有的,所有动画都可以添加动画帧事件。⼀般给其他类型的动画添加帧事件是在Animation窗⼝中操作的。窗⼝中的Add Property按钮就是⽤于添加新事件的,如图6-44所⽰。添加的事件也具有前⽂所提到的参数,具体使⽤⽅法也类似。
6.4.7 反向动⼒学(IK)
IK全称为Inverse Kinematic,⼀般翻译为反向动⼒学。⼀般来说,它是⼀种极为细致的动画微调技术,例如在以下情景中的应⽤。
情景1,⾓⾊在⾛上台阶时,利⽤IK让脚总是刚好踩在台阶上。
情景2,⾓⾊⼿持不同形状的枪时,⼿总是刚好抓着枪柄。
情景3,⾓⾊进⾏攀爬时,⼿部和脚步紧贴墙壁。在上⾯的这些情景中,有两个关键:⼀是通过程序检测到合适的位置(台阶、枪柄),让⼿脚或其他肢体朝⽬标位置移动;⼆是当⼿脚或其他肢体移动时,其余所有的关节都能配合移动,如⼿部运动时也会带动⼿臂的运动。IK会采⽤相关算法,尽可能让运动看起来合理。
1. 头部IK
头部IK⽐较简单,只需要修改⾓⾊控制脚本ThirdPersonCharacter就可以⽴即看到效果。在该脚本中加⼊的函数如下。
private void OnAnimatorIK(int layerIndex)
{
// 设置注视⽬标的权重为1
m _ Animator.SetLookAtWeight(1);
// ⼀直注视(0,0,0) 点
m _ Animator.SetLookAtPosition(new Vector3(0, 0, 0));
}
运⾏游戏进⾏测试,会发现⾓⾊头部会保持转向某个⽅向,但⽬标在⾓⾊背后时,也不会过度转向。使⽤IK有⼀些注意事项,也只有符合以下规则,IK才会⽣效。
⼀是IK与动画状态机中的动画层相关。在介绍动画层时,我们看到在每⼀层的设置中都有⼀个IK Pass选项,它⽤于开启或关闭IK功能。所有开启了IK Pass的层都会调⽤脚本中的OnAnimatorIK()函数。⼆是有与IK相关的函数,如SetLookAtWeight()函数和SetLookAtPosition()函数都只能在专门的OnAnimatorIK()函数中调⽤。如果编写在其他地⽅⽽不起作⽤,Unity会给出提⽰信息。
上⽂的SetLookAtPosition()函数⽐较好理解,参数是注视的⽬标位置。⽽SetLookAtWeight()函数则是指IK运动的权重,可以理解为IK⼲预动画的程度。权重越⾼,IK运动就越明显,权重为0时相当于关闭了IK功能。
因为⼈物头部转动时,⾝体各部位都需要跟着配合,所以SetLookAtWeight()函数有很多参数可以调整,通常取默认值即可。
// 参数依次为整体权重、⾝体权重、头部权重、眼睛权重。
// 最后clampWeight是⼀个限制参数,防⽌转动过⼤,0代表不限制,1代表完
全限制。
void SetLookAtWeight(float weight, float bodyWeight = 0.0f,
float headWeight = 1.0f,
float eyesWeight = 0.0f, float clampWeight = 0.5f);
2. ⼿脚IK
⼿部和脚部IK也很常⽤,其参考代码如下。
private void OnAnimatorIK(int layerIndex)
{
// pos 是⽬标位置
m _ Animator.SetIKPosition(AvatarIKGoal.LeftHand, pos);
m _ Animator.SetIKPositionWeight(AvatarIKGoal.LeftHand,
1);
// rot 是⽬标朝向
m _ Animator.SetIKRotation(AvatarIKGoal.LeftHand, rot);
m _ Animator.SetIKRotationWeight(AvatarIKGoal.LeftHand,
1);
}
设置⼿脚IK时,有4个常⽤⽅法(⻅表6-2)。它们的第⼀个参数是AvatarIKGoal类型的枚举,只有4种取值:LeftFoot(左脚),RightFoot(右脚),LeftHand(左⼿),RightHand(右⼿)。
在实际游戏开发中,找到合适的位置和朝向很⿇烦,⼀般⽆法直接做到。通常有以下两种寻找IK定位点的⽅式。
⼀是⽤⼀个空物体作为参考点位置。例如,玩家⾓⾊举枪射击时,枪柄的⼦物体⾥有⼀个特殊的空物体,空物体的位置和朝向就是⼿部定位的点。编程时,指定⼿部IK的位置和旋转与空物体⼀样,然后根据需要再微调空物体即可。
⼆是利⽤物理射线定位。例如,制作上楼梯的动作时,可以从⾓⾊的脚朝下发射射线,射线碰到地⾯的位置就是脚部需要踩的位置。从很有限的参数和⽅法可以看出,Unity原⽣仅提供了很基本的IK功能,设计偏写实的游戏时可能会遇到功能不够⽤的情况,这时可以求助于Asset Store中的插件。某些IK插件的功能⾮常强⼤,可以实现更复杂的IK效果。
从整体游戏设计来看,IK属于⼀个专注于细枝末节的技术。很多游戏出于性能等因素的考虑⽽没有使⽤IK。
第7章 脚本与特效
美观且有特⾊的游戏画⾯在吸引玩家眼球⽅⾯⾮常重要,⽽游戏作为动态的艺术形式,动画与特效⾃然更为重要。精美的⾓⾊动作可以制造出极强的节奏感和打击感,但更需要特效进⼀步烘托氛围、增强效果。相对⾓⾊动作⽽⾔,特效受到的约束较少,可供发挥的空间较⼤。在⻛格合适的前提下,加⼊丰富多彩的特效能提升游戏表现⼒。
通常玩家所说的特效,从技术⾓度来看其实可能包含了各种粒⼦、光效、动效和氛围动画等,然⽽各个系统之间可能并没有什么联系,仅仅只是搭配在⼀起形成了综合的特效⽽已。本章将分别讨论这些特效的⽤法和相关的编程要点,侧重点是如何使⽤和管理各种特效素材,⽽不是特效本⾝的制作⽅法。
7.1 特效总览
提到Unity中的特效,⾸先想到的是粒⼦系统。其实⼴义地看,只要能增强游戏表现⼒的效果都可以称为特效。按照具体技术分类,可以包含粒⼦、动画(⾮⾓⾊动画)、动效、贴花、拖尾和后期效果等。
7.1.1 粒⼦
Unity中的粒⼦组件叫作Particle System,如图7-1所⽰。
粒⼦系统顾名思义,与“微粒”有关。粒⼦系统会⽣成和发射很多粒⼦,通过控制粒⼦的⽣成数量、⼤⼩、⾓度、速度、贴图和颜⾊等众多属性,可以实现或真实或炫酷的各种效果。其中,粒⼦的每⼀种属性还可以根据时间变化⽽随机变化,充分释放特效设计师的创造⼒。
例如,⽤粒⼦系统可以实现⽕焰、⾬、雪、⽓流等⾃然现象,也可以实现能量球、魔法弹等幻想中的效果。⽽且现代的粒⼦系统也⽀持基于3D模型的粒⼦,可以实现模型破碎、模型聚合、模型消散等丰富的视觉效果。
7.1.2 动画
Unity的粒⼦系统有它⾃⾝的局限性,因此美术设计师经常结合动画系统和粒⼦系统来制作特效。有经验的美术设计师利⽤图⽚和模型素材,配合精⼼调整的旋转、位移、缩放等基本变换,做出华丽的表现效果。
⽽且,由于动画可以直接对帧进⾏编辑,相⽐只能调整参数的粒⼦系统控制⼒更强,从⽽让设计师更容易调整动态节奏,因此某些情况下动画特效是不可替代的。
7.1.3 动效
动效⼀般是场景或界⾯中元素的⼩幅度动态。例如,UI中⽂字的弹跳、缩放,图⽚的淡⼊淡出,界⾯从屏幕外⻜到屏幕内,这些都可以算作动效。动效看似不起眼,但对于提升⽤户体验来说作⽤巨⼤,⽽且很多休闲类游戏都⼗分注重动效设计。动效是⽤户体验(UE)中举⾜轻重的⼀个环节,例如现代⼿机端操作系统都⾮常重视⽤户操作的动态效果,如图7-2所⽰。
文章来源:https://www.toymoban.com/news/detail-853346.html
在Unity中,动效的实现有两个基本⽅式,⼀是使⽤动画,⼆是使⽤Tween(缓动动画)。缓动动画是直接⽤脚本代码控制的动画,具有易添加、易维护、易修改的特点,它只需添加少量的代码就能做出各种⽣动的动画,⽽不⽤管理⼤量琐碎的动画资源,⾮常⽅便。文章来源地址https://www.toymoban.com/news/detail-853346.html
到了这里,关于Unity 3D脚本编程与游戏开发【3.8】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!