Dungeon Mizarka 002

测试场景设定

传统的FP Dungeon Crawler(FPDC)撇开玩家的视角,玩家的移动实际上是以格状的方式进行,一次一格的方式进行移动。利用Unity本身3D的优势,可以直接以3D方式进行地城场景设置。

先利用方块进行模拟地城环境的墙和玩家角色。日後虽然会利用自动生成的方式进行,但仍是有几关会是固定的埸景,且前期开发时,固定地形较容易进行测试。

利用3D的场景设置是很方便的,但仍需要有和Roguelike游戏相仿的格状场景来进行移动。从这个移动的机制来看,FPDC和Roguelike是很像的,不同点在於FPDC以第一人称方式进行场景移动探索,但Roguelike则是上视角的方式进行。

Vampire Chaos Knight

基於格状移动是基本的一个环节,要用个方式将目前的3D景进行转换成2D格状地图进行使用。

最简单的方式,就是利用Raycast从上方投射下来,如果没有碰到任何场景物件(又或是只碰到地板)则表示该处可通行,若是碰到了障碍物(墙壁等)则记录该处不可走。待完成整个Raycast扫瞄後,将其记录下来的格状地图用以後续的寻路、移动。

和寻路机制进行结合

说到寻路(Pathfinding),自然地就会想到在Unity里有现成的Pathfinding机制,然在Unity的环境中,只提供了NavMesh的Graph,对於这个格状移动并没有太大的帮助。还好在Unity Asset Store(UAS)里有个非常知名的寻路外挂可以协助这块。

UAS中的版本还停在4.2.15版,但实际上A★的开发者已於2019年就开始着手4.3.x版本撰写,主要的修改是搭配Unity ECS使其Search效能更佳。但Unity ECS本身一直都还没有到穏定的阶段,所以A★的开发者在UAS里并没有释出4.3.x版,若是有从UAS里购买4.2.x版的使用者,可自行於其官网下载4.3.x版。

利用A★里的Grid Graph再进行一些设定

进行场景Scan时则可以发现,A★就是利用之前提及的Raycast做转换,将现有的场景转换成内部的格将资料。

地城的地版很寛敞时,没有出界的侦测

将场地的地板缩小後,没有额外定义阻挡物时,会全部都被判定成可以移动的区域

加入了阻碍物後,再次扫瞄才会有想要的结果

实际利用A★

可以从A★的扫瞄结果了解到在A★自身的资料里已经有整个场景的格状资料,接下来就是抽取出来进行使用。

程序码部份最主要的片段

astarPath.Scan();

// Get the nodes in the first graph
astarPath.graphs[0].GetNodes(gn => {
    if (gn is GridNode gridNode)
    {
        // Use casted grid node instead of original graph node
    }
});

先进行Scan的动作,让整个Graph建立起来。再进行每个Grid Node的查询,看玩家目前的位置是对应到哪个Gird Node。

四方向自由移动

在接合A★之前,先进行移动的行为制作。虽然是以手机平台为主,但开发期间能够利用键盘进行移动也是方便於除错的,还没有进入UI之前,仍以Keyboard Input进行基本移动的操控。

利用Input System进行Action设定。为了呈现FPDC的移动机制,四方向移动加上左、右旋转是必要的基本控制。

接收到Movement Input後,利用Visual Scripting(VS)处理移动行为。这里的移动是没有考量到障碍物的情况下,可以自由的做四方向移动。

加上了处理旋转後的行为

在移动时用Translate进行,一但旋转後其前後左右的定义也不用做修正就是正确的。

自由移动的部份完成後,接下来就是要和现有的Grid Graph做接合,进行移动时的检查,并决定是否可以完成移动。

加入A★资料判定

这套A★在做格状时,如果是四方向,则依顺序为下右上左,也就是说0代表负Z的方向,1代表正X的方向,2代表正Z,而3代表负X。

不过自己的习惯是前右後左,为了避开运算向量的麻烦,则利用表格存下玩家面向按下的四方向输入会对应到A★哪个方向。其实已经是用了vs,游戏类型又是回合式移动,效能并不是最优先考量,用表格的方记录也只是避免复杂的运算。

修正过後的VS

如预期般的方向的转换和移动都是正确的,但这里有几个问题要记录下来

  • 一开始的玩家方向预设需为0,也就是正Z的方向需为初始值
  • 在程序码中直接利用了Code进行位置改变和所在GridNode的转换

对於直接在Code进行位置改变这件事,如果是平常纯以Code方式处理并无不妥,不过用了VS,就表示可以更有弹性的在VS里进行。

若是直接引用A★的Node资料可以用这个API进行

var gridNodeBase = _atGridNode.GetNeighbourAlongDirection(moveDirection);

先记录下来,之後再找时间调整。


<<:  Leetcode 挑战 Day 11 [242. Valid Anagram]

>>:  【Day14】变数的地盘—作用域(scoop)与提升(Hoisting)

Day3-React Hook 篇-认识 useEffect

今天要介绍的是常用的 hook,useEffect。 功用 处理各种的 side effect,针对...

【day15】DashboardFragment X Firestore搜寻

今天要来带大家看一下搜寻资料,Firestore最简单的方式就是直接透过get()来拿到资料,但是...

大共享时代系列_020_共同工作空间(Coworking Space)

透过开放式的工作空间,让我们发现有更多的可能性~~~ 在哪上班? 当你问朋友:嘿,你现在在哪上班? ...

#24 JS: HTML DOM Events - Part 2

For the topic today, I can't fully understand the ...

Oracle Row to Column 函式介绍

Oracle row to column在10G版本仅能使用 CASE or DECODE,11G版...