添加了部分来自于BedrockWiki的文章!

This commit is contained in:
boybook
2025-03-19 22:17:04 +08:00
parent 41635cf9bb
commit c25ebf2767
558 changed files with 96136 additions and 24 deletions

View File

@@ -0,0 +1,183 @@
---
title: 持续效果应用指南
category: 教程
tags:
- 实验性内容
- 初级难度
mentions:
- MysticChair
- SirLich
- MedicalJewel105
- QuazChick
---
# 持续效果应用指南
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
::: tip 格式要求 & 最低引擎版本 `1.20.30`
本教程假设您已掌握[方块状态](/blocks/block-states)的基本概念。建议在开始前先阅读[方块基础指南](/blocks/blocks-intro)。
:::
::: warning 实验性功能
需要启用 `假日创作者功能` 来触发事件。
:::
本教程将展示如何在实体持续站立于方块时为其附加状态效果。
## 设置步骤
我们需要在代码中添加以下组件,首先创建一个用于记录站立状态的布尔值:
::: code-group
```json [minecraft:block > description]
"states": {
"wiki:stood_on": [false, true]
}
```
:::
接下来添加 `minecraft:queued_ticking` 组件,当检测到站立状态为 `true` 时触发效果事件:
::: code-group
```json [minecraft:block > components]
"minecraft:queued_ticking": {
"looping": true,
"interval_range": [1, 1],
"on_tick": {
"event": "wiki:add_effect",
"target": "self",
"condition": "q.block_state('wiki:stood_on')"
}
}
```
:::
使用 `minecraft:on_step_on` 事件组件在实体踏上方块时更新状态:
::: code-group
```json [minecraft:block > components]
"minecraft:on_step_on": {
"event": "wiki:step_on"
}
```
:::
通过 `minecraft:on_step_off` 事件组件在实体离开时重置状态:
::: code-group
```json [minecraft:block > description]
"minecraft:on_step_off": {
"event": "wiki:step_off"
}
```
:::
配置事件处理逻辑。首先定义状态更新事件:
::: code-group
```json [minecraft:block > components]
"events": {
"wiki:step_on": {
"set_block_state": {
"wiki:stood_on": true
}
},
"wiki:step_off": {
"set_block_state": {
"wiki:stood_on": false
}
}
}
```
:::
最后添加效果触发事件:
::: code-group
```json [minecraft:block > components]
"wiki:add_effect": {
"run_command": {
"command": "effect @e[r=1] wither 2 2"
}
}
```
:::
完成!上述代码将在实体持续站立时施加凋零效果。
## 示例JSON
<Spoiler title="凋零方块实现案例">
::: code-group
```json [BP/blocks/wither_block.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:wither_block",
"menu_category": {
"category": "nature"
},
"states": {
"wiki:stood_on": [false, true]
}
},
"components": {
"minecraft:geometry": "geometry.wither_block",
"minecraft:material_instances": {
"*": {
"texture": "wither_block"
}
},
"minecraft:loot": "loot_tables/empty.json",
"minecraft:on_step_on": {
"event": "wiki:step_on"
},
"minecraft:on_step_off": {
"event": "wiki:step_off"
},
"minecraft:queued_ticking": {
"looping": true,
"interval_range": [1, 1],
"on_tick": {
"event": "wiki:add_effect",
"condition": "q.block_state('wiki:stood_on')"
}
},
"minecraft:map_color": "#181818"
},
"events": {
"wiki:step_on": {
"set_block_state": {
"wiki:stood_on": true
}
},
"wiki:step_off": {
"set_block_state": {
"wiki:stood_on": false
}
},
"wiki:add_effect": {
"run_command": {
"command": "effect @e[r=1] wither 2 2"
}
}
}
}
}
```
:::
</Spoiler>
## 技术说明
关于代码实现的几点说明:
- **问**:为何使用 `run_command` 事件响应来触发效果,而不是专用的 `add_mob_effect` 响应?
- **答**:当通过 `minecraft:queued_ticking` 触发时,`add_mob_effect` 无法获取有效目标,因此必须改用 `/effect` 命令的目标选择器。
注意当效果时长设置小于2秒时可能出现异常。如果效果会造成持续伤害如中毒伤害会在效果施加时立即生效。这将导致实体受到的伤害频率高于原版机制当实体快速移动时。可通过将命令中的效果时长设为1秒进行对比测试。保持2秒时长可确保伤害间隔符合原版节奏。

View File

@@ -0,0 +1,74 @@
---
title: 规避状态值上限
category: 教程
tags:
- 专家
mentions:
- Kaioga5
- QuazChick
---
# 规避状态值上限
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
## 前言
方块每个状态最多只能拥有16个有效状态值。本指南将解释如何避免触及这个上限。
:::tip
本教程不会直接展示如何突破16个状态值的限制但通过以下方法可以模拟实现类似效果
:::
## 实现原理
该方法通过组合两个或多个状态值进行复用并在排列组合或条件判断中读取这些组合值。例如一个需要表示26个英文字母的方块可以通过数值组合的方式减少状态值数量。
## 逻辑推演
以下示例代码演示了如何通过组合实现字母映射:
```
1 & 1 = A 1 & 5 = E 1 & 9 = I 1 & 13 = M
1 & 2 = B 1 & 6 = F 1 & 10 = J
1 & 3 = C 1 & 7 = G 1 & 11 = K
1 & 4 = D 1 & 8 = H 1 & 12 = L
```
继续扩展:
```
2 & 1 = N 2 & 5 = R 2 & 9 = V 2 & 13 = Z
2 & 2 = O 2 & 6 = S 2 & 10 = W
2 & 3 = P 2 & 7 = T 2 & 11 = X
2 & 4 = Q 2 & 8 = U 2 & 12 = Y
```
通过这种组合方式仅需15个状态值即可实现26个字母的映射。可用组合值越多状态上限的扩展空间就越大。
## 实际应用
参照上述示例,您的状态定义应如下所示:
::: code-group
```json [minecraft:block > description]
"states": {
"wiki:value": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],
"wiki:division": [1, 2]
}
```
:::
对应的条件判断语句应如下编写:
```json
"condition": "q.block_state('wiki:division') == 1 && q.block_state('wiki:value') == 1"
```
```json
"condition": "q.block_state('wiki:division') == 1 && q.block_state('wiki:value') == 2"
```
## 知识总结
您已掌握如何通过状态值组合突破64个状态值的限制使用更少的资源实现更复杂的逻辑。
:::tip
通过增加组合维度使用2个以上的状态值您可以获得更多可能的组合结果。
:::

