單機(jī)與聯(lián)機(jī)的差異和轉(zhuǎn)換

饑荒分為單機(jī)版和聯(lián)機(jī)版,一般來說,內(nèi)容相同的MOD,聯(lián)機(jī)版相對單機(jī)版來說,總是要多一些對網(wǎng)絡(luò)數(shù)據(jù)的處理,總歸是要復(fù)雜一些。越復(fù)雜的MOD,從單機(jī)移植到聯(lián)機(jī)就越困難。

本文主要講述單機(jī)和聯(lián)機(jī)的差異,以及從單機(jī)轉(zhuǎn)入聯(lián)機(jī)時(shí),應(yīng)該注意的東西。

主要資料來自Klei官方論壇的長篇教程:[Guide] Getting started with modding DST (and some general tips for DS as well)
原作者是rezecib,當(dāng)然,也結(jié)合了自己做MOD積累的經(jīng)驗(yàn)。

相同的部分

相通之處和細(xì)節(jié)差異

  • 調(diào)用美術(shù)資源的方式,都是使用assets表和Asset函數(shù)。不過在聯(lián)機(jī)版里,如果你要使用自定義的美術(shù)資源,還需要在在modinfo里添加語句all_clients_require_mod = true,這條語句會告訴系統(tǒng)要求所有加入房間的人都下載這個(gè)MOD。
  • 大部分在單機(jī)里可用的MOD API 如AddPrefabPostInit,AddComponentsPostInit等,用法都是不變的。有一點(diǎn)需要特別注意的是,AddSimPostInit,這個(gè)函數(shù)在單機(jī)版里常常被用于在游戲開始之后對玩家進(jìn)行修改(比如說在游戲開始之后,在玩家附近生成一個(gè)專屬寵物),這個(gè)函數(shù)在聯(lián)機(jī)版里不能這樣用了,因?yàn)楫?dāng)它被執(zhí)行的時(shí)候,還沒有玩家生成,所以你應(yīng)該根據(jù)情況,選擇新的方法了。如果你想修改UI,用AddClassPostConstruct對playerhud或contraols這兩個(gè)widget進(jìn)行修改。
  • 不要再使用AddSimPostInit來修改UI了,在單機(jī)時(shí)這樣做可能僅僅是不太合適,但在聯(lián)機(jī)里很可能會造成游戲崩潰。如果要修改UI,請使用上面提到的AddClassPostConstruct。
  • 添加新動作,單機(jī)和聯(lián)機(jī)有些許的不同,具體請參考我這個(gè)博客里的另一篇關(guān)于如何添加新動作的教程。

讓你的MOD在兩個(gè)游戲中都能運(yùn)行

一般來說,不推薦在兩個(gè)游戲中運(yùn)行同一個(gè)MOD,這不方便維護(hù),我建議針對兩個(gè)游戲發(fā)布各自的版本。不過如果你非要這么做的話,也是可以的。方法是使用TheSim:GetGameID()來區(qū)分兩個(gè)游戲要執(zhí)行的不同的代碼塊。

在聯(lián)機(jī)版中,TheSim:GetGameID()的返回值是"DST",可以用TheSim:GetGameID() == "DST"這個(gè)語句來判斷當(dāng)前運(yùn)行MOD的游戲是單機(jī)版還是聯(lián)機(jī)版。

此外,你還需要在modinfo添加mod api的版本號。單機(jī)的api版本為6,聯(lián)機(jī)則為10。寫法就是如下:api_version = 6;api_version_dst = 10 。

新的東西

變化

GetWorld()和GetPlayer()

在單機(jī)版中存在的兩個(gè)重要而且常用的全局函數(shù)——GetWorld()獲取世界和GetPlayer()獲取玩家,在聯(lián)機(jī)版中,被改為了全局變量TheWorld和ThePlayer,在聯(lián)機(jī)版中,直接調(diào)用這兩個(gè)變量就可以,不再需要運(yùn)行函數(shù)了。需要注意的是聯(lián)機(jī)版是多人游戲,直接用ThePlayer可能會對其他玩家造成誤操作。所以你在改單機(jī)為聯(lián)機(jī)時(shí),不可直接將GetPlayer()改為ThePlayer就完事了,而是要仔細(xì)分析每個(gè)GetPlayer()的使用情景來決定怎樣替換。

TheNet

