《炉⽯传说》游戏架构设计分析:卡牌技能数据
经过前⾯⼏次的尝试,我们对炉⽯的代码已经不陌⽣了。除了⽹络机制还没有了解以外,本机的逻辑已经⽐较熟悉了。
接下来继续向暴雪最NB的技能系统进发,我们的⽬标是:
分析技能的静态数据描述;
分析技能的运⾏时数据、逻辑组织;
这篇笔记主要记录对其分析数据。
静态数据组织
卡牌数据
卡牌的基本数据对于的AstFamily为:AstFamily.CardXML圆的半径公式
;
数据对于的资源包为“cardxml0.unity3d”;
资源包中的资源类型为:TextAst;
资源加载使⽤的接⼝为:AstLoader:LoadCardXml();
运⾏时对应的数据类型为:EntityDef;
xml⽂件中保存有多个Entity对象数据,具体数据例如:
1. <Entity version="2" CardID="CS1_042">
2. <Tag name="CardName" enumID="185" type="String">闪⾦镇步兵</Tag>
3. <Tag name="CardSet" enumID="183" type="CardSet" value="2" />
4. <Tag name="CardType" enumID="202" 夕阳照
type="CardType" value="4" />
5. <Tag name="Faction" enumID="201" type="Faction" value="2" />
6. <Tag n胭脂扣歌曲
ame="Rarity" enumID="203" type="Rarity" value="1" />
7. <Tag name="Cost" enumID="48" type="Number" value="1" />
8. <Tag name="Atk" enumID="47" type="Number" value="1" />
9. <Tag name="Health" enumID="45" type="Number" value="2" />
10. <Tag name="AttackVisualType" enumID="251" type="AttackVisualType" value="1" />
11. <Tag name="CardTextInHand" enumID="184" type="String"><b>嘲讽</b></Tag>
12. <Tag name="DevState" enumID="268" type="DevState" value="2" />
13. <Tag name="Collectible" enumID="321" type="Bool" value="1" />
14. <Tag name="EnchantmentBirthVisual" enumID="330" type="EnchantmentVisualType" value="0" />
15. <Tag name="EnchantmentIdleVisual" enumID="331" type="EnchantmentVisualType" value="0" />
16. <Tag name="ArtistName" enumID="342" type="String">Donato Giancola</Tag>
17. <Tag name="HowToGetThisGoldCard" enumID="365" type="String">圣骑⼠达到57级后解锁。</Tag>
18. <Tlol游戏名字
ag name="FlavorText" enumID="351" type="String">如果闪⾦镇都是由1/2的步兵把守的话,那它早在多年以前就被毁
了。</Tag>
19. <Tag name="Taunt" enumID="190" type="Bool" value="1" />
20. <Power definition="54e57583-ce5c-46e3-899a-39bd2181468d" />
21. </Entity>
复制代码
牌实体
卡牌实体对象对应的AstFamily为:AstFamily.Car签名英文
dPrefab;
数据对应的资源包为“cards?.unity3d”,⽬前共有4个;
资源包中的资源类型为:Prefab;
资源加载对应的接⼝为:AstLoader:LoadCardPrefab();
卡牌资源使⽤CardID进⾏索引,例如“闪⾦镇步兵”对应“CardID="CS1_042"”;
Prefab中的GameObject主要包含:Transform、Material、CardDef,这三个Component;
CardDef有很多CustomEditField,主要分为以下⼏类:
EditType.SOUND_PREFAB;
Material,美女的臀部
主要是Portrait--头像;
EditType.SPELL,其实是string类型,保存的是Spell对象的资源路径;
技能对象
技能对象对应的AstFamily为:AstFamily.Spell;
数据对应的资源包为“spells?.unity3d”,⽬前共有3个;
资源包中的资源类型为:Prefab;
资源加载对应的接⼝为:AstLoader:LoadSpell();
卡牌通过Card静字组词
Def中指定相关技能资源的路径;
Prefab中的GameObject主要包含:AudioClip、AudioSource、Material、ParticleSystem、ParticleSystemRenderer、Transform等组件;
涉及到的脚本主要有:PlayerMaker相关的类,Spell及其派⽣类、SoundDef;
我们看到Spell有很多的派⽣类,这⾥⽤到了⼀个⼩技挪威战役
巧:GetComponent()是可以把基类作为参数来获得⼦类对象的。例如,⼀个对象绑定了ArmorSpell对象,⽽ArmorSpell是Spell的派⽣类,那么gameObject.GetComponent<Spell>()是可以获得这个ArmorSpell对象的。
总结⼀下:
卡牌和技能相关的数据主要包括以上三种,其中EntityDef是使⽤“策划填表”或者类似的⽅式,⽽且卡牌和技能资源,则使⽤Unity编辑成Pefab。技能对象中⽤到了PlayerMaker插件。
本次分析涉及到的类,请详见下图。
主要的类
通过之前的分析,卡牌&技能涉及到⼏个类体系:Entity,Actor,Card,Spell,令⼈⼗分困惑,特别是前两者。在这⾥先略带武断的说⼀下这⼏个类的基本定位:
Entity主要⽤来做⽹络数据同步⽤的;
Actor主要处理客户端的渲染对象的控制,作为Component挂载在资源对象上;
Spell是技能Prefab挂载的脚本;
Card是卡牌Prefab挂载的脚本,在假期用英语怎么读
运⾏时处于中⼼地位,处理前3者的联系。
Entity
Entity是通过⽹络数据创建的,主要是Network.PacketID.POWER_HISTORY这个消息。详见GameState.CreateNewEntities()函数。因为Entity并不是MonoBehavior派⽣类,所以是new出来的,然后添加到GameState中管理(GameState.AddEntity()),⽹络传来的Entity数据主要是Tags(每个Tag是⼀个name->value对),然后调⽤Entity.InitEntity();
Actor
Actor也是⼀种资源,通过AstLoader.LoadActor()加载;
对应于AstFamily.Actor;
对应的资源包为“actor?.unity3d”,包内的为GameObject;
Actor的加载⼊⼝是在:Card.DetermineActorThenTransitionToZone()
Spell
Spell的加载⼊⼝是在Entity.ProcessCardDefAstRequest()
Card
在InitEntity中调⽤了Entity.InitCard(),它做的⼯作只是创建⼀个空的GameObject,然后使⽤AddComponent把Card添加上去。
真正的卡牌Prefab加载是在Entity.LoadCard()中进⾏的,这个函数是在处理PowerTask时GameState.OnShowEntity()中调⽤的;
具体的加载操作是通过 DefLoader.LoadCardDef()进⾏的,其内部再调⽤AstLoader.LoadCardPrefab()来进⾏资源加载;
卡牌&技能的加载流程
Entity的创建,以及Card、Spell的加载,都由⽹络消息触发;整个过程⽐较复杂,主要是有很多异步回调,⽐较难⽤⽂字描述,请见下图: