Unity3D架构设计NavMesh寻路

国庆闲来没事把NavMesh巩固一下。以Unity3D引擎为例写一个底层c# NavMesh寻路。因为Unity3D中本身自带的NavMesh寻路不能很好的融入到游戏项目当中,所以重写一个NavMesh寻路是个必经之路。NavMesh在很多游戏中应用广泛,不同种类的框架下NavMesh寻路发挥的淋漓尽致。与传统的A星寻路相比,NavMesh不仅减少了内存空间占有量,加快了寻路速度,还可以加入寻路角色的宽高限制,以及动态物体寻路等功能,基本上适应了大部分项目变化多端的需求。

我把写NavMesh的过程分成好几个部分,一一进行描述:

一.首先要理解NavMesh核心算法。NavMesh的核心算法就是用三角形代替传统寻路的方格,用计算拐点优化寻路路径来代替合并路径直线。

如下图1NavMesh寻路:

以及如下图2传统的方格寻路:

看到两者的差别了吧,NavMesh已三角形为寻路块,而传统以方格为寻路块。其实两者都使用A*寻路,但就是其网格生成不一样,导致当有大范围寻路时,其效率和要求也不一样。

二.NavMesh寻路中的路径优化之拐点计算。其实NavMesh中比较常用的是光照射线法,但这里不做详细介绍,光照射浅法详细内容地址:http://www.cnblogs.com/neoragex2002/archive/2007/09/09/887556.html

拐点计算优化路径就是到达目的地需要经过的一堆三角形中计算出最简洁的移动方式。其核心算法就是从当前点到另一个三角形中的点之间的线段,与这条线段相交的线段全部是路径所穿越的线段,就是拐点,把所有的拐点找出来,并得到一条最长的拐点,那个拐点就是最佳的拐点位置。

三.NavMesh类设计详解(这里只设计2D的寻路,对于3D方向的寻路,其实是可以2D寻路代替的):

1.所有类都在同一的命名空间NavMesh内 namespace NavMesh

Triangle 三角形基础类

NavTriangle 寻路三角形类 (继承Triangle)

Line2D 线段类

Polygon 多边形类

Seeker 寻路主算法类

—————————————– 让大家久等了 ————————————

在寻路前,我们需要建立MESH三角形网格,这是NAV_MESH的重点之一。

1.首先我们先要画出一个范围来确定我们的可行走范围。

2.再在可行走范围中去添加不可行走的范围。

3.我们用多个多边形Polygon代替以上的范围,也就是说,一个大的可行走Polygon内包含了若干个小的不可行走的Polygon。

这是生成MESH前我们需要知道的生成范围,然后再由这些多边形的各个顶点来生成三角形网格,三角形网格的生成算法如下:

Step 1 :  用可行走Polygon的任意一条边作为起点,将其推入堆栈列表。到Step2.

Step 2:  从堆栈中推出一条边,在所有三角形中计算出边的DT点,构成约束Delaunay三角形,到Step3。如果没有DT点就重复做Step2,直到堆栈为空就结束整个程序。

Step 3:  将所构成的三角形,另两边做如下处理:检查堆栈中是否已存在,如果存在就删除该边,如果不存在就加入到堆栈中。

生成mesh后如图:(绿色的为多边形边框,蓝色的为寻路路径,红色的为编辑器选中的多边形)

核心源码为:

这里对如何计算DT点进行一个说明:

Step1. 构造三角形的外接圆,以及外接圆的包围盒
Step2. 依次访问网格包围盒内的每个网格单元:
若某个网格单元中存在可见点 p, 并且 ∠p1pp2 > ∠p1p3p2,则令 p3=p,转Step1;
否则,转Step3.
Step3. 若当前网格包围盒内所有网格单元都已被处理完,也即C(p1,p2,p3)内无可见点,则 p3 为的 p1p2 的 DT 点
核心源码为:

为了让各位能更容易读懂此文,此文仍会继续补充。现在我将所有源码都存放在了Github上,请各位跟随我到Github去取源码:https://github.com/luzexi/Unity3DNavMesh

转载请注明出处:http://www.luzexi.com