--
聯(lián)機(jī)版新增了一個(gè)網(wǎng)絡(luò)類:TheNet,用于處理各種與網(wǎng)絡(luò)相關(guān)的內(nèi)容,常用的函數(shù)有:

TheNet:GetIsServer() -- 判斷是否是主機(jī)(創(chuàng)建游戲者)
TheNet:GetIsClient() -- 判斷是否是客機(jī)(加入游戲者)
TheNet:IsDedicated() -- 判斷是否是服務(wù)器
TheNet:Announce(message) -- 發(fā)送服務(wù)器公告,典型例子是XX死于XXX
TheNet:Say(message, whisper) -- 在聊天框里顯示信息,如果whisper的值為true,則這個(gè)消息只會被附近的人看到

另外,有些人喜歡用TheWorld.ismastersim來代替TheNet:GetIsServer() (還有"not TheWorld.ismastersim" 代替TheNet:GetIsClient()),這在大多數(shù)時(shí)候沒有錯(cuò),不過碰上某些時(shí)候,TheWorld還沒創(chuàng)建的情況,就會產(chǎn)生報(bào)錯(cuò),因此還是建議使用TheNet:GetIsServer()。
TheNet類當(dāng)然也有其它的一些函數(shù),不過最常用的還是上面介紹的那幾個(gè),如果想要了解更多,可以查閱游戲目錄\data\sripts\screen下的playerstatusscreen.lua找到其他的一些函數(shù),不過這些函數(shù)對MOD而言并沒有什么卵用(TheNet類不是用lua寫的,所以找不到函數(shù)的定義,只能看到使用它們的例子)。

modinfo

聯(lián)機(jī)版的modinfo,相比單機(jī)版,添加了一些新的內(nèi)容。

api_version = 10 --api版本,聯(lián)機(jī)版目前為10,如果不填10,則會被提示mod已經(jīng)過期。
api_version_dst = 10 -- 這個(gè)是可選的,如果你想要讓這個(gè)MOD同時(shí)在單機(jī)和聯(lián)機(jī)上都能運(yùn)行,則需要添加這句和下面的那句,并把上面那句的賦值改為6,如果只打算在聯(lián)機(jī)版運(yùn)行,可不寫此句和下面一句。
dst_compatible = true --此值為true則表明MOD兼容聯(lián)機(jī)版
all_clients_require_mod = true--讓客機(jī)知道自己是否需要訂閱這個(gè)MOD并下載下來,通常,有自定義美術(shù)資源的,都需要令此項(xiàng)為true。
client_only_mod = false--這一項(xiàng)和上一項(xiàng)正好相反,如果此項(xiàng)為true,則這是一個(gè)客機(jī)MOD,可以在游戲mod界面啟動。否則,需要在開啟房間的界面啟動。
server_filter_tags = {"character", "rog", "reign of giants"}--服務(wù)器過濾標(biāo)簽表,主要用于玩家搜索房間。一個(gè)房間如果開啟了這個(gè)mod,就會加入這個(gè)mod標(biāo)簽表里的標(biāo)簽。

prefab

聯(lián)機(jī)版的prefab,相比單機(jī)版,要多一些額外的關(guān)于網(wǎng)絡(luò)處理的部分。

  • AddNetwork
   inst:AddNetwork() 

當(dāng)你添加上面這條語句時(shí),就會讓這個(gè)prefab能被所有人看見(如果它本身是可見的)。否則,只能被創(chuàng)建這個(gè)物品的電腦看到。比如說,幾何種植顯示的那些方格,其實(shí)也是prefab,但沒有添加上面這條語句,所以只能被種植者本人看到,不會被其他玩家看到。

  • 主機(jī)判斷
   if not TheWorld.ismastersim then
       return inst
   end

這個(gè)if判斷塊在幾乎所有的prefab中都十分重要,代碼的含義是,如果這段代碼運(yùn)行在客機(jī)上,那么就到這里就結(jié)束prefab的初始化了。
因?yàn)樵诼?lián)機(jī)里,客機(jī)上存在的組件是極少的。包括物品欄組件inventoryitem,人物三圍hunger,sanity,health在內(nèi)的眾多組件都是不存在的,所以如果不上面的那段代碼,客機(jī)就會運(yùn)行執(zhí)行后面的代碼,但由于相應(yīng)的組件不存在,就一定會造成客機(jī)游戲崩潰,這也是單機(jī)轉(zhuǎn)聯(lián)機(jī)的人普遍會遇到的第一個(gè)崩潰問題。相應(yīng)的,Tag,以及其他會被所有玩家看到的內(nèi)容,比如說動畫表現(xiàn)(AnimState),形態(tài)(Transform),人物說話的文字(talker)等,就必須加在上面這段代碼之前,否則客機(jī)就看不到相應(yīng)的界面表現(xiàn)了。

另外,對聯(lián)機(jī)版的人物,初始化函數(shù)分成了兩部分,一部分是common_postinit,另一部分是master_postinit。前者是會在主機(jī)和客機(jī)上都執(zhí)行的代碼,后者則只在主機(jī)上執(zhí)行。上面的if判斷已經(jīng)內(nèi)置在了MakePlayerCharacter函數(shù)中,所以無需再添加。

  • SetPristine
   inst.entity:SetPristine() 

這條語句的意思是這條語句執(zhí)行之前的內(nèi)容都是運(yùn)行在主機(jī)和客機(jī)上的,然后再往下的內(nèi)容就不要再動用網(wǎng)絡(luò)了。理論上可以省一點(diǎn)網(wǎng)絡(luò)帶寬,然而這東西很難感覺得出來,也很難做測試,權(quán)當(dāng)沒啥卵用吧,一般緊鄰著上面的if判斷寫。寫在之前還是之后無所謂。

prefab新內(nèi)容的實(shí)例代碼釋義

下面給出聯(lián)機(jī)版長矛的初始化函數(shù)的代碼,參照著上面講解的內(nèi)容,很容易就能理解你需要為一個(gè)聯(lián)機(jī)版的prefab額外添加哪些東西。

local function fn() 
    local inst = CreateEntity()
    inst.entity:AddTransform()  
    inst.entity:AddNetwork()    --添加聯(lián)網(wǎng)組件,要想讓這個(gè)prefab被其他人看到,就必須添加這句,相反的,如果不希望被看到,比如說建筑幾何學(xué)的網(wǎng)格,就不要加這句。
    MakeInventoryPhysics(inst)    
    inst.AnimState:SetBank("spear")    
    inst.AnimState:SetBuild("spear")   
    inst.AnimState:PlayAnimation("idle")
    if not TheWorld.ismastersim then return inst end    --這個(gè)if判斷區(qū)分了客機(jī)和主機(jī)
    inst.entity:SetPristine()--節(jié)約一點(diǎn)網(wǎng)絡(luò)帶寬
    inst:AddComponent("weapon")    
    inst.components.weapon:SetDamage(TUNING.SPEAR_DAMAGE)        
    inst:AddComponent("finiteuses") 
    inst.components.finiteuses:SetMaxUses(TUNING.SPEAR_USES) 
    inst.components.finiteuses:SetUses(TUNING.SPEAR_USES) 
    inst.components.finiteuses:SetOnFinished(inst.Remove)
    inst:AddComponent("inspectable")
    inst:AddComponent("inventoryitem")
    inst:AddComponent("equippable")
    inst.components.equippable:SetOnEquip(onequip)
    inst.components.equippable:SetOnUnequip(onunequip)
    MakeHauntableLaunch(inst)
end

主客機(jī)數(shù)據(jù)交互

如果你想要做復(fù)雜的,深入游戲核心的聯(lián)機(jī)版MOD,主客機(jī)的數(shù)據(jù)交互幾乎是不可能繞過去的。如果處理得不好,造成主客機(jī)數(shù)據(jù)不同步,輕則無法順利實(shí)現(xiàn)自己想要的功能,重則直接崩掉服務(wù)器(有一段時(shí)間,精靈公主聯(lián)機(jī)版不穩(wěn)定,經(jīng)常崩服務(wù)器,就是因?yàn)闆]有處理好這個(gè)問題。如果你想要做復(fù)雜的MOD,又想保證一定的可靠性,那么就必須要深入理解這一段的知識。

基本機(jī)制

聯(lián)機(jī)版的主機(jī),就和單機(jī)版一樣,有著幾乎所有的prefab,component,stategraph和brain。但在客機(jī)上,prefab依然存在,但它們只會運(yùn)行其中一小部分代碼(在TheWorld.ismastersim的判斷塊之前的代碼)。這一小部分代碼,只會給prefab添加少量與界面交互有關(guān)的組件,比如動畫、圖片或者文字表現(xiàn),或者是直接關(guān)系者游戲操作的,比如:talker,transparentonsanity,playercontroller, 和playeractionpicker。brain和stategraph都只存在于主機(jī)上。相應(yīng)的,為了使得大多數(shù)組件也能在客機(jī)上流程地運(yùn)轉(zhuǎn),游戲在客機(jī)上使用了replica和classified(為什么不直接使用組件?因?yàn)檫@會造成數(shù)據(jù)的歧義性。比如說一個(gè)人物,吃了食物之后,會加飽食度。吃東西這個(gè)行為是發(fā)生在客機(jī)上的,如果客機(jī)有Hunger組件,那么調(diào)用客機(jī)的hunger組件,增加飽食度,那么在客機(jī)上,這個(gè)人物的飽食就變化了,但主機(jī)上的飽食并沒有變化,兩者的數(shù)據(jù)就不一致了。為了解決這個(gè)問題,就需要把數(shù)據(jù)都放在主機(jī)上,客機(jī)只負(fù)責(zé)接收來自主機(jī)的更新數(shù)據(jù)。)

主客機(jī)之間的數(shù)據(jù)交換,則是通過一個(gè)雙重系統(tǒng)——remote procedure call(RPC)和netvar來操作??蜋C(jī)通過發(fā)送RPC碼向主機(jī)發(fā)出要求。主機(jī)則改變netvar的值來向客機(jī)傳遞數(shù)據(jù)(大多數(shù)被儲存在了classified中)

Replica

Replica是component的副件,與component不同,不管是主機(jī)還客機(jī),replica都是必定會存在的,replica的主要用途就是幫助客機(jī)玩家流暢地完成原本component要完成的操作,但這些操作通常都只是游戲界面的變化,比如說播放動畫,顯示文字之類的,較少涉及到與主機(jī)的數(shù)據(jù)交換(數(shù)據(jù)交換的工作,主要由classified完成)。在主機(jī)中調(diào)用component的函數(shù),如果在replica中存在同名函數(shù),也會被同時(shí)調(diào)用。利用這個(gè)特性,可以在同名函數(shù)的方法體中。對主機(jī),執(zhí)行更新客機(jī)數(shù)據(jù)的代碼,對客機(jī),執(zhí)行動畫之類的操作(如果有必要的話)。(對主客機(jī)執(zhí)行不同的代碼,可以用上面提到的TheWorld.ismastersim這個(gè)變量來區(qū)分,或者用TheNet:IsServer()這個(gè)函數(shù)。)

如果你想為自己自定義的新組件設(shè)置replica的話,只需要兩步便可完成。
1、在components文件夾下,新建一個(gè)文件,文件名為"組件名_replica.lua",文件里的定義格式同一般的組件,內(nèi)容則自行決定。
2、在modmain中,添加一行代碼AddReplicableComponent("組件名")
這樣一來,你便有了一個(gè)自定義的replica。
具體的實(shí)例,請參看我的聯(lián)機(jī)版samansha,里面有一個(gè)sa_car的replica。如果覺得看不懂,可以在評論區(qū)回復(fù),我會考慮專門寫一個(gè)教學(xué)用的實(shí)例mod。

Netvar&Classified

Classified和netvar的聯(lián)系非常緊密,要解釋Classified就需要解釋netvar,這里就一并講了。

