【Unity3D】自动寻路的跳跃

《【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碰撞,则重新回到自动寻路的状态。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值