不常见但可以极大地提升用户地游戏体验的三种动画:
①基于变形动画的形状混合:如嘴唇和面部动画
②逆向动力学:即运行期内角色的手部和脚部的定位方式
③电影纹理: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 () {
}
}