不常见但可以极大地提升用户地游戏体验的三种动画:
①基于变形动画的形状混合:如嘴唇和面部动画
②逆向动力学:即运行期内角色的手部和脚部的定位方式
③电影纹理:3D表面上作为纹理播放前期渲染完毕的视频文件
1、形状混合
面部动画包括 脸部变化 和 嘴唇动画,通常需要使用Blend Shape或变形动画,这一类动画效果一般通过设计人员或3D软件予以完成,并于随后导入至Unity中,在面板中激活 Import BlendShapes。
针对构建过程,变形动画需要两个处理步骤:
设计人员定义面板网格的极限位置,即将全部面部网格顶点定位、排列于某一极限位置,创建Shape Key或Blend Shape记录对应姿势的网格状态。
通过记录一系列不同的姿势,可生成不同姿势间的加权平均混合结果,进而生成最终的面部动画,Animations实现。
2、逆向动力学
大多数3D应用软件均对IK提供了相关支持,但此类数据通常无法转换至Unity
全部IK动画将作为 Forward Kinematics(FK)导入Unity,需要人工方式配置Unity的IK进行数据访问
启动IK所需的Mecanim Avatar系统
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ArmIK : MonoBehaviour { public float leftHandPositionWeight; public float leftHandRotationWeight; public float rightHandPositionWeight; public float rightHandRotationWeight; public Transform leftHandObj; public Transform rightHandObj; private Animator animator; // Use this for initialization void Start () { animator = GetComponent<Animator>(); } // Update is called once per frame void Update () { } private void OnAnimatorIK(int layerIndex) { animator.SetIKPositionWeight(AvatarIKGoal.LeftHand, leftHandPositionWeight); animator.SetIKRotationWeight(AvatarIKGoal.LeftHand, leftHandRotationWeight); animator.SetIKPosition(AvatarIKGoal.LeftHand, leftHandObj.position); animator.SetIKRotation(AvatarIKGoal.LeftHand, leftHandObj.rotation); animator.SetIKPositionWeight(AvatarIKGoal.RightHand, rightHandPositionWeight); animator.SetIKRotationWeight(AvatarIKGoal.RightHand, rightHandRotationWeight); animator.SetIKPosition(AvatarIKGoal.RightHand, rightHandObj.position); animator.SetIKRotation(AvatarIKGoal.RightHand, rightHandObj.rotation); } }
3、电影纹理
Audio Source组件,负责播放电影中的音频内容
创建Material,针对着色器类型,选择 Unlit | Texture
播放脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(AudioSource))] public class PlayVideo1 : MonoBehaviour { public bool loop1 = true; public bool playFromStart1 = true; public MovieTexture video1; public AudioClip audioClip1; private AudioSource audio1; // Use this for initialization void Start () { audio1 = GetComponent<AudioSource>(); if (!video1) video1 = GetComponent<Renderer>().material.mainTexture as MovieTexture; if (!audioClip1) audioClip1 = audio1.clip; video1.Stop(); audio1.Stop(); video1.loop = loop1; audio1.loop = loop1; if (playFromStart1) ControlMovie1(); } private void OnMouseUp() { ControlMovie1(); } public void ControlMovie1() { if (video1.isPlaying) { video1.Pause(); audio1.Pause(); } else { video1.Play(); audio1.Play(); } } // Update is called once per frame void Update () { } }