看很多游戏都有类似 角色站在一个圆形台阶上,原型台阶在地图上从 A 点移动到 B 点,然后角色站在台阶上跟着台阶一起动,而且可以在途中跳跃到其他台阶上,然后闯地图
这个功能核心是移动代码要放在 LateUpdate 里把被装载的对象位置算一个相同位移。
其实如果站在台阶上不需要控制的话,那么直接把台阶设置为角色的父级就可以了
如果站在台阶上还需要调用角色控制器控制角色移动跑跳,那么设置父级会对坐标控制以及摄像机控制有很大影响,当然也是可以算的,只是比较麻烦
这里简单的方法是在台阶的移动时 在 LateUpdate 里算出自身在上一帧经过的位移,如果台阶上有角色,那么角色也要调用角色控制器的 Move 这么多位移
这个简单方法只能实现简单的坐台阶跟台阶一起移动,并且在台阶上还可以控制角色,但是如果台阶在飞行阶段遇见其他障碍物把角色挡住,那么还要进行下一步处理。
这里说下具体实现步骤
要做这个功能前,首先要实现 角色通过角色控制器移动,台阶直接 K 帧从地图的 A 地方移动到 B 地方
台阶模型就是一个 cube,在其上有 2 个 BOXCOLLIDER,一个选 TRIGGER 一个不选,选 Trigger 的放上面一点,然后尽量在台阶的中心小一点,免得一碰到台阶台阶就开始动,那么人物还没整个走到台阶上,不要和另外个 collider 重叠
角色附加一个普通的 charactercontroller 就可以了,触发器用来触发台阶开始播放动画的,下面的 boxcollider 是为了不让角色掉下去的。
放截图吧,截图不动刷新试试
角色碰到台阶时,触发台阶的开始移动,同时记录当前台阶位置,记录碰撞到台阶上的角色
代码,TestFly 为测试脚本, 上面带了一个 Animator 形的 K 帧动画,设置了一个变量 flyCube 开启这个 K 帧动画(从 A 点到 B 点找 2 个点,然后 K 位置)
MeteorUnit 是角色控制器附加的那个对象上带的,也就是管理角色的,可以自行替换
using UnityEngine;
using System.Collections;
public class TestFly : MonoBehaviour {
public Animator ctrl;
Vector3 lastpos;
bool inWalk = false;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
private void LateUpdate()
{
if (inWalk)
{
Vector3 vdiff = transform.position - lastpos;
if (objAttach != null)
objAttach.GetComponent<CharacterController>().Move(vdiff);
lastpos = transform.position;
}
}
GameObject objAttach;
public void OnTriggerEnter(Collider other)
{
if (other.gameObject.GetComponent<MeteorUnit>() != null && !inWalk)
{
//other.gameObject.transform.SetParent(transform);
ctrl.SetBool("flyCube", true);
lastpos = transform.position;
inWalk = true;
}
//不论是不是在动画中,只要碰到了触发器,就算坐上了台阶
if (other.gameObject.GetComponent<MeteorUnit>() != null)
objAttach = other.gameObject;
}
public void OnTriggerExit(Collider other)
{
objAttach = null;
}
public void OnFlyEnd()
{
ctrl.Stop();
inWalk = false;
}
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于