使用Unity3D 自主实战开发的赛车游戏实例,关键点记录 (六)之自动寻路及优化

一.综述

赛车游戏的敌人赛车自动寻路一般有两种方式,一种是路点寻路,另外一种就是使用Unity自带组件NavMeshAgent进行寻路了,我介绍的是后者,另外后者在水平面上的汽车寻路导航还不错,但是一旦有Y方向的爬坡、下坡等,汽车就会因为角度依然保持水平显得很不自然,并且轮胎也不会旋转,我对此进行了优化

二.NavMeshAgent

这个和NavMesh是一对,用来设置寻路的游戏对象。关于属性,我不再一一介绍,我就距我的设置来说一下:

1.AgentSize

如下图中,那个圆柱形就是NavMeshAgent了,其中AgentSize调整到更好适合车辆就可以了;

2.Stopping Distance

我将Stopping Distance设置为0,是因为,我每次都会将寻路目标设置为下一个道路监测点,如果Stopping Distance设置为大于0的话,就会看到车辆会不停地减速加速减速加速,不够连贯;

3.Speed

这个我最后查出来的它的尺寸是M/S,所以我设置的它的速度是47km/h,当然我的游戏赛道比较难跑,设置这个值比较合适。

4.Auto Traverse Off Mesh Link

这个指的是是否自动通过OffMeshLink,我这里没有什么特殊需求,不需要有些OffMeshLink需要设置才能通过,自然是自动通过最好了。

5.Obstacle Avoidance Quality

然后属性Obstacle Avoidance Quality是值的躲避障碍物的质量,对于我的游戏来说,障碍物只有一种,那就是封路用的,如下图中的导流牌,这个导流牌就添加了组件Nav Mesh Obstacle,它的作用就是动态的用作障碍物,如果隐藏掉这个组件或者直接隐藏掉组件所在的对象,障碍物效果就没有了,图中的道路就又通了

三.NavMesh

NavMesh就是NavMeshAgent就来赖以前行的寻路网格,将自己需要作为寻路路径的那部分游戏对象设置为NavMesh Static,然后再Navigation中进行Bake烘焙即可。

如下图

我将所有的道路到设置为了NavMesh Static,然后烘焙后蓝色区域就覆盖了整个道路。

需要注意的是道路有可能有不平整的地方,需要自己将道路检查一遍,如果哪些地方有断裂,需要铺平道路后重新烘焙

上图中也需要设置Agent信息,作用就是用来根据代理进行烘焙,因为代理Radius Height的不同都会导致烘焙结果的不同。

比如你将Agent Radius设置得较大,路面上的蓝色区域就会越窄,因为NavMesh会考虑给路两边留够距离。

然后Max Slope的设置就得考虑车辆最高爬坡角度了。

接下来就是对断裂地带实在没办法连接的地方进行处理了

四.Off Mesh Link

这个是专门对断裂地带进行连接的,如下图

由于坡度过大,无法贯通,于是使用Off Mesh Link。

1.首先在自动汽车对象上添加组件Off Mesh Link。

2.然后分别点击左边需要连接的木板和右边需要连接的木板,点击Navigation,选择Object选项卡,会出现Generate OffMeshLinks选项打钩,重新Bake,如下图

3.分别将左右木板对象拖曳到自动汽车的OffMeshLink组件的Start和End属性上,这样在两个木板间就会出现一个弧形的桥,连接两端。这样道路就导通了,车辆会飞跃过去。

5.NavMeshAgent.SetDestination

直接设置自动寻路汽车的寻路目标是终点显然是不合适的。想要寻路汽车可以规规矩矩按照既定的路线前行,需要不断地更新目标点,到前方一个较近的位置。

我就使用的是当汽车碰到第一个道路监测点后,设置目标为下一个道路监测点,这样汽车就会不断地往前行进了。

:我在开发时遇到一个问题,就是汽车到某个点后停止不动了。最后发现原因是,由于汽车身上的NavMeshAgent比较大,导致先接触到下一个道路监测点,这个时候,道路监测点还没有碰撞到汽车,导致没能再去设置下一个寻路目标,解决办法就是把车身上的Agent设置的较小一些,车的碰撞体靠前一些,这样每次都是先检测到碰撞,而还没有到达寻路目的地。

6.修正汽车上下坡时车辆未倾斜的问题

我发现使用NavMeshAgent给汽车做寻路导航,缺点就是汽车只会在水平面上转弯,上坡下坡的时候还是水平的,不会沿着坡道做倾斜,我想原因是因为这个Agent也可以给人用的缘故吧,因为人上下坡时身体不会沿着坡道做倾斜。

刚开始我试图直接修改汽车游戏对象的Rotation,发现一直受Agent的干扰。最后想到的解决办法就是:

由于汽车车体/轮胎其实都是汽车对象的子对象,我直接修改子对象的角度就好了。并不会受到Agent的干扰。

我的做法是每次设置自动寻路汽车的下一个寻路目标时,顺便设置汽车角度,如下:

//设置敌人自动寻路汽车的下一个寻路目标点
    private void SetEnemyCarDestionation(int index)
    {
    //假如当前游戏模式是竞赛模式
        if (ConfigurationManager.Instance.CurrentGameModel == ConfigurationManager.GameModel.RacingModel) {
        //获取下一个道路监测点
            Vector3 vec = GetTheEnemyPlayerNextCollider(index).transform.position;
       //设置敌人的下一个寻路目标           _enemyPlayerMeshAgent[index].SetDestination(vec);
        //获取敌人的车体(是敌人游戏对象的子对象)的当前Transform
            Transform currentEnemyTrans = _enemyPlayers[index].transform;
        //计算车体面向下一个监测点,需要的四元数
            Quaternion rotation = Quaternion.LookRotation(vec - currentEnemyTrans.position);
        //设置角度,使车辆面向下一个监测点
    _enemyPlayersManager[index].TurnCarDirection(rotation);

        }
    }

7.修改自动寻路汽车,车轮不转动的问题

由于自动寻路汽车,并不是 物理意义上的汽车,WheelCollider并没有用。我看一个教程上使用的WayPoint方法,是可以实现物理意义上的寻路的。

所以我想给自动寻路汽车加上一个比较看起来真实的转动轮胎。

也就是说,随着汽车速度的加快,轮胎转动变快,速度变慢,轮胎转动变慢。

所以需要从速度转换出当前每秒转多少度:

设当前汽车速度为N m/s,

轮胎半径为R m

则汽车转速为 N / (2 * R * π)

汽车轮胎每秒转N / (2*R*π) * 360°

代码如下:

    void FixedUpdate()
    {
        _angularSpeed = (_thisCarNavMesh.velocity.magnitude / _wheelCircle) * 360 * 0.2f;
        for (int i = 0; i < Wheels.Length; i++) {
            Wheels[i].Rotate(Vector3.right, _angularSpeed * Time.fixedDeltaTime);
        }
    }

其中参数0.2f,是我根据效果写的修正参数,不然轮胎转的角度太大,导致效果不好。

上面这个办法我目前实验的效果还不错,但是不知道其他人怎么认为,肯定还有很多别的好办法。

时间: 2024-12-24 15:40:14

使用Unity3D 自主实战开发的赛车游戏实例,关键点记录 (六)之自动寻路及优化的相关文章

极客学院前端实战开发 网页小游戏/网页布局/导航/标签页/语音识别

===============课程目录===============<实战开发教程>├<1 围住神经猫-HTML5实战游戏开发教程>│  ├1. 围住神经猫-游戏玩法.mp4│  ├2.围住神经猫-使用createjs.mp4│  ├3. 围住神经猫-绘制页面元素.mp4│  ├4.围住神经猫-添加监听事件.mp4│  ├5.围住神经猫-简单的逻辑实现游戏效果.mp4│  ├6. 围住神经猫-完整游戏效果实现.mp4│  └<source>├<10 回到顶部功能实

使用Html5+C#+微信 开发移动端游戏详细教程:(六)游戏界面布局与性能优化

本篇教程我们主要讲解在游戏界面上的布局一般遵循哪些原则和一些性能优化的通用方法. 接着教程(五),我们通过Loading类一次性加载了全部图像素材,现在要把我们所用到的素材变成图片对象显示在界面上,由上而下,首先是top层,top里面包涵了玩家(微信)头像,关卡信息,怪物血条信息,玩家金币,玩家宝石,玩家总攻击力. 定义函数 setTop 来初始化top层: function setTop() { TopDiv = new LSprite();//定义top层 var Topshape = ne

Cocos2d-x3.0游戏实例之《别救我》第一篇——前言

我们能学到什么? 这是一个很简单的游戏,但是用到的东西比较多(对新手而言),起码,对于一个实例来说,它涉及的确实有点多. 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址:http://www.benmutou.com/blog/archives/797 文章来源:笨木头与游戏开发 通过这个游戏实例,可爱的你(小若:那不可爱的人呢?),可以学到以下知识点: 1. Cocos2d-x3.0物理引擎的简单使用 2. 读取Json文件作为怪物和物品配置 3. 利用Tiled地图实现可视化

Unity3D游戏引擎实战开发视频教程

Unity3D游戏引擎实战开发从入门到精通(坦克大战项目实战.NGUI开发.GameObject) 适合人群:初级 课时数量:20课时 用到技术:Unity3D.VS2008.NGUI2.61.GameObject 涉及项目:坦克大战项目实战 咨询qq:1840215592 课程内容简介 Unity3D游戏引擎实战开发从入门到精通课程由浅入深的介绍Unity3D的开发流程.从软件使用到API接口的使用,从成品到优化.介绍整个Unity3D的基本开发过程及开发中碰到的基础问题进行深入讲解.对代码重

使用Unity3D的设计思想实现一个简单的C#赛车游戏场景

最近看了看一个C#游戏开发的公开课,在该公开课中使用面向对象思想与Unity3D游戏开发思想结合的方式,对一个简单的赛车游戏场景进行了实现.原本在C#中很方便地就可以完成的一个小场景,使用Unity3D的设计思想(即一切游戏对象皆空对象,拖拽组件才使其具有了活力)来实现却需要花费大量时间与精力,究竟它神奇在什么地方?本文通过实现这个小例子来看看. 一.空对象与组件 在Unity3D最常见的就是GameObject,而一个GameObject被实例化后确啥特性与行为都没有,只有当我们往其中拖拽了一

unity3d 赛车游戏——复位点检测

一直没有时间写博客 昨天我的CarWaypoints插件也告一段落了 今年没回家,过年就我一个人 挺无聊的,那就休息一天写几篇博客吧 我的代码可能很少,但是思路很重要 希望不懂的朋友别只copy代码 赛车游戏的话赛车难免会冲出跑道.掉入水坑.卡在障碍物上....等情况 那么问题来了,遇到这些情况怎么办呢? 玩家玩得好好的,难道就因为遇到这些情况要退出游戏重新进入吗? 那当然是不现实的,要是我的话果断卸载游戏 还要骂一句做游戏的人是脑残啊 我想你不希望玩家骂你是脑残吧,哈哈哈 新技能,赶快GET起

【课程下载】基于Cocos2d-x游戏引擎实战开发炸弹超人

我这里有套课程想和大家分享,需要的朋友可以加我qq和我联系.QQ2059055336. 课程讲师:Jason.Z 课程分类:ios适合人群:初级课时数量:31课时更新程度:完毕 一.本课程是怎么样的一门课程(全面介绍) 1.1.课程的背景 Cocos2d-x 是一个支持多平台的 2D 手机游戏引擎,使用 C++ 开发,基于OpenGL ES,基于Cocos2d-iphone,支持 WOPhone, iOS 4.1, Android 2.1 及更高版本, WindowsXP & Windows7,

unity3d 赛车游戏——复位点检测优化、反向检测、圈数检测、赛道长度计算

接着上一篇文章说 因为代码简短且思路简单 所以我就把这几个功能汇总为一篇文章 因为我之前就是做游戏外挂的 经过验证核实,**飞车的复位点检测.圈数检测就是以下的方法实现的 至于反向检测和赛道长度计算,没去深入研究,不过应该也八九不离十 在告诉大家个小秘密: **飞车的复位点检测和圈数检测利用以下文章中的代码思路可以做出外挂 感兴趣的可以试试!我只是技术交流,不是传播外挂,别打我 复位点检测优化: 首先感谢 @太粗难进 他的原话: “不过 你知道 高架桥么?就是 如果大的轮船经过 会 把 桥 中间

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签