文章目录
-
-
- 一、前言
- 二、Animator状态机组织
- 三、过渡条件
- 四、用代码设置过渡条件,触发动画播放
- 五、CharacterAniLogic.cs完整代码
-
一、前言
文章列表
Unity游戏开发——新发教你做游戏(一):打开游戏开发新世界的大门
Unity游戏开发——新发教你做游戏(二):60个Unity免费资源获取网站
Unity游戏开发——新发教你做游戏(三):3种资源加载方式
Unity游戏开发——新发教你做游戏(四):角色移动控制
Unity游戏开发——新发教你做游戏(五):导航系统Navigation
Unity游戏开发——新发教你做游戏(六):教你2个步骤实现摇杆功能
Unity游戏开发——新发教你做游戏(七):Animator控制角色动画播放
本工程
Demo
我已上传到GitHub
,感兴趣的同学可以下载下来学习。GitHub
工程地址:https://github.com/linxinfa/Unity-RpgGameDemo文章图片
嗨,大家好,我是新发,上一篇文章我们讲了摇杆功能的实现。今天,来讲讲
Animator
控制角色动画播放的实现。二、Animator状态机组织
现在,假设我们已经有了各个动画文件,比如站立、跑、攻击、受击等,用
Animator
把各个状态组织起来。思路:默认状态是
stand
,然后stand
和run
可以相互过渡,然后从任意状态,都可以播放attack
、hit
、hit2
、death
,其中除了death
,其他都要自动过渡回stand
,这样,我们组织的状态机连线图如下:文章图片
三、过渡条件
这些过渡连线需要设置一些过渡条件,条件判断需要变量,所以,先创建两个变量:
Speed
,Action
,类型都是Int
。文章图片
设置状态过渡的条件
文章图片
规则:移动相关的,用
Speed
来控制,行为相关的,用Action
来控制。所有过渡条件如下:state1 | state2 | conditions |
---|---|---|
stand | run | Speed == 1 |
run | stand | Speed == 2 |
Any State | attack | Action == 1000 |
Any State | hit | Action == 2000 |
Any State | hit2 | Action == 2001 |
Any State | death | Action == 3000 |
【Unity3D|(完结)Unity游戏开发——新发教你做游戏(七)(Animator控制角色动画播放)】接下来就是用代码控制动画了:接口主要是用到
Animator
的SetInteger
和GetInteger
两个接口。为了方便控制,可以封装一个类,我这里封装好了一个
CharacterAniLogic.cs
(在文章最下面)封装出几个对外接口:
///
/// 播放跑步状态
///
public void PlayRun();
///
/// 播放站立状态
///
public void PlayIdle();
///
/// 播放不同动作ID
///
///
///
public void PlayAnimation(int actionID)
我们再定义一个枚举
public enum CharacterAniId
{
Run = 1,
Idle = 2,Attack = 1000,Hit = 2000,
Hit2 = 2001,Death = 3000,
}
这样,我们通过定义的枚举,就可以播放对应的动画了,比如播放
attack
m_animator.SetInteger("Action", (int)CharacterAniId.Attack);
还要,可能我们需要判断当前是在某个动画状态,可以通过
AnimatorStateInfo
来判断//判断当前动画状态是否为run
public bool IsPlayingRunAni()
{
AnimatorStateInfo stateinfo = m_animator.GetCurrentAnimatorStateInfo(0);
return stateinfo.IsName("run");
}
五、CharacterAniLogic.cs完整代码
// CharacterAniLogic.csusing UnityEngine;
using System.Collections.Generic;
// 角色动画逻辑
public class CharacterAniCtrler
{
private const string STR_ACTION = "Action";
private const string STR_SPEED = "Speed";
private const string STR_DEATH = "death";
private Animator m_animator;
///
/// 准备播放的动作
///
private Queue m_animQueue = new Queue();
private AnimatorClipInfo[] mClips = null;
///
/// 是否播放跑步动作
///
public bool IsPlayRunAction = false;
public void Init(Animator ani)
{
m_animator = ani;
}public void LateUpdate()
{
if (m_animator == null)
{
return;
}
if (!m_animator.isInitialized || m_animator.IsInTransition(0))
{
return;
}
if (null == mClips)
mClips = m_animator.GetCurrentAnimatorClipInfo(0);
if (null == mClips || mClips.Length == 0)
return;
int actionID = m_animator.GetInteger(STR_ACTION);
if (actionID > 0)
{
//将Action复位
m_animator.SetInteger(STR_ACTION, 0);
}
//将剩余队列的动作重新拿出来播放
PlayRemainAction();
if (IsPlayRunAction)
{
IsPlayRunAction = false;
PlayRun();
}
}///
/// 将剩余队列的动作重新拿出来播放
///
void PlayRemainAction()
{
if (m_animQueue.Count > 0)
{
PlayAnimation(m_animQueue.Dequeue());
}
}public void PlayDieImmediately()
{
PlayAniImmediately(STR_DEATH);
}public void PlayAniImmediately(string name)
{
m_animator.Play(name, 0, 0.95f);
}///
/// 播放不同动作ID
///
///
///
public void PlayAnimation(int actionID)
{
if (m_animator == null)
return;
if (m_animator != null && (!m_animator.isInitialized || m_animator.IsInTransition(0) && actionID != 20))
{
m_animQueue.Enqueue(actionID);
return;
}
m_animator.SetInteger(STR_ACTION, actionID);
}///
/// 播放站立状态
///
public void PlayIdle()
{
if (null == m_animator || !m_animator.isInitialized)
return;
m_animator.SetInteger(STR_SPEED, (int)CharacterAniId.Idle);
}public bool IsPlayingRunAni()
{
AnimatorStateInfo stateinfo = m_animator.GetCurrentAnimatorStateInfo(0);
return stateinfo.IsName("run");
}///
/// 播放跑步状态
///
public void PlayRun()
{
if (null == m_animator || !m_animator.isInitialized)
return;
m_animator.SetInteger(STR_SPEED, (int)CharacterAniId.Run);
}public void ClearAnimQueue()
{
if (m_animQueue.Count > 0)
{
m_animQueue.Clear();
}
}
}public enum CharacterAniId
{
#region 使用Speed参数
Run = 1,
Idle = 2,
#endregion#region 使用Action参数
Attack = 1000,Hit = 2000,
Hit2 = 2001,Death = 3000,
#endregion
}
推荐阅读
- Unity3D|【游戏开发实战】Unity UGUI实现循环复用列表,显示巨量列表信息,含Demo工程源码
- CSS|CSS实现水滴动效
- Unity常见的优化性能设置
- 游戏|元宇宙密室逃脱游戏攻略来啦!
- 每天记录学习的新知识 : ObjectAnimator 基础和用法
- Unity3d|Unity中的层级以及渲染顺序
- Unity|unity 一些控制物体移动 小技巧
- Unity|Unity 学习 SpaceShooter 第二次记录
- Unity|Unity 游戏开始UI设计