1. 程式人生 > >《爐石傳說》架構設計賞析(5):卡牌 & 技能的靜態資料組織

《爐石傳說》架構設計賞析(5):卡牌 & 技能的靜態資料組織

經過前面幾次的嘗試,我們對爐石的程式碼已經不陌生了。除了網路機制還沒有了解以外,本機的邏輯已經比較熟悉了。

接下來繼續向暴雪最NB的技能系統進發,我們的目標是:

  • 分析技能的靜態資料描述;
  • 分析技能的執行時資料、邏輯組織;
這篇筆記主要記錄對其分析靜態資料。

靜態資料組織

卡牌資料

  • 卡牌的基本資料對於的AssetFamily為:AssetFamily.CardXML;
  • 資料對於的資源包為“cardxml0.unity3d”;
  • 資源包中的資源型別為:TextAsset;
  • 資源載入使用的介面為:AssetLoader:LoadCardXml();
  • 執行時對應的資料型別為:EntityDef;
  • xml檔案中儲存有多個Entity物件資料,具體資料例如:
<Entity version="2" CardID="CS1_042">
    <Tag name="CardName" enumID="185" type="String">閃金鎮步兵</Tag>
    <Tag name="CardSet" enumID="183" type="CardSet" value="2" />
    <Tag name="CardType" enumID="202" type="CardType" value="4" />
    <Tag name="Faction" enumID="201" type="Faction" value="2" />
    <Tag name="Rarity" enumID="203" type="Rarity" value="1" />
    <Tag name="Cost" enumID="48" type="Number" value="1" />
    <Tag name="Atk" enumID="47" type="Number" value="1" />
    <Tag name="Health" enumID="45" type="Number" value="2" />
    <Tag name="AttackVisualType" enumID="251" type="AttackVisualType" value="1" />
    <Tag name="CardTextInHand" enumID="184" type="String"><b>嘲諷</b></Tag>
    <Tag name="DevState" enumID="268" type="DevState" value="2" />
    <Tag name="Collectible" enumID="321" type="Bool" value="1" />
    <Tag name="EnchantmentBirthVisual" enumID="330" type="EnchantmentVisualType" value="0" />
    <Tag name="EnchantmentIdleVisual" enumID="331" type="EnchantmentVisualType" value="0" />
    <Tag name="ArtistName" enumID="342" type="String">Donato Giancola</Tag>
    <Tag name="HowToGetThisGoldCard" enumID="365" type="String">聖騎士達到57級後解鎖。</Tag>
    <Tag name="FlavorText" enumID="351" type="String">如果閃金鎮都是由1/2的步兵把守的話,那它早在多年以前就被毀了。</Tag>
    <Tag name="Taunt" enumID="190" type="Bool" value="1" />
    <Power definition="54e57583-ce5c-46e3-899a-39bd2181468d" />
  </Entity>

卡牌實體

  • 卡牌實體物件對應的AssetFamily為:AssetFamily.CardPrefab;
  • 資料對應的資源包為“cards?.unity3d”,目前共有4個;
  • 資源包中的資源型別為:Prefab;
  • 資源載入對應的介面為:AssetLoader:LoadCardPrefab();
  • 卡牌資源使用CardID進行索引,例如“閃金鎮步兵”對應“CardID="CS1_042"”;
  • Prefab中的GameObject主要包含:Transform、Material、CardDef,這三個Component;
  • CardDef有很多CustomEditField,主要分為以下幾類:
    • EditType.SOUND_PREFAB;
    • Material,主要是Portrait--頭像;
    • EditType.SPELL,其實是string型別,儲存的是Spell物件的資源路徑;

技能物件

  • 技能物件對應的AssetFamily為:AssetFamily.Spell;
  • 資料對應的資源包為“spells?.unity3d”,目前共有3個;
  • 資源包中的資源型別為:Prefab;
  • 資源載入對應的介面為:AssetLoader:LoadSpell();
  • 卡牌通過CardDef中指定相關技能資源的路徑;
  • Prefab中的GameObject主要包含:AudioClip、AudioSource、Material、ParticleSystem、ParticleSystemRenderer、Transform等元件;
  • 涉及到的指令碼主要有:PlayerMaker相關的類,Spell及其派生類、SoundDef;
    我們看到Spell有很多的派生類,這裡用到了一個小技巧:GetComponent()是可以把基類作為引數來獲得子類物件的。例如,一個物件綁定了ArmorSpell物件,而ArmorSpell是Spell的派生類,那麼gameObject.GetComponent<Spell>()是可以獲得這個ArmorSpell物件的。
總結一下:卡牌和技能相關的資料主要包括以上三種,其中EntityDef是使用“策劃填表”或者類似的方式,而且卡牌和技能資源,則使用Unity編輯成Pefab。技能物件中用到了PlayerMaker外掛。本次分析涉及到的類,請詳見下圖。

最後,按照慣例,還是秀一下戰績: