截圖中的 AdjustedWidth 跟 AdjustedHeight 即是 ×4 過後的寬與高,如果你對拋物線還熟悉的話,應該會知道像是 y^2 = 4cx 這種形式的式子。
為了求輸入的寬高能夠直接性地反映 Unity 的座標系統,我們想要輸入 Width = 2; Height = 2; 的時候,拋物線能夠呈現寬高各佔 2 世界座標單位的樣子。
拋物線的基礎功能大致上就這些。
然而,這些是建立在拋物線的寬高還有起始點皆為已知資訊的情況下。實際要進行地形狀況的判讀時,將會有可能缺乏部分資訊,甚至是需要加入額外的拋物線控制條件的場合。
也因此,接下來要探討的兩個功能,方向將會集中在於反向推算出所我們需要的目標拋物線上。
◆【經過指定座標的拋物線】
試問:
如果已經知道拋物線的起始座標點 StartPoint,寬高係數及頂點位置皆是未知,那繪製一個拋物線,經過指定點 TargetPoint,則將會有多少種可能?
理論上這將會是無限種 ∞
現在把這個概念應用到 AI 角色跳躍到指定位置上,角色跳起點為 StartPoint,指定位置即為 TargetPoint。
然而,角色的垂直跳躍高度和水平移動速度將會是有限制的,這表示在跳躍軌跡上並不是無限可能。遊戲中,角色的水平移動速度是維持定值,也就是說,角色跳得越高,在水平方向的移動距離也就越遠。
這麼一來,就能透過自由落體 h = 1/2gt^2 來推導跳躍高度與移動距離的關係了。
※ 目前專案中的物理演算有經過調整,所以有使用額外的非線性轉換表。
回到上面的問題,既然知道了要尋找的拋物線,其寬高會隨一定的比例縮放,這樣可能性就限縮到了相當小的範圍了。(這個範圍將視誤差的容許值而定)
於設計走向上,我們將與拋物線對稱方向垂直的軸向稱為「基準軸」(水平對稱的拋物線即為垂直高度軸),反之與其平行的稱為「乘算軸」。
方法內,我們將給定基準軸的允許最大值,預設為遊戲中角色的最高跳躍力值,設為 20。這個數值已經可以從畫面底部跳到高過整個遊戲畫面了。
然後,根據調整基準軸的值來進行迭代,生成大小不等的拋物線,來逐步進行比對。這邊就用上了我們前面製作的功能,判定目標點是否於拋物線的開口內側:
而這個基準軸值的迭代處理,想必不是從最小值逐步遍歷到最大值。
我們可以模擬類似於二分搜尋的演算法,每次迭代都把處理範圍進行折半,讓調整基準值的過程中,使拋物線逐步逼近我們所設的目標點。迭代的次數會受到容許值的大小,以及處理範圍偏差允許值來決定。
就現在的設置來說,比較極端的場合最多也只需要 20 次上下的迭代而已,且該結果都會進行額外的暫存。
如果有必要的場合,像是針對地形會有頻繁移動的狀況,僅讓特定的敵人 AI 常駐即時運算在效能上應該也是可以接受的。
當能夠獲取兩點間的拋物線後,就能得知 AI 角色跳到指定地點所需的跳躍力,還有移動速度了。
最後則是對該拋物線上進行碰撞體的判定,確認不會受到其他地形的阻礙,再進而實行跳躍這個行為:
然而,這個生成拋物線的方法,比較適合的作用目標是跳上單向平台地形時使用,因為該地形可以由下往上穿越。
但如果目標的地形是實心地形,這代表根據拋物線往上跳的時候,會受到目標地形的阻擋,故我們需要另一種拋物線生成方法來應對。
◆【“拐杖型”拋物線】
這是一種存在抽象概念上的拋物線,建立於角色貼牆跳躍時,垂直速度不會被其影響作為前提。
拐杖型拋物線一詞,指的是當基準軸判定值未達到高度點處時(該高度點亦為目標點的對稱點),將它的乘算軸值無視。當到達對稱點時,與目標點的中心乘算軸處將構成拋物線頂點,並繼續延伸為一拋物線。
由於此方法主要用於 AI 角色貼牆並跳上牆上特定目標點,貼牆時乘算軸的座標會維持不變,整體的移動軌跡會像是拐杖般,故稱為拐杖型拋物線。
Δ 角色的移動軌跡呈拐杖般的樣貌
由於角色在高度點處時,其加速度並非為零,故我們直接生成拐杖上半弧狀處的拋物線的話,可能會增加計算上的困難。
但我們已經確定了高度點還有目標點,也知道了拋物線會經過它們,這麼一來就可以推算出頂點的 X 座標處,根據這個頂點,反推出我們需要的拋物線。
而「拐杖」的底部 Y 軸,這相當於角色起跳的位置,也就是拋物線起始座標 StartPoint 的 Y 座標,這也是後面拋物線的限制條件之一。
也就是說,我們的目標即為尋找這個除了寬高大小不被確定,連起始座標 StartPoint 的 X 軸也是未知數的拋物線。
所幸的是,有了前面生成經過指定座標拋物線的概念,配合上頂點的 X 座標已經確定的條件,還是能夠透過迭代基準軸的值來尋找目標拋物線:
由於高度點跟目標點呈對稱關係,故只要判定其中一個點是否被拋物線所經過,即表示該拋物線即為我們所要尋找的。
找到拋物線後,同樣對移動路徑進行碰撞體的判定,這與上一個方法後面所提及的功能是一樣的。
Δ 拋物線在高度到達地形上方之前,水平軸位置會被目標地形所限制,模擬貼牆跳躍的路徑。
AI 角色在不同平台之間移動最複雜的部分應該就屬這些了,總算知道為什麼有幾款玩過的橫向平台類的遊戲,敵人在追擊玩家時不是突然瞬間移動,就是無視地形直接穿過來。
看起來不外乎就是運算上的效能考量,或是嫌麻煩乾脆就用其他替代方案來應對。
自己是認為如果敵人會在平台之間跳躍,也替玩家提供了一定的優勢,能夠預測敵人跳躍的時機對它來個出其不意的攻擊。
所以一些比較強的菁英怪或是 Boss,應該還是會讓它們採用瞬間移動的方式,至少這個實裝起來會比去計算拋物線還要簡單上個好幾倍。

先說一下,這是個人的體驗,可以當作參考聽聽就好。
如果你也打算開發有橫向平台要素的遊戲,或是還在開發初期的階段,條件允許且有需要的情況下,我會建議把這類跟物理演算或是尋路系統有關的用插件來先行補足。
自己是因為平台地形相關的功能已經寫了大半,再買新的插件除了需要額外的學習成本,還有可能會和已有的機制產生不兼容的狀況,所以才作罷。

使用插件的重點當然是能夠節省大量的時間成本,不用在前人已經走過的路上再折騰一遍。
當然,除非是想在這塊的功能上從中學習汲取經驗,去享受那個過程。又或是有高度的自訂需求的話,那就是另當別論囉。
以上是我試驗拋物線機制這段期間的心得,挺希望能有辦法給數年前的自己看看的。
接下來的進度就是補上 AI 角色跳下平台的判定行為,以及讓敵人能夠掌控場景內連續地形的位置關係,從而嘗試尋找最佳路徑,在地形之間穿梭。
預計應該是不會再碰上比拋物線還難搞的東西了啦🚩
先預祝大家新年快樂

這個 2024 自己是一刻也待不下去了,我現在只想看母雞卡。