今天实现的内容:
加入降落动画
降落发生在跳跃之后,所以网络游戏角色降落动画要紧接着跳跃动画播放,动画机如下。
这两条Transition都has exit time,并且jump到fall的优先级高于jump到ground,因为目前为止这两个转换都没有条件。
在图示位置调整优先级。
落地检测的实现及相关动画运用
要实现落地检测,需要使用Physics.Overlap里的东西,使用Physics.Overlap可以找到某个形状范围内有重合的所有碰撞体。比如我们要用到的Physics.OverlapCapsule就是在一个给定的胶囊体内得到所有与胶囊体有重合的特定layer的碰撞体,Overlap只能得到有哪些碰撞体重合,而不知道其它信息(先后,远近等等)。
我们新建落地检测器脚本OnGroundSensor,挂载到PlayerController游戏对象的子物体sensor下,sensor对象将专门由于各种检测器的挂载。
OnGroundSensor代码如下。通过SendMessage来告诉PlayerController当前是否正在地面。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 落地检测器
public class OnGroundSensor : MonoBehaviour
{
// 用于引用PlayerController游戏对象上的CapsuleCollider
public CapsuleCollider capCol;
// 用于绘制胶囊检测器的两个点
private Vector3 point1;
private Vector3 point2;
// 用于绘制胶囊检测器的半径
private float radius;
void Awake()
{
radius = capCol.radius;
}
void FixedUpdate()
{
// 更新检测器的位置
point1 = transform.position + transform.up * radius;
point2 = transform.position + transform.up * (capCol.height - radius);
// 检测地面碰撞
Collider[] outputCols =
Physics.OverlapCapsule(point1, point2, radius, LayerMask.GetMask("Ground"));
// 判断是否撞到地面 并向父物体发送对应消息
if(outputCols.Length != 0)
{
// 在地面
SendMessageUpwards("IsGround");
}
else
{
// 不在地面
SendMessageUpwards("IsNotGround");
}
}
}
接下来要做的就是,在PlayerController中实现消息接收。
// 在地面时执行的方法 通过OnGroundSensor中的SendMessage调用
public void IsGround()
{
m_anim.SetBool("isGround", true);
}
// 不在地面时执行的方法 通过OnGroundSensor中的SendMessage调用
public void IsNotGround()
{
m_anim.SetBool("isGround", false);
}
在动画机中添加新参数isGround,用于PlayerController进行控制。
好的,现在调回先前的jump转换优先级,将jump到ground和fall到ground的转换条件设置为isGround为true。
到目前为止,落地检测的实现及相关动画运用基本完成。
落地检测器优化
建议改小检测器的半径以及稍微将检测器向下移动一点。来得到更好的检测结果。
// 检测器偏移量
public float offset = 0.1f;
void Awake()
{
m_radius = capCol.radius * 0.6f;
}
void FixedUpdate()
{
// 更新检测器的位置
m_point1 = transform.position + transform.up * (m_radius - offset);
m_point2 = transform.position + transform.up * (capCol.height - m_radius - offset);
// ...
}
失足掉落
由于我们的掉落动画只有在跳跃的前提下才能触发,所以特此加入失足掉落的设置。这样一来,只要离开地面就会播放,而不是离开地面依旧和在地面没有两样(在没有跳起来离开地面的情况下)。是的,我们在没有起跳的情况下离开地面和在地面没有区别,依然可以正常操作。
首先是动画机的设置,直接拉一条transition从ground到fall就行,条件为isGround为false。
接下来,在掉落时要和跳跃一样锁死操作。现在就当一次笨蛋,在进入fall状态时发送消息给PlayerController(更好的方法是在离开ground时发送消息,这样还可以省掉进入跳跃时发送消息这个操作)。
// 进入掉落时执行的方法 通过PlayerController动画机中的fall节点上挂载的FSMOnEnter中的SendMessage调用
public void OnFallEnter()
{
// 关闭输入并且锁定平面移动
DisableInput_LockPlanar();
}
// 关闭输入并且锁定平面移动
private void DisableInput_LockPlanar()
{
// 关闭输入模块
pi.inputEnabled = false;
// 锁死平台移动计算
m_lockPlanar = true;
}
动画的优化及改进
除了jump到fall,其它所有的transition都不要勾选has exit time,这样能带来更流畅的动画效果。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。