一個MMORPG的常規技能系統

轉載自:http://www.gameres.com/729192.htmlhtml

廣義的的說,和戰鬥結算相關的內容都算技能系統,包括技能信息管理、技能調用接口、技能目標查找、技能表現、技能結算、技能創生體(buff/法術場/彈道)管理,此外還涉及的模塊包括:AI模塊(技能調用者)、動做模塊、尋路/移動模塊以及人物屬性和傷害數值結算等。

先說下技能模塊每一個部分的職責和原理:

數組

  • 技能信息管理:管理unit所擁有的技能以及技能的等級、cd等。在咱們遊戲中,這裏還須要負責管理符文,符文會對技能信息進行修改。
  • 技能調用接口:AI或者UI操做觸發技能,觸發技能時可能選擇了一個目標(AI),也可能並無目標。
  • 技能流程管理:一個技能可能由多個子技能以移動的執行模式組合而成,而每個最終執行的技能執行過程也存在一個流程,通常包括:前搖過程-結算點-後搖過程。技能在前搖結束時進入技能真正的結算流程,結算流程可能建立子彈,也可能觸發buf或者建立法術場。
  • 技能目標查找:若技能觸發時已經設置了技能目標unit(如怪物AI釋放技能),則直接將其做爲目標unit,不然須要根據必定的策略選擇一個目標。此外,技能釋放的時候還須要釋放方向和釋放位置等信息,也經過這個模塊獲取。
  • 技能表現:技能釋放過程當中,須要建立相應的特效以及執行相應的動做。
  • 技能創生體(buf/彈道/法術場)管理:buf掛在unit身上,可能影響unit的一些行爲和狀態;法術場通常由場景管理,影響場景中某範圍內的unit;彈道就是技能建立的一個子彈,這個子彈可能以不一樣的路線移動(直線/拋物線/直接命中等)


一、技能表

首先說下實現技能的基本思路。實現技能的基本思路就是經過策劃填寫表格,來配製成某些技能,在執行某個技能的時候,分別去根據這些表格中的內容,肯定技能如何表現。基本的邏輯是:數據結構

  1. if skillTable.get("技能動做"):
  2.      paly 動做
  3. if skillTable.get("特效"):
  4.      播放特效
  5. if skillTable.get("法術場"):
  6.     建立法術場
  7. ....
複製代碼


二、技能信息管理

unit建立時,此模塊管理unit可以使用哪些技能,好比遊戲中玩家能夠選擇使用哪些技能。

遊戲中技能的升級、技能加點、技能池管理都在這個模塊。

此模塊還須要管理技能等級/符文/裝備等外部模塊對技能參數的修改。

三、技能調用接口

提供技能調用的接口供AI或玩家操做調用,調用時能夠提供一個目標unit,也能夠不提供讓技能本身查找。

提供三個接口:

優化

  • 技能開始skill_enter:開始執行技能,若技能不循環進行,則技能能夠自動結束。
  • 技能結束skill_exit:有的技能不能本身結束,好比某些循環技能,對於循環技能玩家能夠按住按鈕一直釋放。當玩家鬆開按鈕,調用技能結束接口,告訴當前技能使其結束,此時技能到達後搖點時,技能再也不繼續執行。
  • 技能中止skill_stop:當技能被強制打斷時,如被攻擊、暈眩、藍不足等,技能會被強制中止。


此外,當前一個技能正在執行時新的技能調用啓動,此時新的技能調用信息會被保存。通常來講,並不會把全部新的技能調用信息保存下來,那樣就成了一個技能執行的序列。咱們遊戲僅保存一個新的技能調用信息。

總的來講,技能模塊提供儘可能少的接口供AI/UI等上層邏輯使用,這樣能夠有效的與AI和UI進行解耦。

四、技能流程管理

技能流程這裏分兩點討論:

(1)一個技能可能由多個子技能以必定的模式組合起來。

一個技能經常由多個子技能以必定的模式組合而成,好比三段擊、好比衝鋒斬(先衝鋒、後斬)等,甚至還存在根據不一樣的環境選擇執行不一樣的子技能。分析策劃需求發現,技能能夠分紅一個樹形結構,這個樹形結構很是相似行爲樹,一樣能夠將節點分爲控制節點和執行節點,甚至能夠包括condition節點。爲此,咱們項目引入一個技能樹概念來描述這種數據結構。

