最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

大廠如何開(kāi)發(fā)多語(yǔ)言系統(tǒng)

2022-09-22 17:58 作者:獨(dú)立游戲人-老雷  | 我要投稿

版權(quán)聲明

  • 本文為“優(yōu)夢(mèng)創(chuàng)客”原創(chuàng)文章,您可以自由轉(zhuǎn)載,但必須加入完整的版權(quán)聲明

  • 更多學(xué)習(xí)資源請(qǐng)加QQ:1517069595或WX:alice17173獲?。ㄆ髽I(yè)級(jí)性能優(yōu)化/熱更新/Shader特效/服務(wù)器/商業(yè)項(xiàng)目實(shí)戰(zhàn)/每周直播/一對(duì)一指導(dǎo))

  • 點(diǎn)贊、關(guān)注、分享可免費(fèi)獲得配套學(xué)習(xí)資源

需求分析與系統(tǒng)設(shè)計(jì)

需求分析

  • 文字顯示

    • 多語(yǔ)言系統(tǒng)中第一個(gè)要實(shí)現(xiàn)的需求就是文字顯示,要針對(duì)玩家所使用的母語(yǔ)顯示不同的語(yǔ)言文字

    • 技術(shù)要點(diǎn):要獲取到玩家手機(jī)所使用的語(yǔ)言,然后自動(dòng)化地根據(jù)手機(jī)語(yǔ)言配置來(lái)顯示對(duì)應(yīng)的語(yǔ)言文字

  • 語(yǔ)言切換

    • 要實(shí)現(xiàn)語(yǔ)言切換需要提供語(yǔ)言切換UI界面,在點(diǎn)擊這個(gè)UI界面上語(yǔ)言切換按鈕時(shí),所有的語(yǔ)言都要改變

    • 還需要支持的一個(gè)功能是格式化字符串的切換,因?yàn)樯蠄D中的寶箱打開(kāi)等待時(shí)間是根據(jù)實(shí)際時(shí)間填進(jìn)去的,后面的時(shí)間單位也要隨著語(yǔ)言的切換而切換

系統(tǒng)設(shè)計(jì)

  • 用例圖

    • 用例圖是由一些人形角色以及圓圈來(lái)構(gòu)成的,其中人形角色表示這個(gè)系統(tǒng)里的一些角色,圓圈表示這個(gè)角色所能做的一些操作

    • 在設(shè)計(jì)系統(tǒng)之前,先給大家介紹一個(gè)系統(tǒng)的分析設(shè)計(jì)方法:用例圖(如上圖)

  • 系統(tǒng)設(shè)計(jì)

    • 用例圖上的每一個(gè)角色都是要在程序里實(shí)現(xiàn)的某個(gè)程序模塊

    • 比如多語(yǔ)言控制模塊,它會(huì)有兩個(gè)功能

      • 1,響應(yīng)語(yǔ)言切換請(qǐng)求

      • 2,讀取數(shù)據(jù)

快速實(shí)現(xiàn)多語(yǔ)言系統(tǒng)

定義多語(yǔ)言數(shù)據(jù)模型

  • 定義多語(yǔ)言數(shù)據(jù)常量類,叫做MultiLangConst,所有的多語(yǔ)言數(shù)據(jù)都會(huì)放在這個(gè)類里,類中的代碼如下


