博主总算赶在这个月底写出了这篇文章。这个月由于期末考试一直没时间研究太多关于技术方面的东西。尽管博客一直在更新,但是对于文章的质量博主还是有一个非常清楚的认识的。那么。作为这个月的最后一篇文章,今天博主想和大家分享的是关于Unity3D中的Mecanim动画系统。
博主非常早就想写这篇文章了。但是由于各种原因一直没有机会去深入地研究这个问题,这几天考完试时间变得宽裕起来,所以博主就花时间研究了下这个问题。
Mecanim动画系统是Unity3D推出的全新的动画系统,具有重定向、可融合等诸多新特性,通过和美工人员的紧密合作,能够帮助程序设计人员高速地设计出角色动画。
今天文章的标题叫做《Unity3D游戏开发之当仙剑遇上Mecanim动画系统》,为什么取这样一个题目呢?由于博主今天想和大家分享的是Mecanim动画系统的重定向特性,众所周知。《仙剑奇侠传》是一部经典的RPG游戏,这部游戏到今天依旧焕发着强大的生命力。博主在网上认识了一个制作《仙剑奇侠传》同人游戏的小团队,他们眼下正在着手制作一个称为《仙剑奇侠传五外传:心愿》的同人游戏。该游戏基于Unity3D,由于技术上的一致性,博主向他们索取了一些游戏素材,而这成为了博主决心要研究Mecanim动画系统的一个主要原因。如图是《仙剑奇侠传五前传》中瑕的一个模型:
拿到这个模型的时候,博主发现这个模型的全部动画都是放在一个AnimationClip中的,所以博主果断将这个动画文件进行了切割,切割的方法是在资源文件夹中找到这个AnimationClip。然后在右側的属性窗体中选择Animations选项卡中通过+号来新建一个AnmationClip,在指定了起点帧数和终点帧数后就实现对动画的切割。如图示博主经过切割后的动画文件列表:
能够看到这里博主将一个动画片段切割成了4个动画片段,这样我们就能够通过Animation组件来实现对动画的播放。而这正是在Mecanim动画系统推出之前Unity3D採用的动画控制形式。由于这个模型在建模的时候存在问题,所以导致瑕在游戏场景中的角度出现错误,博主仅仅好自己用3D建模软件进行调整。结果意外得发现瑕的模型中是有骨骼的,博主忽然间想到了一个问题,能否够利用Mecanim动画系统来为这个模型加入动画呢?答案是肯定的。由于这个模型在建模的时候将动画和模型一起创建了,因此我们须要首先将这个动画从模型中去除,由于Mecanim动画系统的一个主要思路就是让一套动画能够通过重定向应用到不同的模型上,既然有动画可用,那么模型自带的动画能够临时去除。而让动画从模型中去除的方法非常easy,就是在导出FBX模型的时候将嵌入的媒体选项不要勾选,这样我们的模型就能够和动画分离开了,经过这一步后,我们正式開始Mecanim动画系统的解说。要理解Mecanim动画系统。首先须要了解这样几个概念:
一、Avater,即阿凡达,这是Mecanim动画系统中实现动画绑定的一个接口,该接口能够实现骨骼和肌肉系统的匹配。从而保证角色在运行动画的时候,角色能够依照预先设定的动画来运动。我们首先在项目资源窗体中找到了模型文件,如图:
我们注意到在右側的属性窗体中有三个选项卡:Model、Rig、Animations。这里我们选择Rig选项卡。将Animation Type设为Humanoid。即双足类型的动画。
这样的类型能够支持大多数的类人形的模型。
此外,Lagacy类型用来兼容Unity3D低版本号中的模型动画,Generic类型是一种介于人形和非人形的模型之间的通用类型。我们选择Humanoid类型后。在下方选择生成Avater的类型诶Create Form This Model,即通过当前的模型来生成一个Avater。此时。Configurebutton由不可用状态变成可用状态,我们点击该button,假设我们没有保存游戏场景的话,此时Unity3D会提示我们保存场景。我们直接选择保存,接下来回打开一个新的场景,如图:
此时场景中会显示模型的骨骼结构,对应地,在右側窗体中显示了该模型基本的身体结构,能够看到此时右側窗体中全部的点都是以绿色显示的。这表示当前模型的骨骼关节和模型匹配正确。此时,我们能够切换到Muscles选项卡中,这是我们能够通过拖动滑块来检查模型匹配是否正确。在使用Avater的时候,有两点须要注意:
1、假设模型建模没有严重的错误的话。能够通过窗体底部的Mipping->AutoMap来实现对模型的自己主动匹配,这一点能够提高工作效率。但是作为一名有节操的开发者。我们绝不能过度地依赖于这一功能。
2、当在手动调整模型匹配时,假设提示T-Pose错误,能够通过Pose->Enforce T-Pose来实现强制转化,博主近期才開始学习游戏建模,所以这里可能临时无法解释清楚,大家就作为经验之谈来看吧。
确认模型匹配没有什么问题后,点击Done完毕编辑。
二、AnimatorController:假设说Avater是将模型的身体和骨骼实现匹配的接口。那么AnimatorController就是讲动画和模型实现绑定的接口。
我们这里创建一个XiaAnimaterController。双击该文件,会打开Animator窗体,如图:
博主这里不想具体介绍关于Unity3D动画系统中的状态机和混合树等概念,由于这些概念如今解释起来实在困难,博主打算放在下一篇文章中来具体的解说Mecanim动画的状态机和混合树的概念。今天我们仅仅是对Mecanim动画系统做一个初步的了解,由于要想彻底理解这个动画系统,绝非一朝一夕之功啊。博主在这里创建了6种动画状态,并通过带箭头的线条将它们连了起来。博主这里想实现什么功能呢?博主希望在一定条件下能够触发对应的条件,当出发结束后立即回到默认的状态,这里默认的状态是Idle。预计大家到这里会有点混乱,博主前面不是说这个模型没有动画的嘛。那么这个的动画是哪里来的呢?对此,博主这里做一下解释啊。博主在创建这个项目之前呢。提前准备了一个叫做WomanKnightAnimationPack的动画包,它提供了游戏中经常使用的动画,我们这里就是要通过Mecanim的重定向功能将这个动画运用到我们的模型上去。这个动画包能够从官方的资源商店中下载。好了,如今我们来解说怎么讲动画和模型绑定。我们单击默认的Idle动画,在窗体右側将会显演示样例如以下内容:
通过Motion文本框我们能够为当前的状态绑定一种动画,选中Foot IK和Mirror这两个选项,似乎能够解决角色在行走或者奔跑过程中出现的问题,但是博主在查API文档的时候并没有找到相关的解释,假设有朋友知道的话,希望能够告诉博主啊。相似地,我们能够为不同的状态绑定一个动画片段,但是问题立即又来了。我们怎样依照游戏策划在适当地时候播放对应的动画呢?这就是动画的触发问题了,博主请大家想一想有限状态机的概念,假设不知道这个概念的。请自行了解。这是游戏设计中非常重要、非常实用的一个概念。我们知道在有限状态机中。不管我们使用switch-case结构还是if-else结构。都须要一个状态值来作为推断的根据。那么在Mecanim中这个原则依旧适用。由于,Mecanim动画系统就是基于状态机的。
好了。以下我们来创建一个状态值。如图,
在Mecanim动画系统中提供了四种类型的状态值,各自是Float、Int、Bool、Trigger,当中Trigger和OnTrigger()方法能够联用。实现触发式播放动画。好了,如今我们创建一个整型的状态值,默认值为0。
我们首先选中Idle->Walk这条路线,在右側的窗体中将參数设为ActionID,将值设为1,将方法设为Equals,其含义是当ActionID的取值为1时将运行Walk动画。相同地,我们将Walk->Idle这条路线选中。设将參数设为ActionID。将值设为0,将方法设为Equals,其含义是当ActionID的取值为1时将运行Idle动画。
其余的动画状态參数和Walk设置方法相同,从Idle出发的线路依次为1,2,3,4,5,指向Idle的路线全部为0。如今我们将这个AnimatorController指定给场景中的模型。如图:
此时我们运行程序,由于我们已经为瑕指定了默认的动画。于是我们将看到:
尽管这个动画和我们的瑕妹子搭配得有点违和,但是我们已经初步掌握了使用Mecanim动画系统的方法。好了。以下我们来编写一段脚本来控制人物切换动画,由于仅仅有默认动画是没有什么实际用途的:
using UnityEngine;
using System.Collections; public class MecanimController : MonoBehaviour { //Mecanim动画组件
private Animator mAnim; void Start ()
{
mAnim=GetComponent<Animator>();
} void Update ()
{
//假设按下W则步行前进
if(Input.GetKey(KeyCode.W))
{
//播放行走动画
mAnim.SetInteger("ActionID",1);
transform.Translate(Vector3.forward * 2.5f * Time.deltaTime);
}
//假设按下Shift+W则跑步前进
if(Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.LeftShift))
{
//播放奔跑动画
mAnim.SetInteger("ActionID",2);
transform.Translate(Vector3.forward * 2.5f * Time.deltaTime);
}
//假设按下I。则播放攻击动画1
if(Input.GetKey(KeyCode.I))
{
//播放攻击动画1
mAnim.SetInteger("ActionID",3);
}
//假设按下J。则播放攻击动画2
if(Input.GetKey(KeyCode.J))
{
//播放攻击动画2
mAnim.SetInteger("ActionID",4);
}
//假设按下K,则播放攻击动画3
if(Input.GetKey(KeyCode.K))
{
//播放攻击动画3
mAnim.SetInteger("ActionID",5);
} //假设松开各键位。则还原为Idle状态
if(Input.GetKeyUp(KeyCode.W) || Input.GetKeyUp(KeyCode.I) || Input.GetKeyUp(KeyCode.J)
|| Input.GetKeyUp(KeyCode.J) || Input.GetKeyUp(KeyCode.K) || Input.GetKeyUp(KeyCode.LeftShift))
{
//播放待机动画
mAnim.SetInteger("ActionID",0);
}
}
}
最后我们一起来看实际的效果吧!
场景中的地形由Unity3D自带的地形工具创建,事实上博主是想搭建一个《仙剑奇侠传五前传》中的云来石的场景,由于博主坚信。凭借瑾轩的智慧怎么会想不到在和瑕双双坠崖后召唤云来石呢。所以博主坚信他们俩都没有死。由于暮姐最后回眸的一瞬间表情是喜悦的。而背后传来了一急一慢两种脚步声。所以结局大家能够自己去想象啦。在同人游戏《仙剑奇侠传五后传:心愿》中他们策划的剧情和博主的基本一致,也许这就是《仙剑奇侠传》系列游戏之所以能让博主一直愿意乐观下去、努力下去的原因吧。我们都是普通人。但是我们并非由于普通而普通,而是我们选择了不作为。曾经博主听说过一款由仙剑玩家发起的游戏《仙剑奇侠传四:回到起点》,当时看到游戏的宣传动画时激动了好一阵子,但是到了后来这部游戏由于制作团队的解散而宣布停止,这似乎总让人想起上海软星的过去。细心的朋友一定发现了博主使用的素材是仙剑四中的模型,能够发现这个模型是较为简陋的,树木基本上是纸片拼成的。影子是在模型里创建的,当年弓长君带领上软制作仙剑三、仙剑三外传、仙剑四的艰难程度可窥一斑。
只是眼下由上软核心骨干组成的上海烛龙已经从当年的困境中走了出来,成为和大宇双剑抗衡的第三把剑。为何博主总是钟情于剑呢?由于剑的传说,直到永恒。好了,谢谢大家关注我的博客,今天的内容就是这样了,希望大家喜欢啊,呵呵。
学习Mecanim动画系统推荐视频地址:http://www.tudou.com/programs/view/Ul78LC6rukI/
每日箴言:事情并非由于难而让我们不敢做。而是由于我们不敢做事情才变得难.
转载请注明出处,本文作者:秦元培,本文出处:http://blog.csdn.net/qinyuanpei/article/details/35330525
版权声明:本文博客原创文章,博客,未经同意,不得转载。转载请注明出处和作者,谢谢!