0. 前言
在上回我們透過合成台配方進行客製化物品的生成,但礙於目前的架構限制,沒法使用特殊道具作為素材,因此我們必須透過 Floor Crafting 達成此目標,順便做出視覺效果。
另外我們要避免隨便丟在地上的物品意外合成,勢必需要設定專用的合成站。那我們今天這一篇我們會進行 execute 的基礎使用與介紹。
1. 重點
修正資訊(Jul. 30, 2024)
🙏感謝 [巴哈姆特] 貓狗貓 提供以下關於修正資訊
透過 function 進行 tp 與 storage 測試後,tp 在 tick 瞬間是會消除 Motion 的,但為何物體會前移仍不明。
2. 內容
2.1. execute 基礎篇
關於 execute … run 我們能視作篩選後的結果,當滿足 subcommand 的篩選條件後,執行 run 之後的相應動作。那其中最常用分別為 as 與 at 這兩個,那我們就來看看他們的用途吧。
2.1.1. as
首先講述到的 as 我們能看做 “當” 的概念,比如下方的指令方塊內容代表「當 entity 型態為 item (掉落物) 的時候執行 tp 到指令方塊的上一格」。
execute as @e[type=item] run tp ~ ~1 ~
那麼丟些道具並拉下拉桿後,物體就該被傳送到方塊上方,代表有偵測到這些物件。
2.1.2. at
那 at 的概念則是相當於 “在” 的概念,那像下方 Repeat 指令方塊的內容則表示「在 item (掉落物) 的位置顯現粒子效果」。
execute at @e[type=item] run particle flame ~ ~ ~ 0.125 0.125 0.125 0 10
當我按下拉桿後,當我丟出物體就該持續有粒子效果跟著物體移動。
2.1.3. as 與 at 的區別
在後方的 Repeat 指令方塊中我寫了較為詳細的語法,透過 as 搭配 at 進行組合。前後文效果是一樣的。
execute as @e[type=item] at @s run particle flame ~ ~ ~ 0.125 0.125 0.125 0 10
但我們直接用 at 不是運行好好的嗎?那切割點在於 as 是回傳物體與其資訊,然 at 只回傳座標資訊,假若用 at 直接銜接其他 subcommand 可能無法正常運作。便宜偷懶是可以用 at,但有牽扯到其他判斷式時就建議採用詳細的寫法避免後續出現問題又可能拉長 debug 的時間。
2.1.4. if / unless
我們另外看到經常使用的 if 肯定的判斷式,那其相對的就是 unless 作為否定的判斷式。他們可以銜接的包括生態環境(biome), 方塊類別(block/blocks), 物體資訊(data)。
另外其他的包括境界的判斷 (dimension), 物體(entity), 方法是否執行成功(function), 玩家包包檢查(items)。
最後兩個比較例外少用的指定座標是否有被世界加載(loaded), 關於 Datapack 的數值比對(predicate)。
2.1.5. align
講到對齊我們會使用的便是 align 方法,那有 xyz 三軸嘛,他的組合數就是 C3 取一 + C3 取二 + C3 取三,等同於 2^3 – 1 共 7 個組合。
x y z xy xz yz xyz
那我們可以假設說當我們 align xyz 時,我們就在那單個方塊的 0, 0, 0 座標上,因此若 x 與 z 設為 ~0.5 代表在地面的正中心,另外加上 y 為 ~0.5 就是該方塊的正中心點。
2.1.6. as 與 at 的驗證
這邊我們回頭為 as 與 at 做個證明,順便用上一些我們剛介紹的判斷架構。透過 Repeat 指令方塊,可以看到下方我們先使用 at 嘗試去對齊 xyz,而當掉落物下方的方塊為含水大鍋就會停止物體並取消重力。
但在下方的測試中並沒有跳出指令方塊的回饋也沒有讓物體滯空。
execute at @e[type=item] align xyz if block ~ ~-1 ~ water_cauldron run data merge entity @s {Motion:[0.0,0.0,0.0], NoGravity:1b}
這時我們把指令修改一下為複合的準確型態。這時我們重新嘗試就能看到指令方塊的執行回饋,並且明顯看到物體神奇的浮在空中。
execute as @e[type=item] at @s align xyz if block ~ ~-1 ~ water_cauldron run data merge entity @s {Motion:[0.0,0.0,0.0], NoGravity:1b}
2.2. Datapack 的 function 架構
這似乎是我們首次提到 function 目錄,那事實上有幾個特殊的目錄是沒有寫入在 versions 的版本執行檔,必須去到 Minecraft Wiki 進行查詢。
那我們首先必須講到的就是 minecraft/tags/function 內部的兩個 JSON 檔案,其中可以透過陣列的方式選定要執行那些動作。而 load.json 所代表的是加載資源包時執行的動作,而 tick.json 所代表是遊戲每 tick (1 sec = 20 tick)去執行的動作。
{
"values": [
"BRANCH:PATH/OF/MCFUNCTION"
]
}
那相應他們的名稱,我個人的命名習慣在最頂層就有 load(建立計分板, 隊伍等等), tick(需要隨時偵測的內容), unload(相對於 load 讓玩家可以安全卸載資源包)。那當然後面細分時可能就會有更多目錄與特殊的 mcfunction 。
基礎三個方法個人採用階層式的方法,當我有要移除任何階層時相對好管理減少到處呼叫的問題,另外就是同一種分類的 function 都寫在一塊容易管理。
另外這些寫好的 mcfunction 實際上都能夠在遊戲中透過 /function 這個指令來直接進行呼叫。
2.3. 坩鍋實作
我們接著進入到今日的實作部分,當然在一點修改下也適用於判斷其他方塊,各位可以自行發揮。
2.3.1. tp 動量驗證
那在我們直接執行正解之前先來做個關於 tp 的實驗,我們在 Datapack 確認每 tick 觸發後,先只測試將物品傳送到鍋的中心而沒有動量消除的部分。
我們回到遊戲通過 /reload 加載後丟點東西到含水大鍋上方可以看到物品有確實被吸入,但當我們抽乾之後卻會發現物品不在中心而是壁面。但我們不是設定 x 與 z 的 .5 了嗎?原因在於 tp 不會消除物體動量。
# Teleport item into water cauldron
execute as @e[type=item] at @s align xyz if block ~ ~-1 ~ water_cauldron run tp @s ~.5 ~-.5 ~.5
我們快速做個驗證,跟朋友一起玩過的可能就體驗過,當我們從高空墜落一段時間後,即使 /tp 到地面玩家身邊,那瞬間還是會摔死的,主要就在於動量沒被消除,玩家還是以其速度撞向地面。
2.3.2. 視覺效果
我們接著加上前面測試的方法來消除動量與重力。完成修改後回到遊戲進行 /reload,接著丟點東西嘗試一下。那由於我有使用 NoGravity 將物品浮空在鍋內中間,掉落物自然上下起伏的動畫剛好能讓玩家看到自己放了那些素材進去。
#
# When item flying across water cauldron, teleport item into it
#
# Detect if item flying across water cauldron then freeze it
execute as @e[type=item] at @s align xyz if block ~ ~-1 ~ water_cauldron run data merge entity @s {Motion:[0.0,0.0,0.0], NoGravity:1b}
# Teleport item into water cauldron
execute as @e[type=item] at @s align xyz if block ~ ~-1 ~ water_cauldron run tp @s ~.5 ~-.5 ~.5
3. 後話
但若我們只是將素材丟入坩鍋是否還是太過無趣,我們下期就要介紹 /particle 與 /playsound 來給予視覺與聽覺的效果。那我們就下期再會啦。
4. 參考
[1] Datapack – Minecraft Wiki
https://minecraft.wiki/w/Data_pack
[2] Execute – Minecraft Wiki
https://minecraft.wiki/w/Commands/execute