編寫(xiě)多語(yǔ)言控制腳本和處理腳本

  • 創(chuàng)建了多語(yǔ)言數(shù)據(jù)常量類后,還需要再寫(xiě)一個(gè)控制層組件來(lái)完成的在不同的語(yǔ)言環(huán)境下切換文字的功能

  • 控制層腳本

  • 要使GameObject能夠接收消息就需要再寫(xiě)一個(gè)腳本組件,這個(gè)組件里有一個(gè)方法,名字就叫OnLanguageChanged,這樣才就能接收到事件通知

  • 在寫(xiě)腳本之前先來(lái)創(chuàng)建UI界面

  • 創(chuàng)建完UI界面后就能發(fā)現(xiàn)Canvas是整個(gè)UI的根節(jié)點(diǎn),將剛才寫(xiě)的MultiLangCtrl腳本掛載到Canvas上面,設(shè)置腳本中的canvas字段是Canvas本身,這樣在調(diào)用腳本里的SetupLanguage方法時(shí),就會(huì)向它下面的每一個(gè)節(jié)點(diǎn)發(fā)送消息

  • 給顯示文本組件增加一個(gè)腳本,叫MultiLangHandler

  • 它的功能是接收語(yǔ)言改變的通知,并在語(yǔ)言改變時(shí)顯示對(duì)應(yīng)的語(yǔ)言文字

  • 在添加腳本時(shí)需要指定一下該文本組件要轉(zhuǎn)換的語(yǔ)言文字(如下圖)

  • 添加完腳本后需要給按鈕綁定語(yǔ)言切換的事件,以實(shí)現(xiàn)在點(diǎn)擊按鈕時(shí)切換語(yǔ)言文字的功能

  • 在Button組件的點(diǎn)擊事件里添加上MultiLangCtrl腳本的SetupLanguage方法

  • 并指定對(duì)應(yīng)的語(yǔ)言文字(如下圖)

  • 這樣在點(diǎn)擊語(yǔ)言切換按鈕時(shí),就會(huì)調(diào)用多語(yǔ)言切換的方法

  • 如果把MultiLangHandler里的LangKey更改為”txt_level“,文本顯示組件里顯示的內(nèi)容就會(huì)變成Level和等級(jí)


增加更多字符串進(jìn)行測(cè)試

  • 第三步里主要內(nèi)容是讓大家思考一下:把所有的字符串的都是放在MultiLangConst類里的兩個(gè)字典里是否合適?


事件的定義、訂閱與發(fā)布

  • 原本的代碼里采用的是BroadcastMessage來(lái)廣播消息

  • 這種方式在處理消息時(shí)是把消息發(fā)送給下面的每一個(gè)組件,這就存在一些性能問(wèn)題,因?yàn)樾枰獧z測(cè)每一個(gè)游戲?qū)ο笊厦鎾燧d的每一個(gè)組件,檢測(cè)其中有沒(méi)有OnLanguageChanged方法

  • 這樣做的性能會(huì)比較低,所以要使用另外一種模式:事件訂閱和通知模式

  • 會(huì)在MultiLangHandler的Start、OnDestroy里訂閱和取消事件

  • 這樣做的好處是:

    • 因?yàn)镸ultiLangHandler只是綁定在那些有文本組件的對(duì)象上,所以只有有文本組件的對(duì)象能收到事件通知

整體效果測(cè)試

  • 為MultiLangConst的兩個(gè)字典增加一些語(yǔ)言文字,并在場(chǎng)景中創(chuàng)建多個(gè)TextUI界面

  • 測(cè)試效果

實(shí)現(xiàn)要點(diǎn)與討論

語(yǔ)言數(shù)據(jù)源組件

  • 語(yǔ)言數(shù)據(jù)源組件是用來(lái)存放數(shù)據(jù)的,上面代碼中使用的方案是方案一,方案一就是把所有的多語(yǔ)言數(shù)據(jù)全部放在程序代碼里,這是最差的一個(gè)方法

    • 因?yàn)槎嗾Z(yǔ)言數(shù)據(jù)源組件作為MonoBehaviour腳本是不能熱更新的,采用這種方式,代碼的維護(hù)將非常困難,而且代碼里本就不應(yīng)該放這些數(shù)據(jù)

  • 這種方案顯然是不合適的,所以需要考慮使用第二種方案:把文字?jǐn)?shù)據(jù)交給Unity原生提供的ScriptableObject來(lái)存儲(chǔ)

  • ScriptableObject是Unity提供的數(shù)據(jù)存儲(chǔ)方案,也能做到熱更新,但這種方案有一個(gè)明顯的缺點(diǎn):

    • 它的編輯全都是在ScriptableObject的專門(mén)編輯器里進(jìn)行編輯的(如上圖),如果只是編輯小批量的數(shù)據(jù)還是挺方便的,但是數(shù)據(jù)量大了以后再用這種方式編輯就不太方便了

  • 而且還有一個(gè)致命缺陷:

    • 當(dāng)程序上的這些字段名稱變化時(shí)就需要重新綁定數(shù)據(jù),即使不改變數(shù)據(jù)名稱,只是在上面或下面增加一個(gè)字段,也會(huì)造成數(shù)據(jù)丟失

  • 所以這種方法只適合開(kāi)發(fā)一些小游戲或超休閑游戲,如果想要了解這種方案,可以在文末找愛(ài)麗絲老師領(lǐng)取我們的爐石傳說(shuō)卡牌數(shù)據(jù)管理,以及數(shù)據(jù)管理的十種方式

  • 方案三是一種表驅(qū)動(dòng)方案,在游戲開(kāi)發(fā)中讓策劃去Excel表里編輯數(shù)據(jù),它大概需要五個(gè)步驟

    • 1,建立語(yǔ)言字符串表

    • 2,把表數(shù)據(jù)導(dǎo)出為一種通用格式(如Json或xml格式)

    • 3,在程序里定義一個(gè)數(shù)據(jù)結(jié)構(gòu)

      • 注意:使用表驅(qū)動(dòng)時(shí)需要在程序里建立對(duì)應(yīng)的類,比如語(yǔ)言類,不管是Lua還是ILRunTime都需要在程序里建立對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu),來(lái)轉(zhuǎn)換表里的數(shù)據(jù)到程序的數(shù)據(jù)結(jié)構(gòu),這是比較麻煩一點(diǎn)

    • 4,在程序里定義一個(gè)數(shù)據(jù)模型類(數(shù)據(jù)模型是負(fù)責(zé)管理程序數(shù)據(jù)的)

    • 5,程序啟動(dòng)時(shí)解析文本數(shù)據(jù),轉(zhuǎn)換為”內(nèi)存中的“字符串表

      • 轉(zhuǎn)換時(shí)會(huì)存在性能開(kāi)銷(xiāo),是數(shù)據(jù)解析的開(kāi)銷(xiāo),因?yàn)槲淖衷诮忉寱r(shí)要判斷數(shù)據(jù)格式,然后根據(jù)數(shù)據(jù)格式來(lái)匹配后面的數(shù)據(jù)

  • 方案4是建立語(yǔ)言字符串表,然后直接把它導(dǎo)出成內(nèi)存里的字符串?dāng)?shù)據(jù),省去了數(shù)據(jù)解析的過(guò)程,而且中間數(shù)據(jù)模型的定義都是不需要程序員手動(dòng)完成的

  • 所以方案3中的這些步驟其實(shí)都是可以改進(jìn)的,在我們的《皇室戰(zhàn)爭(zhēng)》項(xiàng)目框架里通過(guò)表驅(qū)動(dòng),加上工作流的改進(jìn),只要一步操作就可以完成表數(shù)據(jù)的加載

語(yǔ)言控制組件

  • 要控制語(yǔ)言顯示就需要檢測(cè)系統(tǒng)的默認(rèn)語(yǔ)言

    • 只要調(diào)用Application.systemLanguage就能夠獲得系統(tǒng)的當(dāng)前語(yǔ)言,然后根據(jù)它的語(yǔ)言來(lái)通過(guò)SetupLanguage切換到對(duì)應(yīng)的語(yǔ)言

  • 語(yǔ)言控制組件還要負(fù)責(zé)讀取語(yǔ)言數(shù)據(jù)

  • 發(fā)布語(yǔ)言切換通知

    • 這是比較重要的一點(diǎn),因?yàn)闋可娴揭恍┬阅軉?wèn)題,剛才也已經(jīng)講了幾種模式

      • BroadcastMessage模式

      • BroadcastMessage模式的缺點(diǎn)是要遍歷整個(gè)Canvas,它是使用多個(gè)for循環(huán)來(lái)遍歷每一個(gè)對(duì)象,以及對(duì)象上的每一個(gè)組件和方法,檢查其中有沒(méi)有發(fā)布消息所對(duì)應(yīng)的方法名稱

      • 所以會(huì)有性能問(wèn)題,因?yàn)樾枰ㄖ械慕M件,而不僅僅只是文字組件,這是非常浪費(fèi)性能的,解決方案就是使用事件訂閱發(fā)布模式

      • 事件、訂閱發(fā)布模式

      • 這種模式的問(wèn)題在于熱更新,由于事件訂閱、發(fā)布模式的事件接收腳本是原生的C#層代碼,而控制語(yǔ)言切換的腳本是處于熱更層的,是一個(gè)熱更腳本,它們之間進(jìn)行交互會(huì)有跨域的開(kāi)銷(xiāo)

      • 既然這種方式會(huì)有跨域的開(kāi)銷(xiāo),那么在項(xiàng)目里應(yīng)該怎么樣去做事件切換通知呢?

解決方案

  • 我們的項(xiàng)目里的大部分程序邏輯都是全熱更實(shí)現(xiàn)的,這樣就沒(méi)有跨域開(kāi)銷(xiāo)了,為什么呢?

    • 因?yàn)樗械拇a都不跨域,都是在熱更工程里完成的

文字顯示組件

  • 文字顯示組件的基本需求

    • 1,響應(yīng)語(yǔ)言改變通知

    • 2,處理語(yǔ)言改變

  • 前面已經(jīng)通過(guò)腳本實(shí)現(xiàn)了上面的兩個(gè)需求,但還有一些問(wèn)題,就是Text組件為什么需要額外掛一個(gè)組件來(lái)實(shí)現(xiàn)多語(yǔ)言切換

    • 這是因?yàn)門(mén)ext組件不支持多語(yǔ)言切換,所以需要額外掛一個(gè)組件

  • 那怎樣讓Text組件從不支持多語(yǔ)言升級(jí)到支持多語(yǔ)言呢?

  • 有兩種方案,前面實(shí)現(xiàn)的是方案2,方案1是繼承一個(gè)Text組件,來(lái)把Text組件替換掉,然后在繼承了Text的組件中實(shí)現(xiàn)所有的多語(yǔ)言功能

  • 但這種方案也有一些缺點(diǎn),所有前面使用了方案2,因?yàn)榉桨?的組件化設(shè)計(jì)對(duì)于后續(xù)的項(xiàng)目拓展更有利

方案1:繼承Text組件

  • 在派生類中實(shí)現(xiàn)多語(yǔ)言支持的優(yōu)點(diǎn)是

    • 簡(jiǎn)單直觀,只要替換組件就可以了

  • 缺點(diǎn)

    • 如果在項(xiàng)目開(kāi)始時(shí)并沒(méi)有考慮到多語(yǔ)言支持,之后想要通過(guò)繼承來(lái)實(shí)現(xiàn)多語(yǔ)言支持就需要把所有原本的Text的組件替換掉,并保留原本Text組件上的所有設(shè)置,這是需要手動(dòng)去做的

