【Godot4筆記】TileMap補(bǔ)充-實(shí)現(xiàn)2D地圖高度效果



????????實(shí)現(xiàn)2D地圖的高度效果,需要解決的關(guān)鍵問題就是地圖邊緣的碰撞,其次是地圖與角色的顯示層級關(guān)系。
????????為解決碰撞關(guān)系,可以利用角色的Collision屬性和TileMap的Physical Layers屬性,兩者對應(yīng)的Layer、Mask值相同時有碰撞關(guān)系,不同時沒有碰撞關(guān)系。而顯示層級則可以通過修改TileMap的Layers中某個地圖層級的Y Sort Origin值,如果去修改玩家的Y Sort Origin屬性的話,可能會影響與其他地圖層的顯示順序。
????????為TileMap添加至少兩個Physical Layers,并選擇不同的值,對應(yīng)這兩個值,角色的Collision屬性也要點(diǎn)亮相同的值。


????????首先解決從某些地形的上方或者下方穿越過去,比如兩個地圖之間的橋面、自然形成的石拱門(這兩種情況下,如果需要穿越的帶碰撞的景物不大的話,可以給這些地圖塊創(chuàng)建備選圖塊,然后不要碰撞,替換掉這些帶碰撞的地圖塊就可以)。
????????被穿越的地形使用的是layer_0的碰撞屬性,不可穿越的地形使用的是layer_1的碰撞屬性,那么當(dāng)角色某個區(qū)域后,將角色Collision的Layer、Mask的1給禁用即可,c.set_collision_layer_value(1, false),離開該區(qū)域后再啟用。


????????TileMap的Custom Data(自定義數(shù)據(jù))。在TileMap中新建Custom Data Layers,選擇好Type為bool。在TileSet中將橋面的該自定義屬性修改為True,如果橋面和下層碰撞靠的很近,以至于角色走不上橋面,可以新建一些地圖塊,將自定義屬性修改為True鋪在橋上(至少要全覆蓋被穿越的地形)。


以上參考:https://youtu.be/6YT0UafdrOc

????????當(dāng)然也可以使用Area2D來制作,見下文。
????????上面的方法適合的是單純從上面或者下面穿過地形,如果地形既要被穿過也可以讓角色在上層或者下層行動,就需要用其他方法了,因?yàn)镃ustom Data不管角色在上還是下都會觸發(fā),修改角色的碰撞屬性后,可能會影響角色所在層應(yīng)該正常存在的碰撞,而如果通過Custom Data檢測后修改地圖塊的碰撞屬性,是可行的,但會導(dǎo)致游戲卡頓,因?yàn)镃ustom Data是在process中不斷通過角色位置獲取信息的,每次都要遍歷所有地圖塊并確認(rèn)屬性。所以需要一個能夠一次修改地圖塊屬性的方法,那就是Area2D來檢測角色是否要進(jìn)行穿越地形。
????????如果地形存在多個出入口,記得每個出入口都要安排上Area2D。


總結(jié):
利用Custom Data來做地圖高低效果,需要不停檢索角色所在位置地圖塊的信息,匹配上信息后,通過修改角色的Collision Layer和Collision Mask的值來控制角色和地圖塊的碰撞關(guān)系。
利用Custom Data不適合修改地圖塊屬性,每幀遍歷會非常占資源,適合單純穿過上層或下層地圖的時候使用,因?yàn)镃ustom Data地圖塊要鋪在碰撞的周圍和上面,所以在穿過地圖時,會把正在穿過的那層地圖該有的碰撞關(guān)系都給取消掉。
Area2D來做地圖高低效果,獲得進(jìn)出Area2D的位置,來判斷下一步做何操作。通過修改地圖的某個Physical Layers的值來控制地圖塊與角色之間的碰撞關(guān)系,通過修改某個層級的地圖的y sort origin值來控制地圖塊與玩家的前后關(guān)系。
set_physics_layer_collision_layer()和set_layer_y_sort_origin()在修改地圖屬性的時候,要注意周圍使用了相同物理層、地圖層的同類型的地圖塊,在這些不需要修改的地圖塊上可以加一層透明的其他層級的帶碰撞的地圖塊。
地圖塊的碰撞不要畫的花里胡哨的,一是操作起來被各種歪七八扭的地形攔住很不舒服,二是不規(guī)則的碰撞配上這兩種做地圖高低效果的方法非常容易卡在某個奇葩的碰撞角落里。
如果是有進(jìn)出口的地形,在進(jìn)出口都要安排上Area2D。
注意角色通過Area2D的方向,左右、上下。進(jìn)入Area2D內(nèi)又從進(jìn)來的方向出去,就不需要變更碰撞關(guān)系和顯示層級。