Netvar,正如其名,是網(wǎng)絡(luò)變量的意思。Netvar是官方設(shè)計(jì)用來從主機(jī)向客機(jī)傳遞數(shù)據(jù)的一組數(shù)據(jù)類型,它們的定義和用法,在netvar.lua里有官方的說明。官方也寫過一個(gè)教程并配上了相應(yīng)的示例MOD。不過我覺得官方寫得并不夠清晰,讓我當(dāng)初學(xué)習(xí)的時(shí)候走了不少彎路。這里按照我自己的理解來寫一下,希望能幫到各位讀者。

  1. 聲明網(wǎng)絡(luò)變量
    對于有C或java之類強(qiáng)類型語言基礎(chǔ)的讀者來說,都很清楚聲明變量時(shí)必須要聲明數(shù)據(jù)類型。netvar也一樣。netvar有多種數(shù)據(jù)類型以供不同規(guī)模的數(shù)據(jù)傳輸需要,比如net_bool-1位(true,false),net_tinybyte-3位(0-7)等等,具體可以在netvar中查到。在實(shí)際使用中,為了節(jié)約帶寬,我們應(yīng)當(dāng)盡量選小數(shù)據(jù)類型來用。聲明一個(gè)網(wǎng)絡(luò)變量的格式為:ReferenceName = NetvarType(entity.GUID, "UniqueName", "DirtyEvent" 。ReferenceName是引用名,NetvarType就是網(wǎng)絡(luò)變量的數(shù)據(jù)類型,entity.GUID就是這個(gè)網(wǎng)絡(luò)變量要依附的entity的GUID,一般來說,這個(gè)網(wǎng)絡(luò)變量是誰的,就依附誰。比如說你把這個(gè)網(wǎng)絡(luò)變量寫在了一個(gè)人物的初始化函數(shù)里,那么這個(gè)entiy就是inst。UniqueName是唯一名,只需要保證你的網(wǎng)絡(luò)變量不與其它網(wǎng)絡(luò)變量重名就行,DirtyEvent是當(dāng)這個(gè)網(wǎng)絡(luò)變量的數(shù)據(jù)發(fā)生改變時(shí),會觸發(fā)的事件,一般稱為這個(gè)網(wǎng)絡(luò)變量的dirty事件。Dirty事件會在主機(jī)和客機(jī)上都觸發(fā),客機(jī)可以利用這一個(gè)事件來改變HUD的狀態(tài),對做自定義的UI非常有用。

一個(gè)示例:inst.level = net_smallbyte(inst.GUID,"MyLevel","leveldirty")

另外,網(wǎng)絡(luò)變量必須要在主機(jī)和客機(jī)中都有聲明,也就是說,如果你想給人物添加一個(gè)網(wǎng)絡(luò)變量,必須要寫在common_init函數(shù)里。寫在其它prefab里,則要在TheWorld.ismastersim的判斷語句塊之前寫。如果要寫在組件里,則必須要保證組件也在客機(jī)上存在(否則你應(yīng)該寫在replica里)。

  1. 使用網(wǎng)絡(luò)變量
    網(wǎng)絡(luò)變量不可直接賦值,也不可直接讀取,需要調(diào)用函數(shù)來完成。有三個(gè)函數(shù)可以用,分別是set,value和set_local,具體用法如下,
 netvar:set(x)--只能在主機(jī)端調(diào)用這個(gè)函數(shù),會自動同步客機(jī)的數(shù)據(jù)(在一個(gè)新的同步周期開始時(shí))。如果這個(gè)函數(shù)確實(shí)改變了netvar的值,會在主機(jī)和客機(jī)上都觸發(fā)相應(yīng)的dirty事件。
 netvar:value()--可以在主機(jī)和客機(jī)上調(diào)用這個(gè)函數(shù),讀取當(dāng)前網(wǎng)絡(luò)變量的值。

  netvar:set_local(x)--可以在主機(jī)或客機(jī)上調(diào)用,改變相應(yīng)的值但不觸發(fā)數(shù)據(jù)同步或dirty事件。但當(dāng)主機(jī)下一次調(diào)用set函數(shù)時(shí),無論變量的值是否發(fā)生了改變,都會同步一次數(shù)據(jù)。

同樣的,我的聯(lián)機(jī)版samansha也包含了網(wǎng)絡(luò)變量,仍然是那個(gè)sa_car組件及其replica。我主要用到的是dirty事件,對于數(shù)據(jù)傳輸,因?yàn)闆]有使用需求,就沒有寫。不過我會考慮以后加上一個(gè)示例的MOD。

Netvar就講解這么多。下面簡單來說一下Classified。Classified,實(shí)質(zhì)上是一個(gè)prefab。這個(gè)prefab,根據(jù)使用的需求,打包了一些聯(lián)系比較緊密的網(wǎng)絡(luò)變量,并為他們設(shè)置一些共用的函數(shù),以方便被調(diào)用(主要是被replica調(diào)用)。Classified有好幾個(gè),和人物聯(lián)系緊密的是player_classified,其中包含了關(guān)聯(lián)著饑餓、精神、血量等變量的網(wǎng)絡(luò)變量。這里不詳細(xì)展開。對于Classified,主要的用途是,當(dāng)我們想讓客機(jī)獲取諸如饑餓之類的屬性,進(jìn)行一些與主機(jī)無關(guān)的操作時(shí),去調(diào)取player_classified里的關(guān)聯(lián)hunger的網(wǎng)絡(luò)變量。但實(shí)際上這個(gè)應(yīng)用的范圍很小,因?yàn)橐玫綌?shù)據(jù),又與主機(jī)無關(guān)的,一般就剩下控制HUD表現(xiàn)了。大多數(shù)時(shí)候,我們想要的是,在客機(jī)上,呼叫主機(jī)執(zhí)行某一段代碼。比如說呼叫主機(jī)讓hunger減少50點(diǎn)。這個(gè)就屬于客機(jī)向主機(jī)發(fā)起溝通的范疇了,而這就需要使用RPC。