方案2:添加一個(gè)多語(yǔ)言組件

  • 方案2中需要添一個(gè)組件,名叫MyLangText,它的作用是控制Text組件和顯示多語(yǔ)言文字,除此之外還有一些高級(jí)功能

  • 高級(jí)功能

    • 可以通過(guò)MyLangText組件實(shí)現(xiàn)對(duì)Text組件的控制,原理是定義一個(gè)TextId字段,這個(gè)字段的值就是Text組件要顯示多語(yǔ)言字符串的id

    • MyLangText組件也是多語(yǔ)言系統(tǒng)的控制組件,是用來(lái)控制文字的讀取和送顯的,送顯是讀取文字并送到Text組件里的Text屬性里顯示

  • 這種方案的好處是:UI里的文本內(nèi)容可以完全交給策劃同學(xué)來(lái)設(shè)定

  • 但它也是有缺點(diǎn)的:

    • 不能支持格式化的字符串也不支持熱重載技術(shù)

    • 因?yàn)镸yLangText組件承擔(dān)了兩個(gè)功能

      • 記錄要顯示的文字串id

      • 控制文字串id與文字內(nèi)容的轉(zhuǎn)換

    • 這樣做是不太好的,因?yàn)橐话闱闆r下都不會(huì)把程序里的邏輯控制放到原生的C#層里,這樣不能熱更,而且也不知道策劃會(huì)加什么樣的奇怪需求

    • 把邏輯控制放在原生的C#層就意味著這個(gè)組件將來(lái)只能控制文字的讀取和送顯,如果將來(lái)有新的需求了,原生的C#腳本也是沒(méi)有辦法更新業(yè)務(wù)邏輯的

  • 這樣就整理出了新需求:

    • 1,多語(yǔ)言要支持格式化字符串

      • 要盡量避免MyLangText組件既處理文本id的存儲(chǔ),又處理文本id到文字的顯示

    • 2,支持熱重載控制文字表現(xiàn)

支持格式化字符串

  • 如果把格式化字符串的功能放在前面的非熱更代碼中,也就是MyLangText代碼中合不合適呢?

  • 這顯然是不合適的,因?yàn)椴邉澋男枨笫嵌嘧兊?,非熱更層的代碼只能滿足今天的需求,而不能滿足明天的,所以在寫(xiě)代碼時(shí)要盡量把控制層的代碼放到熱更代碼里去

支持熱重載控制文字表現(xiàn)

  • 很多時(shí)候在程序里發(fā)現(xiàn)一個(gè)bug時(shí)就要把程序停掉重新開(kāi)發(fā),再進(jìn)行測(cè)試,這樣效率會(huì)比較低,要解決這個(gè)問(wèn)題需要使用到熱重載技術(shù)

  • 熱重載的程序代碼是在熱更代碼程序域里的,但它又高于熱更技術(shù)實(shí)現(xiàn),因?yàn)槿绻麤](méi)有框架支持,熱更代碼在熱更時(shí)需要把代碼停掉,重新啟動(dòng)一次才能使熱更代碼生效

  • 而熱重載可以使代碼立刻生效,不需要重新啟動(dòng),現(xiàn)在的VS2022,還有Unity本身都能夠支持熱重載,當(dāng)然了,這是引擎層面和開(kāi)發(fā)環(huán)境層面上的,你自己的程序里仍然是不能實(shí)現(xiàn)熱重載的,除非有項(xiàng)目架構(gòu)的支持,而我們的項(xiàng)目架構(gòu)就是能夠支持熱重載的(詳細(xì)演示可以點(diǎn)擊鏈接查看)

寫(xiě)在最后

  • 更多學(xué)習(xí)資源請(qǐng)加QQ:1517069595或WX:alice17173獲?。ㄆ髽I(yè)級(jí)性能優(yōu)化/熱更新/Shader特效/服務(wù)器/商業(yè)項(xiàng)目實(shí)戰(zhàn)/每周直播/一對(duì)一指導(dǎo))

  • 點(diǎn)贊、關(guān)注、分享可免費(fèi)獲得配套學(xué)習(xí)資源

  • 詳細(xì)內(nèi)容可參考下方完整視頻


大廠如何開(kāi)發(fā)多語(yǔ)言系統(tǒng)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
灵山县| 罗甸县| 澜沧| 兰考县| 凤山市| 贵定县| 措勤县| 陆川县| 原阳县| 凤山县| 天镇县| 临清市| 阳信县| 苍溪县| 招远市| 北碚区| 漾濞| 九寨沟县| 永州市| 田阳县| 濮阳县| 昌江| 菏泽市| 商都县| 棋牌| 双牌县| 瑞昌市| 交城县| 和林格尔县| 新沂市| 太湖县| 广水市| 谢通门县| 体育| 小金县| 三亚市| 岳普湖县| 白城市| 双鸭山市| 盘锦市| 防城港市|