(2)一個具體的技能(技能樹執行節點)也有一個固定的執行流程。這個流程通常爲:前搖過程、前搖過程結束=技能結算時間點、後搖時間點。

4.1 技能樹

技能樹參考傳統行爲樹的設計,使用樹形結構控制技能的執行流程。

技能樹和行爲樹在結構上比較相似,可是在運行邏輯上有很大的不一樣。

首先,技能樹的重點並非根據上下文選擇一個合適的節點執行,而是以必定的策略將技能樹從頭至尾遍歷執行一遍。

其次,技能樹沒有tick的概念,而是基於回調的,好比一個順序節點,順序節點中一個子節點執行完畢後,立刻通知順序節點,順序節點執行下一個子節點,直至順序節點的最後一個子節點執行完畢,順序節點就會通知父節點(若是有)它已經執行完畢。

此外,爲了完成技能的一些需求,控制節點每每存儲更多的控制信息來控制子節點的執行流程。具體的信息根據策劃需求設置,好比順序結點包括原子屬性和循環屬性。若是一個順序節點具備原子屬性,則這個順樹節點在執行的過程當中並不會被end,只有所有子節點執行結束才能夠end。

以咱們遊戲中戰士普攻三段擊爲例:

spa


三段擊自己是一個順序節點,當技能開始時,此節點順序執行三個子節點。對於第一個子節點,它依然是一個順序節點,首先衝鋒至目標單位身前,而後對目標單位進行揮砍。可是衝鋒節點還包括了一個condition,若和目標的距離很近,則跳過沖鋒節點,直接揮砍。

普攻是一個循環技能,這個技能只要玩家點着按鈕不放開,技能就會一直執行,所以根節點(普攻)是一個具備循環屬性的順序節點。而對於子技能1(控制節點),他是一個具備原子屬性的順序技能,即當單位正在衝鋒時,玩家鬆開按鈕,單位也會執行完揮砍後纔會推出技能。

!關於技能樹的使用和思考

技能樹開始的設計思路是,有些技能的執行流程和行爲樹相似,好比以必定的順序執行一系列子技能,好比根據不一樣的上下文肯定技能的執行流程。簡單的說,技能樹的引入有如下好處:1.使技能模塊能夠得到部分AI的能力,從而將和技能強相關的AI邏輯放在技能模塊使技能模塊和AI模塊下降耦合,2.能夠清晰的描述技能流程,3.使用樹增長拓展性,策劃能夠設計出各類各樣複雜的技能。

關於好處1,舉個例子:屠夫boss的勾子技能能夠將玩家拉過來,若成功的拉過來,boss會執行一個攻擊子技能,不然不執行。經過這樣能夠將勾人和攻擊做爲兩個子技能構成技能樹,攻擊子技能有一個condition過程,即判斷上一個子技能是否成功。

技能樹在使用後慢慢發現一些問題,首先,技能樹的同步要求每一個樹節點都進行同步,增長同步負擔,其次,技能自己並不會有太複雜的控制結構。

爲此,後來咱們對技能樹進行了優化:

設計

  • 簡化同步信息,再也不同步全部節點的enter/exit信息(具體參考文章《技能模塊的同步》)。

 

  • 取消並行節點,經過拓展表頭實現一個技能同時執行多件事情。


最終的技能樹基本上是隻有順序/隨機兩種控制類型節點,節點擁有較輕度的condition功能。

4.2 執行節點的技能流程

通常來講,技能的執行流程包括:

前搖時間:技能開始,可是技能真正的結算流程還沒開始。技能開始之後,機能相關的特效和動做就開始播放。

前搖時間結束:技能前搖結束時技能開始真正的釋放以及結算,等技能前搖結束之後,技能真正的釋放並結算。釋放包括建立相應的彈道/法術場和buff。

技能後搖點:技能播放到後搖點時間時,技能真正的結束。這時,技能對應的特效以及人物動做可能還會繼續播放,可是技能流程已經正式結束了。也就是說,下一個技能能夠執行。

五、技能目標查找

技能釋放時,目標可能已經由AI傳給了技能模塊,也有可能沒有一個目標,如玩家控制單位。

技能在釋放法術場、彈道的時候,重要的是技能的方向而不是技能目標通常來講,技能得到一個目標對象之後,技能的方向就是釋法者到目標的方向。

此外,技能方向可能須要一些配置,如前搖鎖定(前搖過程當中目標移動,技能方向不變),UI可控制(技能釋放過程當中,玩家能夠經過控制UI控制技能的釋放方向)。

六、技能表現

技能的表現包括動做、特效、shader、音效等。其中,特效比較複雜,須要配置的內容也比較多。好比,有些特效掛在模型上,有的特效掛在場景裏。對於法術場的特效,分別能夠分爲法術場開始、結算、結束特效,分別在法術場開始時、結算時、結束時顯示。對於buff也相似。

七、彈道、法術場和buff等技能創生體

狹義的來講,技能只是負責技能的執行流程(技能樹管理以及技能流程管理),而技能真正的結算主要是由其創生體結算的。當技能前搖結束開始生效時,技能建立相應的彈道和法術場,法術場彈道擊中敵人時又有可能產生相應的buff。

通常來講,法術場是一個場景的某塊檢測區域,每隔一段時間法術場檢測此區域的敵人,並對其攻擊結算。

彈道是一類子彈移動路徑的抽象,建立一個彈道就表示一個子彈特效沿這個彈道移動並檢測路徑上的敵人。

buff就是掛在單位身上的一個具備持續時間的狀態,狀態對單位產生一些正面或者負面的影響,而且在此段時間內,每隔一段時間進行一次傷害結算 。

對於技能、法術場、buff之間的功能界定並非很固定,好比技能可否直接對單位形成傷害,法術場可否對單位形成傷害,甚至技能只能建立法術場,法術場只能檢測目標不能形成傷害,只能掛buff,而全部的傷害都是經過buff來結算。固然,這樣並不必定好,通常來講,技能和法術場均可以對單位形成傷害。

總之,創生體功能的界定須要根據策劃需求、效率考慮等因素調整。

7.1 Buff狀態

Buff就是掛在單位身上持續必定時間的有益或者有害的狀態,這裏狀態=buff。

Buff模塊有個須要注意的是Buff之間的相互關係,如排斥(A狀態在,B狀態掛不上去),清除(A狀態掛上去同時致使B狀態消失)等。

爲了實現以上功能,最簡單的方式是在狀態A中直接填寫狀態關係狀態字段,如狀態A排斥狀態B/C/D/E...,A狀態清除狀態X/Y/Z...。

以上的實現方式有個問題,等遊戲作到後期,咱們有成千上萬個buff狀態,那麼一個魔法免疫狀態,策劃須要填表的排斥狀態可能成千上萬。

爲了解決這個問題,可使用分類的思想解決。定義某類狀態和另外一類狀態之間的規則。

基於以上思想,引入一個叫buff原子狀態的概念,原子狀態表示一類狀態,如減速、禁魔、魔免、懸空、暈眩、變羊等等等。

在給單位掛一個新的buff的以前,查詢此buff持有的原子狀態和單位身上已經有的原子狀態之間的關係,根據單位身上已有的原子狀態斷定新的原子狀態應該使用何種行爲處理。

此處的何種行爲,表明的就是原子狀態之間的規則,如排斥等。這些規則可讓策劃填一個名字叫「原子狀態關係」的表,此表是一個n*n的二維數組,n爲遊戲中全部的原子狀態的數量。

原子狀態的數量遠遠小於buff的數量,因此能夠很容易的定義這些規則。

7.2 法術場

法術場描述對一塊區域的影響,這塊區域能夠每隔一段時間進行一次檢測,檢測這塊區域內的單位而且對單位進行結算。

法術場須要注意一個問題,就是一個法術場每次結算可能使用不一樣的參數進行結算,好比一個技能,第一次結算對每一個單位進行暈眩,第二次結算對單位進行傷害。

解決這種問題比較直接的方式是技能直接建立兩個法術場,每一個法術場結算一次,第二個法術場建立具備延遲時間。可是這種方式有個問題,有可能策劃需求作一個結算十次並且每次結算的參數都不一樣的法術場。那麼,一個技能以必定的時間間隔建立是個法術場,同時法術場的管理具備必定的成本,從而致使效率的下降。

爲解決這個問題,咱們優化了法術場結算的實現機制,增長了一種新的法術場:序列法術場。這類法術場策劃能夠配置法術場每次結算之間的時間間隔以及每次結算所使用的法術場參數。code

相關文章
相關標籤/搜索