RPC

RPC是Remote Procedure Call的縮寫,意思就是遠(yuǎn)程程序調(diào)用。這里不需要了解其內(nèi)在機(jī)理。只需要知道它是客機(jī)用來向主機(jī)發(fā)送執(zhí)行代碼信號的工具就行了。重點(diǎn)在于學(xué)習(xí)如何使用它。

RPC是不能隨意發(fā)送整一段的代碼給主機(jī)的,它只能發(fā)送一條簡短的RPC消息,然后主機(jī)根據(jù)這條消息,尋找相應(yīng)的RPC處理器,如果找得到的話,就會執(zhí)行處理器預(yù)先設(shè)置的代碼塊。所以,我們想要使用RPC,就需要先(在主機(jī))用AddModRPCHandler函數(shù)添加一個(gè)RPC處理器,然后在需要的時(shí)候,執(zhí)行SendModRPCToServer來發(fā)送一條RPC消息給主機(jī)。
我們通過一個(gè)例子來學(xué)習(xí):

local function GrowGiant(player)    
    player.Transform:SetScale(2,2,2)
end
AddModRPCHandler(modname, RPCname, GrowGiant)--添加RPC處理器,這個(gè)語句可以寫在任何會被主機(jī)執(zhí)行到的地方。三個(gè)參數(shù),第一個(gè)為命名空間的名字,建議寫mod的名字;第二個(gè)參數(shù)為RPC的名字,必須是唯一的,如果有同名的,就會根據(jù)先后順序,被后面的覆蓋。這兩個(gè)參數(shù)都必須是字符串。第三個(gè)參數(shù)則是要執(zhí)行的函數(shù),這個(gè)函數(shù)的第一個(gè)參數(shù)固定為玩家的引用,這里的玩家,指的是執(zhí)行下面的Send

local function SendGrowGiantRPC()   
    SendModRPCToServer(MOD_RPC[modname]["RPCname"])--[[向主機(jī)發(fā)送RPC消息,第一個(gè)參數(shù)為MOD_RPC[modname]["RPCname"],MOD_RPC是不能修改的,后面的modname,RPCname就和上面的意思是一樣的。另外,這個(gè)函數(shù)可以傳入更多的參數(shù),只要寫在第一個(gè)參數(shù)后面就行。這些參數(shù)講會被上面的AddModRPCHandler里的執(zhí)行函數(shù)接收到。在某些時(shí)候會非常有用。
end
GLOBAL.TheInput:AddKeyDownHandler(118, SendGrowGiantRPC)--按v鍵執(zhí)行上面定義的SendGrowGiantRPC函數(shù)。除了這里通過按鍵來觸發(fā)外,我們還可以根據(jù)情況,靈活調(diào)用SendModRPCToServer來達(dá)到不同的目的。

同樣的,我的聯(lián)機(jī)版samansha的sa_car組件,也展示了改如何使用RPC,也是可以參考的對象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這一章講解Prefab。Prefab是饑荒世界構(gòu)成的基礎(chǔ),也是Mod技術(shù)的基本內(nèi)容。 Prefab,中文譯名叫預(yù)制...
    LongFei_aot閱讀 16,825評論 6 40
  • 這篇文章將闡述如何讓你的函數(shù)能夠在自己設(shè)置的限定條件下,通過外部輸入(主要是鼠標(biāo))來觸發(fā)執(zhí)行。 對于很多有了一定M...
    LongFei_aot閱讀 5,645評論 0 17
  • 這個(gè)系列教程很長,涉及到很多編程、游戲方面的概念。與其讓你云里霧里地看著看著就放棄,不如先教你如何快速入門,通過模...
    LongFei_aot閱讀 13,742評論 9 77
  • 本章的目的是為了幫助你了解Mod知識的全貌,把握學(xué)習(xí)的節(jié)奏。如果你急著學(xué)習(xí)更多的技術(shù)知識,可以先跳過本章,不會影響...
    LongFei_aot閱讀 4,241評論 3 27
  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 4,100評論 0 9

友情鏈接更多精彩內(nèi)容