不過解決辦法還是很簡單的,我在此處加了個斷點(我怎麼也沒想到這將是我倒數第二次用它)並監視direction的值後發現值有這幾種可能:-1,-0.7,0,0.7,1。我們利用這個值更改scale進行轉身,所以加個三元表達式把值控制在兩種可能就行了
接下來就到了這期的正式內容。這期的代碼我斷斷續續寫了三個星期,然後一半都沒完成
(其實是我菜)
所以完整的內容我可能會分兩期,而且這期還有別的新玩意(儘量完整復原一個正常人是怎麼寫代碼寫崩潰的=(
首先要請出我們的老朋友,來自 橘白 的房間素材(鐵打的素材流水的系列)。不過這次我們要隨機房間大小,所以要把這張圖片切成幾塊不重複的sprite
《不重複》
艹我不知道怎麼切,我想把重複的刪掉或者不切出來,網上搜不到我也不會······不過無傷大雅
切完之後我打算分析原版的地牢生成規律。我一開始的猜測是每個關卡都是模版,因為基本上游戲玩多了可以發現地圖房間的分佈大概率就那幾種,而且有的時候可以猜到哪邊通往傳送門房。於是我在網上找到了各種各樣的相關小圖,把它們一個一個抄下來
分析個鬼啊,我越抄心裡越疑惑,怎麼它們看著那麼像但其實根本就沒有重複的呢?要麼連接的通道不一樣,要麼特殊房間的位置不同,要麼房間的擺放不一樣······於是我毅然決然,決定《完全》靠自己寫一個地牢隨機生成算法
“得先把一個房間生成出來再考慮一堆房間。”我的心裡其實早就盤算好了,就用tilemap。
我學習的unity教程是2016年的,所以當我自信滿滿地打開菜單時,我意識到時代變了。“Assets-Create-2D-Tile···s?這些都是什麼玩意啊?”
(真實情況:由於幾個月沒碰過tilemap了,所以我先去瀏覽器上搜了一下tile在哪裡創建(⌒-⌒; )
不過你永遠可以相信官方文檔。粗略看了一眼後,我決定使用ruletile(其他的要麼看起來更高級不像是我一下子能學會的,要麼根本看不懂)
一個新建的ruletile長這樣
Default sprite是一個tile的默認樣子(到後面我就發現基本一點用沒有)
default gameobject/collider:官方新手教程說先別理它。官方說的我還能不聽?
重點是這個number of tiling rule。直譯就是平鋪tile的規則數。我就跟著教程照葫蘆畫瓢地做了
做著做著就懂了(也許吧),因為一個房間它是四四方方的,除了外面那層圍牆裡面都是地板磚(樣式可能不同)。這裡的箭頭和叉指的就是tile的可能發散方向。箭頭表示可以繼續向周圍發散,叉表示當前這塊就是邊緣了。邊上的tile在自己所在的方向上無法發散,角上的tile兩邊都無法繼續發散
現在可以在tile palette上畫一下。這比我之前學的智能多了,tile會根據周圍tile的變化自動變換,而以前是需要手動切換使用的tile的
點擊鏈接觀看視頻“這樣在代碼生成階段我就可以不用判斷外圍了!這麼簡單一天不就寫得出來?”這就是噩夢開始的地方
我之前就說過我想在這個系列儘量寫出高質量的代碼,所以關於素材的引用,我不想直接在inspector面板開個引用,然後把tile拖進去。我覺得這樣之後萬一要增加素材或者怎麼樣的不方便(現在我只想抽我自己,哪裡不方便了?)
“我考慮下素材放哪······”我本來想放到resources裡的,以前也是這麼學的。
但是我忘了啊!我又去瀏覽器搜,然後發現官方說不推薦使用resources,說是佔內存而且會增加啟動時間,且無法進行熱更新。
關我啥事啊,我是電腦,不缺這點內存,而且熱更新跟我一點關係都沒有。我就頭鐵地繼續使用resources+textasset路徑配置文件,並且決定使用UWR(Unity web request,之前的www被棄用了)進行素材的加載
事實證明編程是“面向瀏覽器”,我壓根就不會UWR,就去網上找了一段常用代碼測試一下
我還沒測出個名堂來,unity突然罷工了。之後我只要一運行上面這段“死亡代碼”,我的unity就立刻崩潰,一個下午崩了五六次
我妥協了。不僅僅是因為這個,我的VS2019它突然沒提示了什麼鬼啊?所有根unity有關的API它就裝作不認識,根本就不理我
(人崩潰的第一步)
最後不知道怎麼就修好了。我尋思著就不用UWR了,直接Resources.LoadAll,後面再優化
我@&*#¥*&@¥%,為什麼不行???
我也不知道為啥,怎麼樣都加載不出來,網上也查不到解決辦法,我就這麼被迫地使用了更為複雜的assetbundle
首先我又去了官網查assetbundle的用法,找到了這麼一個腳本,一鍵打包所有指定了標籤的assetbundle
指定的標籤必須是小寫(是大寫unity也給你掰回小寫),並建以.assetbundle或.unity3d結尾
最開始我沒有把打包完成的assetbundle放到streamingAssets路徑下,所以沒辦法加載出assetBundle。那麼我怎麼知道的呢?出bug了當然是用斷點對吧?
這個斷點不給我綁就過分了啊!現在我基本上已經失去高質量代碼的夢想,只想早點收工。於是我用了笨方法找bug
結果又多報了三個錯。報錯正常啊(咬牙切齒),但是這些腳本我壓根就沒寫過啊?
(如果你們的unity也這樣抽風,不要理它,該怎麼樣怎麼樣,後面它自己就消失了)
最後寫了個工具類幫助加載資源和配置文件
(說實話我應該把它換個名字,現在已有的方法全部跟assetbundle有關)
當第一塊瓦片出現在屏幕上的時候,兩個星期的時間跨度讓我恍惚著以為已經結束了。實際上差遠了!我已經可以預料到這個系列結束時我總結什麼了(剛開始就想著結束的屑)
我把地圖生成器拆分成兩個部分:template和decorator。template兩者都有頂層的抽象接口進行統一,template負責整個地圖的生成,decorator是單個房間的裝飾。(decorator下期再寫了,沒素材,或許我可以去網上找點)可能有點狀態模式或者策略模式(兩者我不太分得清),再或者橋接模式(這個完全不懂,不要聽我胡說)的味道?當然由於趕著收工,我沒怎麼規劃代碼,後面再考慮重構吧,而且我確實沒什麼經驗,也不知道怎麼寫比較好
levelTemplate的頂層抽象接口我也寫得很拉垮,因為不知道還有什麼其他的模版所以不知道怎麼提取公有方法和字段。所以就寫了一大堆,一邊寫一邊吐槽“這什麼玩意啊?怎麼是這樣的啊?”
(不要理那個GenerateRoad,這期沒用,而且亂寫的)
就這些破東西我就寫了一天,而且一大半還是註釋。到這裡還好,下面才是真正的絕望
我看了很多關於元氣的地牢生成算法,發現它們都沒有讓過道的長度都是一致的。所以不能複製粘貼(不是,是借鑑ᶘ ᵒᴥᵒᶅ)了。不過我倒是學到了幾個有用的思路:
1.隨機遊走算法(超簡易版),也就是拿一個點,讓它自己亂走,走過的路徑生成一個房間。要解決路徑重複的問題
2.房間寬和高最好是奇數,方便把遊走點放到正中央
······沒了,因為我剩下的懶得看了,很多都過於複雜或者要碰撞體或者預製體,我一個都不知道怎麼做,搜也搜不到。“自己······寫?”被現實敲打過的我已經在半懵半絕望的狀態了
接下來這套半完成的算法耗費了我兩天的腦細胞(真的就是對著電腦坐了將近兩天),但是更拉垮了,回到了上個系列的水平(低情商:就TM亂寫)
這幾百行代碼前前後後憋了我好幾天,今天終於寫完了。看著也不復雜怎麼我就寫了這麼久呢?中間由於沒有斷點我只能一個一個debug.log判斷哪裡出了問題。結果最後還是有bug(經典留下一期,我估計下一期就沒有什麼別的內容了)
點擊鏈接觀看視頻我就用笨方法刷新了,真的懶得上網查那種編輯器拓展了(體內的擺爛基因開始發作),大家可以查一下方便測試
最後的bug是並不是所有的房間的間隔都一致。而且由於算法的缺陷,想要在兩個房間中間添加過道的話基本只有一條遊走點經過的路徑,跟原版不符。而且出生房和傳送房必須是最遠路徑且單一過道。這個可能還要再來個算法(被初中數學殺幾百回的我還不給算法打成渣?)
在查微軟官方文檔時(沒錯我連C#的語法也忘了),發現了很多我之前沒學過的中高級語法。可能還要找時間全部看一遍(還好有中文,要是英文我真的就想毀滅了)
好了就這樣了。我也不知道下期是多久以後了。所以明年見!
(這期寫得奔放了點,人已經麻上加麻了)
來個首尾呼應(也不算太首)。總結:不要學編程