---
title: 自定义流体
category: 原版再创作
tags:
- 实验性
- 中级
- 脚本
mentions:
- Provedule
- JaylyDev
- QuazChick
---
# 自定义流体
::: tip 格式要求 & 最低引擎版本 `1.20.30`
本教程假设您已具备方块和execute命令的高级知识。
开始前请先阅读[方块指南](/wiki/blocks/blocks-intro)。
:::
::: warning 实验性功能
需要使用`假日创造者功能`来支持方块标签Molang查询和触发方块事件。
需要使用`Beta API`来调用版本号为`1.6.0-beta`的[@minecraft/server](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/minecraft-server)模块。
:::
目前尚无法创建与原版完全相同的流体,但您可以制作类似的效果!本模板/教程将指导您创建自定义的"半流体"。
## 流动逻辑
- 流体方块具有定义是否为源方块及其深度的状态
- 当流体方块下方存在空气时,会转化为下落的流体
- 深度大于`1`的流体会向四周扩散并递减深度
- 若下方存在下落的流体则不会扩散
- 流动方块必须与其他流体方块相邻才能维持存在
- 源方块不需要周围有其他流体方块
**当前实现因复杂度问题暂未包含面剔除功能**
## 源流体方块
以下是自定义流体的基础代码。请将`custom_fluid`全局替换为您的流体名称。当源方块检测到周围存在空气时,会将其替换为外围流体方块。若源方块下方存在空气,则会在下方生成下落的流体方块。
下载自定义流体模型
::: code-group
```json [BP/blocks/custom_fluid.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_fluid",
"menu_category": {
"category": "none"
},
"states": {
"wiki:source": [true, false],
// 流体深度 - 默认为4
"wiki:depth": [4, 5, 3, 2, 1]
}
},
"components": {
"minecraft:light_dampening": 0,
"minecraft:collision_box": false,
"minecraft:selection_box": false,
"minecraft:destructible_by_explosion": false,
// 触发流体扩散
"minecraft:queued_ticking": {
"looping": true,
"interval_range": [20, 20], // 流体流速(单位:tick)
"on_tick": {
"event": "wiki:flow"
}
},
"minecraft:material_instances": {
"*": {
"texture": "custom_fluid", // 在`RP/textures/terrain_texture.json`中定义的短名称
"render_method": "blend",
"ambient_occlusion": false,
"face_dimming": false
}
},
"minecraft:loot": "loot_tables/empty.json",
"tag:custom_fluid": {}
},
"events": {
"wiki:flow": {
"sequence": [
// 干涸检测
{
"condition": "!q.block_state('wiki:source') && ((q.block_state('wiki:depth') == 5 && !q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')) || (q.block_state('wiki:depth') == 1 && !(q.block_neighbor_has_any_tag(1, 0, 0, 'custom_fluid_2') || q.block_neighbor_has_any_tag(-1, 0, 0, 'custom_fluid_2') || q.block_neighbor_has_any_tag(0, 0, 1, 'custom_fluid_2') || q.block_neighbor_has_any_tag(0, 0, -1, 'custom_fluid_2')) || q.block_state('wiki:depth') == 2 && !(q.block_neighbor_has_any_tag(1, 0, 0, 'custom_fluid_3') || q.block_neighbor_has_any_tag(-1, 0, 0, 'custom_fluid_3') || q.block_neighbor_has_any_tag(0, 0, 1, 'custom_fluid_3') || q.block_neighbor_has_any_tag(0, 0, -1, 'custom_fluid_3'))) || (q.block_state('wiki:depth') == 3 && !(q.block_neighbor_has_any_tag(1, 0, 0, 'custom_fluid_4', 'custom_fluid_5') || q.block_neighbor_has_any_tag(-1, 0, 0, 'custom_fluid_4', 'custom_fluid_5') || q.block_neighbor_has_any_tag(0, 0, 1, 'custom_fluid_4', 'custom_fluid_5') || q.block_neighbor_has_any_tag(0, 0, -1, 'custom_fluid_4', 'custom_fluid_5'))))",
"die": {}
},
// 扩散逻辑
{
"condition": "q.block_state('wiki:depth') == 4",
"run_command": {
"command": [
"execute if block ~~~1 air run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute if block ~~~-1 air run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute if block ~1~~ air run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute if block ~-1~~ air run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]"
]
}
},
{
"condition": "q.block_state('wiki:source') && q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')",
"set_block_state": {
"wiki:depth": 5
}
},
{
"condition": "q.block_state('wiki:source') && !q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')",
"set_block_state": {
"wiki:depth": 4
}
},
{
"condition": "q.block_state('wiki:depth') == 3",
"run_command": {
"command": [
"execute if block ~~~1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]",
"execute if block ~~~-1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]",
"execute if block ~1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]",
"execute if block ~-1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=2]"
]
}
},
{
"condition": "q.block_state('wiki:depth') == 2",
"run_command": {
"command": [
"execute if block ~~~1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]",
"execute if block ~~~-1 air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]",
"execute if block ~1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]",
"execute if block ~-1~~ air unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=1]"
]
}
},
{
"condition": "q.block_state('wiki:depth') == 5 && q.block_neighbor_has_any_tag(0, 1, 0, 'custom_fluid')",
"run_command": {
"command": [
"execute if block ~~-1~ wiki:custom_fluid [\"wiki:depth\"=3] run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]",
"execute if block ~~-1~ wiki:custom_fluid [\"wiki:depth\"=2] run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]",
"execute if block ~~-1~ wiki:custom_fluid [\"wiki:depth\"=1] run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~1~~ air run setblock ~1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~~~1 air run setblock ~~~1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~-1~~ air run setblock ~-1~~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]",
"execute unless block ~~-1~ air unless block ~~-1~ wiki:custom_fluid if block ~~~-1 air run setblock ~~~-1 wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=3]"
]
}
},
// 下落逻辑
{
"run_command": {
"command": "execute if block ~~-1~ air run setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]"
}
},
{
"condition": "q.block_neighbor_has_any_tag(0, -1, 0, 'flowing_custom_fluid')",
"run_command": {
"command": "setblock ~~-1~ wiki:custom_fluid [\"wiki:source\"=false,\"wiki:depth\"=5]"
}
}
]
},
"wiki:pick_up": {
"die": {},
"decrement_stack": {},
"run_command": {
"command": "give @s lava_bucket",
"target": "other"
}
}
},
"permutations": [
{
"condition": "q.block_state('wiki:source')",
"components": {
// 允许通过指定物品拾取方块
"minecraft:selection_box": {
"origin": [-7.5, 0.5, -7.5],
"size": [15, 13, 15]
},
"tag:custom_fluid_source": {}
}
},
{
"condition": "!q.block_state('wiki:source')",
"components": {
"tag:flowing_custom_fluid": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 5",
"components": {
"minecraft:geometry": "geometry.fluid.5",
"tag:custom_fluid_5": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 4",
"components": {
"minecraft:geometry": "geometry.fluid.4",
"tag:custom_fluid_4": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 3",
"components": {
"minecraft:geometry": "geometry.fluid.3",
"tag:custom_fluid_3": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 2",
"components": {
"minecraft:geometry": "geometry.fluid.2",
"tag:custom_fluid_2": {}
}
},
{
"condition": "q.block_state('wiki:depth') == 1",
"components": {
"minecraft:geometry": "geometry.fluid.1",
"tag:custom_fluid_1": {}
}
}
]
}
}
```
:::
## 流体桶
要放置自定义流体,您需要自定义桶物品。以下是流体桶的JSON配置,请将`custom_fluid`替换为您的流体名称。
::: code-group
```json [BP/items/custom_fluid_bucket.json]
{
"format_version": "1.20.30",
"minecraft:item": {
"description": {
"identifier": "wiki:custom_fluid_bucket",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:max_stack_size": 1,
"minecraft:icon": {
"texture": "custom_fluid_bucket" // 在`RP/textures/item_texture.json`中定义的短名称
},
"minecraft:block_placer": {
"block": "wiki:custom_fluid"
}
}
}
}
```
:::
## 脚本
该脚本为流体添加了玩家漂浮/下沉功能及雾气效果。将您的新流体ID添加到`fluids`字符串数组中即可生效。
::: code-group
```json [BP/manifest.json]
{
"modules": [
...
{
"type": "script",
"language": "javascript",
"entry": "fluids.js",
"uuid": ...,
"version": [1, 0, 0]
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "1.6.0-beta"
}
]
}
```
:::
::: code-group
```javascript [BP/scripts/fluids.js]
import { system, world } from "@minecraft/server";
const fluids = ["wiki:custom_fluid"];
system.runInterval(() => {
const players = world.getPlayers();
for (const player of players) {
// 流体效果
if (
fluids.includes(world.getDimension(player.dimension.id).getBlock({ ...player.location, y: player.location.y + 1 }).typeId) ||
fluids.includes(world.getDimension(player.dimension.id).getBlock(player.location).typeId)
) {
player.addEffect("slowness", 3, { amplifier: 2, showParticles: false });
player.addEffect("slow_falling", 4, { showParticles: false });
if (player.isJumping) {
player.addEffect("levitation", 3, { amplifier: 2, showParticles: false });
}
}
// 流体雾气
if (fluids.includes(world.getDimension(player.dimension.id).getBlock({ ...player.location, y: player.location.y + 1.63 }).typeId)) {
player.runCommand("fog @s push wiki:custom_fluid_fog fluid_fog");
} else {
player.runCommand("fog @s remove fluid_fog");
}
}
});
```
:::
## 最终成果
完成后的BP文件夹结构应如下所示:
## 示例包下载
如果遇到问题或需要完整模板文件,可在此下载。该资源包包含流体所需的所有必要文件。
下载MCADDON