准备工作
打开准备好的场景。
将上一章节的EasyTouch摇杆和按钮添加到此场景中。
导入一个角色模型:
将模型放到空节点下:
将上一章的脚本挂到空节点player下,并添加Character Controller组件:
看看效果:
Unity操作
在角色目录下创建AnimatorController文件夹,在文件夹下创建名为PlayerAnimatorController的Animator Controller:
给角色模型添加Animator组件:
将角色模型的Avatar和创建好的PlayerAnimatorController拖拽到Animator组件中:
Avatar如果没有可以自己创建一个:选中模型中的Rig选项卡,将Avatar Definition指定为Create From This Model,点击Apply。当然,最好还是用跟模型相匹配的Avatar,不然动作很可能会变形。
打开PlayerAnimatorController,右键点击空白处创建一个名为Idle的空白状态(Create State --> Empty),再将此状态设置为默认状态(Set as Layer Default State),通常情况下创建的第一个状态会自动被指定为默认状态,黄色状态即为默认状态。
再创建Die和Run两个状态,按照下图,右键点击各个状态将动线连接到相应的状态(Make Transition)。
切换到Parameters选项卡,添加三个bool变量(idle、run、die)。
左键选中Idle状态,将停止状态对应的动画拖拽到Motion字段中。按照此方式分别给Die、Run也指定动画。
选中单个动画文件,点击编辑按钮(Edit)。
勾选Loop Time,使该动画可以重复播放,然后点击Apply保存修改。Idle和Run都需要做此操作,而Die则不需要,除非你的角色需要不停的Die。
左键选择一条动线(Transition),取消勾选Has Exit Time以保证动画可以立即切换。然后在下方Conditions添加一个条件,从Idle到Run的条件是run为true;从Run到Idle的条件是run为false;从Any State到Die的条件是die为true。
注意,动画之间切换是有一个过渡时间的,拖拽此处可以调整过渡时间。
代码调整
将上一章CharacterMotor的代码改为:
using UnityEngine;
namespace ARPGFinish.Character
{
/// <summary>
/// 角色马达
/// 用于处理角色移动
/// </summary>
public class CharacterMotor : MonoBehaviour
{
/// <summary>
/// 动画系统
/// </summary>
private CharacterAnimation chAnim;
/// <summary>
/// 角色控制器
/// </summary>
private CharacterController chController;
/// <summary>
/// 移动速度
/// </summary>
public float moveSpeed = 5;
/// <summary>
/// 转向速度
/// </summary>
public float rotationSpeed = 0.5f;
/// <summary>
/// 重力
/// </summary>
private float gravity = 2;
/// <summary>
/// 跳跃速度
/// </summary>
public float jumpSpeed = 3;
/// <summary>
/// 跳跃时间
/// </summary>
public float jumpTime = 0.5f;
/// <summary>
/// 累计跳跃时间用来判断是否结束跳跃
/// </summary>
public float jumpTimeFlag = 0;
/// <summary>
/// 是否移动
/// </summary>
private bool isMoving = false;
/// <summary>
/// 是否跳跃
/// </summary>
private bool isJump = false;
private void Start()
{
chAnim = GetComponent<CharacterAnimation>();
chController = GetComponent<CharacterController>();
}
/// <summary>
/// 移动方法
/// </summary>
public void Move(float x, float z)
{
if (x != 0 || z != 0)
{
isMoving = true;
// 1转向 前往的方向
LookAtTarget(new Vector3(x, 0, z));
}
}
/// <summary>
/// 转向
/// 通过Lerp实现转向
/// </summary>
private void LookAtTarget(Vector3 target)
{
if (target != Vector3.zero)
{
Quaternion dir = Quaternion.LookRotation(target);
transform.rotation = Quaternion.Lerp(transform.rotation, dir, rotationSpeed);
}
}
/// <summary>
/// 停止移动方法
/// </summary>
public void MoveFinish()
{
isMoving = false;
}
/// <summary>
/// 角色跳跃
/// </summary>
public void Jump()
{
isJump = true;
}
private void Update()
{
//float distance = Vector3.Distance(dir.GetTargetPosition(),this.transform.position);
if (isMoving)
{
chController.Move(transform.forward * moveSpeed * Time.deltaTime);
// 3播放运动动画
chAnim.PlayAnimation("run");
}
else
{
chAnim.PlayAnimation("idle");
}
// 如果在跳跃状态,并且当前时间没有到达跳跃时间,则持续向上移动如果到达跳跃时间,那么持续下降直到遇到地面
if (isJump)
{
if (jumpTimeFlag < jumpTime)
{
chController.Move(transform.up * jumpSpeed * Time.deltaTime);
jumpTimeFlag += Time.deltaTime;
}
else if (jumpTime < jumpTimeFlag)
{
chController.Move(transform.up * -gravity * Time.deltaTime);
}
if (chController.collisionFlags == CollisionFlags.Below)
{
jumpTimeFlag = 0;
isJump = false;
}
}
}
}
}
在Character文件夹添加一个新脚本CharacterAnimation,代码如下:
using UnityEngine;
namespace ARPGFinish.Character
{
/// <summary>
/// 角色动画系统
/// </summary>
public class CharacterAnimation : MonoBehaviour
{
/// <summary>
/// 动画组件
/// </summary>
private Animator anim;
/// <summary>
/// 上一个播放的动画
/// </summary>
string preAnimName = "idle";
private void Start()
{
anim = GetComponentInChildren<Animator>();
}
/// <summary>
/// 播放动画
/// 结束上一个动画,播放当前动画
/// </summary>
/// <param name="animName">需要播放的动画名称</param>
public void PlayAnimation(string animName)
{
Debug.Log("========" + animName);
// 结束上一个动画
anim.SetBool(preAnimName, false);
// 开始新的动画
anim.SetBool(animName, true);
// 将当前动画设为上一个动画
preAnimName = animName;
}
}
}
将新脚本拖拽到Player中。
运行结果
关于场景和建模
由于本章节主要讲解Unity动画开发部分,所以建模以及动画的相关工作并为在此章节提及。如果有需要可以考虑在Asset Store中下载,或者在一些模型动画商城购买。
更多内容请查看总目录【Unity】Unity学习笔记目录整理