虽然只为初版最小demo做了五个地点(蓝色和绿色框住的地方,现在在做更多的),但已经可以感受到巨大的痛苦。简单来说,需求就是连通从每一个地点到每一个地点的路。以前没有用过Unity的Spline,大概是一个很方便的可以构建任何曲线轨迹的官方插件,然后沿着这个曲线生成物体或者让物体沿着它移动都很简单,其他引擎也有很类似的东西。
所以我最开始用的就是最直接的方法,自己在每两个地点之间连线,重复的部分就尽量复制一下让它们保持重合(截图是现在的,没有那个时候的了,所以已经用的不是这个方法)。最开始我只有四个地点,所以连了六条Spline,然后复制Spline物体Reverse Spline Flow,总共12条。然后我还要把每条需要用到的路拖进inspector里我的代码定义的变量里,这样我才能在逻辑里使用。加入第五个地点的时候,又手动加了四条Spline加上复制和Reverse,以及拖拽这一堆东西进inspector,逐渐崩溃。
用中学数学算算,如果我已经有n个地点,那么我新加入一个地点的成本就是我手动连n条Spline,以及其他繁琐的东西,想想就会崩溃。如果是2D游戏的话,也许很自然地会用直线连接,然后弄一个类似网络的东西,然后就可以随便给出两点来寻找路径了,那么3D游戏也应该可以用类似的思路,以Spline为基础代替直线,写一点简单的东西构建一个network。这样的话,新加入一个地点的成本就算不是1也只会是一个很小的常数,特别是如果我预先计划留好了岔路口作为网络中的一个节点。
最后的方案其实还是比较潦草,不过对我目前来讲够用了,应该至少短时间内不用改了。我会接受一个list,里面是Spline container,container里每一个spline连接两个节点,节点可以是地点或者岔路,然后我用了Object Data的Key来存起点节点和终点节点(写在任何地方都可以,只是反正我也不用这些data存储什么,所以就用这些地方来写我需要的信息了)。
下图是我的路网管理script。
我只需要在我改了路径之后添加在这里,然后按Refresh,以及在游戏开始的时候也调用一下Refresh,就可以得到我想要的网络了。Refresh network具体就是循环每一个Spline,然后大概做下面的这些处理,计算一下位置,存储一下信息。我把每一个Spline单独存储是因为SplineAnimate只接受SplineContainer而不是Spline(一个container里能有挺多Spline的,我估计是跟我不同的使用场景),所以索性把每个Spline放在单独的Container里了。在这块代码的下方再Copy一个这个Spline,然后Reverse一下,同样存储起来。
编辑器里也简单加了一下Label,这样我可以很清楚看到我加过什么节点,一定程度上解决了我会忘记节点名字的问题...如果不小心有typo,应该也能看出来。
至此就变成了2D游戏里的节点,然后写一个简单的深度/广度优先搜索路径的代码,就可以搜索从任意节点到任意节点的路径了(不想写的话这种简单的东西就让AI写,我好像甚至都没怎么需要改,本来也很简单)。理论上我之后还可以写一个测试,确保地图上每一个地点之间都应该存在路径。
以上是我在这个问题上的挣扎历程。这个潦草的solution其实很快就做好了,refactor之后感叹不如一开始就多试试更聪明的方案,还好也不是太多地方在使用这个路径的东西,不然改起来会更痛苦。也许有比我这个只是能用的方法更好的方法~
----------------------------------------------------------
关于我业余开发了三个月的游戏:这是一款以马车运输货物为主题的模拟经营游戏,探索未知的区域,购买更多的马车,跨越危险为客户运送货物并赚取更多资金来扩大商业版图。
看着还是挺有吸引力的,开发的挠头过程写的也挺清楚的哈哈(看到一半我还在想估计后面就要搞编辑器工具了,也确实搞搞更省心哈哈,挺真实的)
总之,爱看,多写,赞
@Zephyr Guardian:感谢哈哈哈,会更新遇到的问题的!确实搞完心里舒服多了,就算还有些手动的操作,也能接受了