View File

@@ -0,0 +1,84 @@
---
title: 纹理变体
category: 教程
tags:
- 中级
mentions:
- SirLich
- solvedDev
- Hatchibombotar
- SmokeyStack
- MedicalJewel105
- QuazChick
---
# 纹理变体
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
方块纹理变体是指单个方块可以拥有多个纹理。这在需要表现细微差异的方块(如带有小石块的泥土或不同生长阶段的草方块)时非常实用。
要启用纹理变体功能,需在资源包的`textures`文件夹中创建`terrain_texture.json`文件。在方块定义中,纹理应设置为包含`variations`键的字典,该键对应一个由字典组成的数组。每个字典必须包含指向纹理文件的`path`键,并可添加`weight`参数控制纹理出现的概率。
## 应用纹理变体
以下是为泥土方块创建三种纹理变体的示例:
- 在资源包中创建`textures/terrain_texture.json`文件
- 在JSON文件中定义需要添加变体的方块示例如下
::: code-group
```json [RP/textures/terrain_texture.json]
{
"texture_name": "atlas.terrain",
"resource_pack_name": "wiki", // 资源包ID
"padding": 8, // 防止纹理视觉溢出
"num_mip_levels": 4, // 远距离/倾斜视角下的纹理质量
"texture_data": {
"dirt": {
"textures": {
"variations": [
{ "path": "textures/blocks/dirt0" },
{ "path": "textures/blocks/dirt1" },
{ "path": "textures/blocks/dirt2" }
]
}
}
}
}
```
:::
- 创建或修改三个泥土纹理文件,分别命名为`dirt0.png`、`dirt1.png`和`dirt2.png`
- 将纹理文件放置于`path`参数指定的路径下(可添加子文件夹保持整洁)
## 权重控制变体分布
完成基础配置后,可通过添加权重值调整纹理出现概率:
::: code-group
```json [RP/textures/terrain_texture.json]
{
"texture_name": "atlas.terrain",
"resource_pack_name": "wiki", // 资源包ID
"padding": 8, // 防止纹理视觉溢出
"num_mip_levels": 4, // 远距离/倾斜视角下的纹理质量
"texture_data": {
"dirt": {
"textures": {
"variations": [
{ "path": "textures/blocks/dirt0", "weight": 70 }, // 70%出现概率
{ "path": "textures/blocks/dirt1", "weight": 20 }, // 20%出现概率
{ "path": "textures/blocks/dirt2", "weight": 10 } // 10%出现概率
]
}
}
}
}
```
:::
注意事项:
- 当前版本存在纹理集文件引用问题可能导致无法正确识别MER文件或常规纹理文件
-- [官方漏洞报告](https://bugs.mojang.com/browse/MCPE-126617)

View File

@@ -0,0 +1,279 @@
---
title: 伪方块
category: 教程
tags:
- 中级
mentions:
- SirLich
- solvedDev
- Joelant05
- MedicalJewel105
- aexer0e
- ThijsHankelMC
- QuazChick
---
# 伪方块
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
::: warning 实验性功能
需要启用 `Holiday Creator Features` 来触发方块事件。
:::
当你的方块需要实现Minecraft原生不支持的功能时可以通过创建具有方块特征的实体来模拟实现。
## 创建碰撞箱
[固体实体教程](/entities/solid-entities)中介绍了四种创建碰撞箱的方式,涉及 `runtime_identifiers`、方块和组件组合方案。
## 基础组件
以下组件是让实体模拟方块行为的关键配置。注意不要添加 `"minecraft:physics": {}` 组件,否则实体会受重力影响坠落或与水/岩浆等方块发生异常碰撞。
::: code-group
```json [BP/entities/your_entity.json#minecraft:entity/components]
{
// 需要击退抗性来防止实体被击退
"minecraft:knockback_resistance": {
"value": 1
},
// 控制实体是否可被推动
"minecraft:pushable": {
"is_pushable": false,
"is_pushable_by_piston": true
},
// 设置实体可被推动的穿透距离
"minecraft:push_through": {
"value": 1
},
// 使实体无敌
"minecraft:damage_sensor": {
"triggers": [
{
"deals_damage": false,
"cause": "all"
}
]
}
}
```
:::
## 实体旋转对齐
通过数学计算实现实体旋转对齐:
::: code-group
```json [动画控制器]
"rotation": [ 0, "-q.body_y_rotation + (Math.round(q.body_y_rotation / 90) * 90)", 0 ]
```
:::
将此代码应用在模型动画的核心分组包含其他所有分组的父级确保X轴和Z轴旋转中心点为0以避免视觉错位。同时避免添加以下组件
- `"minecraft:behavior.look_at_entity": {}`
- `"minecraft:behavior.look_at_player": {}`
- `"minecraft:behavior.look_at_target": {}`
这些组件会改变目标Y轴旋转角度导致模型异常位移。同时也不要添加行走类组件。
## 实体位置对齐
位置对齐的实现较为复杂,需分步操作:
1. 在 `minecraft:entity_spawned` 事件中生成临时方块
2. 通过指令生成虚拟实体
3. 将虚拟实体转换为目标实体
::: code-group
```json [BP/entities/your_entity.json#minecraft:entity/events]
// 原实体中的事件
"minecraft:entity_spawned": {
"add": {
"components_groups": [
"despawn" // 需要移除初始实体
]
},
"run_command": {
"command": [
"setblock ~~~ wiki:align"
]
}
}
```
:::
::: code-group
```json [BP/entities/your_entity.json#minecraft:entity/component_groups]
// 原实体中的组件组
"component_groups": {
"despawn": {
"minecraft:despawn": {}
}
}
```
:::
用于生成虚拟实体的对齐方块配置:
::: code-group
```json [BP/blocks/your_dummy_block.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:align"
},
"components": {
"minecraft:light_dampening": 0,
"minecraft:collision_box": false,
"minecraft:selection_box": false,
"minecraft:loot": "loot_tables/empty.json",
"minecraft:geometry": "geometry.empty",
"minecraft:material_instances": {
"*": {
"texture": "empty"
}
},
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 2
},
"minecraft:on_placed": {
"event": "wiki:event"
}
},
"events": {
"wiki:event": {
"run_command": {
"command": [
"setblock ~~~ air", // 移除临时方块
"summon wiki:dummy_align" // 生成虚拟实体
]
}
}
}
}
}
```
:::
虚拟实体的转换配置:
::: code-group
```json [BP/entities/your_dummy_entity.json]
{
"format_version": "1.13.0",
"minecraft:entity": {
"description": {
"identifier": "wiki:dummy_align", // 虚拟实体用于避免触发原实体的生成事件
"is_spawnable": false,
"is_summonable": true,
"is_experimental": false
},
"component_groups": {
"transform": {
"minecraft:transformation": {
"into": "wiki:your_entity",
"delay": 0
}
}
},
"components": {
"minecraft:physics": {
"has_gravity": false
},
"minecraft:collision_box": {
"width": 0.1,
"height": 0.1
},
"minecraft:damage_sensor": {
"triggers": {
"cause": "all",
"deals_damage": false
}
}
},
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": ["transform"]
}
}
}
}
}
```
:::
## 裂纹纹理效果
为实体添加原生方块的破坏裂纹效果:
1. 添加原版裂纹纹理(兼容材质包)
2. 创建专用几何体
3. 配置渲染控制器
::: code-group
```json [RP/entity/your_entity.json#description]
"textures": {
"default": "textures/entity/your_texture",
"destroy_stage_0": "textures/environment/destroy_stage_0",
"destroy_stage_1": "textures/environment/destroy_stage_1",
"destroy_stage_2": "textures/environment/destroy_stage_2",
"destroy_stage_3": "textures/environment/destroy_stage_3",
"destroy_stage_4": "textures/environment/destroy_stage_4",
"destroy_stage_5": "textures/environment/destroy_stage_5",
"destroy_stage_6": "textures/environment/destroy_stage_6",
"destroy_stage_7": "textures/environment/destroy_stage_7",
"destroy_stage_8": "textures/environment/destroy_stage_8",
"destroy_stage_9": "textures/environment/destroy_stage_9"
}
```
:::
创建防Z轴冲突的几何体
::: code-group
```json [RP/entity/your_entity.json#description]
"geometry": {
"default": "geometry.your_geometry",
"broken": "geometry.broken"
}
```
:::
配置动态纹理渲染控制器:
::: code-group
```json [RP/render_controllers/my_entity.json]
"controller.render.broken": {
"arrays": {
"textures": {
"array.broken": [
"texture.destroy_stage_9",
"texture.destroy_stage_8",
"texture.destroy_stage_7",
"texture.destroy_stage_6",
"texture.destroy_stage_5",
"texture.destroy_stage_4",
"texture.destroy_stage_3",
"texture.destroy_stage_2",
"texture.destroy_stage_1",
"texture.destroy_stage_0",
"texture.normal"
]
}
},
"geometry": "Geometry.broken",
"materials": [
{
"*": "Material.default"
}
],
"textures": [
"array.broken[q.health * 1]" // 根据实体生命值调整参数10生命值保持1倍20生命值改为0.540生命值改为0.25...
]
}
```
:::

View File

@@ -0,0 +1,172 @@
---
title: 纹理动画
category:
- 教程
tags:
- 中级
mentions:
- MedicalJewel105
- SquisSloim
- SmokeyStack
- QuazChick
---
# 纹理动画
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
通过本文你将了解:
- 如何为方块应用翻页书贴图
- `RP/textures/flipbook_textures.json` 中可用的参数及其作用
## 应用翻页书贴图
翻页书贴图即动态纹理。火焰、水、岩浆和岩浆块等方块都使用此类贴图。你也可以为自己创建的方块添加动态纹理!
首先以原版岩浆的动效贴图为例。只需在材质实例组件中将 `texture` 值设为 `Vanilla RP/textures/terrain_texture.json` 中定义的纹理名称即可:
```json
"magma": {
"textures": "textures/blocks/magma"
}
```
::: code-group
```json [BP/blocks/flipbook_block.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:flipbook_block",
"menu_category": {
"category": "construction"
}
},
"components": {
"minecraft:unit_cube": {},
"minecraft:material_instances": {
"*": {
"texture": "magma" // 将纹理名称填在此处
}
}
}
}
}
```
:::
![](/assets/images/blocks/flipbook-textures/animated_texture_1.gif)
现在你的方块已经拥有动态纹理了!
## 定义翻页书贴图
在为方块添加动态纹理后,我们需要了解其工作原理。
1. 游戏会根据 `terrain_texture.json` 中定义的纹理名称(如 magma读取对应贴图路径
::: code-group
```json [RP/textures/terrain_texture.json]
{
"texture_name": "atlas.terrain",
"resource_pack_name": "wiki", // 资源包ID
"padding": 8, // 防止贴图边缘像素溢出
"num_mip_levels": 4, // 控制远视角和倾斜视角下的材质质量
"texture_data": {
"magma": {
"textures": "textures/blocks/magma"
}
}
}
```
:::
2. 游戏会根据上述名称magma在 `flipbook_textures.json` 中查找对应的动画参数
::: code-group
```json [RP/textures/flipbook_textures.json]
[
{
"atlas_tile": "magma",
"flipbook_texture": "textures/blocks/magma",
"ticks_per_frame": 10
}
]
```
:::
`"atlas_tile"` 表示将动画参数绑定到 `terrain_texture.json` 中定义的 magma 纹理名称。
3. 所有使用 `magma` 作为纹理的方块都将应用此动态纹理
## 翻页书贴图参数配置
在查阅官方示例时,你可能会发现一些额外的配置参数:
| 参数名 | 类型 | 描述 |
|--------------------|------------------|-------------------------------------------------------------------------------------------------|
| flipbook_texture | string | 纹理文件路径 |
| atlas_tile | string | 在terrain_textures.json中定义的短名称 |
| atlas_index | integer | 短名称对应的纹理数组中目标纹理的索引 |
| atlas_tile_variant | integer | 短名称对应的方块变体数组中纹理的变化索引 |
| ticks_per_frame | integer | 帧切换速度单位ticks20 ticks = 1秒 |
| frames | array 或 integer | 帧索引数组;或表示总帧数的整数值 |
| replicate | integer | 像素倍数仅允许2的幂次值默认1 |
| blend_frames | boolean | 是否启用帧过渡平滑效果默认true |
### `atlas_index`
用于指定需要添加动画效果的纹理在数组中的索引位置
::: code-group
```json [RP/textures/terrain_texture.json#texture_data]
"dirt": {
"textures": [
"textures/blocks/dirt",
"textures/blocks/coarse_dirt" // 假设此纹理需要添加动效
]
}
```
:::
由于要设置第二个纹理索引为1的动效需要在对应配置中设置 `"atlas_index": 1`
### `atlas_tile_variant`
用于指定需要添加动画效果的方块变体(需在 `variations` 数组中定义)索引
::: code-group
```json [RP/textures/terrain_texture.json#texture_data]
"dirt": {
"textures": [
{
"variations": [
{ "path": "textures/blocks/dirt_va" }, // 假设此变体需要添加动效
{ "path": "textures/blocks/dirt0" },
{ "path": "textures/blocks/dirt1" }
]
}
]
}
```
:::
若需要设置索引1的变体动画需在参数中添加 `"atlas_tile_variant": 1`
### `replicate`
控制贴图像素显示倍数。仅允许使用2的幂次数值当原帧分辨率较小时可实现像素扩展效果
| 参数值 | 效果说明 |
|--------------------|----------------------------|
| < 0 | 动画失效 |
| 0 | 动画失效且贴图不显示 |
| 2 | 每像素扩展为4格尺寸缩小1/2 |
| x | 每像素扩展为x²尺寸缩小1/x |
## 效果展示
![](/assets/images/blocks/flipbook-textures/animated_texture_2.gif)
现在你可以开始修改原版动效贴图或创作属于你的动态纹理了

View File

@@ -0,0 +1,215 @@
---
title: 矿石战利品表
category: 教程
tags:
- 简单
mentions:
- SykoUSS
- ExDrill
- MedicalJewel105
- SmokeyStack
- Chikorita-Lover
- SirLich
- TheItsNameless
- QuazChick
- Keyyard
---
# 矿石战利品表
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
::: tip 格式版本 `1.20.30`
本教程假设您已具备方块基础知识。
开始前请先查阅[方块指南](/blocks/blocks-intro)。
:::
::: warning 实验性功能
需要启用`假日创造者特性`来触发事件。
:::
本教程旨在展示一种通过战利品表创建自定义矿石方块的全新方法。使用`minecraft:loot`组件时将始终调用指定战利品表,而通过在战利品表中添加`match_tool`条件,可以逐池限定挖掘工具要求。
- 特性:
- 可使用指定工具挖掘(本教程以铁镐为例)
- 可指定工具附魔等级
- 经验值掉落支持
- 限制:
- 所有工具需逐个单独指定
- 非玩家破坏方式(爆炸/指令等)不会触发掉落
## 方块JSON
以下方块行为文件可作为模板使用。记得通过`terrain_texture.json`设置方块纹理。
::: code-group
```json [BP/blocks/silver_ore.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:silver_ore",
"menu_category": {
"category": "nature",
"group": "itemGroup.name.ore"
}
},
"components": {
...
// 触发加载带有经验奖励结构的事件
"minecraft:on_player_destroyed": {
"event": "wiki:xp_reward"
},
"minecraft:loot": "loot_tables/blocks/silver_ore.json" // 使用精准采集时不会掉落
},
"events": {
"wiki:xp_reward": {
"run_command": {
"command": [
"structure load ore_xp_reward ~~~" // 需下载下方预存经验球的结构文件
]
}
}
}
}
}
```
## 战利品表
以下示例展示了必需组件
::: code-group
```json [BP/loot_tables/blocks/silver_ore.json]
{
"pools": [
{
"rolls": 1,
"conditions": [
{
"condition": "match_tool",
"item": "minecraft:iron_pickaxe",
"count": 1
}
],
"entries": [
{
"type": "item",
"name": "wiki:raw_silver"
}
]
}
]
}
```
## 附魔等级限定
可通过添加`enchantments`区间限定附魔等级。注意每组工具及其等级需独立成池。
目前兼容检测1级和2级附魔。
::: code-group
```json [BP/loot_tables/blocks/silver_ore.json#pools]
"conditions": [
{
"condition": "match_tool",
"item": "minecraft:iron_pickaxe",
"count": 1,
"enchantments": [
{
"fortune": {
"level": 1
}
}
]
}
]
```
## 非实验性方案
若不想通过方块事件触发经验奖励,可选用以下替代方案。
请从[此处](#下载结构文件)下载内含经验球的`ore_xp_reward`结构文件。
### 方案一:虚拟物品与循环函数
**步骤1**:为需要掉落经验的方块创建战利品表。以"minecraft:redstone"为例:
```json
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "minecraft:redstone"
}
]
},
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "minecraft:barrier" // 虚拟物品
}
]
}
]
}
```
此处添加已有物品"minecraft:barrier"作为触发经验掉落的虚拟物品,也可创建专用虚拟物品。
**步骤2**:创建循环函数处理掉落物品。需在`BP/functions/tick.json`中定义:
```c
execute as @e[type=item, name="Barrier"] at @s run structure load ore_xp_reward ~~~
execute as @e[type=item, name="Barrier"] run kill
```
该函数会捕捉名为"Barrier"的掉落物,加载经验奖励结构后销毁虚拟物品。
### 方案二:纯函数循环
**步骤1**:创建基础战利品表。以"wiki:raw_silver"为例:
```json
{
"pools": [
{
"entries": [
{
"type": "item",
"name": "wiki:raw_silver"
}
]
}
]
}
```
**步骤2**:创建标记处理函数。需在`BP/functions/tick.json`中定义:
```c
execute as @e[type=item, name="Raw Silver", tag=!xp] at @s run structure load ore_xp_reward ~~~
execute as @e[type=item, name="Raw Silver", tag=!xp] run tag @s add xp
```
该函数为所有未标记"xp"的银矿掉落物加载经验结构,并通过标签防止重复触发。
请根据实际情况调整物品ID、标签等参数。
## 下载结构文件
<BButton link="/assets/packs/tutorials/blocks/ore-loot-tables/ore_xp_reward.mcstructure" download color=blue> 下载MCSTRUCTURE</BButton>
## 实际效果
![](/assets/images/blocks/ore-loot/result.gif)

View File

@@ -0,0 +1,352 @@
---
title: 精确旋转
category: 教程
tags:
- experimental
- expert
mentions:
- QuazChick
---
# 精确旋转
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
::: tip 格式与最低引擎版本 `1.20.30`
本教程假定您已具备方块的进阶知识与Molang基础。
开始前建议先阅读[方块指南](/blocks/blocks-intro)。
:::
::: warning 实验性功能
需要启用 `Holiday Creator Features` 来触发事件。
:::
本教程将引导您实现可支持次级方位旋转的方块(如爬行者头颅与告示牌),通过一个包含此类旋转类型的"贝壳"方块作为实例进行讲解。
*查看常规旋转方式?请前往[此页面](/blocks/rotatable-blocks)*
![随机朝向的自定义贝壳方块](/assets/images/blocks/precise-rotation/showcase.png)
特性概览:
- 可附着于方块顶部具备16种旋转角度
- 可附着于方块的侧表面(北、东、南、西)
- 旋转行为与原版生物头颅一致,且无需依赖方块实体性能消耗!
## 方块模型
要实现更精确的旋转机制,您的方块模型需额外添加若干骨骼节点。
实现地面精确旋转需要4个基础骨骼节点每个对应不同的Y轴旋转角度:
- `up_0` (Y旋转角度 = 0)
- `up_22_5` (Y旋转角度 = 22.5)
- `up_45` (Y旋转角度 = 45)
- `up_67_5` (Y旋转角度 = 67.5)
**上述角度值采用顺时针方向递增**
这些骨骼除旋转参数外,在结构上通常是互为复制的。
:::tip
建议将所有骨骼的枢轴点设置于 `[0, 0, 0]` ,以确保其围绕方块中心旋转。
:::
此外,还需一个 `side` 骨骼用于侧表面附着时的定位调整。
下方展示的"贝壳"模型结构可供参考:
![](/assets/images/blocks/precise-rotation/model_bones.png)
<Spoiler title="贝壳模型实例">
::: code-group
```json [RP/models/blocks/shell.geo.json]
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.shell",
"texture_width": 16,
"texture_height": 16,
"visible_bounds_width": 3,
"visible_bounds_height": 2.5,
"visible_bounds_offset": [0, 0.75, 0]
},
"bones": [
{
"name": "shell",
"pivot": [0, 0, 0]
},
{
"name": "up_0",
"parent": "shell",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-3, 0, -3],
"size": [6, 3, 6],
"uv": {
"north": { "uv": [0, 6], "uv_size": [6, 3] },
"east": { "uv": [0, 6], "uv_size": [6, 3] },
"south": { "uv": [0, 6], "uv_size": [6, 3] },
"west": { "uv": [0, 6], "uv_size": [6, 3] },
"up": { "uv": [6, 6], "uv_size": [-6, -6] },
"down": { "uv": [6, 6], "uv_size": [-6, -6] }
}
}
]
},
{
"name": "up_22_5",
"parent": "shell",
"pivot": [0, 0, 0],
"rotation": [0, 22.5, 0],
"cubes": [
{
"origin": [-3, 0, -3],
"size": [6, 3, 6],
"uv": {
"north": { "uv": [0, 6], "uv_size": [6, 3] },
"east": { "uv": [0, 6], "uv_size": [6, 3] },
"south": { "uv": [0, 6], "uv_size": [6, 3] },
"west": { "uv": [0, 6], "uv_size": [6, 3] },
"up": { "uv": [6, 6], "uv_size": [-6, -6] },
"down": { "uv": [6, 6], "uv_size": [-6, -6] }
}
}
]
},
{
"name": "up_45",
"parent": "shell",
"pivot": [0, 0, 0],
"rotation": [0, 45, 0],
"cubes": [
{
"origin": [-3, 0, -3],
"size": [6, 3, 6],
"uv": {
"north": { "uv": [0, 6], "uv_size": [6, 3] },
"east": { "uv": [0, 6], "uv_size": [6, 3] },
"south": { "uv": [0, 6], "uv_size": [6, 3] },
"west": { "uv": [0, 6], "uv_size": [6, 3] },
"up": { "uv": [6, 6], "uv_size": [-6, -6] },
"down": { "uv": [6, 6], "uv_size": [-6, -6] }
}
}
]
},
{
"name": "up_67_5",
"parent": "shell",
"pivot": [0, 0, 0],
"rotation": [0, 67.5, 0],
"cubes": [
{
"origin": [-3, 0, -3],
"size": [6, 3, 6],
"uv": {
"north": { "uv": [0, 6], "uv_size": [6, 3] },
"east": { "uv": [0, 6], "uv_size": [6, 3] },
"south": { "uv": [0, 6], "uv_size": [6, 3] },
"west": { "uv": [0, 6], "uv_size": [6, 3] },
"up": { "uv": [6, 6], "uv_size": [-6, -6] },
"down": { "uv": [6, 6], "uv_size": [-6, -6] }
}
}
]
},
{
"name": "side",
"parent": "shell",
"pivot": [0, 5, 8],
"rotation": [90, 0, 0],
"cubes": [
{
"origin": [-3, 5, 8],
"size": [6, 3, 6],
"uv": {
"north": { "uv": [0, 6], "uv_size": [6, 3] },
"east": { "uv": [0, 6], "uv_size": [6, 3] },
"south": { "uv": [0, 6], "uv_size": [6, 3] },
"west": { "uv": [0, 6], "uv_size": [6, 3] },
"up": { "uv": [6, 6], "uv_size": [-6, -6] },
"down": { "uv": [6, 6], "uv_size": [-6, -6] }
}
}
]
}
]
}
]
}
```
:::
</Spoiler>
## 基础方块JSON
下方是待添加高级旋转功能的"贝壳"方块基础定义。
::: code-group
```json [BP/blocks/shell.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:shell",
"menu_category": {
"category": "nature"
}
},
"components": {
// `up` 表面的碰撞/选择框
"minecraft:collision_box": {
"origin": [-3, 0, -3],
"size": [6, 3, 6]
},
"minecraft:selection_box": {
"origin": [-3, 0, -3],
"size": [6, 3, 6]
},
"minecraft:material_instances": {
"*": {
"texture": "shell" // 在 `RP/textures/terrain_texture.json` 中定义的短名称
}
},
// 阻止方块附着于 `down` 表面
"minecraft:placement_filter": {
"conditions": [
{
"allowed_faces": ["up", "side"]
}
]
}
}
}
}
```
:::
## 方块状态
为实现头颅式旋转机制需为方块添加2种状态参数
::: code-group
```json [minecraft:block]
"description": {
...
"traits": {
// 方块附着面 - 默认为 `north`
"minecraft:placement_position": {
"enabled_states": ["minecraft:block_face"]
}
},
"states": {
// 当附着于 `up` 表面时的精确旋转参数
"wiki:rotation": {
"values": { "min": 0, "max": 15 } // 使用更方便的定义整数范围的语法
}
}
}
```
:::
## 旋转Molang表达式
相较于逐个定义每个 `wiki:rotation` 值的范围,运用[复合Molang表达式](https://learn.microsoft.com/en-us/minecraft/creator/reference/content/molangreference/examples/molangconcepts/molangintroduction#simple-vs-complex-expressions)配合除法运算可高效实现需求!
```c
// 转换玩家头部Y旋转角度至正值
t.positive_head_rot = q.head_y_rotation(0) + 360 * (q.head_y_rotation(0) != math.abs(q.head_y_rotation(0)));
// 计算头部旋转对应的十六分之一圆角(取整)
t.rotation = math.round(t.positive_head_rot / 22.5);
// 0与16代表重复旋转0度与360度故当值为16时返回0
return t.rotation != 16 ? t.rotation;
```
合并为单行表达式以便嵌入JSON
::: code-group
```json [minecraft:block > components > minecraft:on_player_placing > condition]
"condition": "t.positive_head_rot = q.head_y_rotation(0) + 360 * (q.head_y_rotation(0) != math.abs(q.head_y_rotation(0))); t.rotation = math.round(t.positive_head_rot / 22.5); return t.rotation != 16 ? t.rotation;"
```
:::
## 应用旋转
现在通过Molang表达式动态设定方块属性!
通过事件在玩家放置方块时更新方块属性。此事件上下文可访问 `q.block_face` 与 `q.head_y_rotation`。
在方块JSON中添加以下组件与事件
::: code-group
```json [minecraft:block]
"components": {
...
"minecraft:on_player_placing": {
"condition": "q.block_face == 1", // 精确旋转仅作用于 `up` 表面
"event": "wiki:set_rotation"
}
},
"events": {
"wiki:set_rotation": {
"set_block_property": {
// 应用之前的Molang表达式设置rotation属性
"wiki:rotation": "q.block_face == 1 ? { t.positive_head_rot = q.head_y_rotation(0) + 360 * (q.head_y_rotation(0) != math.abs(q.head_y_rotation(0))); t.block_rotation = math.round(t.positive_head_rot / 22.5); return t.block_rotation != 16 ? t.block_rotation; };"
}
}
}
```
:::
<br>
接着,使用[置换](/blocks/block-permutations)定义基础朝向旋转,由模型中的精细骨骼进一步细化。
按顺序在方块JSON中添加以下置换条件
::: code-group
```json [minecraft:block]
"permutations": [
{
"condition": "q.block_property('wiki:rotation') >= 4 || q.block_property('minecraft:block_face') == 'east'",
"components": {
"minecraft:transformation": { "rotation": [0, -90, 0] }
}
},
{
"condition": "q.block_property('wiki:rotation') >= 8 || q.block_property('minecraft:block_face') == 'south'",
"components": {
"minecraft:transformation": { "rotation": [0, 180, 0] }
}
},
{
"condition": "q.block_property('wiki:rotation') >= 12 || q.block_property('minecraft:block_face') == 'west'",
"components": {
"minecraft:transformation": { "rotation": [0, 90, 0] }
}
}
]
```
:::
## 骨骼可见性
并非所有骨骼节点始终可见,因此需利用 `minecraft:geometry` 的骨骼可见性属性精确控制渲染。多个骨骼存在的目的是因为 `minecraft:transformation` 仅支持90度的整数倍旋转而精确旋转需要22.5度的增量。
在方块组件中加入以下内容:
::: code-group
```json [minecraft:block > components]
"minecraft:geometry": {
"identifier": "geometry.shell", // 第一步创建的模型
"bone_visibility": {
"up_0": "q.block_property('minecraft:block_face') == 'up' && !math

View File

@@ -0,0 +1,403 @@
---
title: 可旋转方块
category: 教程
mentions:
- Ultr4Anubis
- SmokeyStack
- ihategravel2
- MedicalJewel105
- MajestikButter
- QuazChick
---
# 可旋转方块
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
::: tip 格式与最低引擎版本 `1.20.30`
本教程假设您已掌握方块基础知识,包括[方块状态](/blocks/block-states)与[方块特性](/blocks/block-traits)。
开始前请先阅读[方块指南](/blocks/blocks-intro)。
:::
## 旋转类型
- ### [基本方向旋转](#cardinal-direction-rotation)
- 适用于雕刻南瓜和熔炉
- 4个方向 - 'north'(北)、'south'(南)、'east'(东)、'west'(西)
- ### [面向方向旋转](#facing-direction-rotation)
- 适用于发射器和观测器
- 6个方向 - 'down'(下)、'up'(上)、'north'(北)、'south'(南)、'east'(东)、'west'(西)
- ### [方块面附着旋转](#block-face-rotation)
- 适用于梯子和物品展示框
- 6个附着方向 - 'down'(下)、'up'(上)、'north'(北)、'south'(南)、'east'(东)、'west'(西)
- ### [原木/柱体旋转](#log-rotation)
- 适用于原木和玄武岩
- 3个轴对齐方向
- ### [精确旋转](/blocks/precise-rotation)
- 适用于头颅、告示牌和旗帜
- 16个方向以22.5度递增)
- 4个侧面附着方向
## 基本方向旋转
### 特性
使用`minecraft:placement_direction`方块特性并启用`minecraft:cardinal_direction`状态来设置方块方向。
::: code-group
```json [minecraft:block]
"description": {
"identifier": "wiki:cardinal_direction_example",
// 在此处定义方块特性
"traits": {
"minecraft:placement_direction": {
"enabled_states": ["minecraft:cardinal_direction"], // 可在查询中使用,例如`q.block_state('minecraft:cardinal_direction') == 'north'`
"y_rotation_offset": 180 // 朝向玩家
}
}
}
```
:::
### 置换
通过方块置换实现旋转。每个置换包含`minecraft:transformation`组件,检查`minecraft:cardinal_direction`状态并应用相应旋转。
**下方旋转值假设模型正面朝北**
::: code-group
```json [minecraft:block]
"permutations": [
// 面向北
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'north'",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
// 面向西
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'west'",
"components": {
"minecraft:transformation": { "rotation": [0, 90, 0] }
}
},
// 面向南
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'south'",
"components": {
"minecraft:transformation": { "rotation": [0, 180, 0] }
}
},
// 面向东
{
"condition": "q.block_state('minecraft:cardinal_direction') == 'east'",
"components": {
"minecraft:transformation": { "rotation": [0, -90, 0] }
}
}
]
```
:::
## 面向方向旋转
### 特性
使用`minecraft:placement_direction`方块特性并启用`minecraft:facing_direction`状态来设置方块方向。
::: code-group
```json [minecraft:block]
"description": {
"identifier": "wiki:facing_direction_example",
// 在此处定义方块特性
"traits": {
"minecraft:placement_direction": {
"enabled_states": ["minecraft:facing_direction"], // 可在查询中使用,例如`q.block_state('minecraft:facing_direction') == 'north'`
}
}
}
```
:::
### 置换
通过方块置换实现旋转。每个置换包含`minecraft:transformation`组件,检查`minecraft:facing_direction`状态并应用相应旋转。
**下方旋转值假设模型正面朝北**
::: code-group
```json [minecraft:block]
"permutations": [
// 朝下
{
"condition": "q.block_state('minecraft:facing_direction') == 'down'",
"components": {
"minecraft:transformation": { "rotation": [-90, 0, 0] }
}
},
// 朝上
{
"condition": "q.block_state('minecraft:facing_direction') == 'up'",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 0] }
}
},
// 朝北
{
"condition": "q.block_state('minecraft:facing_direction') == 'north'",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
// 朝西
{
"condition": "q.block_state('minecraft:facing_direction') == 'west'",
"components": {
"minecraft:transformation": { "rotation": [0, 90, 0] }
}
},
// 朝南
{
"condition": "q.block_state('minecraft:facing_direction') == 'south'",
"components": {
"minecraft:transformation": { "rotation": [0, 180, 0] }
}
},
// 朝东
{
"condition": "q.block_state('minecraft:facing_direction') == 'east'",
"components": {
"minecraft:transformation": { "rotation": [0, -90, 0] }
}
}
]
```
:::
## 方块面附着旋转
### 特性
使用`minecraft:placement_position`方块特性并启用`minecraft:block_face`状态来设置方块附着面。
::: code-group
```json [minecraft:block]
"description": {
"identifier": "wiki:facing_direction_example",
// 在此处定义方块特性
"traits": {
"minecraft:placement_position": {
"enabled_states": ["minecraft:block_face"], // 可在查询中使用,例如`q.block_state('minecraft:block_face') == 'north'`
}
}
}
```
:::
### 置换
通过方块置换实现旋转。每个置换包含`minecraft:transformation`组件,检查`minecraft:block_face`状态并应用相应旋转。
**下方旋转值假设模型正面朝北**
::: code-group
```json [minecraft:block]
"permutations": [
// 朝下
{
"condition": "q.block_state('minecraft:block_face') == 'down'",
"components": {
"minecraft:transformation": { "rotation": [-90, 0, 0] }
}
},
// 朝上
{
"condition": "q.block_state('minecraft:block_face') == 'up'",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 0] }
}
},
// 朝北
{
"condition": "q.block_state('minecraft:block_face') == 'north'",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
// 朝西
{
"condition": "q.block_state('minecraft:block_face') == 'west'",
"components": {
"minecraft:transformation": { "rotation": [0, 90, 0] }
}
},
// 朝南
{
"condition": "q.block_state('minecraft:block_face') == 'south'",
"components": {
"minecraft:transformation": { "rotation": [0, 180, 0] }
}
},
// 朝东
{
"condition": "q.block_state('minecraft:block_face') == 'east'",
"components": {
"minecraft:transformation": { "rotation": [0, -90, 0] }
}
}
]
```
:::
## 原木旋转
实现与原版原木相同的旋转方式
::: warning 实验性功能
需要启用`假日创作者功能`来触发事件
:::
### 方块状态
::: code-group
```json [minecraft:block > description]
"states": {
"wiki:axis": [0, 1, 2]
}
```
:::
### 方块事件与触发
使用Molang表达式通过查询方块附着面来确定坐标轴方向转换为0、1或2
::: code-group
```json [minecraft:block > events]
"wiki:set_axis": {
"set_block_state": {
"wiki:axis": "数学运算.floor(q.block_face / 2)"
}
}
```
:::
使用`minecraft:on_player_placing`触发器组件调用事件
::: code-group
```json [minecraft:block > components]
"minecraft:on_player_placing": {
"event": "wiki:set_axis"
}
```
:::
### 置换
::: code-group
```json [minecraft:block]
"permutations": [
{
"condition": "q.block_state('wiki:axis') == 0",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 1",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 2",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 90] }
}
}
]
```
:::
### 原木旋转示例
::: warning 实验性功能
本示例需要启用`假日创作者功能`以使用`minecraft:unit_cube`
:::
<Spoiler title="基础自定义原木JSON">
::: code-group
```json [BP/blocks/custom_log.json]
{
"format_version": "1.20.30",
"minecraft:block": {
"description": {
"identifier": "wiki:custom_log",
"states": {
"wiki:axis": [0, 1, 2]
}
},
"components": {
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1.5
},
"minecraft:destructible_by_explosion": {
"explosion_resistance": 15
},
"minecraft:material_instances": {
"*": {
"texture": "log_side"
},
"end": {
"texture": "log_top"
},
"up": "end",
"down": "end"
},
"minecraft:unit_cube": {},
"minecraft:on_player_placing": {
"event": "wiki:set_axis"
}
},
"events": {
"wiki:set_axis": {
"set_block_state": {
"wiki:axis": "Math.floor(q.block_face / 2)"
}
}
},
"permutations": [
{
"condition": "q.block_state('wiki:axis') == 0",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 1",
"components": {
"minecraft:transformation": { "rotation": [90, 0, 0] }
}
},
{
"condition": "q.block_state('wiki:axis') == 2",
"components": {
"minecraft:transformation": { "rotation": [0, 0, 90] }
}
}
]
}
}
```
:::
</Spoiler>