歡迎你來閱讀本篇自訂方塊教學!Minecraft是由無窮無盡的方塊所組成的,因此在遊戲模組以及地圖製作中,將難免遇到各種各樣新的方塊需求。本篇教學將帶你入門基岩版自訂方塊,了解如何在基岩版加入一個富有特色的方塊。
在閱讀本篇教學之前,請確保你已經能夠建立一個行為包和資源包,若還不能,請先閱讀開始之前;包的構建;執行、除錯與匯出頁面以學習行為包的基礎製作。此外,為簡化本篇的篇幅,請先提前閱讀Tutorial:製作附加包/物品以熟悉自訂內容的一些必要工具和思路。本教學將假設你已經了解了自訂物品的製作方法。
引言[編輯]
不同版本之間的差異[編輯]
自訂方塊亦有三個分水嶺版本存在:
1.10
,加入了對自訂方塊的支援;1.16.100
,加入了非常多全新的方塊元件,然而它們都是實驗性的;1.19.X
,令一些實用的方塊走出了實驗性玩法,並加入了一些新特性。
請按照自己的需求選擇需要的版本。我們推薦你使用穩定的版本和穩定的方塊元件,1.19.70之後的元件已趨於穩定。
1.10至1.16.100的自訂方塊編寫[編輯]
你需要首先建立一個行為包和資源包,建立方法不過多贅述。
行為包部分[編輯]
在行為包目錄下,建立一個名為blocks
的資料夾,並在該資料夾下建立一個檔案my_custom_block.block.json
。你可以看到,這步驟和自訂物品是大同小異的。
- 行為包名稱或其內部ID
- blocks
- my_custom_block.block.json
- manifest.json
- pack_icon.png
- blocks
我們也可以照葫蘆畫瓢地給出一個最基礎的自訂方塊的定義:
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "test:my_custom_block"
}
}
}
相信如果你已經學會了自訂物品的話,理解這段程式碼對你來說應該不是什麼難事。這裡需要指出的一點是,Mojang在1.15時曾對方塊元件做出過更新並修改了方塊元件所能接受的值。本教學基於1.16.0。如果你需要1.15以前的寫法可以參考以下內容:
現在我們不妨直入主題來為我們的方塊加入自訂元件吧!當然,舊版本的自訂方塊的元件也非常的少,但你已經可以用它們來實現最基礎的效果了。舊版本的方塊元件有以下幾個可用:
minecraft:destroy_time
- 指定破壞時間。minecraft:block_light_absorption
- 指定方塊減弱的光照強度。minecraft:block_light_emission
- 指定方塊發出的光照強度。minecraft:explosion_resistance
- 指定方塊的爆炸抗性。minecraft:friction
- 指定方塊的摩擦力。minecraft:loot
- 指定方塊的掉落物。minecraft:map_color
- 指定方塊在地圖上顯示的顏色。
例如,如果我們希望自訂方塊的光照等級是15,並且在被挖掉之後掉落釣魚的戰利品,我們可以寫成:
{
"format_version": "1.16.0",
"minecraft:block": {
"description": {
"identifier": "test:my_custom_block"
},
"components": {
"minecraft:block_light_emission": 1.0, // 旧版本下该值的范围为0.0-1.0
"minecraft:loot": "loot_tables/gameplay/fishing.json"
}
}
}
以下是這段程式碼的解釋:
minecraft:block_light_emission
:方塊光照強度,它支援一個0.0-1.0
的浮點數,值越大則光照越強。minecraft:loot
:戰利品表,當該方塊被挖掘後,呼叫其指定的戰利品表。
資源包部分[編輯]
自訂方塊的資源包部分比較複雜。你可能需要以下檔案(即粗體部分),請先提前建立:
- 資源包名稱或其內部ID
- texts
- en_US.lang
- zh_CN.lang
- textures
- blocks
- (方塊貼圖1).png
- (方塊貼圖2).png
- ...
- terrain_texture.json(連結短ID和貼圖)
- flipbook_textures.json(當你需要一個要涉及到動態貼圖的方塊時建立,例如海燈籠)
- blocks
- blocks.json(連結ID和短ID)
- manifest.json
- pack_icon.png
- texts
blocks.json[編輯]
我們先從blocks.json
入手。需要注意一點,自訂方塊有三種顯示模式:六面全同、分頂面底面和側面、分頂底東西南北。舉兩個簡單的例子,我們知道泥土六個面是完全一樣的,這是利用了最簡單的六面全同模式;草地的頂面是綠色的草貼圖,底面是泥土貼圖,而側面是覆蓋了一層草的貼圖,這就是分頂底側面。在入手之前請先想好自己的方塊應該是什麼樣的,再動手。下面是blocks.json
的基本格式和三個模式的方塊指定方法:
{
"方块ID": { "textures": "短ID", "sound": "音效" }, // 六面全同
"方块ID": { "textures": { "down": "短ID1", "side": "短ID2", "up": "短ID3" }, "sound": "音效" }, // 分顶底侧面
"方块ID": { "textures": { "down": "短ID1", "up": "短ID2", "north": "短ID3", "south": "短ID4", "west": "短ID5", "east": "短ID6" }, "sound": "音效" } // 分顶底东西南北
}
其中音效可以是原版的方塊音效,在被放置、被踩踏以及被破壞後將播放對應方塊的音效,你可以檢視原版的blocks.json
來檢視有哪些內容是能夠允許的。以下是幾種比較常用的音效:
stone
:石頭質音效(例如石頭、混凝土);glass
:玻璃質音效(例如玻璃、螢光石);gravel
:泥質音效(例如泥土、礫石);wood
:木質音效(例如木材、木塊);cloth
:布質音效(例如羊毛、地毯);grass
:草質音效(例如草地、樹葉);metal
:金屬質音效(例如鐵方塊、黃金方塊)。
舉個例子,如果我希望加入一種新的木材,它應該是六面全同,使用木質音效的,因此可以寫為:
{
"test:my_custom_block": { "textures": "my_custom_block", "sound": "wood" }
}
terrain_texture.json[編輯]
接著我們來看terrain_texture.json
。我們在blocks.json
中指定了短ID,該檔案就是將短ID和實際的貼圖檔案連結起來的。假設我們已經在textures/blocks
資料夾裡面放入了一個my_custom_planks.png
的檔案,我們便可以如此指代:
{
"resource_pack_name": "vanilla",
"texture_name": "atlas.terrain",
"padding": 8,
"num_mip_levels": 4,
"texture_data": {
"my_custom_block": { "textures": [ "textures/blocks/my_custom_planks" ] },
"短ID": { "textures": [ "贴图路径" ] },
...
}
}
其中前4行是什麼你並不需要關心,你需要關心的只是其中的texture_data
。它的一般格式也在上面的程式碼中提出,你可以看到短ID就是如此連結到實際貼圖的。
動態貼圖[編輯]
本段落仍需完善。 |
如果你的方塊需要用到動態貼圖,你可能需要用到flipbook_texture.json
。動態貼圖的用法可自行參考原版寫法。
翻譯文字[編輯]
和自訂物品類似,你也需要一個翻譯檔案來指定它們顯示出的名字。開啟en_US.lang
,輸入以下內容:
tile.test:my_custom_block.name=My Custom Block
如你所見,方塊的翻譯文字格式為tile.方块ID.name
。同理地,在zh_CN.lang
輸入以下內容:
tile.test:my_custom_block.name=我的自定义方块
至此,你的方塊編寫就大功告成啦!當然了,本教學也會介紹新版本元件的簡單應用,詳見下文。
1.19.60及更高版本的自訂方塊編寫[編輯]
行為包部分[編輯]
1.19.60版本後又進一步的開放了部分元件。和高版本物品元件是幾乎全新不同,高版本的方塊元件是基於低版本元件的。1.19.60之後有下列元件可以不開啟實驗性玩法使用:
minecraft:geometry
- 指定方塊模型。minecraft:material_instances
- 將模型檔案中的面或繪製映射到實際的紋理。minecraft:collision_box
- 指定方塊的碰撞箱。minecraft:crafting_table
- 設定與方塊互動時開啟一個合成介面。minecraft:display_name
- 指定方塊的名稱。minecraft:placement_filter
- 設定方塊被放置時應滿足的條件。minecraft:selection_box
- 指定方塊的擊中箱。
同時,舊版元件大多數都經過了重新命名,這裡不再詳述。
資源包部分[編輯]
高版本方塊的流程和低版本方塊的流程可以說是幾乎完全相同的。但特別地,當你指定了minecraft:material_instance
的texture
參數時,寫法可能會有一些小變化。在下面的範例中你就可以知道了。
方塊狀態的設定[編輯]
方塊狀態(Block States)是指定方塊所處狀態的一種重要手段,例如半磚是上半磚還是下半磚、羊毛的顏色、按鈕的朝向等等,這些方塊都有相同的ID,但是它們所處的狀態不一樣。在自訂方塊中你可以利用description
中的states
指定方塊所處的方塊狀態,並利用permutations
來另行指代不同方塊狀態下採用的不同元件。以下是微軟文件中給出的一個方塊狀態與置換的範例:
{
"format_version": "1.19.40",
"minecraft:block": {
"description": {
"identifier": "custom:lamp_block",
"states": {
"custom:is_lit": [ true, false ]
}
},
"permutations": [
{
"condition": "query.block_state('custom:is_lit') == true",
"components": {
"minecraft:light_emission": 15
}
},
{
"condition": "query.block_state('custom:is_lit') == false",
"components": {
"minecraft:light_emission": 0
}
}
],
"components": {
"minecraft:friction": 0.6,
"minecraft:map_color": "#00ff00"
}
}
}
對這段程式碼做一些必要的解釋:
states
:方塊狀態,指定方塊可能具有的狀態。在這裡,該方塊被指定了具有custom:is_lit
的方塊狀態,並支援兩個值,分別為true
和false
。permutations
:方塊置換,指定在滿足特定的條件(condition
)下該方塊所具有的元件。我們可以看到,condition
的檢測條件為query.block_state('custom:is_lit') == true
,這是用於檢測該方塊所處狀態的Molang,當custom:is_lit
方塊狀態為true
時將使用元件"minecraft:light_emission": 15
,即光照亮度為15級。下面的條目也是同理的。components
:方塊元件,指定方塊所具有的通用特性。
你可以使用指令/setblock
或/fill
來放置這些具有自訂特性的方塊。
關於方塊狀態和置換,你可以檢視更加詳細的微軟文件。
方塊性狀的設定[編輯]
一些範例[編輯]
無法被破壞和炸毀的泥土[編輯]
如果你希望泥土不再能被破壞,何不以假亂真來做一個新方塊呢?請記住,原版物品和方塊都是不能變更的,因此如果你希望變更原版方塊,請立即放棄這種想法,自己做個新方塊才是更好的選擇。
要實現這點很簡單,我們的核心要素在於「無法破壞」和「無法炸毀」兩點,這分別可以用minecraft:destructible_by_mining
和minecraft:destructible_by_explosion
來解決。因此可以用下面的行為包程式碼:
- 行為包/blocks/dirt.block.json
{
"format_version": "1.19.40",
"minecraft:block": {
"description": {
"identifier": "wiki:dirt"
},
"components": {
"minecraft:destructible_by_explosion": false,
"minecraft:destructible_by_mining": false
}
}
}
資源包方面,我們可以偷個懶,直接呼叫原版的方塊路徑:
- 資源包/blocks.json
{
"wiki:dirt": { "textures": "dirt", "sound": "gravel" }
}
可以呼叫原版的貼圖有一個條件,就是原版的這個對應短ID不能連結到多個紋理,一旦連結到有多個紋理的短ID,就會出現紫黑塊貼圖錯誤。如果不能直接偷懶用原版的短ID,就需要再用terrain_texture.json
來連結到貼圖上(當然這個貼圖也是可以直接連結原版的)。最後搞定翻譯即可:
- 資源包/texts/en_US.lang
tile.wiki:dirt.name=Dirt
- 資源包/texts/zh_CN.lang
tile.wiki:dirt.name=泥土
然後,你就可以獲得一個以假亂真,但是怎麼炸也炸不壞的泥土了!
會發光的玻璃[編輯]
想不想要一種可以自發光的玻璃?我們當然可以實現!想想玻璃的一些需求要素:
- 透明,這可以用
minecraft:material_instance
來實現; - 無掉落物,這可以用
minecraft:loot
掉落一個空的戰利品表來實現; - 發光,這可以用
minecraft:light_emission
來實現; - 還原玻璃的硬度(0.3)和爆炸抗性(0.3),用
minecraft:destructible_by_mining
和minecraft:destructible_by_explosion
來實現。
因此,行為包程式碼也就呼之欲出了。
- 行為包/blocks/glass.block.json
{
"format_version": "1.19.40",
"minecraft:block": {
"description": {
"identifier": "wiki:scene_block_glass"
},
"components": {
"minecraft:material_instances": { "*": { "render_method": "blend" } },
"minecraft:destructible_by_explosion": { "explosion_resistance": 0.3 },
"minecraft:destructible_by_mining": { "seconds_to_destroy": 0.3 },
"minecraft:light_dampening": 0,
"minecraft:light_emission": 15,
"minecraft:loot": "loot_tables/empty.json"
}
}
}
一些基本解釋:
minecraft:material_instance
:令方塊為透明繪製。*
代表所有面都按照透明的方式繪製。minecraft:light_dampening
:對於透明繪製的方塊而言,如果不設定這個值,它本質上是不透明方塊,一是會導致草地的變化,二是會導致方塊與方塊之間在底面出現很重的陰影,對於「發光玻璃」而言,這並不是我們希望的結果。
資源包不做過多解釋,這是很簡單的。
能貫穿又摸不到的假方塊[編輯]
假方塊!在很久以前,基岩版的按鈕錯誤導致其在某個特殊值下會顯示為整個方塊,而其又沒有碰撞箱,是可以穿過的,因此稱之為假方塊。雖然這是一個錯誤,但今天我們卻能實打實的做一個真正的假方塊出來了!要想實現假方塊,我們只需要考慮碰撞箱和擊中箱的問題。這可以利用minecraft:collision_box
和minecraft:selection_box
來解決。我們只需要完全取消掉它的碰撞箱,就可以讓它是可被穿過的:
- 行為包/blocks/fake_oak_planks.block.json
{
"format_version": "1.19.60",
"minecraft:block": {
"description": {
"identifier": "wiki:fake_oak_planks"
},
"components": {
"minecraft:collision_box": false
}
}
}
這將停用它的碰撞箱,成為可穿過的方塊;而如果再引入一個擊中箱:
- 行為包/blocks/fake_oak_planks.block.json
{
"format_version": "1.19.60",
"minecraft:block": {
"description": {
"identifier": "wiki:fake_oak_planks"
},
"components": {
"minecraft:collision_box": false,
"minecraft:selection_box": false
}
}
}
這甚至會讓玩家無法選中這個方塊(包括創造模式玩家)!如果放到了錯誤的地方,你就需要用/setblock
來解決啦。
自訂半磚[編輯]
假設我們在抗爆泥土上再進一步,要實現不可破壞的半磚,顯然這是一種不完整方塊。對於半磚,我們需要考慮以下幾點:
- 方塊不是完整方塊,必須使用特定的方塊模型。方塊模型需要在Blockbench裡自行繪製,假設我們現在已經擁有了
geometry.slab_up
和geometry.slab_down
兩個模型。指定模型可以由minecraft:geometry
來承擔。 - 其碰撞箱和擊中箱都必須是普通方塊的一半;
- 因為呼叫了自訂模型,這個方塊的面的表達已經不再能用普通的三種情況來代替,必須使用
minecraft:material_instance
來選擇性地指定面的貼圖。
基於這樣的考慮,我們給出以下參考程式碼:
- 行為包/blocks/cobblestone_slab_up.block.json
{
"format_version": "1.19.60",
"minecraft:block": {
"description": {
"identifier": "wiki:cobblestone_slab_up"
},
"components": {
"minecraft:destructible_by_explosion": false,
"minecraft:destructible_by_mining": false,
"minecraft:collision_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
"minecraft:selection_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
"minecraft:geometry": { "identifier": "geometry.slab_up" },
"minecraft:material_instances": { "*": { "texture": "cobblestone" } }
}
}
}
關於碰撞箱和選擇箱的寫法,見對應條目。如果我們需要把兩種半磚合在一起寫,就可以利用前面的方塊狀態的設定的內容來合併:
- 行為包/blocks/cobblestone_slab.block.json
{
"format_version": "1.19.70",
"minecraft:block": {
"description": {
"identifier": "wiki:cobblestone_slab",
"states": { "vertical_half": [ "top", "bottom" ] }
},
"components": {
"minecraft:destructible_by_explosion": false,
"minecraft:destructible_by_mining": false,
"minecraft:material_instances": { "*": { "texture": "cobblestone" } }
},
"permutations": [
{
"condition": "query.block_state('vertical_half') == 'top'",
"components": {
"minecraft:collision_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
"minecraft:selection_box": { "origin": [ -8, 8, -8 ], "size": [ 16, 8, 16 ] },
"minecraft:geometry": { "identifier": "geometry.slab_up" }
}
},
{
"condition": "query.block_state('vertical_half') == 'bottom'",
"components": {
"minecraft:collision_box": { "origin": [ -8, 0, -8 ], "size": [ 16, 8, 16 ] },
"minecraft:selection_box": { "origin": [ -8, 0, -8 ], "size": [ 16, 8, 16 ] },
"minecraft:geometry": { "identifier": "geometry.slab_down" }
}
}
]
}
}
最後利用/setblock
等指令對方塊狀態進行控制。是不是很有意思?
關於資源包的問題,事實上你看到了minecraft:material_instances
這個元件指定了texture
,這其實就是blocks.json
中的那個短ID,在方塊中也是存在短ID遷移到行為包中的現象的。因此,blocks.json
就可以進行簡化:
- 資源包/blocks.json
{
"wiki:cobblestone_slab": { "sound": "stone" }
}
即忽略掉texture
參數。至於terrain_texture.json
,其實行為包程式碼也偷了個懶,直接呼叫了原版的cobblestone
紋理,因此根本無需再次變更!