在之前呢我写了一篇文章,讲述了游戏中玩家使用轻功功能,角色在起跳的一瞬间,视觉会突然模糊一下,也就是使用Shader完成径向模糊效果。不了解的同学可以参考:https://www.insideria.cn/article/30568 这篇文章。

然后这一次我来给大家说一下如何使用Unity完成轻功效果。

打开网易新闻 查看更多图片

在最开始的时候,我有一个简单的想法,就是能否将玩家比喻成一颗手雷,给他一个抛物线的力量,如果需要二段跳,可以判断玩家是否与地面接触,其实这个方法确实可行。

说白了就是给物体一个力,这个力不用大,稍微给一些就可以,然后角色本身是有重力的,力度减弱,物体自然就下降了,从而实现了抛物线功能。

可以理解为就是在角色脚下装了一个弹簧。

打开网易新闻 查看更多图片

当然还有直接改变物体的位置也可以。

1.起跳设置 首先人物身上挂CharacterController脚本

代码如下:

//获取到CharacterController实例
CharacterController controller = GetComponent<CharacterController>();

2.核心起跳语句:

float gravity=10F;
float temp =10;
bool checkdis=false;//是否开始轻功计算
void setjump()
{
//点击起跳按钮后的初速度 只执行一次的
moveDirection.y = jumpUpSpeed1;
checkdis = true;
}
void FixedUpdate()
{
......
if(checkdis)
{
moveDirection.y = temp;//每次必须把上次计算的方向y值结果赋值给方向y值
//每一帧计算的,高度减值
moveDirection.y -= gravity * Time.deltaTime;
temp = moveDirection.y;
controller.Move(moveDirection * Time.deltaTime);//注意是一个方向
}
}

接下来我来讲一下如何在空中实现二段跳。

首先如果玩家站在地面上,点击轻功按钮,可以触发轻功第一段功能,然后再次点击轻功按钮,即可触发第二段效果。为了防止点击轻功就触发第二段效果,我们可以用发射一条射线的方式来检测,玩家是否处于地面上。通过Physics.Raycast射线方式,判断角色脚下是否为walk层。代码如下:

//向下发射线
bool IsGrounded(float margin, string layerName = "Walk")
{
//本角色当前位置提高0.9f,然后向下发出1.2f的射线
Vector3 SourcePosition = transform.position;
Vector3 rayStartPoint = SourcePosition + new Vector3(0f, 0.9f, 0f);
RaycastHit hit;
LayerMask mask = 1 << LayerMask.NameToLayer(layerName);//射线打到walk层
if (Physics.Raycast(rayStartPoint, Vector3.down, out hit, margin, mask))
{
//Helper.LogError("距离:::::::::::"+hit.distance);
//Helper.DrawLine(rayStartPoint, hit.point, Color.red);
//如果射线打到walk层就返回true
return true;
}
else
{
return false;
}
}

既然有了二段跳,那么三段,四段都可以的,为了使游戏更精彩,可以令每个跳跃阶段都可以有不同的动画,获取不同的动画名就可以知道应该执行第几段跳跃功能。代码如下:

bool result = false;
//获取当前动作的状态
AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
if (animatorStateInfo.IsName("jumpdown") || CurState == AnimatorState.JumpDown)
{
如果已经是降落状态,返回false
return result;
}
if (animatorStateInfo.normalizedTime >= 0.9f)
{
//动作播放超过了0.9秒,并且是属于四段跳中的一段,则返回true
if (animatorStateInfo.IsName("jump1") || animatorStateInfo.IsName("jump2") || animatorStateInfo.IsName("jump3") || animatorStateInfo.IsName("jump4"))
{
result = true;
}
}

功能实现了,下面我们来说一下问题!

轻功其实很简单,实现的方法有很多,但是在功能实现之后难免会有问题。

比如有些同学可能会说。在使用轻功的过程中,如果碰到障碍物,需要降落,但是降落到的是一个无法行走的区域。这时候是需要制作地图空间的时候就考虑好,障碍物周围都是可行走区域,还是有其他的容错的办法?

在这里呢,我给大家提一个思路,大家想的可能太复杂了。

首先 是飞行问题 我们想要让角色飞起来或者轻功腾空的本质是什么?是该游戏角色的垂直坐标的变化。那就好解决了 对症下药呗。直接操作角色的垂直坐标就行了。

如果按照游戏原本动作节奏上升至空中,将角色的垂直上升高度变化量h=n*k 就行了 其中h为角色的垂直上升高度变化量 n= 角色水平方向变化量的绝对值 k为前进与升高的长度比 比如 角色起步向前奔跑的动作中 第二帧n=5 想要让角色向前奔跑10个单位上升5个单位 那么k=1/2 角色高度 = 角色初始高度累加下一帧的变化量h

这只是举个简单例子

在某高度滞空、飞行就不需要什么计算了直接固定垂直坐标就行了

然后制作一些飞行动作 设置动作切换就行了

至于控制飞行 这些基本就是一些向量运算 或者更简单的计算 无非就是运算一下镜头方向 或者方向按键 手指滑动 这些

然后楼主所说的可行走区域问题 最容易理解的做法就是创建一些物体挡住不允许进入的区域然后设置成不可见就行了 需要的情况下可以添加碰撞事件 保险起见还可以判断角色是否存在于不可进入区域内部是的话将玩家挤出也可以避免一些bug

类似剑灵爬墙的话 参考梯子的实现

总之就是一句话 看情况操作玩家坐标

最后给大家发几个非常漂亮的轻功!

打开网易新闻 查看更多图片

打开网易新闻 查看更多图片