Unity学习记录——模型与动画
前言
本文是中山大学软件工程学院2020级3d游戏编程与设计的作业7
编程题:智能巡逻兵
1.学习参考
除去老师在课堂上讲的内容,本次作业代码与操作主要参考了[傅老師/Unity教學] DarkSouls複刻經典教程#第一季_bilibili
模型动作资源也同样来自傅网课之中老师的给出教程人物模型与动画 (weiyun.com)
2.基本介绍
(1)unity动画1
Unity 有一个丰富而复杂的动画系统(有时称为“Mecanim”)。该系统具有以下功能:
- 为 Unity 的所有元素(包括对象、角色和属性)提供简单工作流程和动画设置。
- 支持导入的动画剪辑以及 Unity 内创建的动画
- 人形动画重定向 - 能够将动画从一个角色模型应用到另一角色模型。
- 对齐动画剪辑的简化工作流程。
- 方便预览动画剪辑以及它们之间的过渡和交互。因此,动画师与工程师之间的工作更加独立,使动画师能够在挂入游戏代码之前为动画构建原型并进行预览。
- 提供可视化编程工具来管理动画之间的复杂交互。
- 以不同逻辑对不同身体部位进行动画化。
- 分层和遮罩功能
(2)发布/订阅模式2
发布/订阅模式(Publish Subscribe Pattern)属于设计模式中的行为(Behavioral Patterns)。
在软件架构中,发布/订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者),而是通过消息通道广播出去,让订阅改消息主题的订阅者消费到。
发布/订阅者模式最大的特点就是实现了松耦合,也就是说你可以让发布者发布消息、订阅者接受消息,而不是寻找一种方式把两个分离的系统连接在一起。当然这种松耦合也是发布/订阅者模式最大的缺点,因为需要中间的代理,增加了系统的复杂度。而且发布者无法实时知道发布的消息是否被每个订阅者接收到了,增加了系统的不确定性。
3.题目要求
智能巡逻兵
提交要求:
游戏设计要求:
创建一个地图和若千巡逻兵(使用动画);
每个巡逻兵走一个3~5个边的凸多边型,位置数据是相对地址。即每次确定下一个目标位置,用自己当前位置为原点计算;
巡逻兵碰撞到障碍物,则会自动选下一个点为目标
巡逻兵在设定范围内感知到玩家,会自动追击玩家;
失去玩家目标后,继续巡逻;
计分: 玩家每次甩掉一个巡逻兵计一分,与巡逻兵碰撞游戏结束;
程序设计要求:
- 必须使用订阅与发布模式传消息
- subject: OnLostGoal
- Publisher: ?
- Subscriber: ?
- 工厂模式生产巡逻兵
友善提示1: 生成 3~5个边的凸多边型
- 随机生成矩形
- 在矩形每个边上随机找点,可得到 3 -4 的多边型
- 5?
友善提示2: 参考以前博客,给出自己新玩法
4.操作与代码详解
(一)Animator Controller制作
1)导入动画
本次人物动画主要用到以下几个动作:
分别为:待机,后跳,下落,跳跃,翻滚,奔跑,行走
2)绘制动画状态图
按照如下变化绘制状态图
3)设置动画混合树
动画混合树是动画状态机中的一个状态,也是多个动画的混合,可以实现多个类似动画的平滑过渡。
右键ground点击Create new BlendTree in State创建动画混合树
设置BlendTree,修改部分数值,并添加处于地面上的三个动画:待机、行走、奔跑
4)变迁
添加转移控制变量如下:
同时为各个变迁添加相应的控制条件变量,以地面状态到翻滚状态的变迁为例,如下:
5)FSM代码
动画状态机之中,对应的动作会引起状态机状态的改变,同时也会带来对应的变化。如果直接在状态之中挂载代码,会使得项目冗杂,难以调试。此时可以使用发布/订阅模式,从状态机的变迁之中获得相应信息进行广播,
编写了FSMClearSignals(),FSMOnEnter(),FSMOnExit(),FSMOnUpdate()
四个函数用于消息的广播与状态机的初始化
以下为FSMClearSignals()
的代码,进行初始化,如下:
public class FSMClearSignals : StateMachineBehaviour {
public string[] ClearAtEnter;
public string[] ClearAtExit;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
foreach (var signal in ClearAtEnter) {
animator.ResetTrigger(signal);
}
}
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
foreach (var signal in ClearAtExit) {
animator.ResetTrigger(signal);
}
}
}
以下为进入状态的代码FSMOnEnter()
,在进入状态时进行广播,FSMOnExit(),FSMOnUpdate()
与此代码基本一致,此处不再放出
public class FSMOnEnter : StateMachineBehaviour {
public string[] onEnterMessages;
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
foreach (var msg in onEnterMessages) {
animator.gameObject.SendMessageUpwards(msg);
}
}
}
将代码挂载在对应状态下,此处仅以ground举例:
6)备注
下载模型动画之后,为了适配本次作业,需要对一部分动作的设置进行修改,主要为Bake