您的位置:首页 > 移动开发 > Unity3D

【Unity3D】自动寻路的跳跃

2017-06-19 10:42 337 查看
《【Unity3D】自动寻路》(点击打开链接)万般好,但锁死Y轴这点导致非常蛋疼的一个问题,我需要在自动寻路的过程允许游戏主角进行跳跃。毕竟玩家都说了,在3D游戏里面不让主角跳跃是一个很严重的问题,就像《阿玛拉王国》本来做得非常好,但就是不能跳,导致大打折扣。那么如果在Unity3D自动寻路的过程中进行跳跃呢?下面举一个例子说明这个问题:



如图所示,假设图中的小球就是我们的主角,我按左键可以让它自动寻路,按右键可以让它跳,同时到了边界还不会出现一堵无形的墙,小球能自然滑落的。

具体制作过程如下所示:

1、一如《【Unity3D】自动寻路》(点击打开链接)拖Plane,整些Cube作障碍体,Sphere做主角,同时设置一个光源,并给这些东西加上材质。然后保存场景,将Plane和Cube设置为Navigation Static,小球加上Nav Mesh Agent和Rigidbody,完成自动寻路的烘培。



2、给小球赋予GameScript.cs如下所示,则完成:

using UnityEngine;
using System.Collections;

public class GameScript : MonoBehaviour
{
private NavMeshAgent navMeshAgent;
private bool is_jumping, out_of_bound;//用于设置小球是否跳跃和已经到达自动寻路边缘的flag

void Start()
{
navMeshAgent = gameObject.GetComponent<NavMeshAgent>();//初始化navMeshAgent
is_jumping = false;
out_of_bound = false;
}

void Update()
{
if (Input.GetMouseButtonDown(0) && !is_jumping && !out_of_bound)
{//如果不是在跳跃、不是到达自动寻路边缘,按下鼠标左键
//自动寻路
Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit mHit;
if (Physics.Raycast(mRay, out mHit))
{
if (mHit.collider.gameObject.name == "Plane")//如果点的是Plane上的一点
{
this.rigidbody.velocity = new Vector3(0, 0, 0);//这里是考虑到跳跃落地之后,用户马上要自动寻路的情况
navMeshAgent.SetDestination(mHit.point);
}
}
}

if (Input.GetMouseButtonDown(1) && !is_jumping && !out_of_bound)//按下鼠标右键的话
{
Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit mHit;
if (Physics.Raycast(mRay, out mHit))
{
if (mHit.collider.gameObject.name == "Plane")
{
navMeshAgent.enabled = false;//取消自动寻路
is_jumping = true;//让小球进行跳跃
this.rigidbody.velocity = new Vector3(0, 0, 0);
this.rigidbody.velocity = mHit.point + new Vector3(0, 5, 0);//基于一个点击位置方向加上y=5的向量速度
}
}

}
if ((this.transform.position.x > 4.6 && this.rigidbody.velocity.x > 0.01) ||
(this.transform.position.x < -4.6 && this.rigidbody.velocity.x < -0.01) ||
(this.transform.position.z > 4.6 && this.rigidbody.velocity.z > 0.01) ||
(this.transform.position.z < -4.6 && this.rigidbody.velocity.z < -0.01))
{//如果已经到了Plane的边缘
out_of_bound = true;
navMeshAgent.enabled = false;//关闭自动寻路
}

if (this.transform.position.y < -3)//如果小球已经掉得太下方
{
Application.LoadLevel("Navmesh_jump");//重新开始
}
}

//小球如果和Plane开始碰撞
void OnCollisionEnter(Collision collision)
{
if (collision.collider.gameObject.name == "Plane" && is_jumping)
{
is_jumping = false;
navMeshAgent.enabled = true;//重新打开自动寻路
}
}

}
这里的难点就是因为自动寻路Nav Mesh Agent锁死了Y轴,导致和刚体Rigidbody想在3D世界中自由进行物理运动产生冲突,那么我们在小球需要跳跃的时候就不要这个自动寻路好了,同时自动寻路Nav Mesh Agent一旦小球到达了Plane的边界也会不知道为何会自动产生一股无形的墙,非要小球不能滑落,这里也和刚体Rigidbody产生冲突的,我们也是需要解除自动寻路Nav Mesh Agent,让小球得以滑落。
综上所述,其实来来去去是如果协调好自动寻路Nav Mesh Agent在何时开关的问题。这里在设置两个flag之后,在用户点击右键则让小球进行跳跃状态,执行《【Unity3D】用鼠标点击事件、AddForce完成跳跃与二段跳》(点击打开链接)对跳跃的处理,然后用到《【Unity3D】利用物体碰撞检测、键盘输入处理完成平衡球游戏》(点击打开链接)对碰撞检查的内容,设置进行跳跃状态的小球一旦与Plane碰撞,则重新回到自动寻路的状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: