精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
Unity3d&C#分布式游戲服務(wù)器ET框架介紹

前幾天寫了《開(kāi)源分享 Unity3d客戶端與C#分布式服務(wù)端游戲框架》,受到很多人關(guān)注,QQ群幾天就加了80多個(gè)人。開(kāi)源這個(gè)框架的主要目的也是分享自己設(shè)計(jì)ET的一些想法,所以我準(zhǔn)備寫一系列的文章,介紹下自己的思路跟設(shè)計(jì),每篇一個(gè)主題,這次介紹的是組件設(shè)計(jì)。

在代碼復(fù)用和組織數(shù)據(jù)方面,面向?qū)ο罂赡苁谴蠹业谝环磻?yīng)。面向?qū)ο笕筇匦岳^承,封裝,多態(tài),在一定程度上能解決不少代碼復(fù)用,數(shù)據(jù)復(fù)用的問(wèn)題。不過(guò)面向?qū)ο蟛皇侨f(wàn)能的,它也有極大的缺陷:

1. 數(shù)據(jù)結(jié)構(gòu)耦合性極強(qiáng)

一旦父類中增加或刪除某個(gè)字段,可能要影響到所有子類,影響到所有子類相關(guān)的邏輯。這顯得非常不靈活,在一套復(fù)雜的繼承體系中,往父類中改變字段會(huì)變得越來(lái)越麻煩,比方說(shuō)ABC是D的子類,某天發(fā)現(xiàn)需要增加一個(gè)AB都有的數(shù)據(jù),但是C沒(méi)有,那么這個(gè)數(shù)據(jù)肯定不好放到父類中,只能將AB抽象出來(lái)一個(gè)父類E,E繼承于D,AB共有的字段加到E中,一旦繼承結(jié)構(gòu)發(fā)生了變化,可能接口也要改變,比方說(shuō)之前有個(gè)接口傳入?yún)?shù)類型是E,當(dāng)AB不再需要共用的那個(gè)字段,那么需要調(diào)整繼承關(guān)系,讓AB重新繼承D,那么這個(gè)接口的傳入?yún)?shù)類型需要改成D,其中的邏輯代碼很可能也要發(fā)生調(diào)整。更可怕的是游戲邏輯變化非常復(fù)雜,非常頻繁,可能今天加了個(gè)字段,明天又刪掉了,假如每次都要去調(diào)整繼承結(jié)構(gòu),這簡(jiǎn)直就是噩夢(mèng)。繼承結(jié)構(gòu)面對(duì)頻繁的數(shù)據(jù)結(jié)構(gòu)調(diào)整感覺(jué)很無(wú)力。

2. 難以熱插拔

繼承結(jié)構(gòu)無(wú)法運(yùn)行時(shí)增加刪除字段,比如玩家Player平常是走路,使用坐騎后就騎馬。問(wèn)題是坐騎的相關(guān)信息就需要一直掛在Player對(duì)象上面。這就顯得很不靈活,我不騎馬的時(shí)候內(nèi)存中為啥要有馬的數(shù)據(jù)?接口也有同樣的問(wèn)題,一個(gè)類實(shí)現(xiàn)了一個(gè)接口,那么這個(gè)接口就永遠(yuǎn)粘在了這個(gè)類身上,你想甩掉她都不行,還是以騎馬為例,玩家Player可以進(jìn)行騎行,那么可能繼承一個(gè)騎行的接口,問(wèn)題是,當(dāng)我這個(gè)Player從坐騎上下來(lái)時(shí),玩家Player身上還是有騎行的接口,根本沒(méi)法動(dòng)態(tài)刪掉這個(gè)接口!可能例子舉得不是很對(duì),但是道理表述的應(yīng)該很清楚了。

使用面向?qū)ο罂赡軐?dǎo)致災(zāi)難性后果,游戲開(kāi)發(fā)中有新人有老人,有技術(shù)好的,有技術(shù)差的。人都是喜歡偷懶的,當(dāng)你發(fā)現(xiàn)調(diào)整繼承關(guān)系麻煩的時(shí)候,有可能AB中增加一個(gè)字段為了省事直接就放到父類D中去了。導(dǎo)致C莫名奇妙的多了一個(gè)無(wú)用的字段。關(guān)鍵還沒(méi)法發(fā)現(xiàn),最后導(dǎo)致父類D越來(lái)越大,到最后有可能干脆就不用ABC了,直接讓所有對(duì)象都變成D,方便嘛!是的,很多游戲就是這么干的,開(kāi)發(fā)到最后根本就不管繼承關(guān)系了,因?yàn)橄牍芤补懿涣肆恕?/p>

面向?qū)ο笤诿鎸?duì)復(fù)雜的游戲邏輯時(shí)很無(wú)力,所以很多游戲開(kāi)發(fā)者又倒退了回去,使用面向過(guò)程進(jìn)行開(kāi)發(fā)游戲,面向過(guò)程,簡(jiǎn)單粗暴,不考慮復(fù)雜的繼承,不考慮抽象,不考慮多態(tài),是開(kāi)發(fā)屆的freestyle,挽起袖子就開(kāi)擼,但同時(shí),代碼邏輯的復(fù)用性,數(shù)據(jù)的復(fù)用性也大大降低。面向過(guò)程也不是一種好的游戲開(kāi)發(fā)模式。

組件模式很好的解決了面向?qū)ο笠约懊嫦蜻^(guò)程的種種缺陷,在游戲客戶端中使用非常廣泛,Unity3d,虛幻4,等等都使用了組件模式。組件模式的特點(diǎn):
1.高度模塊化,一個(gè)組件就是一份數(shù)據(jù)加一段邏輯
2.組件可熱插拔,需要就加上,不需要就刪除
3.類型之間依賴極少,任何類型增加或刪除組件不會(huì)影響到其它類型。

但是目前只有極少有服務(wù)端使用了組件的設(shè)計(jì),守望先鋒服務(wù)端應(yīng)該是使用了組件的設(shè)計(jì),守望先鋒的開(kāi)發(fā)人員稱之為ECS架構(gòu),其實(shí)就是組件模式的一個(gè)變種,E就是Entity,C就是Component,S是System,其實(shí)就是將組件Component的邏輯與數(shù)據(jù)剝離,邏輯部分叫System,話題扯遠(yuǎn)了,還是回到ET框架來(lái)把。

ET框架使用了組件的設(shè)計(jì)。一切都是Entity和Component,任何類繼承于Entity都可以掛載組件,例如玩家類:

public sealed class Player : Entity{    public string Account { get; private set; }    public long UnitId { get; set; }        public void Awake(string account)    {        this.Account = account;    }        public override void Dispose()    {        if (this.Id == 0)        {            return;        }        base.Dispose();    }}

給玩家對(duì)象掛載個(gè)移動(dòng)組件MoveComponent,這樣玩家就可以移動(dòng)了,給玩家掛上一個(gè)背包組件,玩家就可以管理物品了,給玩家掛上技能組件,那么玩家就可以施放技能了,加上Buff組件就可以管理buff了。

player.AddComponent<MoveComponent>();player.AddComponent<ItemsComponent>();player.AddComponent<SpellComponent>();player.AddComponent<BuffComponent>();

組件是高度可以復(fù)用的,比如一個(gè)NPC,他也可以移動(dòng),給NPC也掛上MoveComponent就行了,有的NPC也可以施放技能,那么給它掛上SpellComponent,NPC不需要背包,那么就不用掛ItemsComponent了

ET框架模塊全部做成了組件的形式,一個(gè)進(jìn)程也是由不同的組件拼接而成。比方說(shuō)Loginserver需要對(duì)外連接也需要與服務(wù)器內(nèi)部進(jìn)行連接,那么login server掛上

// 內(nèi)網(wǎng)網(wǎng)絡(luò)組件NetInnerComponent,處理對(duì)內(nèi)網(wǎng)連接Game.Scene.AddComponent<NetInnerComponent, string, int>(innerConfig.Host, innerConfig.Port);// 外網(wǎng)網(wǎng)絡(luò)組件NetOuterComponent,處理與客戶端連接Game.Scene.AddComponent<NetOuterComponent, string, int>(outerConfig.Host, outerConfig.Port);

比如battle server就不需要對(duì)外網(wǎng)連接(外網(wǎng)消息由gateserver轉(zhuǎn)發(fā)),那么很自然的只需要掛載一個(gè)內(nèi)網(wǎng)組件即可。
類似Unity3d的組件,ET框架也提供了組件事件,例如Awake,Start,Update等。要給一個(gè)Component或者Entity加上這些事件,必須寫一個(gè)輔助類。比如NetInnerComponent組件需要Awake跟Update方法,那么添加一個(gè)這樣的類即可:

[ObjectEvent]public class NetInnerComponentEvent : ObjectEvent<NetInnerComponent>, IAwake, IUpdate{    public void Awake()    {        this.Get().Awake();    }    public void Update()    {        this.Get().Update();    }}

這樣,NetInnerComponent在AddComponent之后會(huì)調(diào)用其Awake方法,并且每幀調(diào)用Update方法。
ET沒(méi)有像Unity使用反射去實(shí)現(xiàn)這種功能,因?yàn)榉瓷湫阅鼙容^差,而且這樣實(shí)現(xiàn)的好處是這個(gè)類可以放到熱更dll中,這樣組件的Awake Start,Update方法以及其它方法都可以放到熱更層中。將Entity和Component做成沒(méi)有方法的類,方法都放到熱更層,方便熱更修復(fù)邏輯bug。

組件式開(kāi)發(fā)最大的好處就是不管菜鳥還是高手,開(kāi)發(fā)一個(gè)功能都能很快的知道怎么組織數(shù)據(jù)怎么組織邏輯。可以完全放棄面向?qū)ο蟆J褂妹嫦驅(qū)ο箝_(kāi)發(fā)最頭疼的就是我該繼承哪個(gè)類呢?之前做過(guò)最恐怖的就是虛幻三,虛幻三的繼承結(jié)構(gòu)非常多層,完全不知道自己需要從哪里開(kāi)始繼承。最后可能導(dǎo)致一個(gè)非常小的功能,繼承了一個(gè)及其巨大的類,這在虛幻三開(kāi)發(fā)中屢見(jiàn)不鮮。所以虛幻4改用了組件模式。組件模式的模塊隔離性非常好,技術(shù)菜鳥某個(gè)組件寫得非常差,也不會(huì)影響到其它模塊,大不了重寫這個(gè)組件就好了。

正是因?yàn)镋T使用了可拆卸的組件模式,ET可以將所有服務(wù)器組件都裝到同一個(gè)進(jìn)程上,那么這一個(gè)進(jìn)程就可以當(dāng)作一組分布式服務(wù)器使用。從此用vs調(diào)試分布式服務(wù)器成為了可能。正因?yàn)檫@樣,平常開(kāi)發(fā)只使用一個(gè)進(jìn)程,發(fā)布的時(shí)候發(fā)布成多個(gè)進(jìn)程就行了。說(shuō)實(shí)在的,不是吹牛,這是一個(gè)偉大的發(fā)明,這一發(fā)明解決了分布式游戲服務(wù)器開(kāi)發(fā)中的大大大難題,極大的提高了開(kāi)發(fā)效率。

代碼地址:https://github.com/egametang/Egametang

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Unity中獲取某個(gè)對(duì)象下面的組件
Unity中添加組件的幾種方法
GroupLayout講解2
自制IOC容器(1)
在Unity中使用Lua腳本:語(yǔ)言層和游戲邏輯粘合層處理
[Unity 3D] Unity 3D 性能優(yōu)化(二)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

主站蜘蛛池模板: 柞水县| 禹城市| 大姚县| 大连市| 仙游县| 仙居县| 崇仁县| 南平市| 罗城| 内江市| 莒南县| 铜陵市| 淳化县| 潮州市| 清苑县| 清新县| 南宫市| 嘉禾县| 海门市| 若尔盖县| 丘北县| 宁河县| 阳山县| 荔浦县| 华池县| 藁城市| 德令哈市| 灵丘县| 浦城县| 黑河市| 桑植县| 射洪县| 大竹县| 远安县| 珠海市| 申扎县| 道孚县| 新郑市| 钟祥市| 临海市| 克东县|