Unity3D架构设计NavMesh寻路的更多相关文章

  1. Unity3D架构设计NavMesh寻路(未完待续)

    国庆闲来没事把NavMesh巩固一下.以Unity3D引擎为例写一个底层c# NavMesh寻路.由于Unity3D中本身自带的NavMesh寻路不能非常好的融入到游戏项目其中,所以重写一个NavMe ...

  2. Unity3d 引擎原理详细介绍、Unity3D引擎架构设计

    体系结构 为了更好地理解游戏的软件架构和对象模型,它获得更好的外观仅有一名Unity3D的游戏引擎和编辑器是非常有用的,它的主要原则. Unity3D 引擎 Unity3D的是一个屡获殊荣的工具,用于 ...

  3. Unity3d 引擎原理详细介绍、Unity3D引擎架构设计 - zhibolife

    时间 2014-03-24 11:18:00  博客园-所有随笔区原文  http://www.cnblogs.com/zhibolife/p/3620440.html 体系结构 为了更好地理解游戏的 ...

  4. Unity3D手游开发日记(2) - 技能系统架构设计

    我想把技能做的比较牛逼,所以项目一开始我就在思考,是否需要一个灵活自由的技能系统架构设计,传统的技能设计,做法都是填excel表,技能需要什么,都填表里,很死板,比如有的技能只需要1个特效,有的要10 ...

  5. 解构C#游戏框架uFrame兼谈游戏架构设计

    1.概览 uFrame是提供给Unity3D开发者使用的一个框架插件,它本身模仿了MVVM这种架构模式(事实上并不包含Model部分,且多出了Controller部分).因为用于Unity3D,所以它 ...

  6. iOS应用架构谈(一):架构设计的方法论

    当我们讨论客户端应用架构的时候,我们在讨论什么? 其实市面上大部分应用不外乎就是颠过来倒过去地做以下这些事情: 简单来说就是调API,展示页面,然后跳转到别的地方再调API,再展示页面. 那这有什么好 ...

  7. iOS应用架构谈:架构设计的方法论

    缘由 之前安居客iOS app的第二版架构大部分内容是我做的,期间有总结了一些经验.在将近一年之后,前同事zzz在微信朋友圈上发了一个问题:假如问你一个iOS or Android app的架构,你会 ...

  8. 谈一款MOBA游戏《码神联盟》的服务端架构设计与实现

    一.前言 <码神联盟>是一款为技术人做的开源情怀游戏,每一种编程语言都是一位英雄.客户端和服务端均使用C#开发,客户端使用Unity3D引擎,数据库使用MySQL.这个MOBA类游戏是笔者 ...

  9. 谈一款MOBA类游戏《码神联盟》的服务端架构设计与实现(更新优化思路)

    注:本文仅用于在博客园学习分享,还在随着项目不断更新和完善中,多有不足,暂谢绝各平台或个人的转载和推广,感谢支持. 一.前言 <码神联盟>是一款为技术人做的开源情怀游戏,每一种编程语言都是 ...

随机推荐

  1. SPOJ COT3 - Combat on a tree

    /* 考虑直接使用暴力来算的话 SG[i]表示以i为根的子树的SG值, 然后考虑枚举删除那个子树节点, 然后求拆成的树的sg异或值, 求mex即可 复杂度三次方 然后考虑尝试 整体来做 发现对于每次子 ...

  2. isinstance, type, issubclass

    isinstance: 判断你给对象是否是xx类型的. (向上判断)type: 返回xxx对象的数据类型issubclass: 判断xxx类是否xxx的子类 class Animal: def eat ...

  3. django中路由系统和视图的对应关系(值的传递)-->主要内容(位置参数、关键字参数、额外参数、include分组[urls的分发]、命名分组、反向解析、APPEND_SLASH)

    路由系统也就是 urls.py文件,视图就是 views.py文件 路由系统里面要注意的事项 urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续. 若要从UR ...

  4. css hack 用法注意

    CSS hack 分类:CSS属性前缀法.选择器前缀法以及IE条件注释法 1.属性前缀法(即类内部Hack):例如 IE6能识别下划线""和星号" * ",IE ...

  5. 6.简单提取小红书app数据保存txt-2

    对页面信息进行简单抓取: 需要注意的问题 : auth-sign 和 auth 都是有一定的时效性,还有url原url是https这里要改为http请求. 这参数的问题需要通过mitmdump去获取请 ...

  6. 代码: html 页面小效果 (集合,待补充)

    标签切换(下部内容区跟着切换): 2016-6-2 <script type="text/javascript" src="http://cdn.bootcss.c ...

  7. 41.纯 CSS 绘制一支栩栩如生的铅笔

    原文地址: https://segmentfault.com/a/1190000015153865 感想: 不难 HTML code: <div class="pencil" ...

  8. 浏览器和对象的dom属性

    1 DOM对象:var obj=document.getElementById('*'); obj.scrollWidth 是对象的实际内容的宽,不包边线宽度,会随对象中内容的多少改变(内容多了可能会 ...

  9. 图片 base64转byte[]

    /// <summary> /// 保存base64图片,返回阿里云地址 /// </summary> /// <param name="imgCode&quo ...

  10. JS 事件 Event

    注册事件 target.addEventListener(type, listener, options); 或者 target.addEventListener(type, listener, us ...