添加了部分来自于BedrockWiki的文章!
This commit is contained in:
@@ -5,13 +5,25 @@ next: false
|
||||
|
||||
# 欢迎来到 Wiki
|
||||
|
||||
由于中国版官网的教程写的太差了,因此我们计划使用简洁清晰的风格,重新编写基础入门教程,方便大家查询和学习哦!同时也期待大家共同贡献和维护本Wiki~
|
||||
由于中国版官网的教程写的过于冗长,因此我们计划使用简洁清晰的风格,重新编写基础教程,方便大家查询和学习哦!
|
||||
|
||||
除了原创内容,我们经过授权,从 [Bedrock Wiki](https://wiki.bedrock.dev) 镜像且翻译了一批教程,希望能够帮助到大家。
|
||||
|
||||
<MyFeatures :items="[
|
||||
{
|
||||
title: 'Mod脚本开发',
|
||||
desc: '🚀 快速入门我的世界 Mod 开发',
|
||||
link: '/wiki/1-Mod脚本开发/1-快速入门Mod开发'
|
||||
},
|
||||
{
|
||||
title: '方块',
|
||||
desc: '🧱 方块的定义、行为和特性',
|
||||
link: '/wiki/2-方块/1-基础/blocks-intro'
|
||||
},
|
||||
{
|
||||
title: '实体',
|
||||
desc: '🐾 实体的定义、行为和特性',
|
||||
link: '/wiki/3-实体/1-基础/entity-intro-bp'
|
||||
}
|
||||
]" />
|
||||
|
||||
|
||||
540
docs/wiki/2-方块/1-基础/block-components.md
Normal file
540
docs/wiki/2-方块/1-基础/block-components.md
Normal file
@@ -0,0 +1,540 @@
|
||||
---
|
||||
title: 方块组件
|
||||
description: 方块组件用于改变方块在世界中的外观和功能。
|
||||
category: 常规
|
||||
nav_order: 2
|
||||
mentions:
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- yanasakana
|
||||
- SmokeyStack
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- Chikorita-Lover
|
||||
- Luthorius
|
||||
- TheDoctor15
|
||||
- XxPoggyisLitxX
|
||||
- TheItsNameless
|
||||
- ThomasOrs
|
||||
- Kaioga5
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块组件 Components
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式版本 & 最低引擎版本 `1.20.30`
|
||||
在创建自定义方块时使用最新格式版本可获取最新功能和改进。本wiki旨在提供关于自定义方块的最新信息,当前目标格式版本为`1.20.30`。
|
||||
:::
|
||||
:::danger <nbsp/>
|
||||
每个组件在同一时间只能有一个实例生效。重复的组件将被最新的[permutation(条件置换)](/blocks/block-permutations)覆盖。
|
||||
:::
|
||||
|
||||
需要事件触发组件?[点击此处查看!](/blocks/block-events#event-triggers)
|
||||
|
||||
## 应用组件
|
||||
|
||||
方块组件用于改变方块在世界中的外观和功能。它们被应用在`minecraft:block`或其[permutation(条件置换)](/blocks/block-permutations)的`components`子项中。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [BP/blocks/lamp.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:lamp",
|
||||
"menu_category": {
|
||||
"category": "items"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:light_dampening": 0,
|
||||
"minecraft:light_emission": 15,
|
||||
"minecraft:map_color": [210, 200, 190],
|
||||
"minecraft:geometry": "geometry.lamp",
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "lamp"
|
||||
},
|
||||
"shade": {
|
||||
"texture": "lamp_shade"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 碰撞箱
|
||||
|
||||
设置方块实体/粒子的碰撞箱,单位为<abbr title="1/16方块单位">像素</abbr> - 必须包含在基础方块单位内(16×16×16)。
|
||||
|
||||
- 原点从方块的水平中点和垂直底部开始计算,向东北方向延伸。
|
||||
- 尺寸从原点开始计算,向东北方向延伸。
|
||||
|
||||
**也可定义为布尔值:**
|
||||
|
||||
- `false`时实体可穿过方块
|
||||
- `true`时设置单位大小的立方体作为碰撞箱
|
||||
|
||||
**默认值:** `true`
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.50及以上。_
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:collision_box": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 16]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:collision_box": false
|
||||
```
|
||||
:::
|
||||
|
||||
## 工作台
|
||||
|
||||
将方块变为工作台,交互时打开合成界面。
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.50及以上。_
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:crafting_table": {
|
||||
"table_name": "Wiki工作台", // 在合成菜单中显示的名称,可本地化
|
||||
"crafting_tags": ["crafting_table", "wiki_workbench"] // 用于配方文件的标签
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 可被爆炸破坏
|
||||
|
||||
设置方块对爆炸破坏的抗性。
|
||||
|
||||
**也可定义为布尔值:**
|
||||
|
||||
- `false`时不可被爆炸破坏
|
||||
- `true`时爆炸抗性为`0`
|
||||
|
||||
**默认值:** `true`
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:destructible_by_explosion": {
|
||||
"explosion_resistance": 20
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:destructible_by_explosion": false // 不可被爆炸破坏
|
||||
```
|
||||
:::
|
||||
|
||||
## 可被挖掘破坏
|
||||
|
||||
设置挖掘破坏所需时间。
|
||||
|
||||
**也可定义为布尔值:**
|
||||
|
||||
- `false`时不可被挖掘破坏
|
||||
- `true`时可被瞬间破坏
|
||||
|
||||
**默认值:** `true`
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 0.5
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:destructible_by_mining": false // 不可被挖掘破坏
|
||||
```
|
||||
:::
|
||||
|
||||
## 显示名称
|
||||
|
||||
设置当鼠标悬停在物品栏和快捷栏中的方块时显示的文本对应的语言文件键名。
|
||||
|
||||
如果给定的字符串没有对应的翻译,将直接显示原始字符串。
|
||||
|
||||
**注意**:在某些情况下Minecraft可能会回退使用`tile.<标识符>.name`。
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.60及以上。_
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:display_name": "tile.example_block.red.name"
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
|
||||
```c [RP/texts/zh_CN.lang]
|
||||
tile.example_block.red.name=红色示例方块
|
||||
```
|
||||
:::
|
||||
|
||||
## 可燃性
|
||||
|
||||
设置方块的可燃性参数。
|
||||
|
||||
**也可定义为布尔值:**
|
||||
|
||||
- `false`时方块不会着火或被火焰破坏
|
||||
- `true`时将使用下方示例值
|
||||
|
||||
**默认值:** `false`
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:flammable": {
|
||||
"catch_chance_modifier": 5, // 影响方块在火源旁被点燃的几率
|
||||
"destroy_chance_modifier": 20 // 影响方块在燃烧时被火焰破坏的几率
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:flammable": false // 默认值 - 方块不会自然引燃,但可被直接点燃
|
||||
```
|
||||
:::
|
||||
|
||||
## 摩擦力
|
||||
|
||||
设置方块表面摩擦力(0.0至0.9的小数)。数值越小表面越滑。
|
||||
|
||||
**原版示例值:**
|
||||
|
||||
- 泥土:`0.4`
|
||||
- 冰:`0.02`
|
||||
|
||||
**默认值:** `0.4`
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:friction": 0.4
|
||||
```
|
||||
:::
|
||||
|
||||
## 几何模型
|
||||
|
||||
设置方块使用的模型。当与其他方块相交时,模型不会应用面剔除。
|
||||
|
||||
**自定义方块模型限制:**
|
||||
|
||||
- 模型尺寸限制为30×30×30<abbr title="1/16方块单位">像素</abbr>
|
||||
- 每个轴上至少要有1像素位于基础16×16×16方块内
|
||||
- 模型的位置绝对边界为原点各方向30像素。只要遵守第二条规则,模型可放置在这些边界内的任意位置
|
||||
|
||||
**启用时:**
|
||||
|
||||
- 方块变为可呼吸
|
||||
- 方块不再传导红石信号
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.40及以上。_
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:geometry": "geometry.example_block" // 来自'RP/models/entity'或'RP/models/blocks'文件夹的几何模型标识符
|
||||
```
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### 骨骼可见性
|
||||
|
||||
隐藏模型中骨骼的直接子立方体。
|
||||
|
||||
**Molang表达式需遵守[条件置换限制](/blocks/block-permutations#permutation-conditions)。**
|
||||
|
||||
_自格式版本1.20.10起支持`bone_visibility`中的Molang表达式。_
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.example_block", // 来自'RP/models/entity'或'RP/models/blocks'文件夹的几何模型标识符
|
||||
"bone_visibility": {
|
||||
"wiki_bone": false, // 隐藏该骨骼中的立方体
|
||||
"conditional_bone": "q.block_state('wiki:example_state') == 3", // 使用Molang表达式条件设置可见性
|
||||
"another_bone": true // true为默认值,无实际效果
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 光照衰减
|
||||
|
||||
设置光线穿过方块时的衰减程度(0-15整数) - 数值越大透光越少。
|
||||
|
||||
**原版示例值:**
|
||||
|
||||
- 泥土和染色玻璃:`15`
|
||||
- 铁栏杆和玻璃板:`0`
|
||||
|
||||
**默认值:** `15`
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:light_dampening": 7
|
||||
```
|
||||
:::
|
||||
|
||||
## 光照发射
|
||||
|
||||
设置方块发出的光照强度(0-15整数)。
|
||||
|
||||
**原版示例值:**
|
||||
|
||||
- 蛙明灯:`15`
|
||||
- 红石火把(点亮):`7`
|
||||
|
||||
**默认值:** `0`
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:light_emission": 10
|
||||
```
|
||||
:::
|
||||
|
||||
## 战利品表
|
||||
|
||||
设置方块被破坏时掉落的战利品(无视`精准采集`附魔)。
|
||||
|
||||
**若省略则掉落方块本身。**
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:loot": "loot_tables/blocks/custom_block.json"
|
||||
```
|
||||
:::
|
||||
|
||||
## 地图颜色
|
||||
|
||||
设置方块在地图上的显示颜色(十六进制字符串或[R, G, B]数组,0-255)。
|
||||
|
||||
**若省略则地图不显示该方块。**
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:map_color": "#ffffff"
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:map_color": [255, 255, 255]
|
||||
```
|
||||
:::
|
||||
|
||||
## 材质实例
|
||||
|
||||
配置方块的渲染参数,包括纹理和光照处理。
|
||||
|
||||
- 所有实例必须使用相同的渲染方法
|
||||
- 与其他方块相交时,方块面会无条件变暗
|
||||
|
||||
材质实例可与`RP/blocks.json`条目结合使用,创建具有类不透明属性的方块。这主要用于在[自定义玻璃方块](/blocks/custom-glass-blocks)上启用面剔除。
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.40及以上。_
|
||||
|
||||
### 渲染方法
|
||||
|
||||
渲染方法本质上控制方块在世界中的显示方式,类似于实体的材质。以下是各类型的关键属性:
|
||||
|
||||
| 渲染方法 | _透明度_ | _半透明性_ | _背面剔除_ | 原版示例 |
|
||||
| ---------------- | :------: | :--------: | :--------: | ------------------------ |
|
||||
| opaque(默认) | ❌ | ❌ | ✔️ | 泥土、石头、混凝土 |
|
||||
| double_sided | ❌ | ❌ | ❌ | 无 - 用于不透明2D平面 |
|
||||
| alpha_test | ✔️ | ❌ | ❌ | 藤蔓、铁轨、树苗 |
|
||||
| blend | ✔️ | ✔️ | ✔️ | 玻璃、信标、蜂蜜块 |
|
||||
|
||||
- **_透明度_** - 完全透明区域
|
||||
- **_半透明性_** - 半透明区域
|
||||
- 半透明像素在UI渲染中显示为不透明
|
||||
- **_背面剔除_** - 从背面观察时面不可见
|
||||
- 没有背面剔除的渲染方法在远处会消失(基于迷雾/渲染距离)
|
||||
- 在UI渲染中始终启用背面剔除
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:material_instances": {
|
||||
// '*' 为必需实例 - 方块的默认实例(也用于破坏粒子)
|
||||
// 通配符遵循渲染控制器语法
|
||||
// 内置实例名包括'up', 'down', 'north', 'east', 'south'和'west'
|
||||
"*": {
|
||||
"texture": "texture_name", // 在`RP/textures/terrain_textures.json`中定义的短名称
|
||||
"render_method": "blend", // 上表中的渲染方法之一
|
||||
"face_dimming": true, // 默认true;是否根据方向调暗该材质的表面?
|
||||
"ambient_occlusion": true // 默认true;是否根据周围方块生成阴影?
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 自定义实例名称
|
||||
|
||||
:::tip
|
||||
可在Blockbench中通过右键立方体并打开`材质实例`来定义自定义材质实例名称。
|
||||
:::
|
||||
|
||||
可在材质实例中定义自定义实例名称,可被内置实例名称引用,或在方块模型中引用。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "texture_name",
|
||||
"render_method": "blend" // 必须与其他实例匹配
|
||||
},
|
||||
// 自定义实例名称
|
||||
"end": {
|
||||
"texture": "texture_name_end",
|
||||
"render_method": "blend" // 必须与其他实例匹配
|
||||
},
|
||||
"up": "end",
|
||||
"down": "end",
|
||||
// 模型中定义的实例名称:
|
||||
"flower": {
|
||||
"texture": "texture_name_flower",
|
||||
"render_method": "blend" // 必须与其他实例匹配
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 放置过滤器
|
||||
|
||||
配置方块可存在的条件。当条件不满足时,方块将无法放置;若已放置则会弹出。
|
||||
|
||||
**`block_filter`最多可包含64个条目。**
|
||||
|
||||
**若省略,方块可被放置并存在于任何表面。**
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.60及以上。_
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"], // 可包含'up', 'down', 'north', 'east', 'south', 'west'和'side'
|
||||
"block_filter": [
|
||||
// 测试标识符
|
||||
"minecraft:dirt",
|
||||
// 测试标签
|
||||
{ "tags": "!q.any_tag('stone', 'wiki_tag')" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
查看[此页面](/blocks/block-tags)获取原版标签及相关方块列表。
|
||||
|
||||
## 选择箱
|
||||
|
||||
设置方块的可选区域(点击框),单位为<abbr title="1/16方块单位">像素</abbr> - 必须包含在基础方块单位内(16×16×16)。
|
||||
|
||||
- 原点从方块的水平中点和垂直底部开始计算,向东北方向延伸。
|
||||
- 尺寸从原点开始计算,向东北方向延伸。
|
||||
|
||||
**也可定义为布尔值:**
|
||||
|
||||
- `false`时实体可穿过方块
|
||||
- `true`时设置单位大小的立方体作为碰撞箱
|
||||
|
||||
**默认值:** `true`
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`中发布,适用于格式版本1.19.60及以上。_
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:selection_box": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 16]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
或:
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:selection_box": false
|
||||
```
|
||||
:::
|
||||
|
||||
## 变换
|
||||
|
||||
允许对方块进行平移、缩放和旋转(包含视觉和功能变化)。
|
||||
|
||||
**变换后的模型不得超过[几何模型限制](#geometry)。**
|
||||
|
||||
:::tip
|
||||
学习如何应用[可旋转方块](/blocks/rotatable-blocks),就像熔炉和生物头颅一样根据放置方向旋转!
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:transformation": {
|
||||
"translation": [-5, 8, 0],
|
||||
"rotation": [90, 180, 0],
|
||||
"scale": [0.5, 1, 0.5],
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 单位立方体(实验性功能) {#unit-cube}
|
||||
|
||||
:::warning 实验性功能
|
||||
此组件需要启用`Holiday Creator Features`实验性玩法,未来可能会被移除/修改。
|
||||
:::
|
||||
|
||||
将方块变为16×16×16立方体,覆盖`minecraft:geometry`设置。
|
||||
|
||||
**启用时:**
|
||||
|
||||
- 方块变为不可呼吸
|
||||
- 方块可传导红石信号
|
||||
|
||||
**如果方块的纹理/模型不需要根据条件置换改变,请在`RP/blocks.json`中定义纹理以避免使用此实验性组件。**
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:unit_cube": {}
|
||||
```
|
||||
|
||||
:::
|
||||
623
docs/wiki/2-方块/1-基础/block-events.md
Normal file
623
docs/wiki/2-方块/1-基础/block-events.md
Normal file
@@ -0,0 +1,623 @@
|
||||
---
|
||||
title: 方块事件与触发器
|
||||
description: 方块事件允许你在满足特定条件时操控游戏世界。
|
||||
category: 常规
|
||||
nav_order: 8
|
||||
tags:
|
||||
- 实验性功能
|
||||
mentions:
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- yanasakana
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- SmokeyStack
|
||||
- TheDoctor15
|
||||
- XxPoggyisLitxX
|
||||
- TheItsNameless
|
||||
- ThomasOrs
|
||||
- QuazChick
|
||||
- VactricaKing
|
||||
- BlazeDrake
|
||||
---
|
||||
|
||||
# 方块事件与触发器
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式与最低引擎版本 `1.20.30`
|
||||
创建自定义方块时使用最新格式版本可获得新功能和改进。本wiki旨在分享关于自定义方块的最新信息,当前目标格式版本为`1.20.30`。
|
||||
:::
|
||||
:::warning 实验性功能
|
||||
方块事件需要启用`假日创作者功能`实验性玩法。
|
||||
:::
|
||||
:::danger 警告
|
||||
方块事件已被弃用,将在未来更新中移除。除非必要,否则不建议使用,因为在移除后你需要将所有功能迁移至脚本系统。
|
||||
:::
|
||||
|
||||
## 定义事件
|
||||
|
||||
方块事件允许你在满足特定条件时操控游戏世界,事件定义在`minecraft:block`的`events`子项中。在事件内部,你可以通过配置[事件响应](#事件响应)来设定触发事件时执行的操作。
|
||||
|
||||
[事件触发器](#事件触发器)会在适当条件下运行事件,执行所有关联的事件响应。
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/loot_dropper.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:loot_dropper"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:on_step_on": {
|
||||
"event": "wiki:drop_loot"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"wiki:drop_loot": {
|
||||
"spawn_loot": {
|
||||
"table": "loot_tables/blocks/my_loot_table.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
_此示例在实体踏上方块时生成战利品_
|
||||
|
||||
## 序列响应
|
||||
|
||||
序列允许你多次运行相同响应,或在满足条件时触发特定操作。
|
||||
|
||||
所有事件响应都应包含在序列中。
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > events]
|
||||
"wiki:my_sequence": {
|
||||
"sequence": [
|
||||
{
|
||||
"set_block_state": {
|
||||
"wiki:my_state": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:my_state')", // 可选
|
||||
"trigger": {
|
||||
"event": "wiki:my_entity_event",
|
||||
"target": "other"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 随机响应
|
||||
|
||||
随机执行事件响应。
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > events]
|
||||
"wiki:random_action": {
|
||||
"randomize": [
|
||||
{
|
||||
"weight": 1, // 1/4概率
|
||||
"set_block_state": {
|
||||
"wiki:my_state": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"weight": 3, // 3/4概率
|
||||
"trigger": {
|
||||
"event": "wiki:my_entity_event",
|
||||
"target": "other"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 事件响应
|
||||
|
||||
- [`add_mob_effect`](#添加生物效果)
|
||||
- [`damage`](#造成伤害)
|
||||
- [`decrement_stack`](#减少堆叠)
|
||||
- [`die`](#摧毁)
|
||||
- [`play_effect`](#播放特效)
|
||||
- [`play_sound`](#播放音效)
|
||||
- [`remove_mob_effect`](#移除生物效果)
|
||||
- [`run_command`](#执行命令)
|
||||
- [`set_block`](#设置方块)
|
||||
- [`set_block_at_pos`](#在指定位置设置方块)
|
||||
- [`set_block_state`](#设置方块状态)
|
||||
- [`spawn_loot`](#生成战利品)
|
||||
- [`swing`](#挥动)
|
||||
- [`teleport`](#传送)
|
||||
- [`transform_item`](#转换物品)
|
||||
- [`trigger`](#触发事件)
|
||||
|
||||
### 添加生物效果
|
||||
|
||||
为指定目标添加生物效果。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:effect_event": {
|
||||
"add_mob_effect": {
|
||||
"effect": "poison",
|
||||
"target": "other",
|
||||
"duration": 8,
|
||||
"amplifier": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 造成伤害
|
||||
|
||||
对目标造成指定类型和数值的伤害。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:damage_event": {
|
||||
"damage": {
|
||||
"type": "magic",
|
||||
"target": "other",
|
||||
"amount": 4
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 减少堆叠
|
||||
|
||||
移除玩家当前手持物品堆叠中的一个物品。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:remove_one": {
|
||||
"decrement_stack": {
|
||||
"ignore_game_mode": true // 可选 - 是否影响创造模式玩家(默认为false)
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 摧毁
|
||||
|
||||
摧毁指定目标,若目标为`self`则方块直接消失且不生成战利品或效果。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:destroy": {
|
||||
"die": {
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 播放特效
|
||||
|
||||
在目标位置播放粒子特效。
|
||||
|
||||
支持的`effect`值未知。可通过[`run_command`](#执行命令)配合`playsound`命令实现类似效果。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:particle_effect": {
|
||||
"play_effect": {
|
||||
"effect": "???",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 播放音效
|
||||
|
||||
在目标位置播放音效。
|
||||
|
||||
支持`RP/sounds.json`中大多数原版独立音效事件ID,但自定义音效条目不可用。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:play_sound": {
|
||||
"play_sound": {
|
||||
"sound": "beacon.power",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 移除生物效果
|
||||
|
||||
移除目标的指定生物效果。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:remove_effect_event": {
|
||||
"remove_mob_effect": {
|
||||
"effect": "poison",
|
||||
"target": "other"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 执行命令
|
||||
|
||||
对目标执行命令。
|
||||
|
||||
使用数组可执行多个命令。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:execute_event": {
|
||||
"run_command": {
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"command": "summon pig"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
或...
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:execute_event": {
|
||||
"run_command": {
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"command": [
|
||||
"summon pig",
|
||||
"say 大家欢迎小猪!"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 设置方块
|
||||
|
||||
用指定方块替换当前方块。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:place_block": {
|
||||
"set_block": {
|
||||
"block_type": "minecraft:grass"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
或...
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:place_block": {
|
||||
"set_block": {
|
||||
"block_type": {
|
||||
"name": "minecraft:trapdoor",
|
||||
"states": {
|
||||
"direction": 2,
|
||||
"open_bit": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 在指定位置设置方块
|
||||
|
||||
在方块相对位置生成指定方块。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:generate_stone_above": {
|
||||
"set_block_at_pos": {
|
||||
"block_type": "minecraft:stone",
|
||||
"block_offset": [0, 1, 0]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
或...
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:generate_upper_door_above": {
|
||||
"set_block_at_pos": {
|
||||
"block_type": {
|
||||
"name": "minecraft:wooden_door",
|
||||
"states": {
|
||||
"upper_block_bit": true
|
||||
}
|
||||
},
|
||||
"block_offset": [0, 1, 0]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 设置方块状态
|
||||
|
||||
设置方块状态值(可设置为Molang表达式字符串的返回值)。
|
||||
|
||||
:::warning
|
||||
字符串值会被解析为Molang表达式。因此,要设置字符串状态时,必须用`'`包裹值(见示例)。
|
||||
:::
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:change_state": {
|
||||
"set_block_state": {
|
||||
"wiki:boolean_state_example": false,
|
||||
"wiki:integer_state_example": "q.block_state('wiki:integer_state_example') + 1",
|
||||
"wiki:string_state_example": "'red'"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 生成战利品
|
||||
|
||||
生成战利品表内容。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:drop_loot": {
|
||||
"spawn_loot": {
|
||||
"table": "loot_tables/blocks/my_loot_table.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 挥动
|
||||
|
||||
使关联实体执行挥动动作。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:swing_arm": {
|
||||
"swing": {}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 传送
|
||||
|
||||
将目标随机传送至目标点周围。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:go_away": {
|
||||
"teleport": {
|
||||
"target": "other", // 被传送实体
|
||||
"avoid_water": true, // 避免传入水中
|
||||
"land_on_block": true, // 将目标放置在方块上
|
||||
"destination": [0, 0, 0], // 目标原点
|
||||
"max_range": [5, 6, 7] // 相对原点的最大偏移范围
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 转换物品
|
||||
|
||||
替换目标的当前手持物品。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:replace": {
|
||||
"transform_item": {
|
||||
"transform": "iron_sword"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 触发事件
|
||||
|
||||
触发指定目标的事件。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > events]
|
||||
"wiki:trigger_crack": {
|
||||
"trigger": {
|
||||
"event": "wiki:crack",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 事件触发器
|
||||
|
||||
事件触发器通过[组件](/blocks/block-components)定义,可通过[permutations](/blocks/block-permutations)动态添加、修改或移除。
|
||||
|
||||
- [`minecraft:on_fall_on`](#跌落触发)
|
||||
- [`minecraft:on_interact`](#交互触发)
|
||||
- [`minecraft:on_placed`](#放置触发)
|
||||
- [`minecraft:on_player_destroyed`](#玩家破坏触发)
|
||||
- [`minecraft:on_player_placing`](#玩家放置时触发)
|
||||
- [`minecraft:on_step_off`](#离开触发)
|
||||
- [`minecraft:on_step_on`](#踏入触发)
|
||||
- [`minecraft:queued_ticking`](#队列计时)
|
||||
- [`minecraft:random_ticking`](#随机计时)
|
||||
|
||||
### 跌落触发
|
||||
|
||||
当实体跌落在方块上时触发事件。
|
||||
|
||||
**注意**:需要`minecraft:collision_box`组件的Y轴高度≥4。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_fall_on": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')", // 可选
|
||||
"min_fall_distance": 5
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 交互触发
|
||||
|
||||
当玩家与方块交互时触发事件。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_interact": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 放置触发
|
||||
|
||||
当方块被放置时触发事件。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_placed": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 玩家破坏触发
|
||||
|
||||
当玩家通过挖掘破坏方块时触发事件(创造模式不触发)。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 玩家放置时触发
|
||||
|
||||
当玩家放置方块时触发事件。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 离开触发
|
||||
|
||||
当实体离开方块时触发事件。
|
||||
|
||||
**注意**:需要`minecraft:collision_box`组件的Y轴高度≥4。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_step_off": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 踏入触发
|
||||
|
||||
当实体踏上方块时触发事件。
|
||||
|
||||
**注意**:需要`minecraft:collision_box`组件的Y轴高度≥4。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:on_step_on": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 队列计时
|
||||
|
||||
在`interval_range`范围内随机间隔触发事件。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:queued_ticking": {
|
||||
"looping": true,
|
||||
"interval_range": [20, 20], // 两个游戏刻数值,随机决定延迟时间
|
||||
"on_tick": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 随机Tick
|
||||
|
||||
在每次随机刻触发事件(如作物随机生长机制)。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"event": "wiki:example_event",
|
||||
"target": "self", // 可选 - 默认为'self'(目标为方块)
|
||||
"condition": "q.block_state('wiki:boolean_state_example')" // 可选
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
83
docs/wiki/2-方块/1-基础/block-permutations.md
Normal file
83
docs/wiki/2-方块/1-基础/block-permutations.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
title: 方块变换(转体)
|
||||
description: 方块变换数组提供了一种基于当前置换条件性应用组件的方法。
|
||||
category: 常规
|
||||
nav_order: 7
|
||||
mentions:
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块变换(转体)
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式要求 & 最低引擎版本 `1.20.30`
|
||||
在学习方块变换前,您应当已熟练掌握[方块状态](/blocks/block-states)知识。
|
||||
|
||||
使用方块状态时,请确保资源包清单中的`min_engine_version`为`1.20.20`或更高版本。
|
||||
:::
|
||||
|
||||
方块`permutations`数组提供了一种基于当前置换(状态值集合)条件性应用组件(包括事件触发器和标签)的方式。
|
||||
|
||||
`permutations`数组中的组件可以覆盖方块的基类组件以及其他组件列表中的组件。置换数组中最后出现的条目具有最高优先级。
|
||||
|
||||
## 定义置换
|
||||
|
||||
`permutations`数组是`minecraft:block`的直接子项,由包含组件的对象组成。当条件判断为真值(非false或0)时,相关组件将被应用。
|
||||
|
||||
**置换条件必须遵守其[Molang限制条件](#置换条件限制)。**
|
||||
|
||||
_自实验性玩法`Holiday Creator Features`发布,支持格式版本1.19.70及更高。_
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [BP/blocks/custom_block.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_block",
|
||||
"states": {
|
||||
"wiki:integer_state_example": [2, 4, 6, 8],
|
||||
"wiki:boolean_state_example": [false, true],
|
||||
"wiki:string_state_example": ["red", "green", "blue"]
|
||||
}
|
||||
},
|
||||
"components": {},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "q.block_state('wiki:integer_state_example') == 2",
|
||||
"components": {
|
||||
"minecraft:friction": 0.1
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:boolean_state_example')",
|
||||
"components": {
|
||||
"minecraft:friction": 0.8 // 覆盖之前的置换
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:string_state_example') == 'red' && !q.block_state('wiki:boolean_state_example')",
|
||||
"components": {
|
||||
"minecraft:geometry": "geometry.pig"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 置换条件限制
|
||||
|
||||
当条件评估为真值(非false或0)时,关联的组件列表将被应用。
|
||||
|
||||
置换条件需以Molang表达式字符串形式编写,并具有严格限制:
|
||||
|
||||
- 条件判断完全基于方块的置换状态,因此只能使用`q.block_state`查询函数
|
||||
- 这意味着条件判断不会产生副作用
|
||||
- 禁止使用以下数学函数:`math.die_roll`、`math.die_roll_integer`、`math.random`、`math.random_integer`
|
||||
- 不可进行变量赋值操作
|
||||
|
||||
(注:保留英文术语如Component、Entity、Block等,根据中文技术文档惯例处理专有名词)
|
||||
128
docs/wiki/2-方块/1-基础/block-states.md
Normal file
128
docs/wiki/2-方块/1-基础/block-states.md
Normal file
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: 方块状态
|
||||
description: 方块状态允许你的方块拥有多种变体,每种变体通过使用置换具备独特的功能和外观。
|
||||
category: 常规
|
||||
nav_order: 4
|
||||
mentions:
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块状态
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式要求 & 最低引擎版本 `1.20.30`
|
||||
使用方块状态时,请确保资源包清单中的 `min_engine_version` 设置为 `1.20.20` 或更高。
|
||||
:::
|
||||
|
||||
方块状态允许你的方块拥有多种变体,每种变体通过使用[置换](/blocks/block-permutations)具备独特的功能和外观。
|
||||
|
||||
## 定义状态
|
||||
|
||||
有效状态值可以定义为布尔值、整数或字符串数组,也可以通过对象定义为整数范围。`values` 数组中的第一个元素将作为默认值使用。
|
||||
|
||||
### 置换数量限制
|
||||
|
||||
**每个状态最多可定义 16 个有效值。所有可能的状态值组合([置换](/blocks/block-permutations))总数不应超过 65,536。**
|
||||
|
||||
计算方块置换总数时,需将所有状态的有效值数量相乘。例如下方示例的计算公式为 3 × 2 × 3 × 6,说明该方块具有 108 种可能的置换组合。
|
||||
|
||||
_该功能需启用 `Holiday Creator Features` 实验性玩法(格式版本 1.19.70 及以上)。_
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/custom_block.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_block",
|
||||
"states": {
|
||||
"wiki:string_state_example": ["red", "green", "blue"],
|
||||
"wiki:boolean_state_example": [false, true],
|
||||
"wiki:integer_state_example": [1, 2, 3],
|
||||
"wiki:integer_range_state_example": {
|
||||
"values": { "min": 0, "max": 5 } // 等同于 [0, 1, 2, 3, 4, 5]
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": { ... },
|
||||
"permutations": [ ... ]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 获取状态值
|
||||
|
||||
以下列出在不同上下文中获取方块状态当前值的方法。
|
||||
|
||||
### Molang 查询函数
|
||||
|
||||
可通过 `block_state` 查询函数获取状态值。
|
||||
|
||||
```c
|
||||
q.block_state('wiki:string_state_example') == 'blue'
|
||||
```
|
||||
|
||||
### 命令参数
|
||||
|
||||
在 `execute` 和 `testforblock` 等命令中使用[方块状态参数](/commands/block-states)来检查状态值。
|
||||
|
||||
```c
|
||||
execute if block ~~~ wiki:custom_block["wiki:string_state_example"="blue", "wiki:integer_state_example"=4] run kill
|
||||
```
|
||||
|
||||
### 脚本API
|
||||
|
||||
:::warning 实验性功能
|
||||
使用 [`BlockPermutation.getState()`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/blockpermutation#getstate) 方法需启用 `Beta APIs` 实验性玩法。
|
||||
:::
|
||||
|
||||
通过 [`BlockPermutation.getState()`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/blockpermutation#getstate) 方法可获取不同状态的当前值。
|
||||
|
||||
```js
|
||||
customBlock.permutation.getState("wiki:integer_state_example") === 3
|
||||
```
|
||||
|
||||
## 设置状态值
|
||||
|
||||
### 命令参数
|
||||
|
||||
在 `setblock` 和 `fill` 等命令中使用[方块状态参数](/commands/block-states)来修改默认状态值。
|
||||
|
||||
```c
|
||||
setblock ~~~ wiki:custom_block["wiki:string_state_example"="blue", "wiki:integer_state_example"=4]
|
||||
```
|
||||
|
||||
### 脚本API
|
||||
|
||||
:::warning 实验性功能
|
||||
使用 [`BlockPermutation.withState()`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/blockpermutation#withstate) 方法需启用 `Beta APIs` 实验性玩法。
|
||||
:::
|
||||
|
||||
[`BlockPermutation.withState()`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/blockpermutation#withstate) 方法会返回修改了指定状态值的新置换对象。可通过 [`Block.setPermutation()`](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/block#setpermutation) 方法应用此置换,如下所示:
|
||||
|
||||
```js
|
||||
customBlock.setPermutation(
|
||||
customBlock.permutation.withState("wiki:boolean_state_example", false)
|
||||
);
|
||||
```
|
||||
|
||||
### 事件响应
|
||||
|
||||
:::warning 实验性功能
|
||||
方块事件需启用 `Holiday Creator Features` 实验性玩法。
|
||||
:::
|
||||
|
||||
使用 [`set_block_state`](/blocks/block-events#set-block-state) 事件响应可以修改自定义方块状态的值。
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > events]
|
||||
"wiki:change_state": {
|
||||
"set_block_state": {
|
||||
"wiki:boolean_state_example": false,
|
||||
"wiki:string_state_example": "'red'"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
145
docs/wiki/2-方块/1-基础/block-tags.md
Normal file
145
docs/wiki/2-方块/1-基础/block-tags.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: 方块标签
|
||||
category: 常规
|
||||
nav_order: 3
|
||||
mentions:
|
||||
- SirLich
|
||||
- yanasakana
|
||||
- aexer0e
|
||||
- SmokeyStack
|
||||
- MedicalJewel105
|
||||
- Luthorius
|
||||
- Chikorita-Lover
|
||||
- victorsigma
|
||||
- TheItsNameless
|
||||
- QuazChick
|
||||
- Kaioga5
|
||||
---
|
||||
|
||||
# 方块标签
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
方块标签可用于确保某个方块符合特定条件。
|
||||
|
||||
## 应用标签
|
||||
|
||||
方块标签的应用方式与物品标签相同 - 在方块的`components`组件中添加 - 如下所示:
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/tree_stump.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:tree_stump",
|
||||
"menu_category": {
|
||||
"category": "nature"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"tag:wood": {},
|
||||
"tag:my_lovely_tag": {},
|
||||
"tag:wiki:very_useless": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 测试标签
|
||||
|
||||
可通过以下Molang查询函数检测标签:
|
||||
|
||||
- `q.all_tags`
|
||||
- `q.any_tag`
|
||||
|
||||
:::warning 实验性功能
|
||||
以下查询函数需要启用实验性Molang功能。
|
||||
:::
|
||||
|
||||
- `q.block_has_all_tags`
|
||||
- `q.block_has_any_tag`
|
||||
- `q.block_neighbor_has_all_tags`
|
||||
- `q.block_neighbor_has_any_tag`
|
||||
- `q.relative_block_has_all_tags`
|
||||
- `q.relative_block_has_any_tag`
|
||||
|
||||
物品检测方块标签的示例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/items/custom_pickaxe.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_pickaxe",
|
||||
"menu_category": {
|
||||
"category": "equipment",
|
||||
"group": "itemGroup.name.pickaxe"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:digger": {
|
||||
"use_efficiency": true,
|
||||
"destroy_speeds": [
|
||||
{
|
||||
"speed": 5,
|
||||
"block": {
|
||||
"tags": "q.any_tag('custom_ore', 'stone', 'metal')"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 方块标签列表
|
||||
|
||||
### 原版标签
|
||||
|
||||
原版标签可应用于自定义方块,部分原版方块内部已标记。此类标签不会赋予方块原版特性,仅用于通过标签查询时与原版方块保持相同检测结果。
|
||||
|
||||
| 标签 | 原版用途 |
|
||||
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| wood | 金合欢木门、金合欢木栅栏、金合欢木栅栏门、金合欢木板、金合欢木压力板、金合欢木告示牌、木桶、蜂巢、蜂箱、白桦木门、白桦木栅栏、白桦木栅栏门、白桦原木、白桦木板、白桦木压力板、白桦木告示牌、白桦木台阶、白桦木楼梯、深色橡木门、深色橡木栅栏、深色橡木栅栏门、深色橡木原木、深色橡木板、深色橡木压力板、深色橡木告示牌、深色橡木台阶、深色橡木楼梯、制箭台、丛林木门、丛林木栅栏、丛林木栅栏门、丛林原木、丛林木板、丛林压力板、丛林告示牌、丛林木台阶、丛林木楼梯、梯子、橡木门、橡木栅栏、橡木栅栏门、橡木原木、橡木板、橡木压力板、橡木告示牌、橡木台阶、橡木楼梯、橡木活板门、锻造台、云杉木门、云杉木栅栏、云杉木栅栏门、云杉原木、云杉木板、云杉木压力板、云杉木告示牌、云杉木台阶、云杉木楼梯、云杉木活板门 |
|
||||
| pumpkin | 雕刻过的南瓜、南瓜灯、南瓜 |
|
||||
| plant | 金合欢树苗、白桦树苗、深色橡树苗、丛林树苗、大型蕨、丁香、橡树苗、牡丹、玫瑰丛、云杉树苗、向日葵、高草丛 |
|
||||
| stone | 安山岩、安山岩墙、砖台阶、砖墙、砖块、圆石、圆石台阶、圆石楼梯、圆石墙、闪长岩、闪长岩墙、滴水石块、末地石砖墙、花岗岩、花岗岩墙、苔石、苔石墙、下界砖墙、磨制安山岩、磨制闪长岩、磨制花岗岩、海晶石墙、石英台阶、红色下界砖墙、红砂岩墙、砂岩台阶、砂岩墙、平滑石台阶、石头、石砖墙、石砖台阶 |
|
||||
| metal | 金块、铁块、炼药锅、铁栏杆 |
|
||||
| diamond_pick_diggable | 粗金块、粗铁块、煤矿石、深层煤矿石、深层绿宝石矿石、深层金矿石、深层铁矿石、深层红石矿石、钻石矿石、绿宝石矿石、金矿石、铁矿石、青金石矿石、黑曜石、红石矿石 |
|
||||
| gold_pick_diggable | (无内容) |
|
||||
| iron_pick_diggable | 粗金块、粗铁块、煤矿石、深层煤矿石、深层绿宝石矿石、深层金矿石、深层铁矿石、深层红石矿石、钻石矿石、绿宝石矿石、金矿石、铁矿石、青金石矿石、红石矿石 |
|
||||
| stone_pick_diggable | (无内容) |
|
||||
| wood_pick_diggable | (无内容) |
|
||||
| dirt | 耕地 |
|
||||
| sand | 红沙、沙子 |
|
||||
| gravel | 沙砾 |
|
||||
| grass | 砂土、泥土、草径、草方块 |
|
||||
| snow | 雪 |
|
||||
| rail | 激活铁轨、探测铁轨、动力铁轨、铁轨 |
|
||||
| water | 水 |
|
||||
| mob_spawner | 刷怪笼 |
|
||||
| lush_plants_replaceable | (无内容) |
|
||||
| azalea_log_replaceable | (无内容) |
|
||||
| not_feature_replaceable | 基岩、箱子、末地传送门框架、刷怪笼 |
|
||||
| text_sign | 所有种类的告示牌 |
|
||||
| minecraft:crop | 甜菜根、胡萝卜、马铃薯、小麦 |
|
||||
| fertilize_area | 所有花卉(除高茎花卉和凋灵玫瑰外);绯红菌岩、诡异菌岩、草、苔藓块 |
|
||||
|
||||
### 原版方块标签
|
||||
|
||||
原版方块标签是专门为方块设计的标签,可以为标记的方块赋予某些原版特性。
|
||||
|
||||
| 标签 | 原版应用 | 描述 |
|
||||
| -------- | ---------------- | ------------ |
|
||||
| acacia | 金合欢原木 | |
|
||||
| birch | 白桦原木 | |
|
||||
| dark_oak | 深色橡木原木 | |
|
||||
| jungle | 丛林原木 | |
|
||||
| log | 所有原木类型 | 原木方块 |
|
||||
| oak | 橡木原木 | |
|
||||
| spruce | 云杉原木 | |
|
||||
110
docs/wiki/2-方块/1-基础/block-traits.md
Normal file
110
docs/wiki/2-方块/1-基础/block-traits.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
title: 方块特性
|
||||
description: 方块特性可轻松为自定义方块应用原版方块状态(如朝向),无需借助事件和触发器。
|
||||
category: 常规
|
||||
nav_order: 5
|
||||
mentions:
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块特性
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式要求 & 最低引擎版本 `1.20.30`
|
||||
在学习方块特性前,您应当已熟练掌握[方块状态](/blocks/block-states)知识。
|
||||
|
||||
使用方块状态时,请确保资源包清单中的`min_engine_version`为`1.20.20`或更高版本。
|
||||
:::
|
||||
|
||||
## 应用特性
|
||||
|
||||
方块特性可轻松为自定义方块应用原版方块状态(如朝向),无需借助复杂的事件和触发器系统。
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/custom_slab.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_slab",
|
||||
"menu_category": {
|
||||
"category": "construction",
|
||||
"group": "itemGroup.name.slab"
|
||||
},
|
||||
"traits": {
|
||||
"minecraft:placement_position": {
|
||||
"enabled_states": ["minecraft:vertical_half"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": { ... },
|
||||
"permutations": [ ... ]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
_此示例将在放置时设置`minecraft:vertical_half`方块状态为`'top'`或`'bottom'`——具体取决于玩家视角位置。_
|
||||
|
||||
**仍需通过置换系统配合条件查询来实现功能差异:**
|
||||
|
||||
```c
|
||||
q.block_state('minecraft:vertical_half') // 查询垂直半区状态
|
||||
```
|
||||
|
||||
## 放置朝向
|
||||
|
||||
记录玩家放置方块时的旋转方向信息。
|
||||
|
||||
_自实验性玩法`Upcoming Creator Features`发布,支持格式版本1.20.30及更高。_
|
||||
|
||||
**可启用以下状态:**
|
||||
|
||||
| 状态名称 | 可选值 | 描述 |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| `minecraft:cardinal_direction` | `"south"`(默认)<br>`"north"`<br>`"west"`<br>`"east"` | 放置时玩家的主要朝向(东南西北) |
|
||||
| `minecraft:facing_direction` | `"down"`(默认)<br>`"up"`<br>`"south"`<br>`"north"`<br>`"west"`<br>`"east"` | 放置时玩家的完整朝向(含上下方向) |
|
||||
|
||||
<br>
|
||||
|
||||
**额外参数:**
|
||||
|
||||
- `y_rotation_offset` - 此旋转偏移仅适用于水平方向状态值(北/南/西/东),必须指定轴对齐角度(如90、180、-90)
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > description > traits]
|
||||
"minecraft:placement_direction": {
|
||||
"enabled_states": ["minecraft:cardinal_direction"],
|
||||
"y_rotation_offset": 180 // Y轴旋转偏移量
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 放置位置
|
||||
|
||||
记录玩家放置方块时的具体位置信息。
|
||||
|
||||
_自实验性玩法`Upcoming Creator Features`发布,支持格式版本1.20.30及更高。_
|
||||
|
||||
**可启用以下状态:**
|
||||
|
||||
| 状态名称 | 可选值 | 描述 |
|
||||
| ------------------------- | -------------------------------------------------------------------------------- | ----------------------------- |
|
||||
| `minecraft:block_face` | `"down"`(默认)<br>`"up"`<br>`"south"`<br>`"north"`<br>`"west"`<br>`"east"` | 方块被放置时所处的表面方位 |
|
||||
| `minecraft:vertical_half` | `"top"`<br>`"bottom"`(默认) | 方块被放置时所处的垂直半区位置 |
|
||||
|
||||
<br>
|
||||
|
||||
**_此特性无额外参数_**
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > description > traits]
|
||||
"minecraft:placement_position": {
|
||||
"enabled_states": [
|
||||
"minecraft:block_face", // 方块表面方位
|
||||
"minecraft:vertical_half" // 垂直半区位置
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
62
docs/wiki/2-方块/1-基础/blocks-experimental.md
Normal file
62
docs/wiki/2-方块/1-基础/blocks-experimental.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: 实验性方块
|
||||
category: 通用
|
||||
tags:
|
||||
- 信息
|
||||
- 实验性
|
||||
mentions:
|
||||
- SmokeyStack
|
||||
- MedicalJewel105
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 实验性方块
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式版本 `1.20.30`
|
||||
在创建自定义方块时使用最新格式版本,可获取最新功能和改进。本维基旨在分享自定义方块的最新信息,当前目标格式版本为 `1.20.30`。
|
||||
:::
|
||||
|
||||
本文作为索引文档,概述自定义方块功能的实验性要求。
|
||||
|
||||
## 方块组件
|
||||
|
||||
| 组件 | 所需实验性功能 |
|
||||
| ------------------------------------------------------------------------------------------- | --------------------------------- |
|
||||
| [`minecraft:collision_box`](/blocks/block-components#collision-box) | 无(格式版本1.19.50及以上) |
|
||||
| [`minecraft:crafting_table`](/blocks/block-components#crafting-table) | 无(格式版本1.19.50及以上) |
|
||||
| [`minecraft:destructible_by_explosion`](/blocks/block-components#destructible-by-explosion) | 无 |
|
||||
| [`minecraft:destructible_by_mining`](/blocks/block-components#destructible-by-mining) | 无 |
|
||||
| [`minecraft:display_name`](/blocks/block-components#display-name) | 无(格式版本1.19.60及以上) |
|
||||
| [`minecraft:flammable`](/blocks/block-components#flammable) | 无 |
|
||||
| [`minecraft:friction`](/blocks/block-components#friction) | 无 |
|
||||
| [`minecraft:geometry`](/blocks/block-components#geometry) | 无(格式版本1.19.40及以上) |
|
||||
| [`minecraft:light_dampening`](/blocks/block-components#light-dampening) | 无 |
|
||||
| [`minecraft:light_emission`](/blocks/block-components#light-emission) | 无 |
|
||||
| [`minecraft:loot`](/blocks/block-components#loot) | 无 |
|
||||
| [`minecraft:map_color`](/blocks/block-components#map-color) | 无 |
|
||||
| [`minecraft:material_instances`](/blocks/block-components#material-instances) | 无(格式版本1.19.40及以上) |
|
||||
| [`minecraft:placement_filter`](/blocks/block-components#placement-filter) | 无(格式版本1.19.60及以上) |
|
||||
| [`minecraft:selection_box`](/blocks/block-components#selection-box) | 无(格式版本1.19.60及以上) |
|
||||
| [`minecraft:transformation`](/blocks/block-components#transformation) | 无 |
|
||||
| [`minecraft:unit_cube`](/blocks/block-components#unit-cube) | **`假日创作者功能(Holiday Creator Features)`** |
|
||||
|
||||
## 方块状态
|
||||
|
||||
_从实验性功能 **`假日创作者功能`** 中释放,适用于格式版本1.19.70及以上。_
|
||||
|
||||
## 方块特性
|
||||
|
||||
| 特性 | 所需实验性功能 |
|
||||
| ------------------------------------------------------------------------------- | --------------------------------- |
|
||||
| [`minecraft:placement_direction`](/blocks/block-components#placement-direction) | 无(格式版本1.20.20及以上) |
|
||||
| [`minecraft:placement_position`](/blocks/block-components#placement-position) | 无(格式版本1.20.20及以上) |
|
||||
|
||||
## 方块置换
|
||||
|
||||
_从实验性功能 **`假日创作者功能`** 中释放,适用于格式版本1.19.70及以上。_
|
||||
|
||||
## 方块事件与触发器
|
||||
|
||||
**完整功能仍处于实验性阶段,需启用 `假日创作者功能`。**
|
||||
322
docs/wiki/2-方块/1-基础/blocks-intro.md
Normal file
322
docs/wiki/2-方块/1-基础/blocks-intro.md
Normal file
@@ -0,0 +1,322 @@
|
||||
---
|
||||
title: 方块入门
|
||||
description: A "Hello world" guide in making blocks. Learn the block format and how to create basic custom blocks.
|
||||
category: General
|
||||
nav_order: 1
|
||||
---
|
||||
|
||||
# 方块入门
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 格式版本 & 最低引擎版本 `1.20.30`
|
||||
本页介绍基础方块特性。更多方块组件内容请访问[此处](/blocks/block-components)。
|
||||
:::
|
||||
|
||||
:::danger <nbsp/>
|
||||
原版方块的逻辑是硬编码实现的,无法被修改或访问。
|
||||
:::
|
||||
|
||||
Minecraft 基岩版允许我们添加具有多种类原版特性的自定义方块。自定义方块可以拥有多阶段生长(如植物)、方向朝向等实用功能。
|
||||
|
||||
本教程将指导如何在稳定版 Minecraft 中创建基础方块。
|
||||
|
||||
## 注册方块
|
||||
|
||||
方块定义的结构与实体类似:包含行为描述和定义方块特性的组件列表。
|
||||
|
||||
与实体不同,方块除`RP/blocks.json`外没有其他资源定义。
|
||||
|
||||
以下是将自定义方块加入创造模式物品栏所需的**最低限度**行为包代码:
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [BP/blocks/custom_block.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_block",
|
||||
"menu_category": {
|
||||
"category": "construction", // 方块所在的创造模式物品栏或配方书标签
|
||||
"group": "itemGroup.name.concrete", // 方块所属的可展开分组(可选)
|
||||
"is_hidden_in_commands": false // 是否在命令中隐藏该方块(可选)
|
||||
}
|
||||
},
|
||||
"components": {} // 必须保留,即使为空!
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 方块描述
|
||||
|
||||
- 定义方块的`identifier` - 采用`命名空间:标识符`格式的唯一ID
|
||||
- 配置方块的`menu_category`归属
|
||||
- 可选参数`group`和`is_hidden_in_commands`
|
||||
|
||||
_方块描述还包含[状态](/blocks/block-states)和[特性](/blocks/block-traits),相关内容请参见对应页面。_
|
||||
|
||||
## 添加组件
|
||||
|
||||
目前我们的自定义方块使用的是默认组件值(可参考[此处](/blocks/block-components))。
|
||||
|
||||
现在开始自定义功能配置!
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [BP/blocks/custom_block.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_block",
|
||||
"menu_category": {
|
||||
"category": "construction"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 3
|
||||
},
|
||||
"minecraft:destructible_by_explosion": {
|
||||
"explosion_resistance": 3
|
||||
},
|
||||
"minecraft:friction": 0.4,
|
||||
"minecraft:map_color": "#ffffff",
|
||||
"minecraft:light_dampening": 0,
|
||||
"minecraft:light_emission": 4,
|
||||
"minecraft:loot": "loot_tables/blocks/custom_block.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
- [`minecraft:destructible_by_mining`](/blocks/block-components#destructible-by-mining) 定义玩家破坏方块所需时间(目前无法为不同工具设置不同破坏时间)
|
||||
- [`minecraft:destructible_by_explosion`](/blocks/block-components#destructible-by-explosion) 定义抗爆性。值越高,被炸毁概率越低
|
||||
- [`minecraft:friction`](/blocks/block-components#friction) 定义方块摩擦系数。例如灵魂沙具有高摩擦值会减缓玩家,冰的低摩擦值则产生滑溜效果。经典方块(如木头/石头)的摩擦系数为`0.4`
|
||||
- [`minecraft:map_color`](/blocks/block-components#map-color) 是地图上显示的代表色(十六进制)。`#ffffff`代表白色,可通过[在线取色器](https://www.google.com/search?q=hex+color+picker)获取其他颜色代码
|
||||
- [`minecraft:light_dampening`](/blocks/block-components#light-dampening) 定义光线阻挡程度
|
||||
- [`minecraft:light_emission`](/blocks/block-components#light-emission) 定义方块发光等级
|
||||
- [`minecraft:loot`](/blocks/block-components#loot) 定义战利品表路径。若移除,方块将默认掉落自身。更多战利品表信息请访问[此处](/loot/loot-tables)
|
||||
|
||||
_更多组件配置请访问[方块组件手册](/blocks/block-components)!_
|
||||
|
||||
## 应用纹理
|
||||
|
||||
:::warning
|
||||
`RP/blocks.json`会忽略命名空间。即使不写命名空间或随意填写也不会产生影响。若自定义方块与原版方块同名(仅命名空间不同)可能导致问题
|
||||
:::
|
||||
:::tip <nbsp/>
|
||||
[方块音效](/blocks/block-sounds)也可在`RP/blocks.json`中定义
|
||||
:::
|
||||
|
||||
对于基础的16×16×16像素方块,纹理应在`RP/blocks.json`中定义。
|
||||
|
||||
如需使用自定义模型,应使用[geometry(几何组件)](/blocks/block-components#geometry)和[material_instances(材质实例)](/blocks/block-components#material-instances)。
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [RP/blocks.json]
|
||||
{
|
||||
"format_version": [1, 1, 0],
|
||||
"wiki:custom_block": {
|
||||
"textures": "custom_block", // 此纹理简称需在下方terrain_texture.json中定义
|
||||
"sound": "grass"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
现在需要在`RP/textures/terrain_texture.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": {
|
||||
// 我们的纹理简称:
|
||||
"custom_block": {
|
||||
"textures": "textures/blocks/custom_block" // 指向图片文件名
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 分面纹理
|
||||
|
||||
纹理可按面分别设置。例如一个自定义"指南针方块"可使用以下✨惊艳✨纹理:
|
||||
|
||||
`textures/blocks/compass_block_down.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/blocks-intro/compass_block_down.png" pixelated="true" width="64"/>
|
||||
|
||||
`textures/blocks/compass_block_up.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/blocks-intro/compass_block_up.png" pixelated="true" width="64"/>
|
||||
|
||||
`textures/blocks/compass_block_north.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/blocks-intro/compass_block_north.png" pixelated="true" width="64"/>
|
||||
|
||||
`textures/blocks/compass_block_east.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/blocks-intro/compass_block_east.png" pixelated="true" width="64"/>
|
||||
|
||||
`textures/blocks/compass_block_south.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/blocks-intro/compass_block_south.png" pixelated="true" width="64"/>
|
||||
|
||||
`textures/blocks/compass_block_west.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/blocks-intro/compass_block_west.png" pixelated="true" width="64"/>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
对应的`blocks.json`配置如下:
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [RP/blocks.json]
|
||||
{
|
||||
"format_version": [1, 1, 0],
|
||||
"wiki:compass_block": {
|
||||
"textures": {
|
||||
"down": "compass_block_down",
|
||||
"up": "compass_block_up",
|
||||
"north": "compass_block_north",
|
||||
"east": "compass_block_east",
|
||||
"south": "compass_block_south",
|
||||
"west": "compass_block_west"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
<br>
|
||||
|
||||
若使用[材质实例](/blocks/block-components#material-instances),配置示例如下:
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "compass_block_down" // 此纹理用于破坏粒子效果
|
||||
},
|
||||
"up": {
|
||||
"texture": "compass_block_up"
|
||||
},
|
||||
"north": {
|
||||
"texture": "compass_block_north"
|
||||
},
|
||||
"east": {
|
||||
"texture": "compass_block_east"
|
||||
},
|
||||
"south": {
|
||||
"texture": "compass_block_south"
|
||||
},
|
||||
"west": {
|
||||
"texture": "compass_block_west"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
对应的`terrain_texture.json`数据:
|
||||
|
||||
::: code-group
|
||||
|
||||
```json [RP/textures/terrain_texture.json]
|
||||
{
|
||||
"texture_name": "atlas.terrain",
|
||||
"resource_pack_name": "wiki",
|
||||
"padding": 8,
|
||||
"num_mip_levels": 4,
|
||||
"texture_data": {
|
||||
"compass_block_down": {
|
||||
"textures": "textures/blocks/compass_block_down"
|
||||
},
|
||||
"compass_block_up": {
|
||||
"textures": "textures/blocks/compass_block_up"
|
||||
},
|
||||
"compass_block_north": {
|
||||
"textures": "textures/blocks/compass_block_north"
|
||||
},
|
||||
"compass_block_east": {
|
||||
"textures": "textures/blocks/compass_block_east"
|
||||
},
|
||||
"compass_block_west": {
|
||||
"textures": "textures/blocks/compass_block_west"
|
||||
},
|
||||
"compass_block_south": {
|
||||
"textures": "textures/blocks/compass_block_south"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 定义名称
|
||||
|
||||
最后定义方块的显示名称:
|
||||
|
||||
::: code-group
|
||||
|
||||
```c [RP/texts/en_US.lang]
|
||||
tile.wiki:custom_block.name=自定义方块
|
||||
tile.wiki:compass_block.name=指南针方块
|
||||
```
|
||||
:::
|
||||
|
||||
更多本地化内容请访问[文本与翻译指南](/concepts/text-and-translations)。
|
||||
|
||||
## 成果总结
|
||||
|
||||
通过本教程,您已掌握:
|
||||
|
||||
<Checklist>
|
||||
|
||||
- [x] 方块基础特性
|
||||
- [x] 如何应用统一纹理
|
||||
- [x] 如何设置分面纹理
|
||||
|
||||
</Checklist>
|
||||
|
||||
...但这只是开始,更多精彩内容等待探索!
|
||||
|
||||
## 下一步学习
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-5 m-0 p-0">
|
||||
<Card
|
||||
title="扩展功能"
|
||||
imgsrc-light="assets/images/homepage/crafting_table_0.png"
|
||||
link="/blocks/block-components">
|
||||
学习各类可用[方块组件](/blocks/block-components)打造独特玩法。
|
||||
<br><br>
|
||||
使用[geometry(几何组件)](/blocks/block-components#geometry)为方块添加自定义模型!还可以通过[collision_box(碰撞箱)](/blocks/block-components#collision-box)和[selection_box(选择框)](/blocks/block-components#selection-box)配置物理交互区域。
|
||||
</Card>
|
||||
<Card
|
||||
title="创建变体"
|
||||
imgsrc-light="assets/images/homepage/scripting.png">
|
||||
利用[方块状态](/blocks/block-states)和[permutations(状态切换)](/blocks/block-permutations)实现条件触发的组件功能。
|
||||
<br><br>
|
||||
例如为储液罐方块添加多级液面高度功能,并支持多种液体类型。
|
||||
</Card>
|
||||
<Card
|
||||
title="复刻原版"
|
||||
imgsrc-light="assets/images/homepage/diamond_ore_0.png"
|
||||
link="/blocks/block-components">
|
||||
在<b class="orange px-1 rounded-md">原版复刻</b>分类中查看多个完整实现案例。
|
||||
<br><br>
|
||||
从简单的[自定义玻璃方块](/blocks/custom-glass-blocks)开始,体验[material_instances(材质实例)](/blocks/block-components#material-instances)的应用!
|
||||
</Card>
|
||||
</div>
|
||||
271
docs/wiki/2-方块/1-基础/troubleshooting-blocks.md
Normal file
271
docs/wiki/2-方块/1-基础/troubleshooting-blocks.md
Normal file
@@ -0,0 +1,271 @@
|
||||
---
|
||||
title: 方块故障排除
|
||||
category: 常规
|
||||
tags:
|
||||
- help
|
||||
mentions:
|
||||
- SmokeyStack
|
||||
- SirLich
|
||||
- aexer0e
|
||||
- MedicalJewel105
|
||||
- Sprunkles137
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块故障排除
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip
|
||||
本页包含关于_方块_的故障排除信息。在继续阅读前,建议先查阅我们的[全局故障排除指南](/guide/troubleshooting)。
|
||||
:::
|
||||
|
||||
## 0.0 - 常见问题
|
||||
|
||||
> "我按照教程制作方块时遇到了问题!"
|
||||
|
||||
无需惊慌!本页将帮助您排查常见问题。
|
||||
|
||||
## 1.0 - 纹理问题排查
|
||||
|
||||
修复与方块纹理相关的常见问题。
|
||||
|
||||
## 1.1 - 纹理显示为黑紫相间
|
||||
|
||||
我们将分析三种不同布局的方块类型:
|
||||
|
||||
- 类似泥土的方块 
|
||||
- 类似原木的方块 
|
||||
- 类似草块的方块 
|
||||
|
||||
请定位至 `RP/textures/terrain_texture.json` 文件,确保文件名正确。
|
||||
|
||||
::: code-group
|
||||
```json [RP/textures/terrain_texture.json]
|
||||
{
|
||||
"texture_name": "atlas.terrain",
|
||||
"resource_pack_name": "wiki",
|
||||
"padding": 8,
|
||||
"num_mip_levels": 4,
|
||||
"texture_data": {
|
||||
"dirt_like": {
|
||||
"textures": "textures/blocks/dirt_like" // 此处可替换为任意内容,但需记住此名称
|
||||
},
|
||||
"log_like_top": {
|
||||
"textures": "textures/blocks/log_like_top" // 此处可替换为任意内容,但需记住此名称
|
||||
},
|
||||
"log_like_side": {
|
||||
"textures": "textures/blocks/log_like_side" // 此处可替换为任意内容,但需记住此名称
|
||||
},
|
||||
"custom_grass_top": {
|
||||
"textures": "textures/blocks/custom_grass_top" // 此处可替换为任意内容,但需记住此名称
|
||||
},
|
||||
"custom_grass_bottom": {
|
||||
"textures": "textures/blocks/custom_grass_bottom" // 此处可替换为任意内容,但需记住此名称
|
||||
},
|
||||
"custom_grass_side": {
|
||||
"textures": "textures/blocks/custom_grass_side" // 此处可替换为任意内容,但需记住此名称
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
接下来检查方块配置文件,确保包含 `material_instances` 组件。
|
||||
|
||||
类似泥土的方块配置示例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/dirt_like.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:dirt_like"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "dirt_like"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
类似原木的方块配置示例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/log_like.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:log_like"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "log_like_side"
|
||||
},
|
||||
"end": {
|
||||
"texture": "log_like_top"
|
||||
},
|
||||
"up": "end",
|
||||
"down": "end"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
类似草块的配置示例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/custom_grass.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_grass"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_grass_side"
|
||||
},
|
||||
"up": {
|
||||
"texture": "custom_grass_top"
|
||||
},
|
||||
"down": {
|
||||
"texture": "custom_grass_bottom"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
正确配置后,方块的纹理应正常显示。
|
||||
|
||||
## 1.2 - 纹理显示为带"Update"字样的泥土块
|
||||
|
||||
问题现象:自定义方块变成带有绿色文字的泥土方块。
|
||||
|
||||

|
||||
|
||||
这是_未知方块_的标识,通常由以下原因引起:
|
||||
- 方块标识符被修改
|
||||
- 方块JSON文件格式错误
|
||||
|
||||
解决方案:
|
||||
1. 使用JSON校验工具检查文件格式
|
||||
2. 确认方块标识符未更改
|
||||
3. 确保方块配置包含以下任意组件:
|
||||
- `minecraft:unit_cube`
|
||||
- `minecraft:geometry`
|
||||
- `minecraft:material_instances`
|
||||
- 或正确配置了 `RP/blocks.json` 中的纹理条目
|
||||
|
||||
|
||||
## 2.0 - 渲染问题排查
|
||||
|
||||
本节将描述常见的方块渲染问题及解决方案。
|
||||
|
||||
## 2.1 - 透明效果失效
|
||||
|
||||
问题现象:纹理中的透明像素在游戏中显示为不透明。
|
||||
|
||||
解决方案:在方块的 `material_instances` 组件中添加渲染方法:
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/your_block.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
...
|
||||
"components": {
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"render_method": "alpha_test"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 2.2 - 方块产生阴影
|
||||
|
||||
问题现象:自定义几何体方块产生阴影。
|
||||
|
||||
解决方案:在方块组件中添加光照衰减配置:
|
||||
|
||||
::: code-group
|
||||
```json [minecraft:block > components]
|
||||
"minecraft:light_dampening": 0
|
||||
```
|
||||
:::
|
||||
|
||||
## 2.3 - 模型立方体在物品栏中重叠
|
||||
|
||||
问题现象:自定义几何体方块在物品栏中呈现异常堆叠:
|
||||
|
||||

|
||||
|
||||
解决方案:在Blockbench中调整立方体绘制顺序(从下到上):
|
||||
|
||||
```
|
||||
cube_middle cube_bottom
|
||||
cube_top -> cube_middle
|
||||
cube_bottom cube_top
|
||||
```
|
||||
|
||||
## 2.4 - 方块在物品栏中显示过小
|
||||
|
||||
问题现象:16³标准尺寸方块在物品栏中比原版方块小。
|
||||
|
||||
解决方案分析:
|
||||
- 使用 `RP/blocks.json` 配置纹理可使方块正常显示,但无法使用自定义模型
|
||||
- 使用 `material_instances` 组件时需配合以下配置:
|
||||
- 添加旋转组件需同时配置材质实例
|
||||
- 使用单位立方体或自定义几何体
|
||||
- 确保基础状态使用 `blocks.json` 配置
|
||||
|
||||
---
|
||||
|
||||
## 3.0 - 常见日志错误
|
||||
|
||||
本节将解析常见的日志报错信息。
|
||||
|
||||
## 3.1 - 碰撞/选择框错误
|
||||
|
||||
典型错误提示:
|
||||
|
||||
> `[Blocks][error]-minecraft:collision_box: min 值不能低于 (-8, 0, -8),max 值不能超过 (8, 16, 8)`
|
||||
|
||||
排查步骤:
|
||||
- 检查 X/Z 轴数值是否在 -8 至 8 范围内
|
||||
- 检查 Y 轴数值是否在 0 至 16 范围内
|
||||
- 确保碰撞框不超过 16×16×16 单位区域
|
||||
|
||||
## 3.2 - 模型尺寸错误
|
||||
|
||||
典型错误提示:
|
||||
|
||||
> `geometry.your_block 包含 X 个超出范围的立方体...`
|
||||
|
||||
解决方案:
|
||||
- 缩小几何体尺寸
|
||||
- 将大型模型拆分为多个方块
|
||||
|
||||
---
|
||||
|
||||
## 后续步骤
|
||||
|
||||
若问题仍未解决,欢迎加入Discord社区交流。如发现文档内容有误,请通过GitHub提交修正建议!
|
||||
190
docs/wiki/2-方块/2-外观/block-models.md
Normal file
190
docs/wiki/2-方块/2-外观/block-models.md
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
title: 创建方块模型
|
||||
category: 教程
|
||||
tags:
|
||||
- 新手
|
||||
- 简单
|
||||
mentions:
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 创建方块模型
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
尽管自定义方块无法使用原版的[方块形状](/blocks/block-shapes),但我们可以创建遵循类似实体模型格式的自定义模型。本教程将引导您使用[Blockbench](https://blockbench.net)为"纸袋"创建自定义方块模型。通过学习本教程,您将掌握专为自定义方块设计的Minecraft几何体核心功能。
|
||||
|
||||
**注意:** 自定义方块模型必须符合[模型尺寸限制](/blocks/block-components.html#geometry)。
|
||||
|
||||
## 模型设置
|
||||
|
||||
打开Blockbench并新建一个`Bedrock Block`项目。
|
||||
|
||||

|
||||
|
||||
现在可以为模型设置标识符!您可以在此处决定文件名,或稍后修改。
|
||||
|
||||
UV模式和纹理尺寸应保持不变。
|
||||
|
||||
:::danger 命名空间
|
||||
模型标识符**不使用命名空间且不能包含冒号**。冒号曾用于模型继承,在现代几何格式中已失效。
|
||||
:::
|
||||
|
||||

|
||||
|
||||
## 添加立方体
|
||||
|
||||
虽然不一定是完美立方体,但模型中的元素都称为**立方体**。所有立方体必须包含在作为分组的**骨骼**中。
|
||||
|
||||
首先通过大纲视图点击`Add Group`创建根骨骼。按`F2`可重命名骨骼。
|
||||
|
||||

|
||||
|
||||
"纸袋"模型需要两个立方体:一个作为提手,一个作为主体。选择根骨骼后点击`Add Cube`添加。
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/new_cube.png"
|
||||
alt
|
||||
width="600"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
通过顶部工具栏可移动、缩放和旋转立方体。以下是"paper_bag"模型使用的两个立方体:
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/paper_bag_cubes.png"
|
||||
alt
|
||||
width="300"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
## 移除面
|
||||
|
||||
某些面可能无需可见。在示例中,移除纸袋顶部面以实现透视效果。
|
||||
|
||||
点击预览中的面,在UV面板删除其UV映射即可移除。
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/paper_bag_top_removed.png"
|
||||
alt
|
||||
width="600"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
提手仅需保留南北面。在UV面板按住Ctrl可多选面名称进行操作。
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/paper_bag_handle_faces_removed.png"
|
||||
alt
|
||||
width="600"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
## 预览纹理
|
||||
|
||||
:::tip
|
||||
点击`Create Texture`选择`Blank`即可在Blockbench中创建纹理。
|
||||
:::
|
||||
|
||||
"纸袋"模型包含以下预制纹理:
|
||||
|
||||
- `textures/blocks/paper_bag.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/block-models/paper_bag.png" style="background-color: rgb(0,0,0,0.15);" pixelated="true" width="128"/>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
- `textures/blocks/paper_bag_bottom_fold.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/block-models/paper_bag_bottom_fold.png" style="background-color: rgb(0,0,0,0.15);" pixelated="true" width="128"/>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
|
||||
- `textures/blocks/paper_bag_side_gusset.png`
|
||||
|
||||
<WikiImage src="/assets/images/blocks/block-models/paper_bag_side_gusset.png" style="background-color: rgb(0,0,0,0.15);" pixelated="true" width="128"/>
|
||||
|
||||
将纹理导入Blockbench后拖拽至对应面,初始效果可能不够理想...
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/preview_textures_applied.png"
|
||||
alt
|
||||
width="300"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
## 调整UV布局
|
||||
|
||||
通过UV面板重新定位/缩放面的UV映射来修正纹理位置。选择目标面后操作UV面板即可。
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/paper_bag_handle_uv.png"
|
||||
alt
|
||||
width="300"
|
||||
class="my-4"
|
||||
/>
|
||||
<br>
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/block-models/paper_bag_final.png"
|
||||
alt
|
||||
width="300"
|
||||
class="my-4"
|
||||
/>
|
||||
|
||||
## 修改材质实例
|
||||
|
||||
自定义材质实例名称可便捷定义面渲染方式。
|
||||
|
||||
右键立方体选择`Edit Material Instances`进行编辑。
|
||||
|
||||

|
||||
|
||||
在示例中,东西面需要独立纹理。通过分配材质实例实现。
|
||||
|
||||

|
||||
|
||||
## 应用几何体与纹理
|
||||
|
||||
通过`File > Export > Export Bedrock Geometry`导出至`RP/models/blocks`文件夹后,即可在方块JSON中引用模型。
|
||||
|
||||
通过`RP/textures/terrian_texture.json`短名称应用纹理。本例中纸袋不遮挡光线,故设置光照衰减为0。
|
||||
|
||||
::: code-group
|
||||
```json [BP/blocks/paper_bag.json]
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:paper_bag",
|
||||
"menu_category": {
|
||||
"category": "items"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
// 通过引用模型标识符应用模型
|
||||
"minecraft:geometry": "geometry.paper_bag",
|
||||
// 应用纹理及其他渲染配置
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "paper_bag",
|
||||
"render_method": "alpha_test" // 禁用背面剔除并启用透明
|
||||
},
|
||||
"down": {
|
||||
"texture": "paper_bag_bottom_fold",
|
||||
"render_method": "alpha_test" // 所有实例必须保持一致
|
||||
},
|
||||
// 模型中使用的自定义实例名称
|
||||
"side_gusset": {
|
||||
"texture": "paper_bag_side_gusset",
|
||||
"render_method": "alpha_test" // 所有实例必须保持一致
|
||||
}
|
||||
},
|
||||
// 防止产生阴影
|
||||
"minecraft:light_dampening": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
183
docs/wiki/2-方块/3-巧思案例/applying-effects.md
Normal file
183
docs/wiki/2-方块/3-巧思案例/applying-effects.md
Normal 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秒时长可确保伤害间隔符合原版节奏。
|
||||
74
docs/wiki/2-方块/3-巧思案例/avoiding-state-limit.md
Normal file
74
docs/wiki/2-方块/3-巧思案例/avoiding-state-limit.md
Normal 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个以上的状态值),您可以获得更多可能的组合结果。
|
||||
:::
|
||||
84
docs/wiki/2-方块/3-巧思案例/block-texture-variation.md
Normal file
84
docs/wiki/2-方块/3-巧思案例/block-texture-variation.md
Normal 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)
|
||||
279
docs/wiki/2-方块/3-巧思案例/fake-blocks.md
Normal file
279
docs/wiki/2-方块/3-巧思案例/fake-blocks.md
Normal 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.5,40生命值改为0.25...
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
172
docs/wiki/2-方块/3-巧思案例/flipbook-textures.md
Normal file
172
docs/wiki/2-方块/3-巧思案例/flipbook-textures.md
Normal 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" // 将纹理名称填在此处
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||

|
||||
|
||||
现在你的方块已经拥有动态纹理了!
|
||||
|
||||
## 定义翻页书贴图
|
||||
|
||||
在为方块添加动态纹理后,我们需要了解其工作原理。
|
||||
|
||||
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 | 帧切换速度(单位:ticks,20 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) |
|
||||
|
||||
## 效果展示
|
||||
|
||||

|
||||
|
||||
现在你可以开始修改原版动效贴图或创作属于你的动态纹理了!
|
||||
215
docs/wiki/2-方块/3-巧思案例/ore-loot-tables.md
Normal file
215
docs/wiki/2-方块/3-巧思案例/ore-loot-tables.md
Normal 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>
|
||||
|
||||
## 实际效果
|
||||
|
||||

|
||||
352
docs/wiki/2-方块/3-巧思案例/precise-rotation.md
Normal file
352
docs/wiki/2-方块/3-巧思案例/precise-rotation.md
Normal 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)!*
|
||||
|
||||

|
||||
|
||||
特性概览:
|
||||
|
||||
- 可附着于方块顶部,具备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` 骨骼用于侧表面附着时的定位调整。
|
||||
|
||||
下方展示的"贝壳"模型结构可供参考:
|
||||
|
||||

|
||||
|
||||
<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
|
||||
403
docs/wiki/2-方块/3-巧思案例/rotatable-blocks.md
Normal file
403
docs/wiki/2-方块/3-巧思案例/rotatable-blocks.md
Normal 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>
|
||||
878
docs/wiki/2-方块/4-原版再创作/custom-crops.md
Normal file
878
docs/wiki/2-方块/4-原版再创作/custom-crops.md
Normal file
File diff suppressed because one or more lines are too long
364
docs/wiki/2-方块/4-原版再创作/custom-fluids.md
Normal file
364
docs/wiki/2-方块/4-原版再创作/custom-fluids.md
Normal file
@@ -0,0 +1,364 @@
|
||||
---
|
||||
title: Custom Fluids
|
||||
category: Vanilla Re-Creations
|
||||
tags:
|
||||
- experimental
|
||||
- intermediate
|
||||
- scripting
|
||||
mentions:
|
||||
- Provedule
|
||||
- JaylyDev
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
|
||||
This tutorial assumes an advanced understanding of blocks and the execute command.
|
||||
Check out the [blocks guide](/blocks/blocks-intro) before starting.
|
||||
:::
|
||||
|
||||
::: warning EXPERIMENTAL
|
||||
Requires `Holiday Creator Features` for use of block tag Molang queries and to trigger block events.
|
||||
|
||||
Requires `Beta APIs` to use [@minecraft/server](https://learn.microsoft.com/minecraft/creator/scriptapi/minecraft/server/minecraft-server) module version `1.6.0-beta`.
|
||||
:::
|
||||
|
||||
Creating fluids that are identical to vanilla fluids is not currently possible, but you can make something similar! This template/tutorial is designed to assist you in creating a custom "semi-fluid".
|
||||
|
||||
## Flow Logic
|
||||
|
||||
- The fluid block has states defining whether it is a source and its depth.
|
||||
- If there is air beneath fluid blocks, it will be converted into falling fluid.
|
||||
- Fluids with a depth above `1` will spread horizontally with decreasing depths.
|
||||
- This will not occur if there is falling fluid below.
|
||||
- Flowing fluid block must have another fluid block adjacent to survive.
|
||||
- Source blocks do not need to have other fluid blocks surrounding themselves.
|
||||
|
||||
**This implementation does not include face culling due to its current complexity.**
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/custom-fluids/fluid_display.png"
|
||||
alt=""
|
||||
pixelated="true"
|
||||
width=608
|
||||
/>
|
||||
|
||||
## Source Fluid Block
|
||||
|
||||
Below is the code for a custom fluid. Copy and quick replace `custom_fluid` with your fluid's name. When the source block detects air in its surroundings, it replaces it with the outer fluid blocks. If the source block detects air beneath it, it will also place a falling fluid block underneath.
|
||||
|
||||
<BButton
|
||||
link="https://github.com/Bedrock-OSS/wiki-addon/blob/main/ma-custom_fluids/rp/models/blocks/fluid.geo.json"
|
||||
color=blue
|
||||
>Download Custom Fluid Geometry</BButton>
|
||||
|
||||
<Spoiler title="Custom Fluid Block JSON">
|
||||
|
||||
<CodeHeader>BP/blocks/custom_fluid.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_fluid",
|
||||
"menu_category": {
|
||||
"category": "none"
|
||||
},
|
||||
"states": {
|
||||
"wiki:source": [true, false],
|
||||
// Depth of fluid - default to 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,
|
||||
// Trigger fluid spread
|
||||
"minecraft:queued_ticking": {
|
||||
"looping": true,
|
||||
"interval_range": [20, 20], // Fluid speed in ticks
|
||||
"on_tick": {
|
||||
"event": "wiki:flow"
|
||||
}
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_fluid", // Shortname defined in `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": [
|
||||
// Dry out
|
||||
{
|
||||
"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": {}
|
||||
},
|
||||
// Spread
|
||||
{
|
||||
"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]"
|
||||
]
|
||||
}
|
||||
},
|
||||
// Fall
|
||||
{
|
||||
"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": {
|
||||
// Enables the block to be picked up by an item of choice
|
||||
"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": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Fluid Bucket
|
||||
|
||||
To place your custom fluid you need a custom bucket item. Below is the JSON for the custom bucket. Replace any instance of `custom_fluid` with your fluid's name.
|
||||
|
||||
<Spoiler title="Custom Bucket Item JSON">
|
||||
|
||||
<CodeHeader>BP/items/custom_fluid_bucket.json</CodeHeader>
|
||||
|
||||
```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" // Shortname defined in `RP/textures/item_texture.json`
|
||||
},
|
||||
"minecraft:block_placer": {
|
||||
"block": "wiki:custom_fluid"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Scripts
|
||||
|
||||
The fluids use a script to add the ability for the player to float/sink in the fluid. The script also adds fog. To add your fluid to the script, put the ID of your new fluids in the `fluids` string array.
|
||||
|
||||
<CodeHeader>BP/manifest.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"modules": [
|
||||
...
|
||||
{
|
||||
"type": "script",
|
||||
"language": "javascript",
|
||||
"entry": "fluids.js",
|
||||
"uuid": ...,
|
||||
"version": [1, 0, 0]
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"module_name": "@minecraft/server",
|
||||
"version": "1.6.0-beta"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
<Spoiler title="Fluid Movement & Fog Script">
|
||||
|
||||
<CodeHeader>BP/scripts/fluids.js</CodeHeader>
|
||||
|
||||
```javascript
|
||||
import { system, world } from "@minecraft/server";
|
||||
|
||||
const fluids = ["wiki:custom_fluid"];
|
||||
|
||||
system.runInterval(() => {
|
||||
const players = world.getPlayers();
|
||||
|
||||
for (const player of players) {
|
||||
// Fluid effects
|
||||
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 });
|
||||
}
|
||||
}
|
||||
// Fluid fog
|
||||
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");
|
||||
}
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Result
|
||||
|
||||
By the end your BP folder should look like this:
|
||||
|
||||
<FolderView
|
||||
:paths="[
|
||||
'BP/blocks/custom_fluid.json',
|
||||
'BP/items/custom_fluid_bucket.json',
|
||||
'BP/scripts/fluids.js',
|
||||
'RP/fogs/custom_fluid.json'
|
||||
]"
|
||||
></FolderView>
|
||||
|
||||
## Download Example Pack
|
||||
|
||||
If anything goes wrong, or if you require all of the template files, they are available for download here. The pack includes everything necessary for a functional fluid.
|
||||
|
||||
<BButton
|
||||
link="https://github.com/Bedrock-OSS/wiki-addon/releases/download/download/custom_fluids.mcaddon"
|
||||
color=blue
|
||||
>Download MCADDON</BButton>
|
||||
661
docs/wiki/2-方块/4-原版再创作/custom-glass-blocks.md
Normal file
661
docs/wiki/2-方块/4-原版再创作/custom-glass-blocks.md
Normal file
@@ -0,0 +1,661 @@
|
||||
---
|
||||
title: Custom Glass
|
||||
category: Vanilla Re-Creations
|
||||
tags:
|
||||
- experimental
|
||||
- expert
|
||||
mentions:
|
||||
- Eko-byte
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
Making glass blocks may seem like a simple task, however it comes with many drawbacks as you will find, this tutorial aims to help you achieve a vanilla like glass block.
|
||||
|
||||
By the end you should be able to create something like this!
|
||||
|
||||

|
||||
|
||||
## Basic Glass
|
||||
|
||||
::: tip FORMAT VERSION `1.20.30`
|
||||
This example requires basic knowledge of blocks to understand.
|
||||
Check out the [blocks guide](/blocks/blocks-intro) before starting.
|
||||
:::
|
||||
|
||||
This will create a custom glass block which appears the same as vanilla glass blocks!
|
||||
|
||||
<CodeHeader>BP/blocks/custom_glass.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_glass",
|
||||
"menu_category": {
|
||||
"category": "construction",
|
||||
"group": "itemGroup.name.glass"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:light_dampening": 0,
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"render_method": "blend" // Allows translucency
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader>RP/blocks.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"wiki:custom_glass": {
|
||||
"textures": "custom_glass", // Shortname defined in `RP/textures/terrain_texture.json`
|
||||
"sound": "glass"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Vertically-Connecting Glass
|
||||
|
||||
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
|
||||
This example requires advanced knowledge of blocks and Molang to understand.
|
||||
Check out the [blocks guide](/blocks/blocks-intro), [block states](/blocks/block-states) and [Molang](/concepts/molang) before starting.
|
||||
:::
|
||||
|
||||
::: warning EXPERIMENTAL
|
||||
Requires `Holiday Creator Features` for use of `minecraft:unit_cube` and to trigger events.
|
||||
:::
|
||||
|
||||
<Spoiler title="Vertically-Connecting Glass JSON">
|
||||
|
||||
<CodeHeader>BP/blocks/custom_vertical_connecting_glass.json</CodeHeader>
|
||||
|
||||
```json
|
||||
// Add a "nothing" texture in terrain_texture, and make it have a transparent file
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_vertical_connecting_glass",
|
||||
"menu_category": {
|
||||
"category": "construction",
|
||||
"group": "itemGroup.name.glass"
|
||||
},
|
||||
"states": {
|
||||
// States needed for connected textures, also controls up and down culling
|
||||
"wiki:connection": [0, 1, 2, 3],
|
||||
// States to cull faces depending on surrounding blocks
|
||||
"wiki:cull_north": [false, true],
|
||||
"wiki:cull_south": [false, true],
|
||||
"wiki:cull_east": [false, true],
|
||||
"wiki:cull_west": [false, true]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
// Basic glass components
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 1
|
||||
},
|
||||
"minecraft:queued_ticking": {
|
||||
"looping": true,
|
||||
"interval_range": [0, 0],
|
||||
"on_tick": {
|
||||
"event": "wiki:update"
|
||||
}
|
||||
},
|
||||
"minecraft:unit_cube": {},
|
||||
"minecraft:light_dampening": 0,
|
||||
// Tags used to give connected textures, and remove culling
|
||||
"tag:custom_vertical_connecting_glass": {},
|
||||
"tag:glass": {}
|
||||
},
|
||||
"permutations": [
|
||||
// These permutations control what textures are displayed at different situations
|
||||
// They also use tags to determine what state they are in, (top texture then top tag)
|
||||
{
|
||||
"condition": "q.block_state('wiki:connection') == 0 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
|
||||
"components": {
|
||||
"tag:default": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:connection') == 1 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
|
||||
"components": {
|
||||
"tag:top": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_top"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:connection') == 2 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
|
||||
"components": {
|
||||
"tag:bottom": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_bottom"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:connection') == 3 && !q.block_state('wiki:cull_north') && !q.block_state('wiki:cull_south') && !q.block_state('wiki:cull_east') && !q.block_state('wiki:cull_west')",
|
||||
"components": {
|
||||
"tag:middle": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_middle"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 0",
|
||||
"components": {
|
||||
"tag:default": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"north": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 0",
|
||||
"components": {
|
||||
"tag:default": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"south": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 0",
|
||||
"components": {
|
||||
"tag:default": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"east": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 0",
|
||||
"components": {
|
||||
"tag:default": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"west": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 1",
|
||||
"components": {
|
||||
"tag:top": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_top",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"north": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 1",
|
||||
"components": {
|
||||
"tag:top": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_top",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"south": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 1",
|
||||
"components": {
|
||||
"tag:top": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_top",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"east": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
//in this situation if there is a block to the west and it is the upper connected texture then it shall have the west side invisible and the sides be the upper connected part
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 1",
|
||||
"components": {
|
||||
"tag:top": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_top",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"west": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 2",
|
||||
"components": {
|
||||
"tag:bottom": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_bottom",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"north": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 2",
|
||||
"components": {
|
||||
"tag:bottom": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_bottom",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"south": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 2",
|
||||
"components": {
|
||||
"tag:bottom": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_bottom",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"east": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 2",
|
||||
"components": {
|
||||
"tag:bottom": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_bottom",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"west": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "custom_vertical_connecting_glass_up"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_north') && q.block_state('wiki:connection') == 3",
|
||||
"components": {
|
||||
"tag:middle": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_middle",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"north": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_south') && q.block_state('wiki:connection') == 3",
|
||||
"components": {
|
||||
"tag:middle": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_middle",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"south": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_east') && q.block_state('wiki:connection') == 3",
|
||||
"components": {
|
||||
"tag:middle": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_middle",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"east": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:cull_west') && q.block_state('wiki:connection') == 3",
|
||||
"components": {
|
||||
"tag:middle": {},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_vertical_connecting_glass_middle",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"west": {
|
||||
"texture": "nothing",
|
||||
"render_method": "blend"
|
||||
},
|
||||
"down": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
},
|
||||
"up": {
|
||||
"render_method": "blend",
|
||||
"texture": "nothing"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"events": {
|
||||
"wiki:update": {
|
||||
"sequence": [
|
||||
// Set the block to have no culling
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,0,-1,'custom_vertical_connecting_glass')",
|
||||
"set_block_state": {
|
||||
"wiki:cull_north": "q.block_neighbor_has_any_tag(0,0,-1,'custom_vertical_connecting_glass')",
|
||||
"wiki:cull_south": "q.block_neighbor_has_any_tag(0,0,1,'custom_vertical_connecting_glass')",
|
||||
"wiki:cull_west": "q.block_neighbor_has_any_tag(-1,0,0,'custom_vertical_connecting_glass')",
|
||||
"wiki:cull_east": "q.block_neighbor_has_any_tag(1,0,0,'custom_vertical_connecting_glass')"
|
||||
}
|
||||
},
|
||||
// Control the custom texture state
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,-1,0,'default')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,1,0,'top') && !q.block_neighbor_has_any_tag(0,-1,0,'middle')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,1,0,'top') && q.block_neighbor_has_any_tag(0,-1,0,'middle')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,-1,0,'top')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,-1,0,'bottom') && (q.block_neighbor_has_any_tag(0,1,0,'top') || q.block_neighbor_has_any_tag(0,1,0,'middle'))",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "!q.block_neighbor_has_any_tag(0,1,0,'top', 'default', 'middle', 'bottom') && q.block_neighbor_has_any_tag(0,-1,0,'middle', 'bottom')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "!q.block_neighbor_has_any_tag(0,1,0,'top', 'default', 'middle', 'bottom') && !q.block_neighbor_has_any_tag(0,-1,0,'middle', 'bottom', 'top', 'default')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,1,0,'top', 'middle', 'bottom') && !q.block_neighbor_has_any_tag(0,-1,0,'middle', 'bottom', 'top', 'default')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_neighbor_has_any_tag(0,1,0,'default') && q.block_neighbor_has_any_tag(0,-1,0,'default')",
|
||||
"set_block_state": {
|
||||
"wiki:connection": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
289
docs/wiki/2-方块/4-原版再创作/custom-glazed-terracotta.md
Normal file
289
docs/wiki/2-方块/4-原版再创作/custom-glazed-terracotta.md
Normal file
@@ -0,0 +1,289 @@
|
||||
---
|
||||
title: Custom Glazed Terracotta
|
||||
category: Vanilla Re-Creations
|
||||
tags:
|
||||
- easy
|
||||
mentions:
|
||||
- Kaioga5
|
||||
---
|
||||
|
||||
::: tip FORMAT & MIN ENGINE VERSION `1.20.40`
|
||||
This tutorial assumes a basic understanding of blocks.
|
||||
Check out the [blocks guide](/blocks/blocks-intro) before starting.
|
||||
:::
|
||||
|
||||
|
||||
## Introduction
|
||||
Glazed Terracotta has its own rotation mechanism, enabling players to craft aesthetically pleasing patterns for walls, floors, and ceilings. This guide will instruct you on creating your own blocks resembling glazed terracotta.
|
||||
|
||||
## Custom Glazed Terracotta
|
||||
This will create a vanilla-like custom glazed terracotta.
|
||||
|
||||
<CodeHeader>BP/blocks/custom_glazed_terracotta.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.40",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:glazed_terracotta_template",
|
||||
"menu_category": {
|
||||
"category": "construction",
|
||||
"group": "itemGroup.name.glazedTerracotta"
|
||||
},
|
||||
"traits": {
|
||||
"minecraft:placement_direction": {
|
||||
"enabled_states": [
|
||||
"minecraft:cardinal_direction"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "q.block_state('minecraft:cardinal_direction') == 'north'",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 0, 0] },
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.glazed_terracotta",
|
||||
"bone_visibility": {
|
||||
"bottom_1": false,
|
||||
"bottom_2": false,
|
||||
"bottom_3": false,
|
||||
"bottom_4": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:cardinal_direction') == 'west'",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 90, 0] },
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.glazed_terracotta",
|
||||
"bone_visibility": {
|
||||
"bottom_1": false,
|
||||
"bottom_2": false,
|
||||
"bottom_3": true,
|
||||
"bottom_4": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:cardinal_direction') == 'south'",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 180, 0] },
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.glazed_terracotta",
|
||||
"bone_visibility": {
|
||||
"bottom_1": false,
|
||||
"bottom_2": true,
|
||||
"bottom_3": false,
|
||||
"bottom_4": false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:cardinal_direction') == 'east'",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, -90, 0] },
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.glazed_terracotta",
|
||||
"bone_visibility": {
|
||||
"bottom_1": true,
|
||||
"bottom_2": false,
|
||||
"bottom_3": false,
|
||||
"bottom_4": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.glazed_terracotta"
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "purple_glazed_terracotta",
|
||||
"render_method": "opaque"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Geometry
|
||||
Vanilla glazed terracotta rotates certain faces of the block with some specific values, which is what gives the block it's magic. Use the following geometry to replicate that behavior.
|
||||
|
||||
<Spoiler title="Geometry JSON">
|
||||
|
||||
<CodeHeader>RP/models/blocks/glazed_terracotta.geo.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.glazed_terracotta",
|
||||
"texture_width": 16,
|
||||
"texture_height": 16,
|
||||
"visible_bounds_width": 4,
|
||||
"visible_bounds_height": 3.5,
|
||||
"visible_bounds_offset": [0, 1.25, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "glazed_terracotta",
|
||||
"pivot": [0, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "top",
|
||||
"parent": "glazed_terracotta",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 16],
|
||||
"uv": {
|
||||
"up": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "north",
|
||||
"parent": "glazed_terracotta",
|
||||
"pivot": [0, 8, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 16, 0],
|
||||
"pivot": [0, 8, 0],
|
||||
"rotation": [180, 0, 90],
|
||||
"uv": {
|
||||
"north": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "south",
|
||||
"parent": "glazed_terracotta",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [0, -8, 8],
|
||||
"size": [16, 16, 0],
|
||||
"pivot": [0, 0, 0],
|
||||
"rotation": [180, 0, 270],
|
||||
"uv": {
|
||||
"south": {"uv": [0, 0], "uv_size": [16, 16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "east",
|
||||
"parent": "glazed_terracotta",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, -16, -8],
|
||||
"size": [0, 16, 16],
|
||||
"pivot": [0, 0, 0],
|
||||
"rotation": [0, 0, -180],
|
||||
"uv": {
|
||||
"east": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "west",
|
||||
"parent": "glazed_terracotta",
|
||||
"pivot": [-16, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-24, 0, -8],
|
||||
"size": [0, 16, 16],
|
||||
"pivot": [-16, 0, 0],
|
||||
"rotation": [0, 180, 0],
|
||||
"uv": {
|
||||
"west": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bottom",
|
||||
"parent": "glazed_terracotta",
|
||||
"pivot": [0, 0, 0]
|
||||
},
|
||||
{
|
||||
"name": "bottom_1",
|
||||
"parent": "bottom",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 0, 16],
|
||||
"uv": {
|
||||
"down": {"uv": [0, 0], "uv_size": [16, 16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bottom_2",
|
||||
"parent": "bottom",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 0, 16],
|
||||
"uv": {
|
||||
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bottom_3",
|
||||
"parent": "bottom",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 0, 16],
|
||||
"uv": {
|
||||
"down": {"uv": [0, 0], "uv_size": [16, 16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bottom_4",
|
||||
"parent": "bottom",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 0, 16],
|
||||
"uv": {
|
||||
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
201
docs/wiki/2-方块/4-原版再创作/custom-slabs.md
Normal file
201
docs/wiki/2-方块/4-原版再创作/custom-slabs.md
Normal file
@@ -0,0 +1,201 @@
|
||||
---
|
||||
title: Custom Slabs
|
||||
category: Vanilla Re-Creations
|
||||
tags:
|
||||
- experimental
|
||||
- easy
|
||||
mentions:
|
||||
- Kaioga5
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
|
||||
This tutorial assumes a basic understanding of blocks.
|
||||
Check out the [blocks guide](/blocks/blocks-intro) before starting.
|
||||
:::
|
||||
|
||||
::: warning EXPERIMENTAL
|
||||
Requires `Holiday Creator Features` to trigger block events and for use of the `minecraft:unit_cube` component.
|
||||
:::
|
||||
|
||||
## Introduction
|
||||
Making custom slabs is a simple task, but if you find any drawbacks during recreating slabs, this tutorial will help you with it, and you'll be provided with a template for you to use.
|
||||
|
||||
Issues:
|
||||
- Your custom slab will appear vertically centred when carried.
|
||||
- Your custom slab may appear full-sized in item form (on the ground, in item frames, in hand)
|
||||
|
||||
## Custom Slab
|
||||
This will create a vanilla-like custom slab.
|
||||
|
||||
<CodeHeader>BP/blocks/custom_slab.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_slab",
|
||||
"menu_category": {
|
||||
"category": "construction",
|
||||
"group": "itemGroup.name.slab"
|
||||
},
|
||||
"traits": {
|
||||
"minecraft:placement_position": {
|
||||
"enabled_states": ["minecraft:vertical_half"]
|
||||
}
|
||||
},
|
||||
"states": {
|
||||
"wiki:double": [false, true]
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
// Bottom Slab
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && !q.block_state('wiki:double')",
|
||||
"components": {
|
||||
"minecraft:collision_box": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 8, 16]
|
||||
},
|
||||
"minecraft:selection_box": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 8, 16]
|
||||
},
|
||||
"minecraft:on_interact": {
|
||||
"event": "wiki:form_double",
|
||||
"condition": "q.block_face == 1.0 && q.is_item_name_any('slot.weapon.mainhand', 'wiki:custom_slab')"
|
||||
}
|
||||
}
|
||||
},
|
||||
// Top Slab
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && !q.block_state('wiki:double')",
|
||||
"components": {
|
||||
"minecraft:collision_box": {
|
||||
"origin": [-8, 8, -8],
|
||||
"size": [16, 8, 16]
|
||||
},
|
||||
"minecraft:selection_box": {
|
||||
"origin": [-8, 8, -8],
|
||||
"size": [16, 8, 16]
|
||||
},
|
||||
"minecraft:on_interact": {
|
||||
"event": "wiki:form_double",
|
||||
"condition": "q.block_face == 0.0 && q.is_item_name_any('slot.weapon.mainhand', 'wiki:custom_slab')"
|
||||
}
|
||||
}
|
||||
},
|
||||
// Double Slab
|
||||
{
|
||||
"condition": "q.block_state('wiki:double')",
|
||||
"components": {
|
||||
"minecraft:unit_cube": {},
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "wiki:destroy_double"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 7
|
||||
},
|
||||
"minecraft:destructible_by_explosion": {
|
||||
"explosion_resistance": 6
|
||||
},
|
||||
"minecraft:geometry": {
|
||||
"identifier": "geometry.slab",
|
||||
"bone_visibility": {
|
||||
"bottom_slab": "q.block_state('minecraft:vertical_half') == 'bottom'",
|
||||
"top_slab": "q.block_state('minecraft:vertical_half') == 'top'"
|
||||
}
|
||||
},
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "stone"
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"wiki:form_double": {
|
||||
"set_block_state": {
|
||||
"wiki:double": true
|
||||
},
|
||||
"run_command": {
|
||||
"command": "playsound use.stone @a ~~~ 1 0.8"
|
||||
},
|
||||
"decrement_stack": {}
|
||||
},
|
||||
"wiki:destroy_double": {
|
||||
"spawn_loot": {} // Spawns the block's default loot
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Geometry
|
||||
This will be the geometry used for your custom slabs.
|
||||
|
||||
<Spoiler title="Geometry JSON">
|
||||
|
||||
<CodeHeader>RP/models/blocks/slab.geo.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.slab",
|
||||
"texture_width": 16,
|
||||
"texture_height": 16,
|
||||
"visible_bounds_width": 2,
|
||||
"visible_bounds_height": 2.5,
|
||||
"visible_bounds_offset": [0, 0.75, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "top_slab",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 8, -8],
|
||||
"size": [16, 8, 16],
|
||||
"uv": {
|
||||
"north": {"uv": [0, 0], "uv_size": [16, 8]},
|
||||
"east": {"uv": [0, 0], "uv_size": [16, 8]},
|
||||
"south": {"uv": [0, 0], "uv_size": [16, 8]},
|
||||
"west": {"uv": [0, 0], "uv_size": [16, 8]},
|
||||
"up": {"uv": [16, 16], "uv_size": [-16, -16]},
|
||||
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bottom_slab",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 8, 16],
|
||||
"uv": {
|
||||
"north": {"uv": [0, 8], "uv_size": [16, 8]},
|
||||
"east": {"uv": [0, 8], "uv_size": [16, 8]},
|
||||
"south": {"uv": [0, 8], "uv_size": [16, 8]},
|
||||
"west": {"uv": [0, 8], "uv_size": [16, 8]},
|
||||
"up": {"uv": [16, 16], "uv_size": [-16, -16]},
|
||||
"down": {"uv": [16, 16], "uv_size": [-16, -16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
254
docs/wiki/2-方块/4-原版再创作/custom-trapdoors.md
Normal file
254
docs/wiki/2-方块/4-原版再创作/custom-trapdoors.md
Normal file
@@ -0,0 +1,254 @@
|
||||
---
|
||||
title: Custom Trapdoors
|
||||
category: Vanilla Re-Creations
|
||||
tags:
|
||||
- experimental
|
||||
- intermediate
|
||||
mentions:
|
||||
- Kaioga5
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
|
||||
This tutorial assumes a good understanding of blocks.
|
||||
Check out the [blocks guide](/blocks/blocks-intro) before starting.
|
||||
:::
|
||||
|
||||
::: warning EXPERIMENTAL
|
||||
Requires `Holiday Creator Features` to trigger block events.
|
||||
:::
|
||||
|
||||
## Introduction
|
||||
|
||||
Making custom trapdoors is an often difficult task to do, but after reading this tutorial you'll understand how they work in case you find any drawbacks during recreating them, and you'll be provided with a template for you to use.
|
||||
|
||||
## Custom Trapdoor
|
||||
|
||||
This will create a vanilla-like custom trapdoor.
|
||||
|
||||
<CodeHeader>BP/blocks/custom_trapdoor.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_trapdoor",
|
||||
"menu_category": {
|
||||
"category": "construction",
|
||||
"group": "itemGroup.name.trapdoor"
|
||||
},
|
||||
"traits": {
|
||||
"minecraft:placement_position": {
|
||||
"enabled_states": ["minecraft:vertical_half"]
|
||||
},
|
||||
"minecraft:placement_direction": {
|
||||
"enabled_states": ["minecraft:cardinal_direction"]
|
||||
}
|
||||
},
|
||||
"states": {
|
||||
"wiki:open": [false, true]
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
// Top Closed
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'north' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 0, 180] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'south' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [180, 0, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'east' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [180, -270, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'west' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [180, 270, 0] }
|
||||
}
|
||||
},
|
||||
// Top Open
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'north' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [-270, 0, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'south' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [270, 0, -180] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'east' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 270, 90] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'top' && q.block_state('minecraft:cardinal_direction') == 'west' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": {
|
||||
"rotation": [180, -270, -270]
|
||||
}
|
||||
}
|
||||
},
|
||||
// Bottom Closed
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'north' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 0, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'south' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 180, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'east' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, 270, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'west' && !q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, -270, 0] }
|
||||
}
|
||||
},
|
||||
// Bottom Open
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'north' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [90, 0, 180] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'south' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [270, 0, 0] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'east' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [0, -270, 90] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('minecraft:vertical_half') == 'bottom' && q.block_state('minecraft:cardinal_direction') == 'west' && q.block_state('wiki:open')",
|
||||
"components": {
|
||||
"minecraft:transformation": { "rotation": [180, 270, -270] }
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"minecraft:collision_box": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 3, 16]
|
||||
},
|
||||
"minecraft:selection_box": {
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 3, 16]
|
||||
},
|
||||
"minecraft:geometry": "geometry.trapdoor",
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "spruce_trapdoor",
|
||||
"render_method": "alpha_test"
|
||||
}
|
||||
},
|
||||
"minecraft:on_interact": {
|
||||
"event": "wiki:toggle"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"wiki:toggle": {
|
||||
"sequence": [
|
||||
{
|
||||
"set_block_state": {
|
||||
"wiki:open": "!q.block_state('wiki:open')"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:open')",
|
||||
"run_command": {
|
||||
"command": "playsound close.wooden_trapdoor @a ~~~ 0.9 0.9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "!q.block_state('wiki:open')",
|
||||
"run_command": {
|
||||
"command": "playsound open.wooden_trapdoor @a ~~~ 0.9 0.9"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Geometry
|
||||
|
||||
This will be the geometry used for your custom trapdoors.
|
||||
|
||||
<Spoiler title="Geometry JSON">
|
||||
|
||||
<CodeHeader>RP/models/blocks/trapdoor.geo.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.trapdoor",
|
||||
"texture_width": 16,
|
||||
"texture_height": 16,
|
||||
"visible_bounds_width": 2,
|
||||
"visible_bounds_height": 1.5,
|
||||
"visible_bounds_offset": [0, 0.25, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "trapdoor",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, -8],
|
||||
"size": [16, 3, 16],
|
||||
"uv": {
|
||||
"north": {"uv": [16, 3], "uv_size": [-16, -3]},
|
||||
"east": {"uv": [16, 3], "uv_size": [-16, -3]},
|
||||
"south": {"uv": [16, 3], "uv_size": [-16, -3]},
|
||||
"west": {"uv": [16, 3], "uv_size": [-16, -3]},
|
||||
"up": {"uv": [16, 16], "uv_size": [-16, -16]},
|
||||
"down": {"uv": [0, 0], "uv_size": [16, 16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
:::tip
|
||||
Vanilla trapdoors have a few issues in the direction of the texture in certain faces and having a height of 2.95 when it should be 3. This block template and geometry fixes both of those issues.
|
||||
:::
|
||||
994
docs/wiki/2-方块/4-原版再创作/custom-trees.md
Normal file
994
docs/wiki/2-方块/4-原版再创作/custom-trees.md
Normal file
@@ -0,0 +1,994 @@
|
||||
---
|
||||
title: Custom Trees
|
||||
category: Vanilla Re-Creations
|
||||
tags:
|
||||
- experimental
|
||||
mentions:
|
||||
- MedicalJewel105
|
||||
- TheItsNameless
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
::: tip FORMAT & MIN ENGINE VERSION `1.20.30`
|
||||
This tutorial assumes an advanced understanding of blocks.
|
||||
Check out the [blocks guide](/blocks/blocks-intro) before starting.
|
||||
:::
|
||||
|
||||
::: warning EXPERIMENTAL
|
||||
Requires `Holiday Creator Features` for use of block tag Molang queries and to trigger block events.
|
||||
:::
|
||||
|
||||
Creating your own tree with decaying leaves is complex, but possible! Follow this tutorial and you'll have your own in no time.
|
||||
|
||||
- Features:
|
||||
|
||||
- Decaying leaves
|
||||
- Tree Feature compatable
|
||||
- If leaves were broken using shears, they will drop the block
|
||||
- Leaves don't decay if placed by player
|
||||
- Logs are strippable and rotatable
|
||||
- Stripping logs is compatible with tools from other add-ons (if they have the `minecraft:is_axe` tag)
|
||||
- Saplings can be bonemealed and grow the tree (with structures)
|
||||
|
||||
- Issues:
|
||||
- If you make a structure with these blocks, it will crash the game when generated using features.
|
||||
|
||||
## Decaying Leaves
|
||||
|
||||
You will notice straight away that our custom leaves have a long list to search for a vanilla log/custom log by its block tag, although the code example uses the custom logs for this tutorial. The value is 4 and this method is used to search for the nearest log in a circular radius.
|
||||
|
||||
<WikiImage
|
||||
src="/assets/images/blocks/custom-trees/decaying_leaves_showcase_example.png"
|
||||
alt="Decaying Leaves Showcase"
|
||||
pixelated="false"
|
||||
width=420
|
||||
/>
|
||||
|
||||
Our custom leaves disables ticking when placed by the player which doesn't make the leaves decay and this removes the requirements for another duplicate leave block.
|
||||
|
||||
<Spoiler title="Code">
|
||||
|
||||
<CodeHeader>BP/blocks/custom_leaves.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_leaves",
|
||||
"states": {
|
||||
"wiki:decay_tier": [4, 3, 2, 1, 0], // Distance in blocks to find the log
|
||||
"wiki:should_decay": [true, false], // Used when placed by the player or with features
|
||||
"wiki:opaque": [false, true] // Optional; makes the leaves opaque when surrounded
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"tag:custom_leaves": {},
|
||||
"minecraft:loot": "loot_tables/empty.json",
|
||||
"minecraft:unit_cube": {},
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "wiki:stop_decay"
|
||||
},
|
||||
// Triggers event that spawns different loot
|
||||
"minecraft:on_player_destroyed": {
|
||||
"event": "wiki:on_destroyed"
|
||||
},
|
||||
// We need both of these to work with world generation
|
||||
"minecraft:queued_ticking": {
|
||||
"looping": true,
|
||||
"interval_range": [0, 0],
|
||||
"on_tick": {
|
||||
"event": "wiki:check"
|
||||
}
|
||||
},
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"event": "wiki:check"
|
||||
}
|
||||
},
|
||||
"minecraft:destructible_by_explosion": {
|
||||
"explosion_resistance": 1
|
||||
},
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 0.3
|
||||
},
|
||||
"minecraft:map_color": "#DDDDDD",
|
||||
"minecraft:light_dampening": 0,
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_leaves",
|
||||
"render_method": "blend"
|
||||
}
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
// Defines the loot for the tool
|
||||
"wiki:on_destroyed": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "q.is_item_name_any('slot.weapon.mainhand','minecraft:shears')",
|
||||
"spawn_loot": {
|
||||
"table": "loot_tables/blocks/custom_leaves_shears.json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "!q.is_item_name_any('slot.weapon.mainhand','minecraft:shears')",
|
||||
"spawn_loot": {
|
||||
"table": "loot_tables/blocks/custom_leaves.json"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// Checks for the log
|
||||
"wiki:check": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "q.block_state('wiki:should_decay')",
|
||||
"set_block_state": {
|
||||
"wiki:decay_tier": "(q.block_neighbor_has_any_tag(0,0,-1,'log') || q.block_neighbor_has_any_tag(0,0,1,'log') || q.block_neighbor_has_any_tag(-1,0,0,'log') || q.block_neighbor_has_any_tag(1,0,0,'log') || q.block_neighbor_has_any_tag(0,-1,0,'log') || q.block_neighbor_has_any_tag(0,1,0,'log')) ? 4 : ((q.block_neighbor_has_any_tag(0,0,-1,'decay_tier_4') || q.block_neighbor_has_any_tag(0,0,1,'decay_tier_4') || q.block_neighbor_has_any_tag(-1,0,0,'decay_tier_4') || q.block_neighbor_has_any_tag(1,0,0,'decay_tier_4') || q.block_neighbor_has_any_tag(0,-1,0,'decay_tier_4') || q.block_neighbor_has_any_tag(0,1,0,'decay_tier_4')) ? 3 : ( (q.block_neighbor_has_any_tag(0,0,-1,'decay_tier_3') || q.block_neighbor_has_any_tag(0,0,1,'decay_tier_3 ') || q.block_neighbor_has_any_tag(-1,0,0,'decay_tier_3') || q.block_neighbor_has_any_tag(1,0,0,'decay_tier_3') || q.block_neighbor_has_any_tag(0,-1,0,'decay_tier_3') || q.block_neighbor_has_any_tag(0,1,0,'decay_tier_3')) ? 2 : ( (q.block_neighbor_has_any_tag(0,0,-1,'decay_tier_2') || q.block_neighbor_has_any_tag(0,0,1,'decay_tier_2') || q.block_neighbor_has_any_tag(-1,0,0,'decay_tier_2') || q.block_neighbor_has_any_tag(1,0,0,'decay_tier_2') || q.block_neighbor_has_any_tag(0,-1,0,'decay_tier_2') || q.block_neighbor_has_any_tag(0,1,0,'decay_tier_2')) ? 1 : 0 ) ) )"
|
||||
}
|
||||
},
|
||||
{
|
||||
"set_block_state": {
|
||||
"wiki:opaque": "q.block_neighbor_has_any_tag(0,0,-1,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(0,0,1,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(0,1,0,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(0,-1,0,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(-1,0,0,'log','stone','custom_leaves') && q.block_neighbor_has_any_tag(1,0,0,'log','stone','custom_leaves')"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// When placed
|
||||
"wiki:stop_decay": {
|
||||
"set_block_state": {
|
||||
"wiki:should_decay": false
|
||||
}
|
||||
},
|
||||
// When decayed
|
||||
"wiki:decay": {
|
||||
"die": {},
|
||||
"spawn_loot": {
|
||||
"table": "loot_tables/blocks/custom_leaves.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"permutations": [
|
||||
{
|
||||
"condition": "q.block_state('wiki:decay_tier') == 0",
|
||||
"components": {
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"event": "wiki:decay"
|
||||
}
|
||||
},
|
||||
"tag:decay_tier_0": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:decay_tier') == 1",
|
||||
"components": {
|
||||
"tag:decay_tier_1": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:decay_tier') == 2",
|
||||
"components": {
|
||||
"tag:decay_tier_2": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:decay_tier') == 3",
|
||||
"components": {
|
||||
"tag:decay_tier_3": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:decay_tier') == 4",
|
||||
"components": {
|
||||
"tag:decay_tier_4": {}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:opaque')",
|
||||
"components": {
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_leaves",
|
||||
"render_method": "opaque"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Custom Log
|
||||
|
||||
<Spoiler title="Code">
|
||||
|
||||
<CodeHeader>BP/blocks/custom_log.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_log",
|
||||
"menu_category": {
|
||||
"category": "nature",
|
||||
"group": "itemGroup.name.log"
|
||||
},
|
||||
"states": {
|
||||
// Log direction state
|
||||
"wiki:axis": [0, 1, 2]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"tag:log": {},
|
||||
"minecraft:unit_cube": {},
|
||||
// Sets different textures for sides and top/bottom of log
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_log"
|
||||
},
|
||||
"ends": {
|
||||
"texture": "custom_log_top"
|
||||
},
|
||||
"up": "ends",
|
||||
"down": "ends"
|
||||
},
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 1
|
||||
},
|
||||
// Sets log rotation on player placing
|
||||
"minecraft:on_player_placing": {
|
||||
"event": "wiki:set_axis"
|
||||
},
|
||||
// Make log strippable
|
||||
"minecraft:on_interact": {
|
||||
"condition": "q.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_axe')",
|
||||
"event": "wiki:strip"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"wiki:set_axis": {
|
||||
"set_block_state": {
|
||||
"wiki:axis": "Math.floor(q.block_face / 2)"
|
||||
}
|
||||
},
|
||||
"wiki:strip": {
|
||||
"sequence": [
|
||||
{
|
||||
"run_command": {
|
||||
"command": "playsound hit.wood @a ~~~"
|
||||
},
|
||||
// Damages axe of player who stripped the log
|
||||
"damage": {
|
||||
"type": "durability",
|
||||
"amount": 1,
|
||||
"target": "item"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:axis') == 0",
|
||||
"run_command": {
|
||||
"command": "setblock ~~~ wiki:custom_stripped_log [\"wiki:axis\"=0]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:axis') == 1",
|
||||
"run_command": {
|
||||
"command": "setblock ~~~ wiki:custom_stripped_log [\"wiki:axis\"=1]"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:axis') == 2",
|
||||
"run_command": {
|
||||
"command": "setblock ~~~ wiki:custom_stripped_log [\"wiki:axis\"=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>
|
||||
|
||||
## Stripped Log
|
||||
|
||||
Here all components are the same
|
||||
|
||||
<Spoiler title="Code">
|
||||
|
||||
<CodeHeader>BP/blocks/custom_stripped_log.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_stripped_log",
|
||||
"menu_category": {
|
||||
"category": "nature",
|
||||
"group": "itemGroup.name.log"
|
||||
},
|
||||
"states": {
|
||||
// Log direction state
|
||||
"wiki:axis": [0, 1, 2]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"tag:log": {},
|
||||
"minecraft:unit_cube": {},
|
||||
// Sets different textures for sides and top/bottom of log
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_stripped_log"
|
||||
},
|
||||
"ends": {
|
||||
"texture": "custom_stripped_log_top"
|
||||
},
|
||||
"up": "ends",
|
||||
"down": "ends"
|
||||
},
|
||||
"minecraft:destructible_by_mining": {
|
||||
"seconds_to_destroy": 1
|
||||
},
|
||||
// Sets log rotation on player placing
|
||||
"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>
|
||||
|
||||
## Custom Sapling
|
||||
|
||||
For the sapling we will need structures of our tree to make the sapling semi-realistic as features cannot currently be placed with commands on Minecraft Bedrock.
|
||||
|
||||
<Spoiler title="Code">
|
||||
|
||||
<CodeHeader>BP/blocks/custom_sapling.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:block": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_sapling",
|
||||
"states": {
|
||||
// Sapling's growth stage
|
||||
"wiki:growth_stage": [0, 1, 2]
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:collision_box": false,
|
||||
"minecraft:selection_box": {
|
||||
"origin": [-6, 0, -6],
|
||||
"size": [12, 13, 12]
|
||||
},
|
||||
"minecraft:light_dampening": 0,
|
||||
"minecraft:geometry": "geometry.custom_sapling",
|
||||
"minecraft:material_instances": {
|
||||
"*": {
|
||||
"texture": "custom_sapling",
|
||||
"render_method": "alpha_test",
|
||||
"face_dimming": false,
|
||||
"ambient_occlusion": false
|
||||
}
|
||||
},
|
||||
// Add loot component so it will drop sapling placer item
|
||||
"minecraft:loot": "loot_tables/blocks/custom_sapling.json",
|
||||
// Allows to place block only on these blocks
|
||||
"minecraft:placement_filter": {
|
||||
"conditions": [
|
||||
{
|
||||
"allowed_faces": ["up"],
|
||||
"block_filter": ["minecraft:dirt", "minecraft:grass", "minecraft:podzol"]
|
||||
}
|
||||
]
|
||||
},
|
||||
// Trigger growth on each random tick
|
||||
"minecraft:random_ticking": {
|
||||
"on_tick": {
|
||||
"event": "wiki:grow"
|
||||
}
|
||||
},
|
||||
// Trigger growth when bone meal is used
|
||||
"minecraft:on_interact": {
|
||||
"condition": "q.is_item_name_any('slot.weapon.mainhand', 'minecraft:bone_meal')",
|
||||
"event": "wiki:fertilize"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"wiki:grow": {
|
||||
"sequence": [
|
||||
{
|
||||
"condition": "q.block_state('wiki:growth_stage') < 2",
|
||||
"set_block_state": {
|
||||
"wiki:growth_stage": "q.block_state('wiki:growth_stage') + 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": "q.block_state('wiki:growth_stage') == 2",
|
||||
"run_command": {
|
||||
"command": "structure load custom_tree ~-2~~-2"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"wiki:fertilize": {
|
||||
// Removes item that was used to interact
|
||||
"decrement_stack": {},
|
||||
// Trigger growth
|
||||
"trigger": {
|
||||
"event": "wiki:grow"
|
||||
},
|
||||
// Trigger effects
|
||||
"run_command": {
|
||||
"command": ["particle minecraft:crop_growth_emitter ~~~", "playsound item.bone_meal.use @a ~~~"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Sapling Placer
|
||||
|
||||
<Spoiler title="Code">
|
||||
|
||||
<CodeHeader>BP/items/custom_sapling_placer.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.20.30",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_sapling_placer",
|
||||
"menu_category": {
|
||||
"category": "nature",
|
||||
"group": "itemGroup.name.sapling"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"minecraft:max_stack_size": 64,
|
||||
"minecraft:block_placer": {
|
||||
"block": "wiki:custom_sapling"
|
||||
},
|
||||
"minecraft:icon": {
|
||||
"texture": "custom_sapling_placer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Loot Tables
|
||||
|
||||
<Spoiler title="Code">
|
||||
|
||||
This loot will spawn leaves block (when you break it using shears)
|
||||
|
||||
<CodeHeader>BP/loot_tables/blocks/custom_leaves_shears.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "item",
|
||||
"name": "wiki:custom_leaves"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Leaves default loot
|
||||
|
||||
<CodeHeader>BP/loot_tables/blocks/custom_leaves.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "item",
|
||||
"name": "minecraft:apple",
|
||||
"weight": 1
|
||||
},
|
||||
{
|
||||
"type": "item",
|
||||
"name": "wiki:custom_sapling_placer",
|
||||
"weight": 5
|
||||
},
|
||||
{
|
||||
// Nothing will drop
|
||||
"type": "empty",
|
||||
"weight": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This will spawn `wiki:custom_sapling`
|
||||
|
||||
<CodeHeader>BP/loot_tables/blocks/custom_sapling.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "item",
|
||||
"name": "wiki:custom_sapling_placer"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Exporting Structures
|
||||
|
||||
Build a tree for your sapling to grow into!
|
||||
|
||||

|
||||
|
||||
## Tree Features
|
||||
|
||||
:::tip
|
||||
Tree Features are a really great way to get actual custom trees. You need some understanding on how they work but for this tutorial you can uses these templates.
|
||||
:::
|
||||
|
||||
<Spoiler title="Feature">
|
||||
|
||||
<CodeHeader>BP/feature/custom_tree_feature.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.13.0",
|
||||
"minecraft:tree_feature": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_tree_feature"
|
||||
},
|
||||
"trunk": {
|
||||
"trunk_block": "wiki:custom_log",
|
||||
"trunk_height": {
|
||||
"range_min": 4,
|
||||
"range_max": 7
|
||||
}
|
||||
},
|
||||
"canopy": {
|
||||
"leaf_block": "wiki:custom_leaves",
|
||||
"canopy_offset": {
|
||||
"min": -3,
|
||||
"max": 0
|
||||
},
|
||||
"variation_chance": [
|
||||
{
|
||||
"numerator": 1,
|
||||
"denominator": 2
|
||||
},
|
||||
{
|
||||
"numerator": 1,
|
||||
"denominator": 2
|
||||
},
|
||||
{
|
||||
"numerator": 1,
|
||||
"denominator": 2
|
||||
},
|
||||
{
|
||||
"numerator": 1,
|
||||
"denominator": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"base_block": [
|
||||
"minecraft:dirt",
|
||||
{
|
||||
"name": "minecraft:dirt",
|
||||
"states": {
|
||||
"dirt_type": "coarse"
|
||||
}
|
||||
}
|
||||
],
|
||||
"may_grow_on": [
|
||||
"minecraft:dirt",
|
||||
"minecraft:grass",
|
||||
"minecraft:podzol",
|
||||
{
|
||||
"name": "minecraft:dirt",
|
||||
"states": {
|
||||
"dirt_type": "coarse"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:farmland",
|
||||
"states": {
|
||||
"moisturized_amount": 7
|
||||
}
|
||||
}
|
||||
],
|
||||
"may_replace": [
|
||||
"minecraft:air",
|
||||
{
|
||||
"name": "minecraft:leaves",
|
||||
"states": {
|
||||
"old_leaf_type": "oak"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:leaves",
|
||||
"states": {
|
||||
"old_leaf_type": "spruce"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:leaves",
|
||||
"states": {
|
||||
"old_leaf_type": "birch"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:leaves",
|
||||
"states": {
|
||||
"old_leaf_type": "jungle"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:leaves2",
|
||||
"states": {
|
||||
"new_leaf_type": "acacia"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minecraft:leaves2",
|
||||
"states": {
|
||||
"new_leaf_type": "dark_oak"
|
||||
}
|
||||
}
|
||||
],
|
||||
"may_grow_through": [
|
||||
"minecraft:dirt",
|
||||
"minecraft:grass",
|
||||
{
|
||||
"name": "minecraft:dirt",
|
||||
"states": {
|
||||
"dirt_type": "coarse"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
<Spoiler title="Feature Rule">
|
||||
|
||||
<CodeHeader>BP/feature_rules/custom_tree_feature_rule.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.13.0",
|
||||
"minecraft:feature_rules": {
|
||||
"description": {
|
||||
"identifier": "wiki:custom_tree_feature_rule",
|
||||
"places_feature": "wiki:custom_tree_feature"
|
||||
},
|
||||
"conditions": {
|
||||
"placement_pass": "surface_pass",
|
||||
"minecraft:biome_filter": [
|
||||
{
|
||||
"test": "has_biome_tag",
|
||||
"operator": "==",
|
||||
"value": "plains"
|
||||
}
|
||||
]
|
||||
},
|
||||
"distribution": {
|
||||
"iterations": 1,
|
||||
"x": {
|
||||
"distribution": "uniform",
|
||||
"extent": [0, 16]
|
||||
},
|
||||
"y": "q.heightmap(v.worldx, v.worldz)",
|
||||
"z": {
|
||||
"distribution": "uniform",
|
||||
"extent": [0, 16]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Spoiler>
|
||||
|
||||
## Resource Pack (optional guide)
|
||||
|
||||
Now it is time to make a resource pack!
|
||||
|
||||
Make translations for blocks:
|
||||
|
||||
<CodeHeader>RP/texts/en_US.lang</CodeHeader>
|
||||
|
||||
```
|
||||
tile.wiki:custom_log.name=Custom Log
|
||||
tile.wiki:custom_leaves.name=Custom Leaves
|
||||
tile.wiki:custom_stripped_log.name=Custom Stripped Log
|
||||
tile.wiki:custom_sapling.name=Custom Sapling
|
||||
item.wiki:custom_sapling_placer=Custom Sapling
|
||||
```
|
||||
|
||||
Make terrain_texture.json and textures.
|
||||
|
||||
<CodeHeader>RP/textures/terrain_texture.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"resource_pack_name": "custom-trees",
|
||||
"texture_name": "atlas.terrain",
|
||||
"num_mip_levels": 4,
|
||||
"padding": 8,
|
||||
"texture_data": {
|
||||
"custom_leaves": {
|
||||
"textures": "textures/blocks/leaves_oak"
|
||||
},
|
||||
"custom_log": {
|
||||
"textures": "textures/blocks/log_oak"
|
||||
},
|
||||
"custom_log_top": {
|
||||
"textures": "textures/blocks/log_oak_top"
|
||||
},
|
||||
"custom_stripped_log": {
|
||||
"textures": "textures/blocks/stripped_oak_log"
|
||||
},
|
||||
"custom_stripped_log_top": {
|
||||
"textures": "textures/blocks/stripped_oak_log_top"
|
||||
},
|
||||
"custom_sapling": {
|
||||
"textures": "textures/blocks/sapling_oak"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make geometry for sapling:
|
||||
|
||||
<CodeHeader>RP/models/blocks/custom_sapling.geo.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.custom_sapling",
|
||||
"texture_width": 16,
|
||||
"texture_height": 16,
|
||||
"visible_bounds_width": 2,
|
||||
"visible_bounds_height": 2.5,
|
||||
"visible_bounds_offset": [0, 0.75, 0]
|
||||
},
|
||||
"bones": [
|
||||
{
|
||||
"name": "sapling",
|
||||
"pivot": [0, 0, 0],
|
||||
"cubes": [
|
||||
{
|
||||
"origin": [-8, 0, 0],
|
||||
"size": [16, 16, 0],
|
||||
"pivot": [0, 0, 0],
|
||||
"rotation": [0, 45, 0],
|
||||
"uv": {
|
||||
"north": {"uv": [0, 0], "uv_size": [16, 16]}
|
||||
}
|
||||
},
|
||||
{
|
||||
"origin": [-8, 0, 0],
|
||||
"size": [16, 16, 0],
|
||||
"pivot": [0, 0, 0],
|
||||
"rotation": [0, -45, 0],
|
||||
"uv": {
|
||||
"north": {"uv": [0, 0], "uv_size": [16, 16]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Make item_texture file
|
||||
|
||||
<CodeHeader>RP/textures/item_texture.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"resource_pack_name": "custom-trees",
|
||||
"texture_name": "atlas.items",
|
||||
"texture_data": {
|
||||
"custom_sapling_placer": {
|
||||
"textures": "textures/blocks/sapling_oak"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Add sounds to blocks
|
||||
|
||||
<CodeHeader>RP/blocks.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": [1, 1, 0],
|
||||
"wiki:custom_leaves": {
|
||||
"sound": "grass"
|
||||
},
|
||||
"wiki:custom_log": {
|
||||
"sound": "wood"
|
||||
},
|
||||
"wiki:custom_stripped_log": {
|
||||
"sound": "wood"
|
||||
},
|
||||
"wiki:custom_sapling": {
|
||||
"sound": "grass"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Result
|
||||
|
||||
What you have created:
|
||||
|
||||
<Checklist>
|
||||
|
||||
- [x] Custom Trees with Decaying Leaves
|
||||
- [x] Working Sapling
|
||||
- [x] Rotatable and Stripable Logs
|
||||
|
||||
</Checklist>
|
||||
|
||||
<FolderView :paths="[
|
||||
'BP/blocks/custom_leaves.json',
|
||||
'BP/blocks/custom_log.json',
|
||||
'BP/blocks/custom_stripped_log.json',
|
||||
'BP/blocks/custom_sapling.json',
|
||||
'BP/features/custom_tree_feature.json',
|
||||
'BP/feature_rules/custom_tree_feature_rule.json',
|
||||
'BP/items/custom_sapling_placer.json',
|
||||
'BP/loot_tables/blocks/custom_leaves.json',
|
||||
'BP/loot_tables/blocks/custom_leaves_shears.json',
|
||||
'BP/loot_tables/blocks/custom_sapling.json',
|
||||
'BP/structures/custom_tree.mcstructure',
|
||||
'RP/blocks.json',
|
||||
'RP/texts/en_US.lang',
|
||||
'RP/textures/terrain_texture.json',
|
||||
'RP/models/blocks/custom_sapling.geo.json',
|
||||
'RP/textures/item_texture.json'
|
||||
]"></FolderView>
|
||||
|
||||

|
||||
|
||||
## Download Example Pack
|
||||
|
||||
Template Pack to use in-game to get the idea.
|
||||
|
||||
<BButton
|
||||
link="https://github.com/Bedrock-OSS/wiki-addon/releases/download/download/custom_trees.mcaddon"
|
||||
color=blue
|
||||
>Download MCADDON</BButton>
|
||||
131
docs/wiki/2-方块/5-文档/block-shapes.md
Normal file
131
docs/wiki/2-方块/5-文档/block-shapes.md
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
title: 方块形状
|
||||
category: 文档
|
||||
mentions:
|
||||
- SirLich
|
||||
- yanasakana
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- Luthorius
|
||||
- Fabrimat
|
||||
- TheItsNameless
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块形状
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::warning 已弃用
|
||||
方块形状功能已不再受官方支持,且无法应用于自定义方块,但仍可作用于原版方块。
|
||||
:::
|
||||
|
||||
方块形状本质上是硬编码于原版游戏中的几何模型,这意味着它们的存在不依赖于可见建模文件。
|
||||
|
||||
## 应用方式
|
||||
|
||||
在资源包的`blocks.json`文件中,通过方块对象的`"blockshape"`子项进行定义。具体示例如下:
|
||||
|
||||
::: code-group
|
||||
```json [RP/blocks.json]
|
||||
"wiki:invisible_aluminium_ore": {
|
||||
"blockshape": "invisible",
|
||||
"sound": "stone",
|
||||
"textures": "invisible_aluminium_ore"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 已知方块形状列表
|
||||
|
||||
| 标识符 | 方块形状名称 |
|
||||
| --- | ------------------------- |
|
||||
| -1 | invisible(不可见) |
|
||||
| 0 | block(普通方块) |
|
||||
| 1 | cross_texture(交叉纹理) |
|
||||
| 2 | torch(火把) |
|
||||
| 3 | fire(火焰) |
|
||||
| 4 | water(水体) |
|
||||
| 5 | red_dust(红石粉) |
|
||||
| 6 | rows(行排列) |
|
||||
| 7 | door(门) |
|
||||
| 8 | ladder(梯子) |
|
||||
| 9 | rail(轨道) |
|
||||
| 10 | stairs(阶梯) |
|
||||
| 11 | fence(栅栏) |
|
||||
| 12 | lever(拉杆) |
|
||||
| 13 | cactus(仙人掌) |
|
||||
| 14 | bed(床) |
|
||||
| 15 | diode(二极管) |
|
||||
| 18 | iron_fence(铁栏杆) |
|
||||
| 19 | stem(茎干) |
|
||||
| 20 | vine(藤蔓) |
|
||||
| 21 | fence_gate(栅栏门) |
|
||||
| 22 | chest(箱子) |
|
||||
| 23 | lilypad(睡莲) |
|
||||
| 25 | brewing_stand(炼药台) |
|
||||
| 26 | portal_frame(传送门框架) |
|
||||
| 28 | cocoa(可可豆) |
|
||||
| 31 | tree(树木) |
|
||||
| 32 | cobblestone_wall(圆石墙) |
|
||||
| 40 | double_plant(双层植物) |
|
||||
| 42 | flower_pot(花盆) |
|
||||
| 43 | anvil(铁砧) |
|
||||
| 44 | dragon_egg(龙蛋) |
|
||||
| 48 | structure_void(结构空位) |
|
||||
| 67 | block_half(半砖) |
|
||||
| 68 | top_snow(顶层雪) |
|
||||
| 69 | tripwire(绊线) |
|
||||
| 70 | tripwire_hook(绊线钩) |
|
||||
| 71 | cauldron(炼药锅) |
|
||||
| 72 | repeater(中继器) |
|
||||
| 73 | comparator(比较器) |
|
||||
| 74 | hopper(漏斗) |
|
||||
| 75 | slime_block(粘液块) |
|
||||
| 76 | piston(活塞) |
|
||||
| 77 | beacon(信标) |
|
||||
| 78 | chorus_plant(紫颂植物) |
|
||||
| 79 | chorus_flower(紫颂花) |
|
||||
| 80 | end_portal(末地传送门) |
|
||||
| 81 | end_rod(末地烛) |
|
||||
| 83 | skull(头颅) |
|
||||
| 84 | facing_block(朝向方块) |
|
||||
| 85 | command_block(命令方块) |
|
||||
| 86 | terracotta(陶瓦) |
|
||||
| 87 | double_side_fence(双面栅栏) |
|
||||
| 88 | frame(物品展示框) |
|
||||
| 89 | shulker_box(潜影盒) |
|
||||
| 90 | doublesided_cross_texture(双面交叉纹理) |
|
||||
| 91 | doublesided_double_plant(双面双层植物) |
|
||||
| 92 | doublesided_rows(双面行排列) |
|
||||
| 93 | element_block(元素方块) |
|
||||
| 94 | chemistry_table(化学工作台)|
|
||||
| 96 | coral_fan(珊瑚扇) |
|
||||
| 97 | seagrass(海草) |
|
||||
| 98 | kelp(海带) |
|
||||
| 99 | trapdoor(活板门) |
|
||||
| 100 | sea_pickle(海泡菜) |
|
||||
| 101 | conduit(潮涌核心) |
|
||||
| 102 | turtle_egg(海龟蛋) |
|
||||
| 105 | bubble_column(气泡柱) |
|
||||
| 106 | barrier(屏障) |
|
||||
| 107 | sign(告示牌) |
|
||||
| 108 | bamboo(竹子) |
|
||||
| 109 | bamboo_sapling(竹笋) |
|
||||
| 110 | scaffolding(脚手架) |
|
||||
| 111 | grindstone(砂轮) |
|
||||
| 112 | bell(钟) |
|
||||
| 113 | lantern(灯笼) |
|
||||
| 114 | campfire(营火) |
|
||||
| 115 | lectern(讲台) |
|
||||
| 116 | sweet_berry_bush(甜浆果丛)|
|
||||
| 117 | cartography_table(制图台) |
|
||||
| 119 | stonecutter_block(切石机) |
|
||||
| 123 | chain(锁链) |
|
||||
| 126 | sculk_sensor(侦测器) |
|
||||
| 133 | azalea(杜鹃花丛) |
|
||||
| 133 | flowering_azalea(盛开的杜鹃花丛) |
|
||||
| 134 | glow_frame(荧光物品展示框)|
|
||||
| 135 | glow_lichen(发光地衣) |
|
||||
|
||||
[原作者致谢](https://gist.github.com/toka7290/3bef704d2f57c775bb9ac84443a6df1c)
|
||||
122
docs/wiki/2-方块/5-文档/block-sounds.md
Normal file
122
docs/wiki/2-方块/5-文档/block-sounds.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: 方块声音
|
||||
category: 文档
|
||||
mentions:
|
||||
- MedicalJewel105
|
||||
- TheItsNameless
|
||||
- QuazChick
|
||||
---
|
||||
|
||||
# 方块声音
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
方块声音指的是`blocks.json`中方块条目内的音效属性。
|
||||
该属性用于设置方块的基本音效,包含挖掘音效、踩踏音效、破坏音效和放置音效等。您可以通过以下方式为方块添加音效:
|
||||
|
||||
::: code-group
|
||||
```json [RP/blocks.json]
|
||||
{
|
||||
"format_version": [1, 1, 0],
|
||||
"wiki:custom_log": {
|
||||
"sound": "wood" // 在此定义音效
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
以下为`sound`属性的有效值:
|
||||
|
||||
<!-- page_dumper_start -->
|
||||
| *最后更新于1.20.10版本* |
|
||||
| -------------------------- |
|
||||
| amethyst_block |
|
||||
| amethyst_cluster |
|
||||
| ancient_debris |
|
||||
| anvil |
|
||||
| azalea |
|
||||
| azalea_leaves |
|
||||
| bamboo |
|
||||
| bamboo_sapling |
|
||||
| bamboo_wood |
|
||||
| bamboo_wood_hanging_sign |
|
||||
| basalt |
|
||||
| big_dripleaf |
|
||||
| bone_block |
|
||||
| calcite |
|
||||
| candle |
|
||||
| cave_vines |
|
||||
| chain |
|
||||
| cherry_leaves |
|
||||
| cherry_wood |
|
||||
| cherry_wood_hanging_sign |
|
||||
| chiseled_bookshelf |
|
||||
| cloth |
|
||||
| comparator |
|
||||
| copper |
|
||||
| coral |
|
||||
| decorated_pot |
|
||||
| deepslate |
|
||||
| deepslate_bricks |
|
||||
| dirt_with_roots |
|
||||
| dripstone_block |
|
||||
| frog_spawn |
|
||||
| froglight |
|
||||
| fungus |
|
||||
| glass |
|
||||
| grass |
|
||||
| gravel |
|
||||
| hanging_roots |
|
||||
| hanging_sign |
|
||||
| honey_block |
|
||||
| itemframe |
|
||||
| ladder |
|
||||
| lantern |
|
||||
| large_amethyst_bud |
|
||||
| lever |
|
||||
| lodestone |
|
||||
| mangrove_roots |
|
||||
| medium_amethyst_bud |
|
||||
| metal |
|
||||
| moss_block |
|
||||
| moss_carpet |
|
||||
| mud |
|
||||
| mud_bricks |
|
||||
| muddy_mangrove_roots |
|
||||
| nether_brick |
|
||||
| nether_gold_ore |
|
||||
| nether_sprouts |
|
||||
| nether_wart |
|
||||
| nether_wood |
|
||||
| nether_wood_hanging_sign |
|
||||
| netherite |
|
||||
| netherrack |
|
||||
| nylium |
|
||||
| packed_mud |
|
||||
| pink_petals |
|
||||
| pointed_dripstone |
|
||||
| powder_snow |
|
||||
| roots |
|
||||
| sand |
|
||||
| scaffolding |
|
||||
| sculk |
|
||||
| sculk_catalyst |
|
||||
| sculk_sensor |
|
||||
| sculk_shrieker |
|
||||
| sculk_vein |
|
||||
| shroomlight |
|
||||
| slime |
|
||||
| small_amethyst_bud |
|
||||
| snow |
|
||||
| soul_sand |
|
||||
| soul_soil |
|
||||
| spore_blossom |
|
||||
| stem |
|
||||
| stone |
|
||||
| suspicious_gravel |
|
||||
| suspicious_sand |
|
||||
| sweet_berry_bush |
|
||||
| tuff |
|
||||
| vines |
|
||||
| wood |
|
||||
<!-- page_dumper_end -->
|
||||
273
docs/wiki/3-实体/1-基础/entity-events.md
Normal file
273
docs/wiki/3-实体/1-基础/entity-events.md
Normal file
@@ -0,0 +1,273 @@
|
||||
---
|
||||
title: 实体事件
|
||||
category: 综合
|
||||
mentions:
|
||||
- ChibiMango
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
tags:
|
||||
- 新手
|
||||
---
|
||||
|
||||
# 实体事件
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
实体事件是行为系统中与组件(Component)和组件组(Component Group)并列的基础构建模块之一。它们作为组件组的控制中枢,可以通过组件、动画(Animation)、动画控制器(Animation Controller)及其他事件进行调用。本文旨在详解实体内部及跨实体事件调用的方法,以及事件的基本格式结构。
|
||||
|
||||
## 事件结构
|
||||
|
||||
事件允许我们在特定条件满足时,通过添加或移除组件组来改变实体的行为模式。我们称之为"事件(Event)",因为它们可以被战斗倒计时结束、玩家交互、环境变化等情景所触发。当事件激活时,会根据预定义指令处理组件组的增删操作。
|
||||
|
||||
每个事件可包含七个核心指令键,分别用于执行组件组增删、条件判断、事件触发及属性设置:
|
||||
- add(添加)
|
||||
- remove(移除)
|
||||
- randomize(随机化)
|
||||
- sequence(序列)
|
||||
- filters(过滤器)
|
||||
- trigger(触发器)
|
||||
- set_property(属性设置)
|
||||
|
||||
### 添加/移除
|
||||
|
||||
事件最基础的功能是通过add/remove键直接增删组件组。如下示例中的`wiki:ranged_attacker`事件:
|
||||
|
||||
::: code-group
|
||||
```json [示例]
|
||||
"wiki:ranged_attacker":{
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"attacker",
|
||||
"ranged"
|
||||
]
|
||||
},
|
||||
"remove":{
|
||||
"component_groups":[
|
||||
"standby",
|
||||
"melee"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
:::tip 组件覆盖规则
|
||||
当添加组件组时,若现有活跃组件组中已包含同名组件,后添加的组件组会覆盖原有组件。
|
||||
:::
|
||||
|
||||
### 随机化
|
||||
|
||||
randomize参数允许根据权重概率随机执行组件组操作。原版牛的生成事件即使用该机制,实现95%概率生成成年牛,5%概率生成幼崽:
|
||||
|
||||
::: code-group
|
||||
```json [牛生成逻辑]
|
||||
"minecraft:entity_spawned":{
|
||||
"randomize":[
|
||||
{
|
||||
"weight":95,
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"minecraft:cow_adult"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"weight":5,
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"minecraft:cow_baby"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
:::warning 注意
|
||||
随机化配置中对每组权重进行归一化处理,最终不同选项的选择概率与其权重值占总权重的比例相关。
|
||||
:::
|
||||
|
||||
### 序列/过滤器
|
||||
|
||||
通过sequence参数可实现条件分支逻辑。原版僵尸的溺水转换事件根据是否是幼体执行不同操作:
|
||||
|
||||
::: code-group
|
||||
```json [僵尸溺水转换]
|
||||
"minecraft:convert_to_drowned":{
|
||||
"sequence":[
|
||||
{
|
||||
"filters":{
|
||||
"test":"has_component",
|
||||
"operator":"!=",
|
||||
"value":"minecraft:is_baby"
|
||||
},
|
||||
"add":["minecraft:convert_to_drowned"],
|
||||
"remove":["minecraft:start_drowned_transformation"]
|
||||
},
|
||||
{
|
||||
"filters":{
|
||||
"test":"has_component",
|
||||
"value":"minecraft:is_baby"
|
||||
},
|
||||
"add":["minecraft:convert_to_baby_drowned"],
|
||||
"remove":["minecraft:start_drowned_transformation"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
:::tip 序列执行机制
|
||||
序列中的每个分支会依次检查执行,通过过滤器的分支都会被执行而无互斥性。若无过滤器则默认执行,但不影响后续分支的判断。
|
||||
:::
|
||||
|
||||
下面这个整合多条件的攻击序列示例展示了复杂逻辑的实现:
|
||||
|
||||
::: spoiler title="复杂攻击序列示例"
|
||||
|
||||
::: code-group
|
||||
```json [攻击逻辑]
|
||||
"wiki:on_hit":{
|
||||
"randomize":[
|
||||
{
|
||||
"weight":60 //60%概率无操作
|
||||
},
|
||||
{
|
||||
"weight":40,
|
||||
"sequence":[
|
||||
{"trigger":"attack_event"},
|
||||
{
|
||||
"filters":["!minecraft:is_sheared"],
|
||||
"sequence":[...]
|
||||
},
|
||||
{
|
||||
"filters":["minecraft:is_sheared"],
|
||||
"sequence":[...]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
:::
|
||||
|
||||
### 事件触发
|
||||
|
||||
通过trigger参数可以在事件中调用其他事件,结合target参数可实现跨实体交互。以玩家与猪互动事件为例:
|
||||
|
||||
::: code-group
|
||||
```json [互动事件]
|
||||
"wiki:on_interact": {
|
||||
"trigger": {
|
||||
"filters":{
|
||||
"test":"is_family",
|
||||
"subject":"self",
|
||||
"value":"pig"
|
||||
},
|
||||
"event":"wiki:interacted",
|
||||
"target":"other"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
:::tip 目标上下文
|
||||
事件的执行需要明确的实体上下文。例如互动事件中,"other"指代互动发起者。若无对应上下文时,"target"指令将失效。
|
||||
:::
|
||||
|
||||
## 事件调用方式
|
||||
|
||||
事件可通过以下五种途径触发:
|
||||
1. 组件系统调用(如环境传感器)
|
||||
2. 动画时间轴调用
|
||||
3. 动画控制器状态切换
|
||||
4. 其他事件链式调用
|
||||
5. 控制台命令 `/event`
|
||||
|
||||
以下示例展示不同调用方式:
|
||||
|
||||
### 组件系统调用
|
||||
|
||||
僵尸的水下转换事件通过环境传感器触发:
|
||||
|
||||
::: code-group
|
||||
```json [僵尸转换]
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": {
|
||||
"filters":["is_underwater"],
|
||||
"event":"minecraft:start_transforming"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 动画调用
|
||||
|
||||
在动画时间轴中按时间节点触发扑击事件:
|
||||
|
||||
::: code-group
|
||||
```json [动画事件]
|
||||
"animation.entity.pounce_timer": {
|
||||
"timeline": {
|
||||
"10.0": "@s wiki:start_pouncing"
|
||||
},
|
||||
"animation_length":10.1
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 跨实体事件调用
|
||||
|
||||
唤魔者的特殊技能通过发送事件到特定实体:
|
||||
|
||||
::: code-group
|
||||
```json [唤魔者技能]
|
||||
"minecraft:behavior.send_event":{
|
||||
"event_choices":[{
|
||||
"filters":["is_family:sheep"],
|
||||
"sequence":[{
|
||||
"event":"wololo",
|
||||
"target":"other"
|
||||
}]
|
||||
}]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 内置事件
|
||||
|
||||
系统级自动触发事件需特别注意:
|
||||
|
||||
| 事件名称 | 触发条件 |
|
||||
|------------------------------|--------------------------|
|
||||
| minecraft:entity_spawned | 实体生成时 |
|
||||
| minecraft:entity_born | 繁殖产生新实体时 |
|
||||
| minecraft:entity_transformed | 实体形态转换完成时 |
|
||||
| minecraft:on_prime | 爆炸物引信燃尽准备爆炸时 |
|
||||
|
||||
::: code-group
|
||||
```json [牛实体配置示例]
|
||||
"events": {
|
||||
"minecraft:entity_spawned": {
|
||||
"randomize":[
|
||||
{"weight":95, "add":["minecraft:cow_adult"]},
|
||||
{"weight":5, "add":["minecraft:cow_baby"]}
|
||||
]
|
||||
},
|
||||
"minecraft:entity_born":{
|
||||
"add":["minecraft:cow_baby"]
|
||||
},
|
||||
"minecraft:entity_transformed":{
|
||||
"add":["minecraft:cow_adult"]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
通过合理组合这些功能模块,开发者可以创建出丰富复杂的实体行为逻辑。建议配合动画控制器文档以构建更高级的行为系统。
|
||||
178
docs/wiki/3-实体/1-基础/entity-intro-bp.md
Normal file
178
docs/wiki/3-实体/1-基础/entity-intro-bp.md
Normal file
@@ -0,0 +1,178 @@
|
||||
---
|
||||
title: 实体行为包入门指南
|
||||
category: 基础知识
|
||||
nav_order: 1
|
||||
tags:
|
||||
- 指南
|
||||
- 新手入门
|
||||
mentions:
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- stirante
|
||||
- Joelant05
|
||||
- destruc7ion
|
||||
- MedicalJewel105
|
||||
- ChibiMango
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# 实体行为包入门指南
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
构成行为包实体文件基础的三个主要结构如下:本文将解释它们的含义及使用方法。
|
||||
|
||||
组件组(component group)与组件(components)的混淆是常见的错误来源,请特别注意区分两者的区别。
|
||||
|
||||
## 组件(Components)
|
||||
|
||||
组件是构成Minecraft实体的逻辑构建模块。所有组件均由Mojang开发并提供给开发者使用。组件可实现多种功能,例如设置实体尺寸或赋予游泳能力等。完整组件列表可参考[官方文档](https://bedrock.dev/docs/stable/Entities)。
|
||||
|
||||
_无法_创建自定义组件。所有组件列表由微软硬编码实现并对外提供。
|
||||
|
||||
需要为实体添加行为时,可通过在`minecraft:entity`对象的`components`属性中插入组件。例如要给实体添加攀爬能力,可插入组件:`"minecraft:can_climb": {}`。
|
||||
|
||||
组件统一采用`"minecraft:<组件名称>": { <参数设置> }`格式。不同类型组件需要设置不同参数。
|
||||
|
||||
以下是实体内的组件应用范例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/example.json#minecraft:entity]
|
||||
"components": {
|
||||
"minecraft:type_family": {
|
||||
"family": [
|
||||
"player"
|
||||
]
|
||||
},
|
||||
"minecraft:collision_box": {
|
||||
"width": 0.6,
|
||||
"height": 1.8
|
||||
},
|
||||
"minecraft:can_climb": {},
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
(注意`components`列表_仅_包含组件)
|
||||
|
||||
## 组件组(Component Groups)
|
||||
|
||||
组件组用于整理归类多个组件。通过`事件(events)`可动态添加或移除组件组,从而实现定制化游戏玩法。
|
||||
|
||||
应用示例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/example.json#minecraft:entity]
|
||||
"component_groups": {
|
||||
|
||||
//组件组名称
|
||||
"minecraft:cat_persian": {
|
||||
|
||||
//合法的组件列表(可添加多项)
|
||||
"minecraft:variant": {
|
||||
"value": 6
|
||||
},
|
||||
"minecraft:physics": {}
|
||||
},
|
||||
|
||||
//第二个组件组名称
|
||||
"wiki:example_group": {
|
||||
"minecraft:type_family": {
|
||||
"family": [
|
||||
"wiki_is_awesome!"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
所有组件组均为自定义创建,不可直接引用其他实体的组件组。
|
||||
|
||||
在原版Minecraft实体中,组件组使用`minecraft:`前缀命名(如示例中的`minecraft:cat_persian`)。但需特别注意这些_并非_组件。开发者可自由使用任意命名规则,例如上文中的`wiki:example_group`。更多命名空间信息请参阅[此文档](/concepts/namespaces)。
|
||||
|
||||
放在组件组中的组件不会自动生效,必须通过事件激活才能影响实体行为。多个组件组可同时生效。
|
||||
|
||||
## 事件(Events)
|
||||
|
||||
事件是一种特殊语法,用于在满足条件时通过组件触发添加/移除组件组的操作,从而实现实体的动态行为。
|
||||
|
||||
示例结构:
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/example.json#minecraft:entity#events]
|
||||
"minecraft:ageable_grow_up": { //事件名称
|
||||
"remove": { //需要移除的组件组列表
|
||||
"component_groups": [
|
||||
"minecraft:cat_baby"
|
||||
]
|
||||
},
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"minecraft:cat_adult" //需要添加的组件组列表
|
||||
]
|
||||
}
|
||||
},
|
||||
```
|
||||
:::
|
||||
|
||||
事件与组件组相同,均为完全自定义内容。不可直接照搬其他实体的事件名称(例如`"minecraft:ageable_grow_up"`)。若需类似功能,应自主设计组件组和事件。
|
||||
|
||||
_仅能对组件组进行添加/移除操作_,无法直接操作单个组件。
|
||||
|
||||
当满足某些条件时,特定组件会触发事件。下方示例演示交互功能实现:
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/example.json#minecraft:entity]
|
||||
"components": {
|
||||
"minecraft:interact": {
|
||||
"interactions": [
|
||||
{
|
||||
"on_interact": {
|
||||
"filters": [ //触发条件筛选器
|
||||
{
|
||||
"test":"is_family",
|
||||
"subject": "other",
|
||||
"value": "player" //被交互对象属于玩家
|
||||
}
|
||||
],
|
||||
"target": "self", //作用目标为实体自身
|
||||
"event": "wiki:on_interact" //触发指定事件
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"component_groups": {
|
||||
"wiki:interacted": {
|
||||
"minecraft:scale": { //缩放组件
|
||||
"value": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"events":{
|
||||
"wiki:on_interact":{ //事件定义
|
||||
"add": {
|
||||
"component_groups": [ "wiki:interacted" ] //添加组件组
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
当玩家与该实体交互时,将触发`"wiki:on_interact"`事件,添加`"wiki:interacted"`组件组,从而激活缩放效果。
|
||||
|
||||
想深入了解事件的更多用法,请参阅[实体事件](/entities/entity-events)页面。
|
||||
|
||||
<BButton link="/entities/entity-events">实体事件详解</BButton>
|
||||
|
||||
## 原版应用案例
|
||||
|
||||
组件组与事件是原版实体实现自定义行为的核心工具。以下列举部分原版特性应用:
|
||||
|
||||
- 僵尸在水下停留过久后会通过事件转变为溺尸(drowned)
|
||||
|
||||
- 狐狸根据生成环境的不同,采用`minecraft:fox_red`与`minecraft:fox_active`组件组实现毛色变化
|
||||
|
||||
- 末影人使用事件机制实现被注视时进行攻击
|
||||
273
docs/wiki/3-实体/1-基础/entity-intro-rp.md
Normal file
273
docs/wiki/3-实体/1-基础/entity-intro-rp.md
Normal file
@@ -0,0 +1,273 @@
|
||||
---
|
||||
title: 实体资源包入门指南
|
||||
category: 基础指南
|
||||
nav_order: 2
|
||||
tags:
|
||||
- 新手教程
|
||||
- 入门指南
|
||||
mentions:
|
||||
- SirLich
|
||||
- MedicalJewel105
|
||||
- Overload1252
|
||||
- ChibiMango
|
||||
- Luthorius
|
||||
- TheItsNameless
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# 实体资源包入门指南
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
资源包中的实体文件定义了构成实体视觉效果的各种资源引用,同时包含了如何渲染这些视觉元素的详细逻辑。
|
||||
|
||||
本文将分解实体文件的每个组成部分并进行详细说明。如需创建自定义实体的完整指引,请参考我们的[新手教程](/guide/custom-entity)。
|
||||
|
||||
## 文件大纲
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json]
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"identifier": "wiki:example",
|
||||
"materials": {...},
|
||||
"textures": {...},
|
||||
"geometry": {...},
|
||||
"render_controllers": [...],
|
||||
|
||||
"animations": {...},
|
||||
"scripts": {...},
|
||||
|
||||
"sound_effects": {...},
|
||||
"particle_effects": {...},
|
||||
|
||||
"spawn_egg": {...},
|
||||
"enable_attachables": false,
|
||||
"hide_armor": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
尽管看起来复杂,文件中大部分内容都采用**简称定义**模式。简称定义允许我们将资源路径(如材质纹理)或几何体ID等元素映射为简短名称以便后续引用。这种设计既方便后续资源路径变更时集中修改,也使代码保持简洁。
|
||||
|
||||
## 材质系统
|
||||
材质(Materials)决定了纹理的渲染方式。例如骷髅使用透明材质,而末影人的眼睛材质具有自发光特性。大部分情况下可以直接使用预设材质而无需自定义。
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/spider.entity.json#minecraft:client_entity/description]
|
||||
"materials": {
|
||||
"default": "spider",
|
||||
"invisible": "spider_invisible"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
这里的`default`和`invisible`是简称,分别指向`spider`和`spider_invisible`材质。需要注意的是单纯的简称定义并不会告知实体何时使用不同材质。
|
||||
|
||||
[预置材质列表](/documentation/materials)可供参考。[自定义材质教程](/visuals/materials)适合进阶开发者。
|
||||
|
||||
## 纹理配置
|
||||
纹理(Textures)是映射到模型表面的图像文件。此部分同样使用简称定义系统:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/bee.entity.json#minecraft:client_entity/description]
|
||||
"textures": {
|
||||
"default": "textures/entity/bee/bee",
|
||||
"angry": "textures/entity/bee/bee_angry",
|
||||
"nectar": "textures/entity/bee/bee_nectar",
|
||||
"angry_nectar": "textures/entity/bee/bee_angry_nectar"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
支持定义多状态纹理(如蜜蜂的不同状态),也可叠加纹理层(参考村民的生物群系基底+职业层组合)。详细应用技巧参见[渲染控制器章节](/entities/render-controllers)。
|
||||
|
||||
## 几何体格式
|
||||
几何体(Geometry)由Blockbench等建模工具生成的骨骼模型文件构成:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/creeper.entity.json#minecraft:client_entity/description]
|
||||
"geometry": {
|
||||
"default": "geometry.creeper",
|
||||
"charged": "geometry.creeper.charged"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
这里的简称指向几何体文件的唯一标识符(JSON文件中的`identifier`字段)。以苦力怕为例,充电与普通状态使用不同模型:
|
||||
|
||||
::: tip
|
||||
模型显示异常时,首要检查简称定义是否存在拼写错误。
|
||||
:::
|
||||
|
||||
## 渲染控制器
|
||||
渲染控制器(Render Controllers)是控制实体渲染方式的核心组件,负责协调材质、纹理和模型的搭配使用:
|
||||
|
||||
::: code-group
|
||||
```json [RP/render_controllers/example.rc.json]
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"render_controllers": {
|
||||
"controller.render.example": {
|
||||
"geometry": "geometry.default",
|
||||
"materials": [{ "*": "material.default" }],
|
||||
"textures": ["texture.default"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
该示例始终使用"default"标识的各类资源。进阶用法可支持动态切换纹理与隐藏模型部件,详情参阅[渲染控制器指南](/entities/render-controllers)。
|
||||
|
||||
在实体文件中通过标识符指定渲染控制器:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"render_controllers": ["controller.render.example"]
|
||||
```
|
||||
:::
|
||||
|
||||
最低限度的实体文件须包含材质、纹理、几何体、渲染控制器四个基础模块。
|
||||
|
||||
## 动画系统
|
||||
动画(Animations)定义模型骨骼的运动逻辑,涵盖行走、攻击、视线追踪等交互行为:
|
||||
|
||||
::: code-group
|
||||
```json [RP/animations/example.a.json]
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"animations": {
|
||||
"animation.example.walk": {...},
|
||||
"animation.example.attack": {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
实体文件中需配置动画简称以便调用:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"animations": {
|
||||
"walk": "animation.example.walk",
|
||||
"attack": "animation.example.attack",
|
||||
"attack_controller": "controller.animation.example"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: warning 重要提示
|
||||
单单定义动画简称并不能启动动画,需通过脚本系统主动调用。
|
||||
:::
|
||||
|
||||
## 脚本逻辑
|
||||
脚本(Scripts)通过Molang表达式协调动画播放、变量设置、模型缩放等动态行为:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"scripts": {
|
||||
"initialize": [...],
|
||||
"pre_animation": [...],
|
||||
"animate": [...],
|
||||
"scale": "1"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 初始化脚本
|
||||
实体生成或加载时执行,适合设置初始变量。
|
||||
|
||||
### 预动画脚本
|
||||
每帧渲染前运行,用于计算动画参数。
|
||||
|
||||
### 动画脚本
|
||||
每帧执行动画控制器和播放逻辑:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"animate": [
|
||||
"attack_controller",
|
||||
{ "walk": "q.modified_move_speed" }
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
`q.modified_move_speed`将行走速度映射为动画播放速率。数值`2`表示双倍播放,动态公式使动画与实体速度保持同步。
|
||||
|
||||
### 模型缩放
|
||||
`scale`参数支持通过Molang表达式调整模型尺寸:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"scripts": {
|
||||
"scale": "q.variant",
|
||||
"scaleX": 2,
|
||||
"scaleY": 0.5
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
该示例:
|
||||
- Y轴方向缩放0.5倍
|
||||
- X轴放大2倍
|
||||
- 整体尺寸由变体值决定(`minecraft:variant`组件)
|
||||
|
||||
::: tip 随机尺寸案例
|
||||
`math.random_integer(1,5)`可在初始化时生成1-5的随机缩放系数。
|
||||
:::
|
||||
|
||||
## 音效配置
|
||||
音效简称便于在动画事件中调用:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"sound_effects": {
|
||||
"attack_1": "mob.entity.attack_1",
|
||||
"attack_2": "mob.entity.attack_2",
|
||||
"attack_3": "mob.entity.attack_3"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 粒子系统
|
||||
粒子简称用于动画事件触发:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"particle_effects": {
|
||||
"smoke": "wiki:smoke_particle"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
[自定义粒子教程](/particles/particles) | [动画效果应用](/visuals/animation-effects)
|
||||
|
||||
## 生成蛋设置
|
||||
生成蛋(Spawn Egg)支持纯色或自定义纹理两种风格:
|
||||
|
||||
::: code-group 纯色风格
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"spawn_egg": {
|
||||
"base_color": "#db7500",
|
||||
"overlay_color": "#242222"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
::: code-group 定制纹理
|
||||
```json [RP/entity/example.json#minecraft:client_entity/description]
|
||||
"spawn_egg": {
|
||||
"texture": "wiki.example"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 特殊参数
|
||||
- `enable_attachables`(启用配件):控制实体能否持握工具
|
||||
- `hide_armor`(隐藏护甲):允许穿装备但不显示外观
|
||||
236
docs/wiki/3-实体/1-基础/entity-properties.md
Normal file
236
docs/wiki/3-实体/1-基础/entity-properties.md
Normal file
@@ -0,0 +1,236 @@
|
||||
---
|
||||
title: 实体属性
|
||||
category: 常规
|
||||
tags:
|
||||
- 实验性
|
||||
mentions:
|
||||
- SirLich
|
||||
- sermah
|
||||
- MedicalJewel105
|
||||
- Luthorius
|
||||
- stirante
|
||||
- TheItsNameless
|
||||
---
|
||||
|
||||
# 实体属性
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::warning
|
||||
本文档包含过时信息及实验性内容。如需最新稳定版信息,请查阅[微软官方文档](https://learn.microsoft.com/en-us/minecraft/creator/documents/introductiontoentityproperties)。
|
||||
:::
|
||||
|
||||
本文档介绍在Minecraft基岩版1.16.230.52测试版中加入的新实体属性系统(又称Actor Properties)。实体属性的实现目的是在实体服务端(行为包)高效保存数据或存储数值,无需使用组件或属性(例如"minecraft:variant"),其运作原理类似方块属性。
|
||||
|
||||
## 实体属性定义
|
||||
|
||||
### 定义实体属性
|
||||
|
||||
实体属性定义示例:
|
||||
|
||||
::: code-group
|
||||
```json [实体定义]
|
||||
{
|
||||
"minecraft:entity":{
|
||||
"description":{
|
||||
"identifier":"entity:properties_example",
|
||||
"properties":{
|
||||
"property:number_range_example":{
|
||||
"values":{
|
||||
"min":0,
|
||||
"max":100
|
||||
}
|
||||
},
|
||||
"property:number_enum_example":{
|
||||
"values":[
|
||||
1,
|
||||
2
|
||||
]
|
||||
},
|
||||
"property:string_enum_example":{
|
||||
"values":[
|
||||
"first",
|
||||
"second",
|
||||
"third"
|
||||
]
|
||||
},
|
||||
"property:boolean_enum_example":{
|
||||
"values":[
|
||||
true,
|
||||
false
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 实体属性字段说明
|
||||
|
||||
#### `values`
|
||||
|
||||
:::warning
|
||||
`values`字段为必填项,缺失此字段可能导致属性注册失败。
|
||||
:::
|
||||
|
||||
`values`字段可接受枚举值数组或数值区间(注意当前版本中整数、浮点和布尔枚举最多支持两个值):
|
||||
|
||||
::: code-group
|
||||
```json [数值范围模式]
|
||||
"property:range_example": {
|
||||
"values": {
|
||||
"min": 0,
|
||||
"max": 5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json [枚举模式]
|
||||
"property:enum_example":{
|
||||
"values":[
|
||||
1,
|
||||
2
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
#### `default`
|
||||
|
||||
可通过属性对象内的`default`字段设置属性默认值(默认使用枚举数组的第一个元素):
|
||||
|
||||
::: code-group
|
||||
```json [默认值设置]
|
||||
"property:default_value_example":{
|
||||
"values":[
|
||||
true,
|
||||
false
|
||||
],
|
||||
"default":false
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
如示例所示,当实体生成时该属性会默认为`false`而非`true`。
|
||||
|
||||
#### `client_sync`
|
||||
|
||||
通过设置`client_sync`字段为`true`,可将属性同步到客户端资源包(Resource Pack)使用。默认值为`false`。
|
||||
|
||||
::: code-group
|
||||
```json [客户端同步示例]
|
||||
"property:client_sync_example": {
|
||||
"values": {
|
||||
"min": 0,
|
||||
"max": 20
|
||||
},
|
||||
"client_sync": true
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 操作与访问实体属性
|
||||
|
||||
可通过以下Molang查询访问实体属性:
|
||||
- `q.actor_property`
|
||||
- `q.has_actor_property`
|
||||
|
||||
:::warning
|
||||
这些Molang查询属于实验性功能
|
||||
:::
|
||||
|
||||
可通过`set_actor_property`事件响应设置实体属性值:
|
||||
|
||||
::: code-group
|
||||
```json [事件响应示例]
|
||||
"events":{
|
||||
"event:set_entity_property":{
|
||||
"set_actor_property":{
|
||||
"property:number_enum_example":2,
|
||||
"property:string_enum_example":"'second'",
|
||||
"property:boolean_enum_example":"!q.actor_property('property:boolean_enum_example')"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 实体别名系统
|
||||
|
||||
可通过定义实体别名(aliases),在`summon`指令中调用自定义标识符生成带预置属性的实体:
|
||||
|
||||
::: code-group
|
||||
```json [别名定义]
|
||||
{
|
||||
"format_version": "1.16.0",
|
||||
"minecraft:entity": {
|
||||
"description": {
|
||||
"identifier": "entity:properties_example",
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true,
|
||||
"is_experimental": false,
|
||||
"properties": {
|
||||
"property:property_index": {
|
||||
"client_sync": true,
|
||||
"values": {
|
||||
"min": 0,
|
||||
"max": 2
|
||||
},
|
||||
"default": 0
|
||||
}
|
||||
},
|
||||
"aliases": {
|
||||
"entity:default_alias": {},
|
||||
"entity:first_alias": {
|
||||
"property:property_index": 1
|
||||
},
|
||||
"entity:second_alias": {
|
||||
"property:property_index": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
现在通过`/summon entity:first_alias`指令可生成带有`property:property_index=1`属性的实体。
|
||||
|
||||
## 实体动态组件
|
||||
|
||||
实体动态组件(Entity Permutations)可根据属性条件在每个Tick动态应用组件集合。需在`minecraft:entity`对象内与`components`同级添加`permutations`数组:
|
||||
|
||||
::: code-group
|
||||
```json [动态组件示例]
|
||||
"permutations":[
|
||||
{
|
||||
"condition":"q.actor_property('property:string_enum_example') == 'first'",
|
||||
"components":{
|
||||
"minecraft:scale":{
|
||||
"value":1.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition":"q.actor_property('property:string_enum_example') == 'second'",
|
||||
"components":{
|
||||
"minecraft:scale":{
|
||||
"value":2.0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition":"q.actor_property('property:string_enum_example') == 'third'",
|
||||
"components":{
|
||||
"minecraft:scale":{
|
||||
"value":3.0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
当`property:string_enum_example`属性为"first"时,实体会应用1倍缩放,为"second"时应用2倍缩放,为"third"时则应用3倍缩放。
|
||||
337
docs/wiki/3-实体/1-基础/npc-dialogs.md
Normal file
337
docs/wiki/3-实体/1-基础/npc-dialogs.md
Normal file
@@ -0,0 +1,337 @@
|
||||
---
|
||||
title: NPC 对话框
|
||||
category: 通用
|
||||
tags:
|
||||
- 中级
|
||||
参与贡献:
|
||||
- kyleplo
|
||||
- StuartDA
|
||||
- MedicalJewel105
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- omuhu
|
||||
- Sprunkles137
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# NPC 对话框
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
非玩家角色(NPC)是类似村民的实体,可通过对话框显示消息并提供多个交互按钮。最初设计用于冒险地图,随着 `/dialogue` 命令的引入,现在也能在常规附加包中使用。
|
||||
|
||||
## 对话框文件
|
||||
|
||||
NPC 对话数据存储于行为包根目录下 `dialogue` 文件夹内的 `.diag.json` 文件中。基础模板示例如下:
|
||||
|
||||
::: code-group
|
||||
```json [dialogue/example.diag.json]
|
||||
{
|
||||
"format_version": "1.17",
|
||||
"minecraft:npc_dialogue": {
|
||||
"scenes": [
|
||||
{
|
||||
"scene_tag": "example",
|
||||
"npc_name": "Steve",
|
||||
"text": "你好"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
每个场景包含以下可配置参数:
|
||||
|
||||
#### scene_tag
|
||||
|
||||
场景唯一标识符,用于指定具体场景。
|
||||
|
||||
#### npc_name
|
||||
|
||||
NPC 显示名称。若省略,则使用 NPC 实体名称(默认为`§eNPC`)。
|
||||
|
||||
#### text
|
||||
|
||||
显示在对话框中的文本(可选)。
|
||||
|
||||
#### on_open_commands
|
||||
|
||||
打开对话框时执行的命令列表(可选)。
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"on_open_commands": [
|
||||
"/say 你好"
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
#### on_close_commands
|
||||
|
||||
关闭对话框时执行的命令列表(可选)。
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"on_close_commands": [
|
||||
"/say 再见"
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
#### buttons
|
||||
|
||||
对话框中显示的按钮配置(可选)。
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"buttons": [
|
||||
{
|
||||
"name": "按钮一",
|
||||
"commands": [
|
||||
"/say 按钮一被点击了!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "按钮二",
|
||||
"commands": [
|
||||
"/say 按钮二被点击了!",
|
||||
"/say 第二段命令示例"
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
## 玩家选择器
|
||||
|
||||
在 `on_open_commands`、`on_close_commands` 和各按钮的 `commands` 中可使用本地选择器 `@p`,但会以 NPC 实体为中心选择。特殊选择器 `@initiator` 可始终指向触发对话框的玩家。
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"buttons": [
|
||||
{
|
||||
"name": "获得漂浮效果",
|
||||
"commands": [
|
||||
"/effect @initiator levitation"
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
注意:`@initiator` 专用于 NPC 对话框,不可在其他场景使用。
|
||||
|
||||
## 文本本地化
|
||||
|
||||
可通过翻译键实现多语言支持:
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"npc_name": {
|
||||
"rawtext": [
|
||||
{
|
||||
"translate": "entity.endermite.name"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
需在资源包语言文件中定义对应翻译键,例如 `entity.endermite.name` 对应中文为"末影螨"。
|
||||
|
||||
## 打开对话框
|
||||
|
||||
使用 `/dialogue` 命令开启对话框:
|
||||
```
|
||||
/dialogue open <npc: 目标> <player: 目标> [场景名称:string]
|
||||
```
|
||||
- `<npc: 目标>`:需携带 `minecraft:npc` 组件的实体(如原版 NPC)
|
||||
- `<player: 目标>`:目标玩家
|
||||
- `[场景名称:string]`:指定 `scene_tag`(若省略则显示上一个场景)
|
||||
|
||||
示例命令:
|
||||
```
|
||||
/dialogue open @e[type=npc,c=1] @p example
|
||||
```
|
||||
|
||||
## 切换对话框
|
||||
|
||||
使用以下语法变更 NPC 默认对话框:
|
||||
```
|
||||
/dialogue change <npc: 目标> <场景名称:string> [player: 目标]
|
||||
```
|
||||
- `<场景名称:string>`:指定新场景的 `scene_tag`
|
||||
- `[player: 目标]`:指定生效玩家(若省略则影响所有人)
|
||||
|
||||
示例命令:
|
||||
```
|
||||
/dialogue change @e[type=npc,c=1] example @r
|
||||
```
|
||||
|
||||
## 完整范例
|
||||
|
||||
本节演示创建具有传送功能的道具和对话系统(完整源码可参见[GitHub](https://github.com/Llama-Studios/dialog-demo))。
|
||||
|
||||
### 创建 NPC 实体
|
||||
|
||||
即使隐藏 NPC,也需要通过常加载区域保持存在:
|
||||
|
||||
::: code-group
|
||||
```mcfunction [functions/setup.mcfunction]
|
||||
tickingarea add 0 1 0 0 2 0
|
||||
summon npc "§r" 0 1 0
|
||||
```
|
||||
:::
|
||||
|
||||
:::tip
|
||||
可通过玩家实体触发对话框:
|
||||
1. 为玩家添加 `minecraft:npc` 组件
|
||||
2. 映射行为包对话框场景
|
||||
3. 执行以下命令:
|
||||
```
|
||||
/dialogue open @s @s <scene_tag>
|
||||
```
|
||||
#### 优劣分析
|
||||
`+` 无需维护隐藏 NPC<br/>
|
||||
`+` 无需管理常加载区域<br/>
|
||||
`-` 非正常使用可能导致稳定性问题<br/>
|
||||
`-` 其他玩家点击该玩家时会显示对话框<br/>
|
||||
|
||||
可通过添加交互组件避免问题:
|
||||
::: code-group
|
||||
```json
|
||||
"minecraft:interact": {
|
||||
"interactions": [
|
||||
{
|
||||
"on_interact": {
|
||||
"filters": {
|
||||
"all_of": [
|
||||
{
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "player"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
:::
|
||||
|
||||
### 对话文件配置
|
||||
|
||||
::: code-group
|
||||
```json [dialogue/example.diag.json]
|
||||
{
|
||||
"format_version":"1.17",
|
||||
"minecraft:npc_dialogue":{
|
||||
"scenes":[
|
||||
{
|
||||
"scene_tag":"main_teleport_menu",
|
||||
"npc_name":"传送菜单",
|
||||
"text":"选择传送目的地",
|
||||
"buttons":[
|
||||
{
|
||||
"name":"区域传送",
|
||||
"commands":[
|
||||
"/dialogue open @e[type=npc,c=1] @initiator districts_teleport_menu"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"个人基地",
|
||||
"commands":[
|
||||
"/tp @initiator -20 4 -20"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"世界出生点",
|
||||
"commands":[
|
||||
"/tp @initiator 0 4 0"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"scene_tag":"districts_teleport_menu",
|
||||
"npc_name":"区域传送",
|
||||
"text":"请选择目标区域",
|
||||
"buttons":[
|
||||
{
|
||||
"name":"< 返回",
|
||||
"commands":[
|
||||
"/dialogue open @e[type=npc,c=1] @initiator main_teleport_menu"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"商业区",
|
||||
"commands":[
|
||||
"/tp @initiator 20 4 20"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"娱乐区",
|
||||
"commands":[
|
||||
"/tp @initiator 20 4 -20"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 创建传送物品
|
||||
|
||||
::: code-group
|
||||
```json [items/teleport_menu.json]
|
||||
{
|
||||
"format_version": "1.16.100",
|
||||
"minecraft:item": {
|
||||
"description": {
|
||||
"identifier": "dialog:teleport_menu",
|
||||
"category": "物品"
|
||||
},
|
||||
"components": {
|
||||
"minecraft:on_use": {
|
||||
"on_use": {
|
||||
"event": "open_menu",
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"minecraft:foil": true,
|
||||
"minecraft:icon": {
|
||||
"texture": "ender_pearl"
|
||||
},
|
||||
"minecraft:display_name": {
|
||||
"value": "传送菜单"
|
||||
}
|
||||
},
|
||||
"events": {
|
||||
"open_menu": {
|
||||
"run_command": {
|
||||
"command": [
|
||||
"dialogue open @e[type=npc,c=1] @s main_teleport_menu"
|
||||
],
|
||||
"target": "player"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 测试步骤
|
||||
1. 在超平坦世界启用实验性玩法
|
||||
2. 执行 `/function setup` 创建 NPC
|
||||
3. 获取道具:`/give @s dialog:teleport_menu`
|
||||
4. 切换生存模式使用道具
|
||||
|
||||
## 版权声明
|
||||
|
||||
本教程改编自 [Minecraft 创作者文档](https://docs.microsoft.com/en-us/minecraft/creator/documents/npcdialogue)。
|
||||
310
docs/wiki/3-实体/1-基础/render-controllers.md
Normal file
310
docs/wiki/3-实体/1-基础/render-controllers.md
Normal file
@@ -0,0 +1,310 @@
|
||||
---
|
||||
title: 渲染控制器
|
||||
category: 常规
|
||||
tags:
|
||||
- beginner
|
||||
mentions:
|
||||
- SirLich
|
||||
- MedicalJewel105
|
||||
- Overload252
|
||||
- ChibiMango
|
||||
---
|
||||
|
||||
# 渲染控制器
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
渲染控制器是资源包中常被误解的部分。但您无需畏惧!您可以将渲染控制器视为逻辑包,它们接收来自资源包实体文件中的短名称定义,并决定这些资源在游戏中如何组合/分层/渲染。
|
||||
|
||||
## 定义短名称
|
||||
|
||||
渲染控制器基于资源包实体文件中的短名称定义运作。短名称是我们在资源包实体文件中定义的本地标识符,可供渲染控制器(及其他地方)调用。我们可以在实体中定义`geometry`(几何体)、`materials`(材质)和`textures`(纹理)等变量。
|
||||
|
||||
让我们看看蜘蛛资源包实体文件的简化版本:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/spider.json]
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"identifier": "minecraft:cave_spider",
|
||||
"materials": {
|
||||
"default": "spider",
|
||||
"invisible": "spider_invisible"
|
||||
},
|
||||
"textures": {
|
||||
"default": "textures/entity/spider/cave_spider"
|
||||
},
|
||||
"geometry": {
|
||||
"default": "geometry.spider.v1.8"
|
||||
},
|
||||
"render_controllers": ["controller.render.spider"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
此示例中创建了四个短名称定义:
|
||||
- `default`(材质数组)
|
||||
- `invisible`(材质数组)
|
||||
- `default`(纹理数组)
|
||||
- `default`(几何体数组)
|
||||
|
||||
您可以在每个数组中定义多个短名称(如上方的材质示例)。将短名称定义视为_导入_所需资源的操作。在此阶段,您在定义实体要使用的纹理、几何体和材质。在渲染控制器阶段不会导入新内容,而是使用已导入的资源来构建最终渲染的实体。
|
||||
|
||||
## 简单渲染控制器
|
||||
|
||||
一个基础渲染控制器示例如下:
|
||||
|
||||
::: code-group
|
||||
```json [RP/render_controllers/cow.render.json]
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"render_controllers": {
|
||||
"controller.render.cow": {
|
||||
"geometry": "Geometry.default",
|
||||
"materials": [
|
||||
{
|
||||
"*": "Material.default"
|
||||
}
|
||||
],
|
||||
"textures": ["Texture.default"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
该控制器从实体文件获取短名称定义并进行_渲染_。例如`"textures": [ "Texture.default"]`表达:"采用default纹理并应用于实体"。渲染控制器本身并不知晓default纹理的具体内容,只是执行应用指令。
|
||||
|
||||
## 复用渲染控制器
|
||||
|
||||
由于渲染控制器基于短名称工作,您可以在所有实体中复用同一个渲染控制器。对于只含单一材质、单一纹理和单一几何体的简单实体,无需创建自定义渲染控制器。
|
||||
|
||||
例如上方示例的控制器用于`minecraft:cow`实体。若要在自定义包中使用此控制器,只需在实体文件中声明:`"render_controllers": [ "controller.render.cow" ]`。
|
||||
|
||||
:::warning 注意!
|
||||
渲染控制器基于短名称工作。若使用牛的渲染控制器,必须提供其所需的短名称:
|
||||
- `default`几何体
|
||||
- `default`纹理
|
||||
- `default`材质
|
||||
:::
|
||||
|
||||
## 创建自定义渲染控制器
|
||||
|
||||
当我们需要更精细控制实体渲染时(如分层纹理、多重几何体、不同骨骼应用不同材质),可通过复制原版渲染控制器到`render_controllers`文件夹进行定制化修改。
|
||||
|
||||
## 纹理分层
|
||||
|
||||
通过纹理分层技术可为自定实体创建叠加纹理。基础思路是通过多个纹理的透明像素区域实现叠加显示。
|
||||
|
||||
假设一个**画框**实体:框架固定但画面可变。虽然可以复制10个框架纹理并制作10幅画作,但修改框架时需要改动所有文件。采用分层纹理方案时,首先放置框架纹理,再叠加画作纹理,即可实现框架的集中管理。
|
||||
|
||||
### 通过渲染控制器实现
|
||||
|
||||
若对渲染控制器不熟悉,建议参考原版案例。例如含有多个纹理的`horse`实体具有典型参考价值。
|
||||
|
||||
#### 渲染控制器
|
||||
|
||||
::: code-group
|
||||
```json [RP/render_controllers/controller.render.texture_layering.json]
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"render_controllers": {
|
||||
"controller.render.texture_layering": {
|
||||
"geometry": "Geometry.default",
|
||||
"materials": [
|
||||
{
|
||||
"*": "Material.default"
|
||||
}
|
||||
],
|
||||
"textures": [
|
||||
// 你可以添加任意数量的图层,按从上到下的顺序叠加
|
||||
"Texture.bottom_layer",
|
||||
"Texture.top_layer"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
#### 实体配置
|
||||
|
||||
需要定义所有纹理并使用`villager_v2_masked`材质:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/my_entity.json]
|
||||
"materials": {
|
||||
"default": "villager_v2_masked"
|
||||
},
|
||||
"textures": {
|
||||
"top_layer": "textures/top",
|
||||
"bottom_layer": "textures/bottom"
|
||||
// 在此添加更多纹理短名称定义
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 动态变体分层
|
||||
|
||||
通过动态索引实现纹理切换能创造更灵活的效果:
|
||||
|
||||
#### 实体配置
|
||||
|
||||
定义多个顶部纹理以供索引:
|
||||
|
||||
::: code-group
|
||||
```json [RP/entity/my_entity.json#description]
|
||||
"textures": {
|
||||
"top_1": "textures/top_1",
|
||||
"top_2": "textures/top_2",
|
||||
"top_3": "textures/top_3",
|
||||
"bottom_layer": "textures/bottom"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
#### 渲染控制器
|
||||
|
||||
::: code-group
|
||||
```json [RP/render_controllers/controller.render.wool_only]
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"render_controllers": {
|
||||
"controller.render.wool_only": {
|
||||
"arrays": {
|
||||
"textures": {
|
||||
"Array.top": [
|
||||
"Texture.top_1",
|
||||
"Texture.top_2",
|
||||
"Texture.top_3"
|
||||
]
|
||||
}
|
||||
},
|
||||
"geometry": "Geometry.default",
|
||||
"materials": [
|
||||
{
|
||||
"*": "Material.default"
|
||||
}
|
||||
],
|
||||
"textures": [
|
||||
"Texture.bottom", // 静态底层纹理
|
||||
"Array.top[q.variant]" // 根据实体变体选择顶部纹理
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
通过数组和`q.variant`查询,可根据实体variant值动态选择顶部纹理。
|
||||
|
||||
#### 设置变体值
|
||||
|
||||
要使分层显示生效,需在实体中设置variant组件:
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/my_entity.json#components]
|
||||
"minecraft:variant": {
|
||||
"value": 0
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
注意组件参数采用零索引制,`0`对应第一个纹理,`1`和`2`对应后续纹理。
|
||||
|
||||
#### 动态更换纹理
|
||||
|
||||
如需在游戏中动态更换纹理,只需修改`variant`值。可通过组件组和事件系统实现此功能。
|
||||
|
||||
#### 动态分层进阶
|
||||
|
||||
通过添加更多纹理数组和使用虚拟组件(dummy components)作为索引,可实现更复杂的动态分层效果。关于虚拟组件的详细信息请参阅[此文档](/entities/dummy-components)。
|
||||
|
||||
### 动态几何体切换
|
||||
|
||||
动态切换几何体的原理与纹理类似:
|
||||
|
||||
以下示例展示如何根据variant值切换不同几何体。注意几何体不可分层叠加,因此不需要基础层定义,但仍需使用`villager_v2_masked`材质。
|
||||
|
||||
::: code-group
|
||||
```json [RP/render_controllers/controller.render.player.third_person.json]
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"render_controllers": {
|
||||
"controller.render.player.third_person": {
|
||||
"materials": [
|
||||
{
|
||||
"*": "Material.default"
|
||||
}
|
||||
],
|
||||
"textures": [
|
||||
"Texture.bottom",
|
||||
"Array.top[q.variant]"
|
||||
],
|
||||
"arrays": {
|
||||
"geometries": {
|
||||
"Array.geo": [
|
||||
"Geometry.default",
|
||||
"Geometry.custom_1",
|
||||
"Geometry.custom_2"
|
||||
]
|
||||
},
|
||||
"textures": {
|
||||
"Array.top": [
|
||||
"Texture.bottom",
|
||||
"Texture.top_1",
|
||||
"Texture.top_2"
|
||||
]
|
||||
}
|
||||
},
|
||||
"geometry": "Array.geo[q.variant]"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
#### 实体配置
|
||||
|
||||
确保在实体文件中包含对应几何体变体:
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"geometry": {
|
||||
"default": "geometry.entity.default",
|
||||
"custom_1": "geometry.entity.custom_1",
|
||||
"custom_2": "geometry.entity.custom_2"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 常见错误
|
||||
|
||||
在渲染控制器中:
|
||||
- 可引用多个纹理但只能引用一个几何体(数组形式亦适用)
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"arrays": {
|
||||
"textures": {
|
||||
"array.skin": [],
|
||||
"array.dress": []
|
||||
},
|
||||
"geometries": {
|
||||
"array.geo": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
"textures": [
|
||||
"array.skin[q.variant]",
|
||||
"array.dress[q.skin_id]"
|
||||
],
|
||||
"geometry": "array.geo[q.mark_variant]"
|
||||
```
|
||||
:::
|
||||
159
docs/wiki/3-实体/1-基础/spawn-rules.md
Normal file
159
docs/wiki/3-实体/1-基础/spawn-rules.md
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
title: 实体生成规则
|
||||
category: 常规
|
||||
mentions:
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- Ciosciaa
|
||||
- FrankyRay
|
||||
- Luthorius
|
||||
- TheItsNameless
|
||||
- SmokeyStack
|
||||
---
|
||||
|
||||
# 实体生成规则
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
生成规则定义了实体如何自然生成到世界中。当您希望自定义实体像原版实体一样自然生成时,应该使用生成规则。通过不同的组件可以定义实体生成的时间、地点和方式。
|
||||
|
||||
通常情况下,可以让您的自定义实体采用与原版实体类似的生成方式。例如:像牛一样群生成、像原版僵尸一样仅在夜间生成,或是像鱼类只在水下生成。
|
||||
|
||||
## 生成规则示例
|
||||
|
||||
以下是一个包含字段说明的生成规则示例:
|
||||
|
||||
::: code-group
|
||||
```json [BP/spawn_rules/zombie.json]
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"minecraft:spawn_rules": {
|
||||
"description": {
|
||||
"identifier": "minecraft:zombie",
|
||||
"population_control": "monster"
|
||||
},
|
||||
"conditions": [
|
||||
{
|
||||
"minecraft:spawns_on_surface": {},
|
||||
"minecraft:spawns_underground": {},
|
||||
"minecraft:brightness_filter": {
|
||||
"min": 0,
|
||||
"max": 7,
|
||||
"adjust_for_weather": true
|
||||
},
|
||||
"minecraft:difficulty_filter": {
|
||||
"min": "easy",
|
||||
"max": "hard"
|
||||
},
|
||||
"minecraft:weight": {
|
||||
"default": 100
|
||||
},
|
||||
"minecraft:herd": {
|
||||
"min_size": 2,
|
||||
"max_size": 4
|
||||
},
|
||||
"minecraft:permute_type": [
|
||||
{
|
||||
"weight": 95
|
||||
},
|
||||
{
|
||||
"weight": 5,
|
||||
"entity_type": "minecraft:zombie_villager"
|
||||
}
|
||||
],
|
||||
"minecraft:biome_filter": {
|
||||
"test": "has_biome_tag",
|
||||
"operator": "==",
|
||||
"value": "monster"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
- `description`→`identifier`: 要生成的实体
|
||||
- `population_control`: 控制生成与消失的数量。可选值:`animal`(动物)、`underwater_animal`(水生动物)、`monster`(怪物)、`ambient`(环境生物)
|
||||
- `conditions`: 必须满足的条件列表,生成尝试才会成功
|
||||
- `minecraft:spawns_on_surface`(地表生成)、`minecraft:spawns_underground`(地下生成)和`minecraft:spawns_underwater`(水下生成)控制实体生成的高度范围
|
||||
- `minecraft:brightness_filter`(亮度过滤)取值范围 0-15,控制生成所需光照条件。`adjust_for_weather`选项用于雨天/雷暴天气下是否自动降低有效光照值
|
||||
- `minecraft:difficulty_filter`(难度过滤)设置启用生成的游戏难度范围
|
||||
- `minecraft:herd`(群体生成)设置基于同个生成规则一起生成的实体数量
|
||||
- `minecraft:permute_type`(类型置换)通过`weight`权重和`entity_type`实体类型设置生成实体变异的概率
|
||||
- `minecraft:biome_filter`(生物群系过滤)测试特定生物群系标签。具体过滤器语法和生物群系标签列表请参考官方文档,或查看原版示例资源包
|
||||
|
||||
## 全部已知组件
|
||||
|
||||
以下是所有已知组件列表(随着我们对使用方法的理解加深,将持续补充说明文档):
|
||||
|
||||
```
|
||||
minecraft:weight
|
||||
minecraft:density_limit
|
||||
minecraft:spawns_on_block_filter
|
||||
minecraft:spawns_on_block_prevented_filter
|
||||
minecraft:spawns_above_block_filter
|
||||
minecraft:herd
|
||||
minecraft:permute_type
|
||||
minecraft:brightness_filter
|
||||
minecraft:height_filter
|
||||
minecraft:spawns_on_surface
|
||||
minecraft:spawns_underground
|
||||
minecraft:spawns_underwater
|
||||
minecraft:disallow_spawns_in_bubble
|
||||
minecraft:spawns_lava
|
||||
minecraft:biome_filter
|
||||
minecraft:difficulty_filter
|
||||
minecraft:distance_filter
|
||||
minecraft:is_experimental
|
||||
minecraft:world_age_filter
|
||||
minecraft:delay_filter
|
||||
minecraft:mob_event_filter
|
||||
minecraft:is_persistent
|
||||
minecraft:player_in_village_filter
|
||||
```
|
||||
|
||||
## 组件文档
|
||||
|
||||
### minecraft:herd
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"minecraft:herd": {
|
||||
"min_size": 1,
|
||||
"max_size": 2,
|
||||
"event":"minecraft:entity_born",
|
||||
"event_skip_count": 1
|
||||
},
|
||||
```
|
||||
:::
|
||||
|
||||
- `minecraft:herd`可通过此配置使第二个生成的实体(在此场景中)携带`minecraft:entity_born`事件(表现为幼体)。`event_skip_count`: 2`表示前两个生成的实体不会触发事件,之后生成的都会携带该事件。该功能适用于任意事件类型
|
||||
|
||||
### minecraft:spawns_above_block_filter
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"minecraft:spawns_above_block_filter": {
|
||||
"blocks": "minecraft:stone",
|
||||
"distance": 10
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
- `minecraft:spawns_above_block_filter`(上方方块过滤)会检测垂直方向设定距离内的方块,当条件满足时允许实体生成
|
||||
|
||||
### minecraft:spawns_on_block_prevented_filter
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
"minecraft:spawns_on_block_prevented_filter": [
|
||||
"minecraft:nether_wart_block",
|
||||
"minecraft:shroomlight"
|
||||
]
|
||||
```
|
||||
:::
|
||||
|
||||
- `minecraft:spawns_on_block_prevented_filter`(禁止生成方块过滤)与上方组件功能相反。该数组包含实体永远无法生成于其上的方块标识符
|
||||
158
docs/wiki/3-实体/1-基础/troubleshooting-entities.md
Normal file
158
docs/wiki/3-实体/1-基础/troubleshooting-entities.md
Normal file
@@ -0,0 +1,158 @@
|
||||
---
|
||||
title: 实体问题排查指南
|
||||
category: 常规
|
||||
nav_order: 3
|
||||
tags:
|
||||
- help
|
||||
mentions:
|
||||
- SirLich
|
||||
- BlueFrog130
|
||||
- SmokeyStack
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- ChibiMango
|
||||
- RonarsCorruption
|
||||
---
|
||||
|
||||
# 实体问题排查指南
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip
|
||||
本页面包含关于_实体_的疑难解答信息。在继续阅读前,请务必先查阅[全局问题排查指南](/guide/troubleshooting)。
|
||||
:::
|
||||
|
||||
:::warning
|
||||
请始终记得检查内容日志!
|
||||
:::
|
||||
|
||||
## 0.0.0 - 确认问题存在
|
||||
|
||||
承认吧,某个地方肯定出错了。_任何_水平的开发者在_任何_阶段都可能出现这些疏漏,所以不要觉得被冒犯而想着"我当然会注意这些!",然后跳过必要的检查步骤!
|
||||
|
||||
<BButton color="blue" link="#_1-0-0-are-both-packs-active">继续</BButton>
|
||||
|
||||
|
||||
## 1.0.0 - 确保两个包都已启用
|
||||
|
||||
确认资源包和行为包在世界中都已激活(一个绝佳的防错方法是在两个包的manifest.json文件中互相设置依赖,这样添加或移除其中一个包时会自动同步处理)
|
||||
|
||||
<BButton color="blue" link="#_2-0-0-determine-whether-the-issue-is-in-the-rp-or-the-bp">继续</BButton>
|
||||
|
||||
## 2.0.0 - 确定问题出现在资源包还是行为包
|
||||
|
||||
通过观察实体生成蛋在创造模式物品栏中的显示状态,可以有效定位问题范围。即使您不打算为实体添加生成蛋,请暂时按照以下步骤添加以便定位问题:
|
||||
|
||||
### 在资源包中
|
||||
|
||||
确保.entity文件包含自定义spawn_egg配置:
|
||||
|
||||
::: code-group
|
||||
```json [RP]
|
||||
"spawn_egg":{
|
||||
"base_color": "#FF0000",
|
||||
"overlay_color": "#FFFF00"
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
(建议选择除"#000000"以外的配色以方便排查)
|
||||
|
||||
### 在行为包中
|
||||
|
||||
确保description对象中开启`is_spawnable`和`is_summonable`,并将`is_experimental`设为false:
|
||||
|
||||
::: code-group
|
||||
```json [BP]
|
||||
"description":{
|
||||
"identifier": "wiki:example_entity",
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true,
|
||||
"is_experimental": false
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 现象分析
|
||||
|
||||
完全看不到生成蛋:<BButton color="blue" link="#_3-1-0-bp">前往排查</BButton>
|
||||
|
||||
能看到生成蛋但颜色全黑且无法生成实体:<BButton color="blue" link="#step-3-2-0-rp-entity">前往排查</BButton>
|
||||
|
||||
生成蛋显示正常颜色但仍旧无法生成实体:<BButton color="blue" link="#step-3-3-0-rp-resources-still-writing-because-this-is-going-to-be-extensive">前往排查</BButton>
|
||||
|
||||
## 3.0.0 - 定位具体问题
|
||||
|
||||
## 3.1.0 - 行为包问题
|
||||
|
||||
_即使已在行为文件中设置"is_spawnable": true,在创造模式物品栏中依然无法找到生成蛋_
|
||||
|
||||
这通常表示游戏未能正确识别实体行为文件。常见原因包括:
|
||||
|
||||
- Json语法错误
|
||||
- 文件夹命名错误
|
||||
|
||||
### 3.1.1 - 语法错误
|
||||
|
||||
单个语法错误会导致整个json文件失效。建议使用[JSON验证工具](https://jsonlint.com/)检查文件的语法完整性(注:虽然该网站会将//注释视为错误,但在Minecraft中实际允许使用注释)
|
||||
|
||||
### 3.1.2 - 文件夹误命名
|
||||
|
||||
请确认行为包中的实体文件夹命名为"entities"(资源包对应的是"entity",这个不一致设定确实容易引起困惑)
|
||||
|
||||
## 步骤3.2.0 - 资源包.entity文件问题
|
||||
|
||||
_能在创造模式物品栏中看到生成蛋,但显示为黑色且实体名异常(如"item.spawn_egg.entity.wiki:your_mob.name"),且无法正常生成实体_
|
||||
|
||||
此现象说明行为文件已生效,但资源包未能正确关联对应.entity文件。常见原因包括:
|
||||
|
||||
- .entity文件语法错误
|
||||
- 实体identifier不匹配
|
||||
- 资源引用路径错误
|
||||
- 资源包文件夹应命名为"entity",行为包文件夹应命名为"entities"
|
||||
|
||||
### 步骤3.2.1 - 语法错误
|
||||
|
||||
再次推荐使用[JSON验证工具](https://jsonlint.com/)进行深度校验(注意注释标识的兼容性问题)
|
||||
|
||||
### 步骤3.2.2 - 标识符不匹配
|
||||
|
||||
需确保资源包.entity文件与行为包的identifier字段完全一致,包括命名空间(冒号前的部分,例如`minecraft:bat`中的`minecraft`)。特别注意:
|
||||
|
||||
- 除了冒号外不要使用特殊字符
|
||||
- 命名空间和ID避免以数字或大写字母开头(虽然现行版本允许,但历史版本曾存在兼容性问题)
|
||||
- 非官方实体切勿使用`minecraft`作为命名空间
|
||||
|
||||
### 步骤3.2.3 - 无效资源引用
|
||||
|
||||
检查.entity文件中各项资源引用路径是否正确指向有效文件
|
||||
|
||||
## 步骤3.3.0 - 资源包资源排查(进行中)
|
||||
|
||||
_生成蛋显示正常颜色但在生成/召唤时实体不可见或仅显示阴影_
|
||||
|
||||
这说明基本功能文件已正常加载,但存在次级资源配置问题。根据现象选择排查方向:
|
||||
|
||||
- 完全隐形无阴影 → 资源引用错误:<BButton link="#_3-3-1-invisible-no-shadow" color=blue >前往</BButton>
|
||||
- 隐形但显示阴影 → 几何体问题:<BButton link="#_3-3-2-invisible-shadow-exists" color=blue >前往</BButton>
|
||||
- 可见但贴图异常 → 材质问题:<BButton link="#_3-3-3-visible-weird-texture" color=blue >前往</BButton>
|
||||
- 可见但渲染异常 → 材质类型错误:<BButton link="#_3-3-4-visible-weird-visibility-stuff" color=blue >前往</BButton>
|
||||
|
||||
### 3.3.1 - 完全隐形无阴影
|
||||
|
||||
确认实体未设置立即消失逻辑(如instant_despawn),优先检查实体基础配置。
|
||||
|
||||
### 3.3.2 - 隐形但显示阴影
|
||||
|
||||
此类问题通常涉及模型或材质配置,排查重点:
|
||||
|
||||
1. 几何体文件:检查命名正确性、文件完整性和几何偏移量设置
|
||||
2. 材质匹配:例如透明材质与普通材质的兼容性
|
||||
3. 渲染控制器:验证控制器逻辑与参数设置
|
||||
|
||||
### 3.3.3 - 可见但贴图异常
|
||||
|
||||
(内容开发中)
|
||||
|
||||
### 3.3.4 - 可见但渲染异常
|
||||
(内容开发中)
|
||||
165
docs/wiki/3-实体/2-巧思案例/boat-entities.md
Normal file
165
docs/wiki/3-实体/2-巧思案例/boat-entities.md
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
title: Creating Boats
|
||||
category: Tutorials
|
||||
tags:
|
||||
- recipe
|
||||
- intermediate
|
||||
mentions:
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- MedicalJewel105
|
||||
- StealthyExpertX
|
||||
- TheItsNameless
|
||||
---
|
||||
:::warning Requires Format Version 1.16.100 or Lower
|
||||
|
||||
The behavior format version now requires 1.16.100 or lower for the `minecraft:behavior.rise_to_liquid_level` and `minecraft:buoyant` methods to work.
|
||||
If you find a new method that works in the newer format versions, you should consider helping to contribute by updating the wiki.
|
||||
:::
|
||||
|
||||
## Using Runtime Identifiers
|
||||
|
||||
You can read more about runtime identifiers [here](/entities/runtime-identifier). Using runtime identifiers, you can implement most of the boat's hard-coded behaviors. However, your boat won't rotate with you, and it will always face North.
|
||||
|
||||
## Using Components
|
||||
|
||||
Currently, the best way to create a boat entity is by using components. 1.16 introduced new components that we can use to our advantage: `minecraft:behavior.rise_to_liquid_level` and `minecraft:buoyant`. Striders use the first one in vanilla to make them float on lava, but we can repurpose it for water as well.
|
||||
|
||||
## 1st method: minecraft:behavior.rise_to_liquid_level
|
||||
|
||||
<CodeHeader>BP/entities/bar</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:entity": {
|
||||
"format_version": "1.14.0",
|
||||
"description": {
|
||||
"identifier": "foo:bar",
|
||||
"is_summonable": true,
|
||||
"is_spawnable": true,
|
||||
"is_experimental": false
|
||||
},
|
||||
"components": {
|
||||
//This is the component that does the magic
|
||||
"minecraft:behavior.rise_to_liquid_level": {
|
||||
"priority": 0,
|
||||
//This property can adjust how high your boat is above the water
|
||||
"liquid_y_offset": 0.5,
|
||||
//Positive vertical displacement, in other words, how much the boat will move up
|
||||
"rise_delta": 0.05,
|
||||
//Negative vertical displacement, in other words, how much the boat will move down
|
||||
"sink_delta": 0.05
|
||||
//Use rise_delta and sink_delta to simulate waves/bouncing effect
|
||||
},
|
||||
|
||||
//Sets the boat speed in water
|
||||
"minecraft:underwater_movement": {
|
||||
"value": 5
|
||||
},
|
||||
//This component is important, without it the boat will sink
|
||||
"minecraft:navigation.walk": {
|
||||
"can_sink": false
|
||||
},
|
||||
"minecraft:rideable": {
|
||||
"seat_count": 1,
|
||||
"family_types": ["player"],
|
||||
"interact_text": "action.interact.enter_boat",
|
||||
"seats": {
|
||||
"position": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
//Add this component if you want your boat to be controlled with WASD
|
||||
"minecraft:input_ground_controlled": {},
|
||||
"minecraft:health": {
|
||||
"value": 10,
|
||||
"max": 10
|
||||
},
|
||||
//Sets the boat speed on the ground (set this to zero if you don't want your boats to move on the ground)
|
||||
"minecraft:movement": {
|
||||
"value": 3
|
||||
},
|
||||
//This is to prevent the boat from not stopping whenever a player exits, said the boat
|
||||
"minecraft:movement.basic": {},
|
||||
"minecraft:collision_box": {
|
||||
"width": 1,
|
||||
"height": 1
|
||||
},
|
||||
"minecraft:physics": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2nd method: minecraft:buoyant
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"minecraft:entity": {
|
||||
"format_version": "1.14.0",
|
||||
"description": {
|
||||
"identifier": "foo:bar",
|
||||
"is_summonable": true,
|
||||
"is_spawnable": true,
|
||||
"is_experimental": false
|
||||
},
|
||||
"components": {
|
||||
"minecraft:buoyant": {
|
||||
//Determines whether gravity should be taken into account (useful with waterfalls)
|
||||
"apply_gravity": true,
|
||||
//Range: 0-1. This controls how high the boat is above the water
|
||||
"base_buoyancy": 1.0,
|
||||
//A "wave" makes the entity bounce up and down. A big wave simply amplifies this effect. Note: setting simulate_waves to false won't make the effect go away completely.
|
||||
"simulate_waves": true,
|
||||
//How likely a "big" wave will hit this boat
|
||||
"big_wave_probability": 0.03,
|
||||
//How strong the "big" wave will be
|
||||
"big_wave_speed": 10.0,
|
||||
//How strong will the boat be dragged down in case this component is removed
|
||||
"drag_down_on_buoyancy_removed": 0,
|
||||
//Blocks this entity can be buoyant in. Only actual liquids are allowed: lava and water
|
||||
"liquid_blocks": ["water"]
|
||||
},
|
||||
|
||||
//Sets the boat speed in water
|
||||
"minecraft:underwater_movement": {
|
||||
"value": 5
|
||||
},
|
||||
//This component is important, without it the boat will sink
|
||||
"minecraft:navigation.walk": {
|
||||
"can_sink": false
|
||||
},
|
||||
"minecraft:rideable": {
|
||||
"seat_count": 1,
|
||||
"family_types": ["player"],
|
||||
"interact_text": "action.interact.enter_boat",
|
||||
"seats": {
|
||||
"position": [0, 0, 0]
|
||||
}
|
||||
},
|
||||
//Add this component if you want your boat to be controlled with WASD
|
||||
"minecraft:input_ground_controlled": {},
|
||||
"minecraft:health": {
|
||||
"value": 10,
|
||||
"max": 10
|
||||
},
|
||||
//Sets the boat speed on the ground (set this to zero if you don't want your boats to move on the ground)
|
||||
"minecraft:movement": {
|
||||
"value": 3
|
||||
},
|
||||
//This is to prevent the boat from not stopping whenever a player exits the boat
|
||||
"minecraft:movement.basic": {},
|
||||
"minecraft:collision_box": {
|
||||
"width": 1,
|
||||
"height": 1
|
||||
},
|
||||
"minecraft:physics": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## What method to use?
|
||||
|
||||
Both methods are suitable but have their pros and cons. If you want to disable the bouncing effect, use the first method. If you want more control over it, use the second method. I use the second method for static objects, such as buoys, and the first method for movable entities, such as boats, emulating the vanilla behavior.
|
||||
221
docs/wiki/3-实体/2-巧思案例/detecting-other-entities.md
Normal file
221
docs/wiki/3-实体/2-巧思案例/detecting-other-entities.md
Normal file
@@ -0,0 +1,221 @@
|
||||
---
|
||||
title: Detecting Other Entities
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- ANightDazingZoroark
|
||||
- SmokeyStack
|
||||
- MedicalJewel105
|
||||
- SirLich
|
||||
- Luthorius
|
||||
- TheItsNameless
|
||||
---
|
||||
|
||||
You might have thought about making your entities fire an event when other entities are nearby. This article details the various known ways to do so.
|
||||
|
||||
## minecraft:entity_sensor
|
||||
|
||||
This is probably the most basic way to detect other entities. The main issues is it only accepts one entry and testing if the entity is out of range can be very tricky. Because it's an entity component, you can just place into your entity behavior file and edit the Minecraft filters. Here's a demonstration:
|
||||
|
||||
<CodeHeader>BP/entities/my_entity.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:entity_sensor": {
|
||||
"sensor_range": 2.5, //this is for the radius in blocks it will detect other entities in
|
||||
"relative_range": false, //if true, the sensor range is additive on top of the entity's hitbox size
|
||||
"require_all": true, //if true, all nearby entities must pass the filter conditions for the event to send
|
||||
"minimum_count": 1, //minimum amount of entities required for the event to fire. by default, it's 1
|
||||
"maximum_count": 4, //maximum amount of entities required for the event to fire. by default it's -1, which means infinity
|
||||
"event_filters": { //you can put any filter you want here, the one that's being used in this example just detects players
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "player"
|
||||
},
|
||||
"event": "event:on_player_detected" //the event that fires when all the conditions in event_filters are met
|
||||
}
|
||||
```
|
||||
|
||||
## `/execute`
|
||||
|
||||
Using the new `/execute` command that has been introduced since 1.19.50, you can execute commands as long as another entity is nearby.
|
||||
|
||||
This example you'll be following will make pigs say "oink oink" upon detecting players, though you can replace those with whatever you want. First of all, copy-paste these BP animations.
|
||||
|
||||
<CodeHeader>BP/animations/detection_animation.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animations": {
|
||||
"animation.pig.find_player": {
|
||||
"animation_length": 0.05,
|
||||
"loop": true,
|
||||
"timeline": {
|
||||
"0": [
|
||||
"/execute as @s if entity @e[type=player, r=4] run event entity @s wiki:player_detected"
|
||||
]
|
||||
}
|
||||
},
|
||||
"animation.pig.find_no_player": {
|
||||
"animation_length": 0.05,
|
||||
"loop": true,
|
||||
"timeline": {
|
||||
"0": [
|
||||
"/execute as @s unless entity @e[type=player, r=4] run event entity @s wiki:no_player_detected"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The first one is for detecting if the entity is present, and the other for detecting if the entity is not present. The events used in the `/event` part of the `/execute` commands can be used for adding a [dummy component](/entities/dummy-components) or updating an [actor property](https://learn.microsoft.com/en-us/minecraft/creator/documents/introductiontoentityproperties).
|
||||
|
||||
Next of all, copy paste this BP animation controller. This assumes that you set up the `/event` parts of the `/execute` commands to add or remove `minecraft:is_sheared`.
|
||||
|
||||
<CodeHeader>BP/animation_controllers/pig_animation_controllers.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animation_controllers": {
|
||||
"controller.animation.pig_find_player": {
|
||||
"initial_state": "default",
|
||||
"states": {
|
||||
"default": {
|
||||
"animations": ["find_player"],
|
||||
"transitions": [
|
||||
{
|
||||
"detected": "q.is_sheared"
|
||||
}
|
||||
]
|
||||
},
|
||||
"detected": {
|
||||
"animations": ["find_no_player"],
|
||||
"transitions": [
|
||||
{
|
||||
"default": "!q.is_sheared"
|
||||
}
|
||||
],
|
||||
"on_entry": ["/say oink oink"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Finally, copy-paste this snippet into the behavior file for the pig-like so. Make sure to insert this in `description`.
|
||||
|
||||
<CodeHeader>BP/entities/my_entity.json#description</CodeHeader>
|
||||
|
||||
```json
|
||||
"animations": {
|
||||
"manage_find_player": "controller.animation.pig_find_player",
|
||||
"find_player": "animation.pig.find_player",
|
||||
"find_no_player": "animation.pig.find_no_player"
|
||||
},
|
||||
"scripts": {
|
||||
"animate": [
|
||||
"manage_find_player"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Molang, BP Animations & Animation Controllers
|
||||
|
||||
The `for_each` function and `q.get_nearby_entities` or `q.get_nearby_entities_except_self` can also be used for detecting other entities. They are more effective than using `minecraft:entity_sensor` because they are better at detecting if the entity you want to detect goes away than with `minecraft:entity_sensor`. The only downside is that they're experimental.
|
||||
|
||||
Just like in the previous method we will make pigs say "oink oink" upon detecting players, though you can replace those with whatever you want. First of all, copy-paste this BP animation:
|
||||
|
||||
<CodeHeader>BP/animations/detection_animation.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animations": {
|
||||
"animation.pig.find_player": {
|
||||
"animation_length": 0.05,
|
||||
"loop": true,
|
||||
"timeline": {
|
||||
"0": [
|
||||
"v.x = 0.0; for_each(t.player, q.get_nearby_entities_except_self(16, 'minecraft:player'), { v.x = v.x + 1; }); return v.x > 0.0;"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The first parameter that `q.get_nearby_entities_except_self` needs to work is the radius in blocks it will detect other entities in. The other is the identifier of the mob you want to make it detect.
|
||||
|
||||
Now that's good and all, but on the off chance, you want to make the pig detect players with some attribute that can be detected with Molang, use this.
|
||||
|
||||
<CodeHeader>BP/animations/detection_animation.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animations": {
|
||||
"animation.pig.find_player": {
|
||||
"animation_length": 0.05,
|
||||
"loop": true,
|
||||
"timeline": {
|
||||
"0": [
|
||||
"v.x = 0.0; for_each(t.player, q.get_nearby_entities_except_self(2, 'minecraft:player'), { v.x = v.x + (t.player -> q.is_sheared); }); return v.x > 0.0;"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next of all, copy paste this BP animation controller:
|
||||
|
||||
<CodeHeader>BP/animation_controllers/pig_animation_controllers.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animation_controllers": {
|
||||
"controller.animation.pig_find_player": {
|
||||
"initial_state": "default",
|
||||
"states": {
|
||||
"default": {
|
||||
"animations": ["find_player"],
|
||||
"transitions": [
|
||||
{
|
||||
"detected": "v.x > 0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"detected": {
|
||||
"animations": ["find_player"],
|
||||
"transitions": [
|
||||
{
|
||||
"default": "v.x <= 0"
|
||||
}
|
||||
],
|
||||
"on_entry": ["/say oink oink"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally, copy-paste this snippet into the behavior file for the pig-like so. Make sure to insert this in `description`.
|
||||
|
||||
<CodeHeader>BP/entities/my_entity.json#description</CodeHeader>
|
||||
|
||||
```json
|
||||
"animations": {
|
||||
"manage_find_player": "controller.animation.pig_find_player",
|
||||
"find_player": "animation.pig.find_player"
|
||||
},
|
||||
"scripts": {
|
||||
"animate": [
|
||||
"manage_find_player"
|
||||
]
|
||||
}
|
||||
```
|
||||
184
docs/wiki/3-实体/2-巧思案例/disabling-team-damage.md
Normal file
184
docs/wiki/3-实体/2-巧思案例/disabling-team-damage.md
Normal file
@@ -0,0 +1,184 @@
|
||||
---
|
||||
title: Disabling Team-damage
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- Joelant05
|
||||
- MedicalJewel105
|
||||
- Luthorius
|
||||
- TCLynx
|
||||
---
|
||||
|
||||
If you wish to disable team damage (so one cannot hurt their teammates), assign a tag with the team name to every teammate (I'm going to use `team1`, `team2`, `team3` and `team4` for this example).
|
||||
WARNING: This will NOT work on realms, the reason for this is that on realms there is a bug where modified player.json files in the behavior packs do not work, and the gmae just ignores them (This may be fixed in the future but as of 1.20.15 it is not fixed. (This also applies to older version of minecraft as well.))
|
||||
Now add this damage sensor component into your `player.json`s `"components": {}`. See comments for explanation.
|
||||
|
||||
<CodeHeader>BP/entities/player.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:damage_sensor":{
|
||||
"triggers":[
|
||||
{ //if you already have a damage sensor, simply copy this object into the "triggers" array
|
||||
"on_damage":{
|
||||
"filters":{
|
||||
"any_of":[
|
||||
{
|
||||
"all_of":[
|
||||
{ "test":"has_tag", "value":"team1" }, //Does the player have this tag?
|
||||
{ "test":"has_tag", "subject":"other", "value":"team1" } //If so, does the entity they're trying to hurt have this tag?
|
||||
]
|
||||
},
|
||||
{
|
||||
"all_of":[
|
||||
{ "test":"has_tag", "value":"team2" }, //repeats for every team
|
||||
{ "test":"has_tag", "subject":"other", "value":"team2" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"all_of":[
|
||||
{ "test":"has_tag", "value":"team3" },
|
||||
{ "test":"has_tag", "subject":"other", "value":"team3" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"all_of":[
|
||||
{ "test":"has_tag", "value":"team4" },
|
||||
{ "test":"has_tag", "subject":"other", "value":"team4" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"all_of":[
|
||||
{ "test":"has_tag", "value":"team5" },
|
||||
{ "test":"has_tag", "subject":"other", "value":"team5" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"deals_damage":false //if any of these filters evaluate to true in the current attack interaction, the target will not be hurt.
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Projectiles
|
||||
|
||||
Due to the primitive filters used by projectile entities, you have to use a completely different method to achieve this.
|
||||
|
||||
The process uses:
|
||||
- Tags
|
||||
- Ticking
|
||||
- Hurt on Condition
|
||||
- Functions
|
||||
|
||||
<CodeHeader>BP/entities/player.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
|
||||
//"components"
|
||||
"minecraft:timer": { //This is for applying teams to a projectile to nearby
|
||||
"time": [ //untagged projectiles, through an event.
|
||||
0.0,
|
||||
0.1
|
||||
],
|
||||
"looping": true,
|
||||
"time_down_event": {
|
||||
"event": "wiki:projectile_team",
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"minecraft:hurt_on_condition": { //The projectile will be unable to directly deal
|
||||
"damage_conditions": [ //damage, so instead we'll apply tags to the
|
||||
{ //player, which will trigger this . . .
|
||||
"filters": {
|
||||
"test": "has_tag",
|
||||
"value": "damage"
|
||||
},
|
||||
"cause": "projectile",
|
||||
"damage_per_tick": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:damage_sensor": { //. . . which in turn, will trigger an event
|
||||
"triggers": { //to remove this tag, so the damage only
|
||||
"cause": "projectile", //happens once.
|
||||
"deals_damage": true,
|
||||
"on_damage": {
|
||||
"filters": {
|
||||
"test": "has_tag",
|
||||
"value": "damage"
|
||||
},
|
||||
"event": "wiki:stop_damage"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//"events"
|
||||
"wiki:projectile_team": { //The function here will apply tags depending on
|
||||
"run_command": { //which team tags the player has.
|
||||
"command": [
|
||||
"function wiki-apply_team"
|
||||
]
|
||||
}
|
||||
},
|
||||
"wiki:stop_damage": { //The event that simply removes the damage tag.
|
||||
"run_command": {
|
||||
"command": [
|
||||
"tag @s remove damage"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader>BP/functions/wiki-apply_team.mcfunction</CodeHeader>
|
||||
|
||||
```
|
||||
execute @s[tag=team1] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team1
|
||||
execute @s[tag=team2] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team2
|
||||
execute @s[tag=team3] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team3
|
||||
execute @s[tag=team4] ~ ~ ~ tag @e[rm=0,r=1,c=1,type=arrow,tag=] add team4
|
||||
|
||||
```
|
||||
|
||||
<CodeHeader>BP/entities/arrow.json</CodeHeader>
|
||||
|
||||
```json
|
||||
|
||||
//"components"
|
||||
"on_hit": { //On_hit, trigger an event . . .
|
||||
"definition_event": {
|
||||
"affect_projectile": true,
|
||||
"event_trigger": {
|
||||
"event": "wiki:hit",
|
||||
"target": "self"
|
||||
}
|
||||
},
|
||||
"remove_on_hit": {}
|
||||
}
|
||||
|
||||
//"events"
|
||||
"wiki:hit": { //. . . which executes a function, applying
|
||||
"run_command": { //the damage tag to any players of a different team!
|
||||
"command": [
|
||||
"function wiki-apply_damage"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader>BP/functions/wiki-apply_damage.mcfunction</CodeHeader>
|
||||
|
||||
```
|
||||
execute @s[tag=team1] ~ ~ ~ tag @p[rm=0,r=1,tag=!team1] add damage
|
||||
execute @s[tag=team2] ~ ~ ~ tag @p[rm=0,r=1,tag=!team2] add damage
|
||||
execute @s[tag=team3] ~ ~ ~ tag @p[rm=0,r=1,tag=!team3] add damage
|
||||
execute @s[tag=team4] ~ ~ ~ tag @p[rm=0,r=1,tag=!team4] add damage
|
||||
|
||||
```
|
||||
|
||||
If you modify `arrow.json`, take into consideration the component groups.
|
||||
|
||||
146
docs/wiki/3-实体/2-巧思案例/dummy-entities.md
Normal file
146
docs/wiki/3-实体/2-巧思案例/dummy-entities.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
title: Dummy Entities
|
||||
category: Tutorials
|
||||
tags:
|
||||
- beginner
|
||||
mentions:
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
---
|
||||
|
||||
Dummy entities are invisible entities which are used behind the scenes for game-play purposes. Dummy entities are a very useful tool, and this document will cover some of the ways they are utilized, as well as showing how to set up the resource side of things.
|
||||
|
||||
## Using Dummies
|
||||
|
||||
This is a non-exhaustive list of how dummies can be used:
|
||||
|
||||
- **For data storage**: by adding tags to the entity, we can use it as a "game manager", much like Armor Stands used to be used.
|
||||
- **As a named entity:** by name-tagging a dummy, and then using `execute` to select for it, you can make command-blocks `/say` with a pretty display name.
|
||||
- **As a location marker:** you can run `execute` commands located at a dummy to get relative coordinates at a location.
|
||||
- **As a waypoint:** by making entities which are aggressive to your dummy, you can pathfind entities to any location by placing a dummy there.
|
||||
|
||||
## Creating Dummies
|
||||
|
||||
### Behavior Entity
|
||||
|
||||
You can use whatever behaviors you like, but here is a good template. The important aspects are: no damage, and can't be pushed.
|
||||
|
||||
<CodeHeader>BP/entities/dummy.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.0",
|
||||
"minecraft:entity": {
|
||||
"description": {
|
||||
"identifier": "wiki:dummy",
|
||||
"is_summonable": true,
|
||||
"is_spawnable": false,
|
||||
"is_experimental": false
|
||||
},
|
||||
"components": {
|
||||
"minecraft:breathable": { //Optional, allows the entity to breath underwater
|
||||
"breathes_water": true
|
||||
},
|
||||
"minecraft:physics": {
|
||||
"has_gravity": false, //Optional, allows the entity to not be affected by gravity or water
|
||||
"has_collision": false
|
||||
},
|
||||
"minecraft:custom_hit_test": {
|
||||
"hitboxes": [
|
||||
{
|
||||
"pivot": [0, 100, 0],
|
||||
"width": 0,
|
||||
"height": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:damage_sensor": {
|
||||
"triggers": {
|
||||
"deals_damage": false
|
||||
}
|
||||
},
|
||||
"minecraft:pushable": {
|
||||
"is_pushable": false,
|
||||
"is_pushable_by_piston": false
|
||||
},
|
||||
"minecraft:collision_box": {
|
||||
"width": 0.0001,
|
||||
"height": 0.0001
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to disable collision at all (so you can place a block at it's position), you can use arrow runtime identifier, however, there can be some side effects.
|
||||
|
||||
### Resource Entity
|
||||
|
||||
<CodeHeader>RP/entity/dummy.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"minecraft:client_entity": {
|
||||
"description": {
|
||||
"identifier": "wiki:dummy",
|
||||
"materials": {
|
||||
"default": "entity_alphatest"
|
||||
},
|
||||
"geometry": {
|
||||
"default": "geometry.dummy"
|
||||
},
|
||||
"render_controllers": ["controller.render.dummy"],
|
||||
"textures": {
|
||||
"default": "textures/entity/dummy"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Geometry
|
||||
|
||||
<CodeHeader>RP/models/entity/dummy.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.12.0",
|
||||
"minecraft:geometry": [
|
||||
{
|
||||
"description": {
|
||||
"identifier": "geometry.dummy",
|
||||
"texture_width": 16,
|
||||
"texture_height": 16
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Render Controller (Optional)
|
||||
|
||||
<CodeHeader>RP/render_controllers/dummy.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"render_controllers": {
|
||||
"controller.render.dummy": {
|
||||
"geometry": "Geometry.default",
|
||||
"textures": ["Texture.default"],
|
||||
"materials": [
|
||||
{
|
||||
"*": "Material.default"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Texture (Optional)
|
||||
|
||||
You can either leave the texture location blank, or open the model in blockbench and create a blank texture.
|
||||
570
docs/wiki/3-实体/2-巧思案例/entity-attack.md
Normal file
570
docs/wiki/3-实体/2-巧思案例/entity-attack.md
Normal file
@@ -0,0 +1,570 @@
|
||||
---
|
||||
title: Entity Attacks
|
||||
category: Tutorials
|
||||
mentions:
|
||||
- Luthorius
|
||||
- TheDoctor15
|
||||
- SirLich
|
||||
- MedicalJewel105
|
||||
- epxzzy
|
||||
- ThomasOrs
|
||||
tags:
|
||||
- intermediate
|
||||
---
|
||||
|
||||
Entity attacks are a complex subject that require many different things to work correctly:
|
||||
|
||||
- Navigation and movement abilities to move towards its target
|
||||
- Targeting abilities to pick which entity to attack
|
||||
- Attack type, such as melee or ranged
|
||||
- Attack damage and effects
|
||||
|
||||
## Selecting Targets
|
||||
|
||||
### Movement
|
||||
|
||||
Before a mob can attack, it will need various [movement components](/entities/entity-movement).
|
||||
|
||||
Before starting to create your entity attacks, you should ensure that your entity can walk around, and navigate its surroundings.
|
||||
|
||||
:::warning
|
||||
Even if you are making an unmoving entity (like turret), you still need to add navigation component, so your entity can find the entity to shoot.
|
||||
:::
|
||||
|
||||
### Triggering Hostility
|
||||
|
||||
There are many ways to trigger hostility. The most common type `nearest_attackable_target`, is shown here. It generally allows you to define which entities this entity is interested in attacking:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.nearest_attackable_target": {
|
||||
"must_see": true, //If true, potential target must be in mob's line of sight
|
||||
"reselect_targets": true, //Allows mob to select new target, if one is closer than current
|
||||
"within_radius": 25.0, //Radius that potential target must be withing
|
||||
"must_see_forget_duration": 17.0, //If "must_see" = true, time before forgetting target
|
||||
"entity_types": [
|
||||
{
|
||||
"filters": { //Entities to attack
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "player"
|
||||
},
|
||||
"max_dist": 48.0
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
For more fine control, you may also consider using one of the following components:
|
||||
|
||||
| Component | Note |
|
||||
| -------------------------------------------------------- | ------------------------------------------------------------ |
|
||||
| minecraft:behavior.nearest_attackable_target | Targets entity meeting the given requirements |
|
||||
| minecraft:behavior.nearest_prioritized_attackable_target | Allows for "priority": [integer] to be set after each filter |
|
||||
| minecraft:behavior.defend_trusted_target | Targets entity that hurts any entities specified in filters |
|
||||
|
||||
But there is also one more - `minecraft:lookat`
|
||||
|
||||
This last component is slightly different to the other three, as it is for detecting and targeting entities that attempt eye contact. It is structured like so:
|
||||
|
||||
<CodeHeader>BP/entities/enderman.json</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:lookat": {
|
||||
"search_radius": 64.0,
|
||||
"set_target": true, //Becomes a valid target if true
|
||||
"look_cooldown": 5.0,
|
||||
"filters": {
|
||||
"all_of": [
|
||||
{
|
||||
"subject": "other",
|
||||
"test": "is_family",
|
||||
"value": "player"
|
||||
},
|
||||
{
|
||||
"test": "has_equipment",
|
||||
"domain": "head",
|
||||
"subject": "other",
|
||||
"operator": "not",
|
||||
"value": "carved_pumpkin" //All players not with carved_pumpkin equipped on head
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Target selecting
|
||||
|
||||
:::tip
|
||||
This section shows you how to configure the "Targeting" components, explained above.
|
||||
:::
|
||||
|
||||
Mobs find targets by using [filters](https://bedrock.dev/docs/stable/Entities#Filters) can be used to determine which entities are a valid target, through `test`, `subject`, `operator`, and `value`.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"entity_types":[
|
||||
{
|
||||
"filters":{
|
||||
"any_of":[
|
||||
{
|
||||
"test":"is_family",
|
||||
"subject":"other",
|
||||
"operator":"==",
|
||||
"value":"snow_golem"
|
||||
},
|
||||
{
|
||||
"test":"is_family",
|
||||
"subject":"other",
|
||||
"operator":"==",
|
||||
"value":"iron_golem"
|
||||
}
|
||||
//anything that is equal to either" snow_golem" or "iron_golem"
|
||||
]
|
||||
},
|
||||
"max_dist":24
|
||||
},
|
||||
{
|
||||
"filters":{
|
||||
"all_of":[
|
||||
{
|
||||
"test":"is_family",
|
||||
"subject":"other",
|
||||
"operator":"==",
|
||||
"value":"player"
|
||||
},
|
||||
{
|
||||
"test":"has_equipment",
|
||||
"subject":"other",
|
||||
"domain":"head",
|
||||
"operator":"=!",
|
||||
"value":"turtle_helmet"
|
||||
}
|
||||
//anything equal to player AND not wearing "turtle_helmet" on head
|
||||
]
|
||||
},
|
||||
"max_dist":24
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
This would only target `snow_golem`s, `iron_golem`s, and `player`s that are **not** wearing `turtle_helmet`s.
|
||||
|
||||
## Types of Attack
|
||||
|
||||
Here are the available attacks:
|
||||
|
||||
| Component | Note |
|
||||
| ---------------------------------------------------- | -------------------------------------------------------- |
|
||||
| [minecraft:behavior.melee_attack](#melee) | Deals damage to a single target |
|
||||
| [minecraft:behavior.ranged_attack](#ranged) | Fires a projectile towards a target |
|
||||
| [minecraft:area_attack](#area) | Effectively melee attacks on anything withing range |
|
||||
| [minecraft:behavior.knockback_roar](#knockback-roar) | Similar to minecraft:area_attack, but much more flexible |
|
||||
|
||||
### Melee
|
||||
|
||||
Melee attacks are the most common type of attack, they cause knockback, and have a 100% success rate at accuracy.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:melee_attack": {
|
||||
"minecraft:attack": {
|
||||
"damage": 3,
|
||||
"effect_name": "slowness",
|
||||
"effect_duration": 20
|
||||
},
|
||||
"minecraft:behavior.melee_attack": {
|
||||
"priority": 3,
|
||||
"melee_fov": 90.0, //The allowable FOV the actor will use to determine if it can make a valid melee attack
|
||||
"speed_multiplier": 1,
|
||||
"track_target": false,
|
||||
"require_complete_path": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Set the damage, choose a mob effect, and change some additional properties.
|
||||
|
||||
The value defined in components stating integers of damage can simply be a constant, or a string containing 2 numbers, for a range of possible values.
|
||||
|
||||
`"damage": 3` would result in 3 each time
|
||||
|
||||
`"damage": [ 2, 6 ]` would result in any integer between 2 and 6
|
||||
|
||||
Both the mob effect and duration timer are optional, but when they are used, the available effects are as following:
|
||||
|
||||
| Effect Name |
|
||||
| --------------- |
|
||||
| speed |
|
||||
| slowness |
|
||||
| haste |
|
||||
| mining_fatigue |
|
||||
| strength |
|
||||
| instant_health |
|
||||
| instant_damage |
|
||||
| jump_boost |
|
||||
| nausea |
|
||||
| regeneration |
|
||||
| resistance |
|
||||
| fire_resistance |
|
||||
| water_breathing |
|
||||
| invisibility |
|
||||
| blindness |
|
||||
| night_vision |
|
||||
| hunger |
|
||||
| weakness |
|
||||
| poison |
|
||||
| wither |
|
||||
| health_boost |
|
||||
| absorption |
|
||||
| saturation |
|
||||
| levitation |
|
||||
| fatal_poison |
|
||||
| slow_falling |
|
||||
| conduit_power |
|
||||
| bad_omen |
|
||||
| village_hero |
|
||||
| darkness |
|
||||
|
||||
### Ranged
|
||||
|
||||
Fires specified [projectiles](/documentation/projectiles) towards target at set intervals.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:ranged_attack": {
|
||||
"minecraft:behavior.ranged_attack": {
|
||||
"priority": 2,
|
||||
"ranged_fov": 90.0, //The allowable FOV the actor will use to determine if it can make a valid ranged attack
|
||||
"attack_interval_min": 1.0,
|
||||
"attack_interval_max": 3.0,
|
||||
"attack_radius": 15.0
|
||||
},
|
||||
"minecraft:shooter": {
|
||||
"def": "wiki:projectile"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
List of vanilla projectiles:
|
||||
|
||||
| Vanilla Projectiles |
|
||||
| -------------------------------- |
|
||||
| minecraft:arrow |
|
||||
| minecraft:dragon_fireball |
|
||||
| minecraft:egg |
|
||||
| minecraft:ender_pearl |
|
||||
| minecraft:fireball |
|
||||
| minecraft:fishing_hook |
|
||||
| minecraft:lingering_potion |
|
||||
| minecraft:llama_spit |
|
||||
| minecraft:skulker_bullet |
|
||||
| minecraft:small_fireball |
|
||||
| minecraft:snowball |
|
||||
| minecraft:splash_potion |
|
||||
| minecraft:thrown_trident |
|
||||
| minecraft:wither_skull |
|
||||
| minecraft:wither_skull_dangerous |
|
||||
| minecraft:xp_bottle |
|
||||
|
||||
Only one item has an effect on an entity's ranged attacks. Crossbows. If one is equipped, it is first required for it to be "charged" before the entity can fire anything. Regardless of the projectile stated in `minecraft:shooter`, the item to charge the crossbow with should always be `minecraft:arrow`.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.charge_held_item": {
|
||||
"priority": 2,
|
||||
"items": [
|
||||
"minecraft:arrow"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Once `minecraft:behavior.charge_held_item` has been achieved, the entity will be able to execute the process of `minecraft:behavior.ranged_attack`, and will then need to charge again.
|
||||
|
||||
### Area
|
||||
|
||||
These attacks damage all entities within a set radius. It is different to both ranged and melee in that this component doesn’t actually require a target. Regardless of the entities behaviour, _all_ entities will be affected by this. It appears to be similar to melee attacks, as it deals knockback in a similar manner, though dealing damage at a constant rate.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:area_attack" : {
|
||||
"damage_range": 1, //distance in blocks
|
||||
"damage_per_tick": 2,
|
||||
"cause": "contact",
|
||||
"entity_filter": {
|
||||
"any_of": [
|
||||
{
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "player"
|
||||
},
|
||||
{
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "monster"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[Entity damage sources](https://bedrock.dev/docs/stable/Addons#Entity%20Damage%20Source). It is important to take these into consideration, as certain items in vanilla can protect from some, like armour enchantments, and you can also make mobs immune to specific sources using `minecraft:damage_sensor`.
|
||||
|
||||
### Knockback Roar
|
||||
|
||||
Many similarities between this and `minecraft:area_attack`, this component though having much more flexibility.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:roar_attack": {
|
||||
"minecraft:behavior.knockback_roar":{
|
||||
"priority":2,
|
||||
"duration":0.7,
|
||||
"attack_time":0.2,
|
||||
"knockback_damage":1,
|
||||
"knockback_horizontal_strength":1,
|
||||
"knockback_vertical_strength":1,
|
||||
"knockback_range":5,
|
||||
"knockback_filters":{
|
||||
"test":"is_family",
|
||||
"subject":"other",
|
||||
"operator":"==",
|
||||
"value":"player"
|
||||
},
|
||||
"damage_filters":{
|
||||
"test":"is_family",
|
||||
"subject":"other",
|
||||
"operator":"==",
|
||||
"value":"player"
|
||||
},
|
||||
"on_roar_end":{
|
||||
"event":"wiki:other_event"
|
||||
},
|
||||
"cooldown_time":10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is more like a shockwave of damage. Extremely versatile in uses. Produces a particle effect, which can be disabled by adding a modified version of `knockback_roar.json` to a resource pack's particles folder.
|
||||
|
||||
## More on Attacks
|
||||
|
||||
Entity Attacks don't have to be as simple as Mob being hostile towards X target, doing X attack, dealing X damage.
|
||||
|
||||
### Difficulty Dependant Attacks
|
||||
|
||||
Express components and values to use for each difficulty.
|
||||
|
||||
<CodeHeader>BP/entities/bee.json</CodeHeader>
|
||||
|
||||
```json
|
||||
"easy_attack": {
|
||||
"minecraft:attack": {
|
||||
"damage": 2
|
||||
}
|
||||
},
|
||||
"normal_attack": {
|
||||
"minecraft:attack": {
|
||||
"damage": 2,
|
||||
"effect_name": "poison",
|
||||
"effect_duration": 10
|
||||
}
|
||||
},
|
||||
"hard_attack": {
|
||||
"minecraft:attack": {
|
||||
"damage": 2,
|
||||
"effect_name": "poison",
|
||||
"effect_duration": 18
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Switching Modes
|
||||
|
||||
You can use events to make your mob only attack under specific circumstances, or swap between the different types of attack. This can be achieved through simple usage of [events](/entities/entity-events) and component groups. Two prime examples being `minecraft:environment_sensor` and `minecraft:target_nearby_sensor`. The two are pretty similar in regards of structure, difference being that one is for sensing environments and the other for testing for target distance.
|
||||
|
||||
#### Attacks
|
||||
|
||||
Component groups are required to define the different modes of attack, such as:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:ranged_components": {
|
||||
"minecraft:shooter": {
|
||||
"def": "wiki:projectile"
|
||||
},
|
||||
"minecraft:behavior.ranged_attack": {
|
||||
"priority": 3,
|
||||
"ranged_fov": 90.0,
|
||||
"attack_interval_min": 1.0,
|
||||
"attack_interval_max": 3.0,
|
||||
"attack_radius": 15.0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:melee_components": {
|
||||
"minecraft:attack": {
|
||||
"damage": 6
|
||||
},
|
||||
"minecraft:behavior.melee_attack": {
|
||||
"priority": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Those are examples of your attack modes, but they are not the only ones you can use. `wiki:ranged_components` and `wiki:melee_components` are generic names for the components within them, they can have any name, but it's what's nested inside them that counts.
|
||||
|
||||
#### Events
|
||||
|
||||
These component groups won't actually do anything by themselves. Another component group is required, and some events to add/remove the attack modes.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:melee_swap": { //When triggered, adds component group for ranged and removes melee component group
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"wiki:ranged_components"
|
||||
]
|
||||
},
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"wiki:melee_components"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:ranged_swap": { //When triggered, adds component group for melee and removes ranged component group
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"wiki:melee_components"
|
||||
]
|
||||
},
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"wiki:ranged_components"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The events are effectively for just turning attack modes on and off, by adding and removing different component groups.
|
||||
|
||||
#### Sensors
|
||||
|
||||
To trigger the events, another component group is used. Sensors are components that can trigger events when certain conditions are fulfilled. Here are 2 examples of different sensors:
|
||||
|
||||
- For sensing the distance between the mob and target
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:switcher_range": {
|
||||
"minecraft:target_nearby_sensor": {
|
||||
"inside_range": 4.0,
|
||||
"outside_range": 5.0,
|
||||
"must_see": true,
|
||||
"on_inside_range": { //When target is within 4 blocks range, trigger "wiki:melee_swap" event
|
||||
"event": "wiki:melee_swap",
|
||||
"target": "self"
|
||||
},
|
||||
"on_outside_range": { //When target is beyond 5 blocks range, trigger "wiki:ranged_swap" event
|
||||
"event": "wiki:ranged_swap",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- For sensing certain features of the environment of which the mob is exposed to
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:switcher_environment": {
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": [
|
||||
{
|
||||
"filters": { //When underwater, trigger "wiki:melee_swap" event
|
||||
"test": "is_underwater",
|
||||
"subject": "self",
|
||||
"operator": "==",
|
||||
"value": true
|
||||
},
|
||||
"event": "wiki:melee_swap"
|
||||
},
|
||||
{
|
||||
"filters": { //When not underwater, trigger "wiki:ranged_swap" event
|
||||
"test": "is_underwater",
|
||||
"subject": "self",
|
||||
"operator": "==",
|
||||
"value": false
|
||||
},
|
||||
"event": "wiki:ranged_swap"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This uses `Filters`, similar to how the [target is initially selected](#target-selecting).
|
||||
|
||||
:::tip
|
||||
You aren't limited to just 2 attack types, you can have as many as you want! Just make sure to have the event's and sensors to compensate for them.
|
||||
:::
|
||||
|
||||
## Visual Animations
|
||||
|
||||
Attacks and animations go hand in hand. Within resource packs, the following 3 directories are required:
|
||||
|
||||
- animations (entityname.animation.json)
|
||||
- animation_controllers (entityname.animation_controller.json)
|
||||
- entity (entityname.json)
|
||||
|
||||
Or as long as you know the names of vanilla animations and animation controllers, you can define them in the latter directory and folder.
|
||||
|
||||
### Animations
|
||||
|
||||
Animations are self explanatory. The files themselves contain all specific animations for the given entity. The recommended way to make animations is by using [blockbench](/guide/blockbench).
|
||||
|
||||
Though it is possible to create them in a simple text editor.
|
||||
|
||||
| Vanilla Attack Animations |
|
||||
| -------------------------------------------- |
|
||||
| "animation.zombie.attack_bare_hand" |
|
||||
| "animation.skeleton.attack.v1.0" |
|
||||
| "animation.humanoid.bow_and_arrow.v1.0" |
|
||||
| "animation.humanoid.damage_nearby_mobs.v1.0" |
|
||||
|
||||
A few examples of Animations. Locate /vanilla_resource_pack/animations for all of them.
|
||||
|
||||
### Animation Controllers
|
||||
|
||||
List of states that trigger animations.
|
||||
|
||||
| Vanilla Attack Animation Controllers |
|
||||
| ---------------------------------------------- |
|
||||
| "controller.animation.zombie.attack_bare_hand" |
|
||||
| "controller.animation.skeleton.attack" |
|
||||
| "controller.animation.humanoid.bow_and_arrow" |
|
||||
| "controller.animation.humanoid.attack" |
|
||||
|
||||
A few examples of Animation Controllers. Locate /vanilla_resource_pack/animation_controllers for all of them
|
||||
|
||||
More information on animations can be found [here](https://bedrock.dev/docs/stable/Animations).
|
||||
76
docs/wiki/3-实体/2-巧思案例/entity-holds-item.md
Normal file
76
docs/wiki/3-实体/2-巧思案例/entity-holds-item.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Entity Holds Item
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- pieterdefour
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- stirante
|
||||
- Joelant05
|
||||
- destruc7ion
|
||||
- Dreamedc2015
|
||||
- sermah
|
||||
- 7dev7urandom
|
||||
---
|
||||
|
||||
::: tip
|
||||
This tutorial assumes you have a basic understanding of entities, loot tables, and Blockbench.
|
||||
:::
|
||||
|
||||
In this tutorial, you will learn to have an entity spawn with an item in its hand. I'll be using a custom `mandalorian_armorer` entity and a custom `hammer` item for the examples.
|
||||
|
||||
## Model
|
||||
|
||||
First of all, you'll need to have a model in Blockbench that has a map called `rightArm`. Within this map, there needs to be a submap called 'rightItem'.
|
||||
Now set the position of the pivot point of this submap, so it sits in the place you want the entity to hold the item at.
|
||||
|
||||

|
||||
|
||||
## Behavior Pack-side
|
||||
|
||||
Now you'll need to add a `minecraft:equipment` component in the component list for your entity and add a loot table with the desired item.
|
||||
|
||||
In our example it will look like this:
|
||||
|
||||
<CodeHeader>BP/entity/mandolorian.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:equipment": {
|
||||
"table": "loot_tables/entities/gear/mandolorian.json"
|
||||
}
|
||||
```
|
||||
|
||||
## Loot Table
|
||||
|
||||
Finally, add the loot table for your entity. It needs to be in `loot_tables/entities/<your_loot_table_name>.json` in the behavior pack. In our case, it's called `mandolorian.json`.
|
||||
|
||||
:::warning
|
||||
This isn't the same loot table as what it drops on death. So make sure it has a different name.
|
||||
:::
|
||||
|
||||
To have the entity always spawn with the same item, add the following loot table:
|
||||
|
||||
<CodeHeader>BP/loot_tables/entities/gear/mandolorian.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "item",
|
||||
"name": "dd:hammer",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
If everything went well, you'd have something looking like this:
|
||||
|
||||

|
||||
202
docs/wiki/3-实体/2-巧思案例/entity-movement.md
Normal file
202
docs/wiki/3-实体/2-巧思案例/entity-movement.md
Normal file
@@ -0,0 +1,202 @@
|
||||
---
|
||||
title: Entity Movement
|
||||
category: Tutorials
|
||||
mentions:
|
||||
- SirLich
|
||||
- sermah
|
||||
- MedicalJewel105
|
||||
- TheDoctor15
|
||||
---
|
||||
|
||||
In Minecraft, entities have the ability to move through the world, either by walking, swimming or flying. To get these behaviors, your entity will generally need quite a few behaviors, broken out into various types.
|
||||
|
||||
As you read this tutorial, keep in mind that your entity will need at least:
|
||||
|
||||
- [A component that sets the entities movement speed.](#movement-speed)
|
||||
- [A component to set how the entity will move (walking, flying, etc)](#movement-type)
|
||||
- [A component to set the entities navigation abilities, so it can generate paths.](#navigation-abilities)
|
||||
- [A component that sets where/when the entity should move (AI Goals).](#ai)
|
||||
|
||||
:::tip
|
||||
The best way to create a moving entity is by picking a similar entity from the vanilla behavior pack, and copying the components into your entity.
|
||||
|
||||
For example entities like Phantom, or Ghast, or Parrot are all flying entities, but have very different in-game behavior! Use the closest-matching entity as a template.
|
||||
:::
|
||||
|
||||
## Movement Speed
|
||||
|
||||
The first thing your entity needs is a speed component. This sets how quickly your entity will move through the world.
|
||||
|
||||
| Component | Note |
|
||||
| ---------------------------------------------------------------------------------------------------------------- | -------------------------------- |
|
||||
| [minecraft:movement](/entities/vanilla-usage-components#movement) | Set movement speed (required) |
|
||||
| [minecraft:underwater_movement](/entities/vanilla-usage-components#underwater-movement) | Set movement speed in the water. |
|
||||
| [minecraft:flying_speed](/entities/vanilla-usage-components#flying-speed) | Set the speed in the air. |
|
||||
|
||||
You should always include `minecraft:movement`. Add the other two as needed.
|
||||
|
||||
All vanilla "swimming" entities like Dolphin include `underwater_movement`. Only some flying entities have `flying_speed`. It is not known why this is the case.
|
||||
|
||||
## Movement Type
|
||||
|
||||
Your entity will also need a movement type. Movement types set hard-coded behavior for _how_ your entity will move through the world.
|
||||
|
||||
You may only include one movement type in your entity. Select the component that most closely matches your needs. Generally `basic`, `amphibious` and `fly` are good ones to use.
|
||||
|
||||
| Component | Note |
|
||||
| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| [minecraft:movement.amphibious](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.amphibious) | This move control allows the mob to swim in the water and walk on land. |
|
||||
| [minecraft:movement.basic](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.basic) | This component accents the movement of an entity. |
|
||||
| [minecraft:movement.fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.fly) | This move control causes the mob to fly. |
|
||||
| [minecraft:movement.generic](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.generic) | This move control allows a mob to fly, swim, climb, etc. |
|
||||
| [minecraft:movement.hover](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.hover) | This move control causes the mob to hover. |
|
||||
| [minecraft:movement.jump](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.jump) | Move control causes the mob to jump as it moves with a specified delay between jumps. |
|
||||
| [minecraft:movement.skip](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.skip) | This move control causes the mob to hop as it moves. |
|
||||
| [minecraft:movement.sway](https://bedrock.dev/docs/stable/Entities#minecraft%3Amovement.sway) | This move control causes the mob to sway side to side, giving the impression it is swimming. |
|
||||
|
||||
## Movement Modifiers
|
||||
|
||||
Movement modifiers provide additional information about how your entity will move through the world. These components are not required for normal entities, but you should be aware of them.
|
||||
|
||||
| Component | Note |
|
||||
| ----------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| [minecraft:water_movement](https://bedrock.dev/docs/stable/Entities#minecraft%3Awater_movement) | Sets the friction the entity experiences in water. |
|
||||
| [minecraft:rail_movement](https://bedrock.dev/docs/stable/Entities#minecraft%3Arail_movement) | Sets that the entity can move on rails (only). |
|
||||
| [minecraft:friction_modifier](https://bedrock.dev/docs/stable/Entities#minecraft%3Afriction_modifier) | Sets the friction the entity experiences on land. |
|
||||
|
||||
## Navigation
|
||||
|
||||
The next thing your entity needs is a navigation component. Navigation components have quite a few fields, like whether the entity can open doors or avoid sunlight. How you set these fields is generally more important than the navigation component you pick!
|
||||
|
||||
The reason there are so many navigation components is that each one gives a slightly different hard-coded behavior. Pick the navigation component whose name/description best matches the kind of navigation your entity will be doing.
|
||||
|
||||
You can only have one navigation component at any given time.
|
||||
|
||||
:::tip
|
||||
This component is very important. You should check vanilla examples for inspiration on what fields and values to use.
|
||||
:::
|
||||
|
||||
| Component | Note |
|
||||
| ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| [minecraft:navigation.climb](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.climb) | Allows this entity to generate paths that include vertical walls like the vanilla Spiders do. |
|
||||
| [minecraft:navigation.float](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.float) | Allows this entity to generate paths by flying around the air like the regular Ghast. |
|
||||
| [minecraft:navigation.generic](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.generic) | Allows this entity to generate paths by walking, swimming, flying and climbing around, and jumping up and down a block. |
|
||||
| [minecraft:navigation.fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.fly) | Allows this entity to generate paths in the air as the vanilla Parrots do. |
|
||||
| [minecraft:navigation.swim](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.swim) | Allows this entity to generate paths that include water. |
|
||||
| [minecraft:navigation.walk](https://bedrock.dev/docs/stable/Entities#minecraft%3Anavigation.walk) | Allows this entity to generate paths by walking around and jumping up and down a block like regular mobs. |
|
||||
|
||||
## Navigation Abilities
|
||||
|
||||
On top of the movement and the navigation component, there exist many additional components to augment the abilities of your entity as they move through the world.
|
||||
|
||||
| Component | Note |
|
||||
| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [minecraft:annotation.break_door](https://bedrock.dev/docs/stable/Entities#minecraft%3Aannotation.break_door) | Allows entity to break doors. It must also be turned on in the navigation component. |
|
||||
| [minecraft:annotation.open_door](https://bedrock.dev/docs/stable/Entities#minecraft%3Aannotation.open_door) | Allows entity to open doors. It must also be turned on in the navigation component. |
|
||||
| [minecraft:buoyant](https://bedrock.dev/docs/stable/Entities#minecraft%3Abuoyant) | Specifies which liquids the entity can float in. |
|
||||
| [minecraft:can_climb](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_climb) | Allows this entity to climb up ladders. |
|
||||
| [minecraft:can_fly](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_fly) | Marks the entity as being able to fly. The pathfinder won't be restricted to paths where a solid block is required underneath it. |
|
||||
| [minecraft:can_power_jump](https://bedrock.dev/docs/stable/Entities#minecraft%3Acan_power_jump) | Allows the entity to power jump like the horse does in vanilla. |
|
||||
| [minecraft:floats_in_liquid](https://bedrock.dev/docs/stable/Entities#minecraft%3Afloats_in_liquid) | Sets that this entity can float in liquid blocks. |
|
||||
| [minecraft:jump.dynamic](https://bedrock.dev/docs/stable/Entities#minecraft%3Ajump.dynamic) | Defines a dynamic type jump control that will change jump properties based on the speed modifier of the mob. |
|
||||
| [minecraft:jump.static](https://bedrock.dev/docs/stable/Entities#minecraft%3Ajump.static) | Gives the entity the ability to jump. |
|
||||
|
||||
There are also components like `minecraft:preferred_path`, which will modify navigation based on block-based path-cost.
|
||||
|
||||
## AI Goals
|
||||
|
||||
The navigation component tells the entity _how_ to generate paths, but it doesn't say _when_ or _where_ to generate paths. This is what the AI components are for.
|
||||
|
||||
AI Goals are prefixed with `behavior` and follow a priority system to pick which behavior to run. The lower priorities will be picked first.
|
||||
|
||||
In general, you should usually add quite a few AI components, with different priorities. Layered together, these will create realistic movement and behavior for your entity. As always, vanilla entities provide a good template for which components to add, and with what properties/priorities.
|
||||
|
||||
There are too many AI components that generate paths to list in this document. A few will be provided as examples:
|
||||
|
||||
| Component |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [minecraft:behavior.random_stroll](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.random_stroll) |
|
||||
| [minecraft:behavior.follow_owner](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.follow_owner) |
|
||||
| [minecraft:behavior.move_to_water](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.move_to_water) |
|
||||
| [minecraft:behavior.stroll_towards_village](https://bedrock.dev/docs/stable/Entities#minecraft%3Abehavior.stroll_towards_village) |
|
||||
|
||||
For a full list, visit [bedrock.dev](https://bedrock.dev/docs/stable/Entities#AI%20Goals).
|
||||
|
||||
### Pathfinding
|
||||
|
||||
Making entities go to specific places is one of the most common requests for Marketplace content.
|
||||
The best way to do pathfinding uses a second entity, which the first entity will be attracted to. I am going to call this secondary entity the **marker**. If you are confused on how to create a marker, visit the [Dummy Entities](/entities/dummy-entities) page.
|
||||
|
||||
#### Idea
|
||||
|
||||
The way we are going to do pathfinding is actually fairly simple: Make our entity aggressive towards our marker, and then simply place our marker where we want our entity to path to. The hard part is knowing what components to add so we get really long-range pathing.
|
||||
|
||||
#### Components
|
||||
|
||||
These components can be edited as needed to create good pathing. Make sure to update the `nearest_attackable_target` to point to your marker entity. This takes a `family_type`, so you should set one of those on your marker.
|
||||
|
||||
Don't forget to add some basic movement and navigation components so your entity is able to move.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.nearest_attackable_target": {
|
||||
"priority": 0,
|
||||
"reselect_targets": true,
|
||||
"target_search_height": 1000,
|
||||
"within_radius": 1000,
|
||||
"must_see": false,
|
||||
"entity_types": [
|
||||
{
|
||||
"filters": [
|
||||
{
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "waypoint_1"
|
||||
}
|
||||
],
|
||||
"max_dist": 1000
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:attack": {
|
||||
"damage": 0
|
||||
},
|
||||
"minecraft:behavior.melee_attack": {
|
||||
"priority": 0,
|
||||
"require_complete_path": true,
|
||||
"track_target": true
|
||||
},
|
||||
"minecraft:follow_range": {
|
||||
"value": 1000,
|
||||
"max": 1000
|
||||
}
|
||||
```
|
||||
|
||||
#### Detecting a reached waypoint
|
||||
|
||||
You can use `minecraft:target_nearby_sensor` to detect when you have reached the marker entity:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:target_nearby_sensor": {
|
||||
"inside_range": 2.0,
|
||||
"outside_range": 4.0,
|
||||
"must_see": true,
|
||||
"on_inside_range": {
|
||||
"event": "reached_waypoint"
|
||||
},
|
||||
"on_outside_range": {
|
||||
"event": "not_reached_waypoint"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Other
|
||||
|
||||
:::tip
|
||||
You can trigger entity walking animation via command.
|
||||
`/execute as @e[type=...] at @s run tp @s ^^^0.1`
|
||||
This way you can control where entity goes and make it look natural.
|
||||
:::
|
||||
359
docs/wiki/3-实体/2-巧思案例/flying-entities.md
Normal file
359
docs/wiki/3-实体/2-巧思案例/flying-entities.md
Normal file
@@ -0,0 +1,359 @@
|
||||
---
|
||||
title: Flying Entities
|
||||
category: Tutorials
|
||||
tags:
|
||||
- recipe
|
||||
- intermediate
|
||||
mentions:
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- Dreamedc2015
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- imsolucid
|
||||
- nebulacrab
|
||||
- Luthorius
|
||||
- TheItsNameless
|
||||
---
|
||||
|
||||
Whether making a plane or a dragon, adding controllability to flying entities will probably challenge most devs who haven't dabbled around this concept. Since there is no "right" way of adding a piloting mechanic to flying entities, I'll showcase 3 main workaround ways you can use to achieve this.
|
||||
|
||||
## Great Jump, Slow Fall
|
||||
|
||||
While not exactly "flying", setting the entity's jumping power high and giving it slow falling & speed effects as it falls is probably the most straightforward method.
|
||||
|
||||
To achieve this, we will need to add the `"minecraft:horse.jump_strength"` component to our entity. Adding this will allow you to control its jumping power and disable dismounting when the player presses the jump button.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:horse.jump_strength": {
|
||||
"value": 7
|
||||
}
|
||||
```
|
||||
|
||||
We can also use `"value"` as an object to utilize the **range bar** players will see when holding down the jump button.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:horse.jump_strength": {
|
||||
"value": { "range_min": 0.6, "range_max": 1.2 }
|
||||
}
|
||||
```
|
||||
|
||||
Now we will give it slow falling and speed as it's falling so that it doesn't instantly fall. To do this, we will make an animation controller and give it those effects when it's not on the ground as so:
|
||||
|
||||
(You can read a tutorial on how to use animation controllers to execute commands [here](/animation-controllers/entity-commands).)
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.dragon.flying":{
|
||||
"states":{
|
||||
"default":{
|
||||
"transitions":[
|
||||
{
|
||||
"jumping":"!q.is_on_ground"
|
||||
}
|
||||
]
|
||||
},
|
||||
"jumping":{
|
||||
"transitions":[
|
||||
{
|
||||
"default":"q.is_on_ground"
|
||||
}
|
||||
],
|
||||
"on_entry":[
|
||||
"/effect @s slow_falling 20000 0 true",
|
||||
"/effect @s speed 20000 10 true"
|
||||
],
|
||||
"on_exit":[
|
||||
"/effect @s clear"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We'll also need to hook it up to our entity as so:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"description":{
|
||||
"identifier":"wiki:dragon",
|
||||
"is_spawnable":true,
|
||||
"is_summonable":true,
|
||||
"is_experimental":false,
|
||||
"scripts":{
|
||||
"animate":[
|
||||
"flying"
|
||||
]
|
||||
},
|
||||
"animations":{
|
||||
"flying":"controller.animation.dragon.flying"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, we should have a mechanic at least resemblant of flying. You can change the values like jump_strength and speed, but the entity will always fall using this method.
|
||||
|
||||
## Controlling Through Looking
|
||||
|
||||
This is probably the most popular method of piloting flying entities, and unlike the first method, this one gives players control over the vertical movement of the entity so that you don't always have to fall every time you jump, with the downside being you can't look around freely without changing the entity's vertical trajectory.
|
||||
|
||||
This method detects the riding player's vertical rotation and applies levitation/slow_falling effects to the entity accordingly.
|
||||
|
||||
There are multiple ways of achieving that, but in this tutorial, we'll be using the target selectors `rym` (minimum y-rotation) and `ry` (maximum y-rotation) in a chain of repeating command-blocks to detect the player's pitch, and depending on the range, giving our entity levitation or slowly falling.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```
|
||||
execute @a[rxm=-90,rx=-25] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 6 true
|
||||
execute @a[rxm=-25,rx=-15] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 3 true
|
||||
execute @a[rxm=-15,rx=-5] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 2 true
|
||||
execute @a[rxm=-5,rx=20] ~~~ effect @e[type=wiki:dragon,r=1] levitation 1 1 true
|
||||
execute @a[rxm=20,rx=35] ~~~ effect @e[type=wiki:dragon,r=1] slow_falling 1 1 true
|
||||
execute @a[rxm=35,rx=90] ~~~ effect @e[type=wiki:dragon,r=1] clear
|
||||
```
|
||||
|
||||
**Depending on how big your entity is and how far away the player's seat is from its pivot, you might need to change the radius `r` to a more significant value.**
|
||||
|
||||
After you run those commands in a repeating command block, you should control its vertical movement by looking up and down.
|
||||
or you may use a simple animation controller and link it to the entity, so it always plays the function.
|
||||
|
||||
It's recommended that you link this animation controller to the player.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animation_controllers": {
|
||||
"controller.animation.base": {
|
||||
"initial_state": "default",
|
||||
"states": {
|
||||
"default": {
|
||||
"transitions": [
|
||||
{
|
||||
"base": "(1.0)"
|
||||
}
|
||||
],
|
||||
"on_entry": [
|
||||
"/function dragon_control"
|
||||
]
|
||||
},
|
||||
"base": {
|
||||
"transitions": [
|
||||
{
|
||||
"default": "(1.0)"
|
||||
}
|
||||
],
|
||||
"on_entry": [
|
||||
"/function dragon_control"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The entity will probably still be too slow when flying, so we'll borrow our animation controller from the first method with some changes to give the entity speed when it's flying.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.dragon.flying":{
|
||||
"states":{
|
||||
"default":{
|
||||
"transitions":[
|
||||
{
|
||||
"jumping_1":"!q.is_on_ground"
|
||||
}
|
||||
]
|
||||
},
|
||||
"jumping_1":{
|
||||
"transitions":[
|
||||
{
|
||||
"transition_to_default":"q.is_on_ground"
|
||||
},
|
||||
{
|
||||
"jumping_2":"true"
|
||||
}
|
||||
],
|
||||
"on_entry":[
|
||||
"/effect @s speed 15 10 true"
|
||||
]
|
||||
},
|
||||
"jumping_2":{
|
||||
"transitions":[
|
||||
{
|
||||
"transition_to_default":"q.is_on_ground"
|
||||
},
|
||||
{
|
||||
"jumping_1":"true"
|
||||
}
|
||||
],
|
||||
"on_entry":[
|
||||
"/effect @s speed 15 10 true"
|
||||
]
|
||||
},
|
||||
"transition_to_default":{
|
||||
"transitions":[
|
||||
{
|
||||
"transition_to_default":"true"
|
||||
}
|
||||
],
|
||||
"on_entry":[
|
||||
"/effect @s clear"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
_Since the entity's effects might be cleared when it's being flown, we changed the animation controller to give the entity speed every tick it's not on the ground._
|
||||
|
||||
You might also notice that the entity levitates when you go near it. We can fix this by giving the entity a tag when it's being ridden (removing it when it isn't being ridden) and only applying those effects when the entity has the tag by making and animating another animation controller and updating our commands.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.dragon.test_rider":{
|
||||
"states":{
|
||||
"default":{
|
||||
"transitions":[
|
||||
{
|
||||
"has_rider":"q.has_rider"
|
||||
}
|
||||
]
|
||||
},
|
||||
"has_rider":{
|
||||
"transitions":[
|
||||
{
|
||||
"default":"!q.has_rider"
|
||||
}
|
||||
],
|
||||
"on_entry":[
|
||||
"/tag @s add has_rider"
|
||||
],
|
||||
"on_exit":[
|
||||
"/tag @s remove has_rider"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```
|
||||
execute @a[rxm=-90,rx=-25] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 6 true
|
||||
execute @a[rxm=-25,rx=-15] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 3 true
|
||||
execute @a[rxm=-15,rx=-5] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 2 true
|
||||
execute @a[rxm=-5,rx=20] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] levitation 1 1 true
|
||||
execute @a[rxm=20,rx=35] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] slow_falling 1 1 true
|
||||
execute @a[rxm=35,rx=90] ~~~ effect @e[type=wiki:dragon,r=1,tag=has_rider] clear
|
||||
```
|
||||
|
||||
## Controlling Through Jumping
|
||||
|
||||
A third method of controlling flying entities uses the player's jump button. The entity rises when the player is holding the jump button and falls when they release their jump button.
|
||||
|
||||
To do this, we need an animation controller attached to the player rather than the entity itself to detect when the player uses their jump button. We also need to disable dismounting when the player presses the jump button.
|
||||
|
||||
First, on the entity, disable dismounting and jumping:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:horse.jump_strength": {
|
||||
"value": 0
|
||||
},
|
||||
"minecraft:can_power_jump": {}
|
||||
```
|
||||
|
||||
Next, we need an animation controller that causes the entity to levitate when the player uses their jump button and resets the levitation when they release their jump button.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.fly_dragon":{
|
||||
"initial_state":"falling",
|
||||
"states":{
|
||||
"falling":{
|
||||
"on_entry":[
|
||||
"/effect @e[type=wiki:dragon,r=1,c=1] levitation 0"
|
||||
],
|
||||
"transitions":[
|
||||
{
|
||||
"rising":"q.is_jumping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"rising":{
|
||||
"on_entry":[
|
||||
"/effect @e[type=wiki:dragon,r=1,c=1] levitation 100000 6 true"
|
||||
],
|
||||
"transitions":[
|
||||
{
|
||||
"falling":"!q.is_jumping"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now, we need a copy of the player's behavior file, which we will modify slightly. You can find the player's behavior file in the vanilla behavior pack provided by Mojang (found [here](https://aka.ms/behaviorpacktemplate)). Once you have copied the player's behavior file to your own behavior pack, find their `"description"` object and add the animation controller. We also want to ensure that the entity will only respond to the player's jump input when the player is riding it, so we can use a Molang query in the player's behavior to only activate the animation controller when the player is riding.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"description":{
|
||||
"identifier":"minecraft:player",
|
||||
"is_spawnable":false,
|
||||
"is_summonable":false,
|
||||
"animations":{
|
||||
"fly_dragon":"controller.animation.fly_dragon"
|
||||
},
|
||||
"scripts":{
|
||||
"animate":[
|
||||
{
|
||||
"fly_dragon":"q.is_riding"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The entity can now be controlled with the jump key, but there's a bug. If the player dismounts the entity while holding the jump key, it will continue rising. We can fix this with an animation controller on the entity itself that resets the levitation whenever a player dismounts it.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.reset_levitation":{
|
||||
"initial_state":"no_rider",
|
||||
"states":{
|
||||
"no_rider":{
|
||||
"transitions":[
|
||||
{
|
||||
"has_rider":"q.has_rider"
|
||||
}
|
||||
]
|
||||
},
|
||||
"has_rider":{
|
||||
"on_exit":[
|
||||
"/effect @s levitation 0"
|
||||
],
|
||||
"transitions":[
|
||||
{
|
||||
"no_rider":"!q.has_rider"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
78
docs/wiki/3-实体/2-巧思案例/introduction-to-aec.md
Normal file
78
docs/wiki/3-实体/2-巧思案例/introduction-to-aec.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Introduction to AOE Clouds
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- Sprunkles137
|
||||
- MedicalJewel105
|
||||
---
|
||||
|
||||
**Area-of-effect clouds**, also known as AOE clouds and `minecraft:area_effect_cloud` internally, are special entities that have many unique properties. Normally these entities are created through throwing lingering potions, but with structures and some NBT editing magic we can manipulate them in very powerful ways for map-making.
|
||||
|
||||
## Overview
|
||||
|
||||
Area-of-effect clouds have several special features we can take advantage of:
|
||||
|
||||
- As [dummy entities](/entities/dummy-entities), they are highly performant and barely affect framerate, and they are also completely static and have no collision with the world. This makes them perfect for situations around players or where precise positioning is important.
|
||||
- It does not send the client updates. Once it spawns in, it will visually appear to be frozen in place until it despawns. However, it can still be moved around through commands just fine.
|
||||
- It can apply any potion effect in highly configurable ways. The duration can be set down to the tick, as well as whether or not the effect is ambient, or displays on the screen, if it emits particles, etc.
|
||||
- Entities with a runtime identifier of `minecraft:area_effect_cloud` inherit these same properties.
|
||||
|
||||
## Method 1: Projectile Component
|
||||
|
||||
The projectile component supports spawning in area-of-effect clouds on hit. Minecraft uses this to spawn in AOE clouds from lingering potions.
|
||||
|
||||
[Projectiles Documentation](/documentation/projectiles#spawn-aoe-cloud)
|
||||
|
||||
## Method 2: NBT Editing
|
||||
|
||||
Another way to spawn in these area-of-effect clouds is through structure files. This grants us finer control over the potion effects the cloud can have. So, our first order of business is getting a means to edit these structures.
|
||||
|
||||
### NBT Editors
|
||||
|
||||
One of the following NBT editors are recommended:
|
||||
|
||||
- [NBT Studio](https://github.com/tryashtar/nbt-studio) (a standalone program by tryashtar)
|
||||
- [NBT Viewer](https://marketplace.visualstudio.com/items?itemName=Misodee.vscode-nbt) (a Visual Studio Code extension by Misode)
|
||||
|
||||
### Structure file
|
||||
|
||||
For convenience, this article contains a premade structure file you can download and use. Inside is an AOE cloud that exists for the maximum possible time.
|
||||
|
||||
<BButton
|
||||
link="/assets/packs/entities/aec/aec.mcstructure" download
|
||||
color=blue
|
||||
>Download MCSTRUCTURE</BButton>
|
||||
|
||||
Refer to this article for editing structure files: [.mcstructure](/nbt/mcstructure)
|
||||
|
||||
### NBT Format
|
||||
|
||||
| Tag | Type | Description |
|
||||
| --------------------- | ------- | ----------------- |
|
||||
| Duration | Integer | How long the cloud exists for before expiring, in ticks. |
|
||||
| DurationOnUse | Integer | How much the duration should change when effects are applied. |
|
||||
| InitialRadius | Float | The size of this cloud's radius when created. |
|
||||
| ParticleColor | Integer | The color of the particle effect, in decimal. |
|
||||
| ParticleId | Integer | The particle effect this cloud emits. 0 emits no particles. |
|
||||
| PotionId | Short | This cloud's potion effect ID when created. Has no effect. |
|
||||
| RadiusChangeOnPickup | Float | Unknown. |
|
||||
| RadiusOnUse | Float | How much the radius should change when effects are applied. |
|
||||
| RadiusPerTick | Float | How much the radius changes every tick. |
|
||||
| ReapplicationDelay | Integer | The interval at which effects can be applied, in ticks. |
|
||||
| mobEffects | List | Describes what potion effects should be applied. |
|
||||
|
||||
Below are the parameters for the `mobEffects` tag.
|
||||
|
||||
| Tag | Type | Description |
|
||||
| ------------------------------- | ------- | --------------- |
|
||||
| Ambient | Byte | Defines whether this effect's particles should be translucent or not. |
|
||||
| Amplifier | Byte | The strength of this potion effect. |
|
||||
| DisplayOnScreenTextureAnimation | Byte | Unknown. |
|
||||
| Duration | Integer | The amount of time this effect is applied for, in ticks. |
|
||||
| DurationEasy | Integer | Unknown, seemingly unused. |
|
||||
| DurationNormal | Integer | Unknown, seemingly unused. |
|
||||
| DurationHard | Integer | Unknown, seemingly unused. |
|
||||
| Id | Byte | The potion effect ID for this effect. |
|
||||
| ShowParticles | Byte | Defines whether this effect's particles should appear or not. |
|
||||
67
docs/wiki/3-实体/2-巧思案例/invulnerable-entities.md
Normal file
67
docs/wiki/3-实体/2-巧思案例/invulnerable-entities.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: Invulnerable Entities
|
||||
category: Tutorials
|
||||
tags:
|
||||
- beginner
|
||||
mentions:
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- solvedDev
|
||||
- MedicalJewel105
|
||||
---
|
||||
|
||||
## Using Damage Sensor
|
||||
|
||||
The best and most flexible way of disabling damage for entities is using the `minecraft:damage_sensor` component. The component allows us to use `filters` to determine which damage sources can damage our entity.
|
||||
|
||||
The best way to learn about this component is by using the vanilla examples for damage sensor or reading [documentation](https://bedrock.dev/docs/stable/Entities#minecraft:damage_sensor)
|
||||
|
||||
### Completely Invulnerable Entity
|
||||
|
||||
<CodeHeader>BP/entities/entity.json#minecraft:entity/components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:damage_sensor": {
|
||||
"triggers": {
|
||||
"cause": "all",
|
||||
"deals_damage": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Disable Damage from Player
|
||||
|
||||
<CodeHeader>BP/entities/entity.json#minecraft:entity/components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:damage_sensor": {
|
||||
"triggers": {
|
||||
"on_damage": {
|
||||
"filters": {
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "player"
|
||||
}
|
||||
},
|
||||
"deals_damage": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Min Health
|
||||
|
||||
The `min` property in the `minecraft:health` component allows us to make invincible entities that cannot die. This includes when using `/kill @e`. This is not considered a good solution because entities like this are hard to get rid of.
|
||||
|
||||
If you choose to use this component, please make sure you have another method for killing the entity. Triggering `minecraft:instant_despawn` from something like an environment sensor, a timer, or an interact is a good solution. You also can call it using `/event`.
|
||||
|
||||
<CodeHeader>BP/entities/entity.json#minecraft:entity/components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:health": {
|
||||
"value": 1,
|
||||
"max": 1,
|
||||
"min": 1
|
||||
}
|
||||
```
|
||||
|
||||
Note that setting it to 0 breaks some death and spawn animations/effects.
|
||||
44
docs/wiki/3-实体/2-巧思案例/look-at-entity.md
Normal file
44
docs/wiki/3-实体/2-巧思案例/look-at-entity.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Look at Entity
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- shanewolf38
|
||||
- MedicalJewel105
|
||||
- TheItsNameless
|
||||
- SmokeyStack
|
||||
---
|
||||
|
||||
The following tutorial provides a resource pack method to detect when the player is looking at an entity. The code below must be placed inside the entity that will be looked at by the player, and will provide a variable `v.look_at_entity` which returns true when the entity is being looked at.
|
||||
|
||||
## variable
|
||||
|
||||
<CodeHeader>RP/entity/mob.entity.json</CodeHeader>
|
||||
|
||||
```json
|
||||
"pre_animation": [
|
||||
"v.look_at_entity = Math.abs(Math.abs(q.rotation_to_camera(1) - q.camera_rotation(1)) - 180) < (20 / q.distance_from_camera) && Math.abs(q.rotation_to_camera(0) + q.camera_rotation(0)) < (10 / q.distance_from_camera);"
|
||||
],
|
||||
```
|
||||
|
||||
:::tip
|
||||
Because the query `q.rotation_to_camera` is based at the origin of the entity (their feet), the vertical detection range will be based around the bottom of the entity. The code below creates a modified variable for the vertical angle which takes a positional offset into account to allow the vertical detection range to be based around the center of the entity.
|
||||
:::
|
||||
|
||||
<CodeHeader>RP/entity/mob.entity.json</CodeHeader>
|
||||
|
||||
```json
|
||||
"pre_animation": [
|
||||
"v.rotation_to_camera_0 = -Math.atan2(-q.distance_from_camera * Math.sin(q.rotation_to_camera(0)) - 1, q.distance_from_camera * Math.cos(q.rotation_to_camera(0)));",
|
||||
"v.look_at_entity = Math.abs(Math.abs(q.rotation_to_camera(1) - q.camera_rotation(1)) - 180) < (20 / q.distance_from_camera) && Math.abs(v.rotation_to_camera_0 + q.camera_rotation(0)) < (60 / q.distance_from_camera);"
|
||||
],
|
||||
```
|
||||
|
||||
## Modifying
|
||||
|
||||
The provided code is very accurate for the standard Minecraft mob size of 1 block wide and 2 blocks tall, but for entities of different sizes the parameters should be changed. The `- 1` controls the positional offset of the center of the mob (- is upward, + is downward), the `20` controls the horizontal angle sensitivity, and the `60` controls the vertical angle sensitivity.
|
||||
|
||||
## Explanation
|
||||
|
||||
The variable detects when the player is looking at the entity by checking if the rotation angle required for the entity to look at the player is opposite the rotation angle required for the player to look at the entity. The horizontal and vertical angle sensitivity are modified by the distance of the entity from the camera to maintain accuracy.
|
||||
396
docs/wiki/3-实体/2-巧思案例/sleeping-entities.md
Normal file
396
docs/wiki/3-实体/2-巧思案例/sleeping-entities.md
Normal file
@@ -0,0 +1,396 @@
|
||||
---
|
||||
title: Sleeping Entities
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- MedicalJewel105
|
||||
- SirLich
|
||||
---
|
||||
|
||||
This tutorial will explain how to make entity sleep.
|
||||
|
||||
## Sleeping in beds
|
||||
|
||||
This behavior is inspired from villagers.
|
||||
|
||||
### Features
|
||||
|
||||
- Entity sleeps during the night and wakes up at day time.
|
||||
- Interaction with entity will wake it up and after a while it goes sleeping again.
|
||||
- If entity is hurt, it wakes up.
|
||||
|
||||
### Behavior Pack
|
||||
|
||||
In this section behavior pack components will be discussed.
|
||||
|
||||
#### Components
|
||||
|
||||
Let's start with some basic components that you need to add to your entity.
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:dweller": {
|
||||
"dwelling_type": "village",
|
||||
"dweller_role": "inhabitant",
|
||||
"can_find_poi": true
|
||||
}
|
||||
```
|
||||
|
||||
Undocumented, needed for entity to be able to sleep.
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": [
|
||||
{
|
||||
"filters": {
|
||||
"test": "is_daytime",
|
||||
"value": false
|
||||
},
|
||||
"event": "sleep"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This component is required for entity understand when to sleep.
|
||||
It runs event if it isn't day time.
|
||||
|
||||
:::warning
|
||||
You need some basic navigation components for your entity be able to move to bed.
|
||||
:::
|
||||
|
||||
#### Component Groups
|
||||
|
||||
Now you need some component groups for your entity with some components.
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#component_groups</CodeHeader>
|
||||
|
||||
```json
|
||||
"sleeping": {
|
||||
"minecraft:behavior.sleep": {
|
||||
"priority": 0,
|
||||
"goal_radius": 1.5,
|
||||
"speed_multiplier": 1.25,
|
||||
"sleep_collider_height": 0.3,
|
||||
"sleep_collider_width": 1,
|
||||
"sleep_y_offset": 0.6,
|
||||
"timeout_cooldown": 10
|
||||
},
|
||||
"minecraft:damage_sensor": {
|
||||
"triggers": {
|
||||
"on_damage": {
|
||||
"event": "wake_up"
|
||||
}
|
||||
}
|
||||
},
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": [
|
||||
{
|
||||
"filters": {
|
||||
"test": "is_daytime",
|
||||
"value": true
|
||||
},
|
||||
"event": "wake_up"
|
||||
}
|
||||
]
|
||||
},
|
||||
"minecraft:interact": {
|
||||
"interactions": [
|
||||
{
|
||||
"on_interact": {
|
||||
"filters": {
|
||||
"all_of": [
|
||||
{
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"value": "player"
|
||||
}
|
||||
]
|
||||
},
|
||||
"event": "woken_up"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `minecraft:behavior.sleep`
|
||||
|
||||
Determines sleep details, priority needs to be at `0` (the biggest weight).
|
||||
|
||||
- `minecraft:damage_sensor``
|
||||
|
||||
Add it if you want your entity wake up if it is being attacked.
|
||||
|
||||
- `minecraft:environment_sensor`
|
||||
|
||||
Runs `wake_up` event when it is day time.
|
||||
|
||||
- `minecraft:interact`
|
||||
|
||||
This makes player to be able wake up entity without hurting it.
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#component_groups</CodeHeader>
|
||||
|
||||
```json
|
||||
"sleep_timer": {
|
||||
"minecraft:timer": {
|
||||
"time": 15,
|
||||
"time_down_event": {
|
||||
"event": "sleep_again"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This component group is required for entity to fall asleep again (with some delay) after it was woken up.
|
||||
|
||||
#### Events
|
||||
|
||||
Here you will find all events that you need.
|
||||
I don't really think it needs explanation.
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#events</CodeHeader>
|
||||
|
||||
```json
|
||||
"sleep": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"sleeping"
|
||||
]
|
||||
}
|
||||
},
|
||||
"wake_up": {
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"sleeping"
|
||||
]
|
||||
}
|
||||
},
|
||||
"woken_up": {
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"sleeping"
|
||||
]
|
||||
},
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"sleep_timer"
|
||||
]
|
||||
}
|
||||
},
|
||||
"sleep_again": {
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"sleeping"
|
||||
]
|
||||
},
|
||||
"remove": {
|
||||
"component_groups": [
|
||||
"sleep_timer"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Pack
|
||||
|
||||
Don't forget that you need to add sleeping animation and controller for it to your entity!
|
||||
|
||||
#### Animation
|
||||
|
||||
Just copy/paste it.
|
||||
|
||||
<CodeHeader>RP/animations/sleeping_entity.animation.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"animations": {
|
||||
"animation.sleeping_entity.sleep": {
|
||||
"loop": "hold_on_last_frame",
|
||||
"animation_length": 0.5,
|
||||
"bones": {
|
||||
"body": {
|
||||
"rotation": {
|
||||
"0.0": [0, 0, 0],
|
||||
"0.5": [-90, 0, 0]
|
||||
},
|
||||
"position": [0, 2, -15]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Animation Controller
|
||||
|
||||
Again just copy/paste it if you need.
|
||||
|
||||
<CodeHeader>RP/animations_controllers/ac.sleeping_entity.sleep.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animation_controllers": {
|
||||
"controller.animation.sleeping_entity.sleep": {
|
||||
"initial_state": "default",
|
||||
"states": {
|
||||
"default": {
|
||||
"transitions": [
|
||||
{
|
||||
"sleep": "q.is_sleeping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sleep": {
|
||||
"animations": ["sleeping"],
|
||||
"transitions": [
|
||||
{
|
||||
"default": "!q.is_sleeping"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that you will need to define animation in client entity like this:
|
||||
|
||||
`"sleeping": "animation.sleeping_entity.sleep"`
|
||||
|
||||
### Result
|
||||
|
||||

|
||||
|
||||
## Taking naps
|
||||
|
||||
This behavior is inspired from foxes.
|
||||
|
||||
### Features
|
||||
|
||||
- Entity sleeps when feels safe, far from mobs or when the weather is not a thunderstorm.
|
||||
- Approaching the entity will make it wake up unless it's a trusted or sneaking player, or it's another entity with the family group `sleeping_entity`.
|
||||
- If entity is hurt, it wakes up.
|
||||
|
||||
### Behavior Pack
|
||||
|
||||
In this section behavior pack components will be discussed.
|
||||
|
||||
#### Components
|
||||
|
||||
For this behavior you will need only one component:
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.nap": {
|
||||
"priority": 8,
|
||||
"cooldown_min": 2.0,
|
||||
"cooldown_max": 7.0,
|
||||
"mob_detect_dist": 12.0,
|
||||
"mob_detect_height": 6.0,
|
||||
"can_nap_filters": {
|
||||
"all_of": [
|
||||
{
|
||||
"test": "in_water",
|
||||
"subject": "self",
|
||||
"operator": "==",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"test": "on_ground",
|
||||
"subject": "self",
|
||||
"operator": "==",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"test": "is_underground",
|
||||
"subject": "self",
|
||||
"operator": "==",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"test": "weather_at_position",
|
||||
"subject": "self",
|
||||
"operator": "!=",
|
||||
"value": "thunderstorm"
|
||||
}
|
||||
]
|
||||
},
|
||||
"wake_mob_exceptions": {
|
||||
"any_of": [
|
||||
{
|
||||
"test": "trusts",
|
||||
"subject": "other",
|
||||
"operator": "==",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"test": "is_family",
|
||||
"subject": "other",
|
||||
"operator": "==",
|
||||
"value": "sleeping_entity"
|
||||
},
|
||||
{
|
||||
"test": "is_sneaking",
|
||||
"subject": "other",
|
||||
"operator": "==",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to also use the trusting mechanic, add:
|
||||
|
||||
<CodeHeader>BP/entities/sleeping_entity.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:trust": {}
|
||||
```
|
||||
|
||||
### Resource Pack
|
||||
|
||||
In our resource pack you can run an animation when entity starts to sleep.
|
||||
|
||||
<CodeHeader>RP/animations_controllers/ac.sleeping_entity.sleep.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.10.0",
|
||||
"animation_controllers": {
|
||||
"controller.animation.sleeping_entity.sleep": {
|
||||
"initial_state": "default",
|
||||
"states": {
|
||||
"default": {
|
||||
"transitions": [
|
||||
{
|
||||
"sleep": "q.is_sleeping"
|
||||
}
|
||||
]
|
||||
},
|
||||
"sleep": {
|
||||
"animations": ["sleeping"],
|
||||
"transitions": [
|
||||
{
|
||||
"default": "!q.is_sleeping"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The last thing, you will have to create and register a sleeping animation for you entity. If you don't know how to do it check out the [BlockBench page](/guide/blockbench.html#animating).
|
||||
90
docs/wiki/3-实体/2-巧思案例/solid-entities.md
Normal file
90
docs/wiki/3-实体/2-巧思案例/solid-entities.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Solid Entities
|
||||
category: Tutorials
|
||||
tags:
|
||||
- recipe
|
||||
- intermediate
|
||||
mentions:
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- Chikorita-Lover
|
||||
- Luthorius
|
||||
- MedicalJewel105
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
Solid entities are entities that the player can bump into, step on, or otherwise physically interact with without passing through. Entities like this have many uses, such as emulating blocks.
|
||||
|
||||
This page will discuss some of the ways that solid entities can be created.
|
||||
|
||||
Not all techniques are ideal for all scenarios. Experiment, and figure out what works best for you.
|
||||
|
||||
## Runtime Identifiers
|
||||
|
||||
[Runtime identifiers](/entities/runtime-identifier) can be used to achieve solid entities, but currently only 2, each with a specific shape, and their own side effects. Neither collision shapes are possible to change or scale.
|
||||
|
||||
### Boat
|
||||
|
||||
<CodeHeader>BP/entities/entity_name.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.0",
|
||||
"minecraft:entity": {
|
||||
"description": {
|
||||
"identifier": "wiki:solid_entity",
|
||||
"runtime_identifier": "minecraft:boat"
|
||||
. . .
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Boat-shaped solid collision
|
||||
- Certain other boat-like effects
|
||||
|
||||
### Shulker
|
||||
|
||||
<CodeHeader>BP/entities/entity_name.json</CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.16.0",
|
||||
"minecraft:entity": {
|
||||
"description": {
|
||||
"identifier": "wiki:solid_entity",
|
||||
"runtime_identifier": "minecraft:shulker"
|
||||
. . .
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- 1x1 block sized solid collision.
|
||||
- Sticks to block grid.
|
||||
- Teleports randomly when supporting block removed.
|
||||
|
||||
## minecraft:is_stackable
|
||||
|
||||
Add `minecraft:is_stackable` to your entity you want to be treated as being solid.
|
||||
**Note:** This requires editing `player.json` if you wish the entity to be solid for the player.
|
||||
|
||||
`"minecraft:is_stackable": {}`
|
||||
|
||||
You will also need to add `minecraft:push_through` and set its `value` parameter to 1.
|
||||
|
||||
`"minecraft:push_through": 1`
|
||||
|
||||
(they should both go in `components`)
|
||||
|
||||
## Faking it with blocks
|
||||
|
||||
In some scenarios, it's probably better to `/setblock` or `/fill` to place barrier blocks, either statically or dynamically. There needs to be both a way of placing the barriers, and removing them.
|
||||
|
||||
`/fill ~ ~ ~ ~ ~1 ~ barrier 0 replace air`
|
||||
Places barriers in a 1x1x2 area.
|
||||
|
||||
`/fill ~1 ~1 ~1 ~-1 ~-1 ~-1 air 0 replace barrier`
|
||||
Removes barriers within a 3x3x3 area.
|
||||
|
||||
These [commands](/animation-controllers/entity-commands) will have to be triggering at a constant rate, for consistency. They can either be triggered through entity components, or animation controllers.
|
||||
320
docs/wiki/3-实体/2-巧思案例/timers.md
Normal file
320
docs/wiki/3-实体/2-巧思案例/timers.md
Normal file
@@ -0,0 +1,320 @@
|
||||
---
|
||||
title: Entity Timers
|
||||
category: Tutorials
|
||||
tags:
|
||||
- intermediate
|
||||
mentions:
|
||||
- SirLich
|
||||
- Joelant05
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- Justash01
|
||||
- TheItsNameless
|
||||
- zheaEvyline
|
||||
---
|
||||
|
||||
Time-based interactions are extremely useful tools for map making. This article hopes to provide an extensive list which details the many ways which timers can be made. For convenience, this page will be split up into two main sections: component-based timers and animation-based timers. Each has their own advantages and disadvantages, which will be outlined in their respective sections.
|
||||
You might also find useful [Scoreboard Timers](/commands/scoreboard-timers).
|
||||
|
||||
## Component-based timers
|
||||
|
||||
Component-based timers are done inside the entity.json file of the behavior pack. They have the distinct advantage of persisting upon the entity being reloaded, but are limited by the number of timing components (duplicate components replace each other, which means defining multiple timers using the `minecraft:timer` component isn't possible).
|
||||
|
||||
### minecraft:timer
|
||||
|
||||
This is the simplest but most effective component for triggering events after an elapsed amount of time. The component [minecraft:timer](https://bedrock.dev/docs/1.14.0.0/1.14.30.2/Entities#minecraft:timer) provides three main ways in which the amount of time before the event can be defined:
|
||||
|
||||
- Exact timing: an exact amount of time after which the event will fire is defined (e.g. 3.4 seconds)
|
||||
- Random interval: an interval is defined in which the event will fire at a random time inside that interval (e.g. between 3 to 5 seconds)
|
||||
- Weighted random choice: a number of times are defined and assigned weights, one of which will be chosen for the event to fire (e.g. a 20% chance for the event to fire at 5 seconds, and an 80% chance to fire at 20 seconds)
|
||||
|
||||
In the vanilla Behavior Pack, this component is used in all kinds of circumstances. For example:
|
||||
|
||||
- The dolphin can only spend 20 seconds on land before it dries out
|
||||
- Bees will perish between 10 and 60 seconds after stinging
|
||||
- The wandering trader will only stay for either 2400 or 3600 seconds
|
||||
|
||||
A simple example which triggers an event after 5.6 seconds:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:timer": {
|
||||
"time": 5.6,
|
||||
"time_down_event": {
|
||||
"event": "wiki:my_event"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A more complex example which triggers an event after a randomized amount of delay using weighted values:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:timer": {
|
||||
"looping": false, //true will fires event after every execution, false will fire event only once.
|
||||
"random_time_choices": [
|
||||
{
|
||||
"weight": 25,
|
||||
"value": 0.5 //Half a second of delay
|
||||
},
|
||||
{
|
||||
"weight": 25,
|
||||
"value": 10 //Ten seconds of delay
|
||||
},
|
||||
{
|
||||
"weight": 25,
|
||||
"value": 30 //Thirty seconds of delay
|
||||
},
|
||||
{
|
||||
"weight": 25,
|
||||
"value": 120 //2 minutes of delay
|
||||
}
|
||||
],
|
||||
"time_down_event": {
|
||||
"event": "wiki:event",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A particularly useful way to handle time events is using a single, looping `minecraft:timer` component and processing the events on each tick (or however often you decide to fire the timer). This is done by using the `randomize` parameter in events, where a weight may be used determine how often other events will be run. This can get you a lot of extra mileage out of a single timer component.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"wiki:do_event": {
|
||||
"randomize": [
|
||||
{
|
||||
"weight": 1,
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"wiki:my_event"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"weight": 5,
|
||||
"add": {
|
||||
"component_groups": [
|
||||
"wiki:my_more_frequent_event"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"weight": 50 //Fires nothing
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:environment_sensor
|
||||
|
||||
Another component ([minecraft:environment_sensor](https://bedrock.dev/docs/stable/Entities#minecraft:environment_sensor)) which can be very useful for time-based events is `minecraft:environment_sensor`. Pairing this sensor with the `hourly_clock_time` or `clock_time` filters can be used to trigger events based off in-game time.
|
||||
|
||||
Here is an example which is used to fire an event 800 ticks after the start of the day (valid range is 0 to 24000):
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:environment_sensor": {
|
||||
"triggers": [
|
||||
{
|
||||
"filters": {
|
||||
"test": "hourly_clock_time",
|
||||
"operator": "=",
|
||||
"value": 800
|
||||
},
|
||||
"event": "wiki:my_daily_event"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### minecraft:ageable
|
||||
|
||||
If this component ([minecraft:ageable](https://bedrock.dev/docs/stable/Entities#minecraft:ageable)) is not being used in the entity's behavior for a different purpose, it can be useful as an additional timer. It's important to note that it requires the `minecraft:is_baby` component to be defined in order to function.
|
||||
|
||||
Here is an example which fires an event after four seconds:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:is_baby": {},
|
||||
"minecraft:ageable": {
|
||||
"duration": 4,
|
||||
"grow_up": {
|
||||
"event": "wiki:my_other_event",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Other dummy-timers:
|
||||
|
||||
Taking a peak at the docs suggest there are other components which can also can be used for timing. Essentially, you are looking for any component with a "time down event" or a "duration".
|
||||
|
||||
Non-exhaustive list of promising examples:
|
||||
|
||||
- `minecraft:angry` (requires the entity to have a target, time must be an integer)
|
||||
- `minecraft.behavior.hide`
|
||||
- `minecraft:behavior.celebrate`
|
||||
|
||||
## Animation-based timers
|
||||
|
||||
Behavior pack animations are an extremely powerful tool for triggering time-based events. They have the distinct advantage of providing an "infinite" amount of timers, but are restarted upon an entity being reloaded (leaving and rejoining the world or the chunk containing the entity unloading will cause the timer to restart when the entity reloads).
|
||||
|
||||
Animations function differently in behavior packs than in resource packs. If you are unfamiliar with how they operate, it is recommended to learn more about them by checking out the official documentation or the other pages on this wiki.
|
||||
|
||||
### Simple timers
|
||||
|
||||
By triggering animations from an animation controller or directly from the scripts section, you can execute specific events, commands, or molang expressions in a timed-sequence, called a timeline.
|
||||
|
||||
You can set up timelines like this:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
{
|
||||
"format_version": "1.8.0",
|
||||
"animations": {
|
||||
"animation.command.example_timeline": {
|
||||
"timeline": {
|
||||
"0.0": "/say this will trigger instantly",
|
||||
"3.0": "/say this will trigger after 3 seconds"
|
||||
},
|
||||
"animation_length": 3.1
|
||||
},
|
||||
"animation.command.example_timeline_2": {
|
||||
"timeline": {
|
||||
"100": "/say this will trigger after 100 seconds",
|
||||
"0.0": [
|
||||
"/say you can trigger multiple events at once",
|
||||
"/say by using timelines."
|
||||
],
|
||||
"55.55": "/say this will trigger after 55.55 seconds."
|
||||
},
|
||||
"animation_length": 100.1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Random interval
|
||||
|
||||
A very useful feature of the timer component is its ability to define a random interval in which the event will be triggered. This functionality can be replicated using animations and a controller. Below is an example of an animation triggered by adding the `minecraft:is_sheared` component to an entity which randomly fires an event between 2 to 7 seconds after activation. Animation and controller version 1.10.0.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.shanewolf.random_interval": {
|
||||
"initial_state": "inactive",
|
||||
"states": {
|
||||
"inactive": {
|
||||
"transitions": [
|
||||
{
|
||||
"active": "q.is_sheared"
|
||||
}
|
||||
]
|
||||
},
|
||||
"active": {
|
||||
"on_entry": [
|
||||
"v.random_interval = math.random(2, 7);",
|
||||
"/say random interval started"
|
||||
],
|
||||
"animations": [
|
||||
"wiki:animate_interval"
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"inactive": "q.anim_time >= v.random_interval"
|
||||
}
|
||||
],
|
||||
"on_exit": [
|
||||
"@s wiki:stop_random_interval",
|
||||
"/say random interval finished"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"animation.shanewolf.random_interval": {
|
||||
"animation_length": 100
|
||||
}
|
||||
```
|
||||
|
||||
Explanation: Upon entry into the state beginning the animation, a variable is given a random value between 2 and 7. The animation finishes when the current animation time is greater than or equal to the value of this v.
|
||||
|
||||
**Notes**:
|
||||
- The animation length can be set to any value greater than the maximum end of the time range (100 is used as a general template)
|
||||
- math.random(a, b) is used to trigger an event in the range [a, b]
|
||||
- math.floor(math.random(a, b.99)) may be used to end the timer at integer values (0.99 must be added to b)
|
||||
- Any events or commands to run when the animation is finished are put inside on_exit
|
||||
|
||||
### Weighted random choice
|
||||
|
||||
Another useful feature of the timer component is its ability to trigger events at a time determined by a weighted list of values. This functionality can also be replicated using animations and a controller. Below is an example of an animation triggered by adding the `minecraft:is_charged` component to an entity which randomly fires an event at either 2, 5, or 9 seconds with weights of 30, 60, and 10, respectively. Animation and controller version 1.10.0.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"controller.animation.shanewolf.random_choices": {
|
||||
"initial_state": "inactive",
|
||||
"states": {
|
||||
"inactive": {
|
||||
"transitions": [
|
||||
{
|
||||
"active": "q.is_powered"
|
||||
}
|
||||
]
|
||||
},
|
||||
"active": {
|
||||
"on_entry": [
|
||||
"v.random_choices = math.random(0, 100);",
|
||||
"/say random interval started"
|
||||
],
|
||||
"animations": [
|
||||
"wiki:animate_choices"
|
||||
],
|
||||
"transitions": [
|
||||
{
|
||||
"inactive": "q.anim_time >= 2.0 && v.random_choices < 30"
|
||||
},
|
||||
{
|
||||
"inactive": "q.anim_time >= 5.0 && v.random_choices < 90"
|
||||
},
|
||||
{
|
||||
"inactive": "q.anim_time >= 9.0 && v.random_choices <= 100"
|
||||
}
|
||||
],
|
||||
"on_exit": [
|
||||
"@s wiki:stop_random_choices",
|
||||
"/say random choices finished"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"animation.shanewolf.random_choices": {
|
||||
"animation_length": 100
|
||||
}
|
||||
```
|
||||
|
||||
Explanation: Upon entry into the state beginning the animation, a variable is given a random value between 0 and 100 (sum of the weights). The transitions are laid out with the list of values ordered from the smallest time to the largest time. This is done so multiple && operators are not required in the latter transitions to define the variable's range (the query for the smallest times return true first and have their weights checked before the others--flipping 2 and 5 would result in 2 mistakenly having a weight of 90 instead of 30). The animation finishes when the current animation time is greater than or equal to a time in the list and the value of the random variable falls within that time's defined weight range.
|
||||
|
||||
**Notes**:
|
||||
- The animation length can be set to any value greater than the maximum end of the time range (100 is used as a general template)
|
||||
- For this particular format to work, order the list of valid times from smallest to largest
|
||||
- To assign a weight to a time in the list, add the weight to the value the randomized variable must be less than in the list's previous entry (e.g. 5 seconds has a weight of 90 - 30 = 60)
|
||||
- Any events or commands to run when the animation is finished are put inside on_exit
|
||||
|
||||
Hopefully this spread some light on the subject of handling time in Minecraft Bedrock! As shown above, there are many possible ways it can be done, each with their own pros and cons. If you have any other useful methods for creating time-based events, please [contribute to the wiki](/contribute)!
|
||||
357
docs/wiki/3-实体/2-巧思案例/village-mechanic.md
Normal file
357
docs/wiki/3-实体/2-巧思案例/village-mechanic.md
Normal file
@@ -0,0 +1,357 @@
|
||||
---
|
||||
title: Village Mechanic
|
||||
category: Tutorials
|
||||
mentions:
|
||||
- AeroForta
|
||||
- MedicalJewel105
|
||||
- stirante
|
||||
- SmokeyStack
|
||||
- SirLich
|
||||
- Ciosciaa
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
This article is for anyone who wants to try imitate the village mechanic for their entities
|
||||
|
||||
## Navigation Behavior
|
||||
|
||||
First let's start with some basic navigation behavior.
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:preferred_path":{
|
||||
"max_fall_blocks":1,
|
||||
"jump_cost":5,
|
||||
"default_block_cost":1.5,
|
||||
"preferred_path_blocks":[
|
||||
{
|
||||
"cost":0,
|
||||
"blocks":[
|
||||
"grass_path"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cost":1,
|
||||
"blocks":[
|
||||
"cobblestone",
|
||||
"stone"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cost":50,
|
||||
"blocks":[
|
||||
"bed",
|
||||
"lectern"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Allows entity to do random walk.
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.random_stroll":{
|
||||
"priority":9,
|
||||
"speed_multiplier":0.55,
|
||||
"xz_dist":10,
|
||||
"y_dist":5
|
||||
}
|
||||
```
|
||||
|
||||
Make entity return to inside dwelling bound, in this case inside a village border. Requiring minecraft:dweller component that will be explained below.
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.move_towards_dwelling_restriction": {
|
||||
"priority": 4,
|
||||
"speed_multiplier": 1.0
|
||||
}
|
||||
```
|
||||
|
||||
Makes entity navigate around a village by creating a path to patrol. Used by Iron Golem.
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.move_through_village": {
|
||||
"priority": 3,
|
||||
"speed_multiplier": 0.6,
|
||||
"only_at_night": true
|
||||
}
|
||||
```
|
||||
|
||||
Allows entity to enter a building and also take shelter when raining. Needs open door capabilities.
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.move_indoors":{
|
||||
"priority":5
|
||||
}
|
||||
```
|
||||
|
||||
Makes entity stay indoors while sun is down.
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.restrict_open_door":{
|
||||
"priority": 5
|
||||
}
|
||||
```
|
||||
|
||||
Use in pair with:
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:annotation.open_door":{
|
||||
"priority": 5
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:navigation.walk":{
|
||||
"can_pass_doors":true,
|
||||
"can_open_doors":true
|
||||
}
|
||||
```
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.open_door":{
|
||||
"priority":6,
|
||||
"close_door_after":true
|
||||
}
|
||||
```
|
||||
|
||||
## Main Behavior
|
||||
|
||||
<CodeHeader>BP/entities/custom_villager.json#components</CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:dweller": {
|
||||
"dwelling_type": "village",
|
||||
"dweller_role": "inhabitant",
|
||||
"preferred_profession": "farmer",
|
||||
"update_interval_base": 60,
|
||||
"update_interval_variant": 40,
|
||||
"can_find_poi": true,
|
||||
"can_migrate": true,
|
||||
"first_founding_reward": 5
|
||||
}
|
||||
```
|
||||
|
||||
- `dweller_role: inhabitant`
|
||||
Allows entity claim a bed and bell.
|
||||
`minecraft:behavior.sleep` needed.
|
||||
- `preferred_profession: farmer`
|
||||
Optional for `minecraft:behavior.work`
|
||||
- `can_find_poi`
|
||||
Add it so entity is able to find point of interest.
|
||||
Known POI types:
|
||||
|
||||
```
|
||||
bed
|
||||
jobsite
|
||||
meeting_area
|
||||
```
|
||||
|
||||
- `can_migrate`
|
||||
Defines if entity can migrate from one village to another or not.
|
||||
|
||||
### Sleep
|
||||
|
||||
You can find out how to make your entity sleep [here](/entities/sleeping-entities).
|
||||
|
||||
### Work
|
||||
|
||||
Requires "dweller_role" set to be "inhabitant" also if "preferred_profession" doesn't exist the entity will try to move to the closest any job site.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:behavior.work": {
|
||||
"priority": 4,
|
||||
"active_time": 250,
|
||||
"speed_multiplier": 0.5,
|
||||
"goal_cooldown": 200,
|
||||
"sound_delay_min": 100,
|
||||
"sound_delay_max": 200,
|
||||
"can_work_in_rain": false,
|
||||
"work_in_rain_tolerance": 1000,
|
||||
"on_arrival": {
|
||||
"event": "minecraft:resupply_trades",
|
||||
"target": "self"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Gathering
|
||||
|
||||
Allows the entity to gather.
|
||||
Requires "dweller_role" set to be "inhabitant".
|
||||
|
||||
```json
|
||||
"minecraft:behavior.mingle": {
|
||||
"priority": 4,
|
||||
"speed_multiplier": 0.5,
|
||||
"duration": 30,
|
||||
"cooldown_time": 10,
|
||||
"mingle_partner_type": "my:custom_entity",
|
||||
"mingle_distance": 2.0
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Scheduler
|
||||
|
||||
Now you know everything about needed mechanic, let's try to put all of this together in "minecraft:scheduler"
|
||||
First let's do something simple.
|
||||
Put work behavior in component group work like this:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"component_groups":{
|
||||
"work_schedule":{
|
||||
"minecraft:behavior.work":{
|
||||
"priority":4,
|
||||
"active_time":250,
|
||||
"speed_multiplier":0.5,
|
||||
"goal_cooldown":200,
|
||||
"sound_delay_min":100,
|
||||
"sound_delay_max":200,
|
||||
"can_work_in_rain":true,
|
||||
"work_in_rain_tolerance":1000,
|
||||
"on_arrival":{
|
||||
"event":"minecraft:resupply_trades",
|
||||
"target":"self"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gather_schedule":{
|
||||
"minecraft:behavior.mingle":{
|
||||
"priority": 5,
|
||||
"speed_multiplier": 0.8,
|
||||
"cooldown_time":10.0,
|
||||
"duration": 30.0,
|
||||
"mingle_dist": 1.5,
|
||||
"mingle_partner_type": "my:custom_entity"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Next, make your entity work.
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"minecraft:scheduler":{
|
||||
"min_delay_secs":0,
|
||||
"max_delay_secs":10,
|
||||
"scheduled_events":[
|
||||
{
|
||||
"filters":{
|
||||
"all_of":[
|
||||
{
|
||||
"test":"hourly_clock_time",
|
||||
"operator":">=",
|
||||
"value":0 //Morning
|
||||
},
|
||||
{
|
||||
"test":"hourly_clock_time",
|
||||
"operator":"<",
|
||||
"value":12000 //Evening
|
||||
}
|
||||
]
|
||||
},
|
||||
"event":"work"
|
||||
},
|
||||
{
|
||||
"filters":{
|
||||
"all_of":[
|
||||
{
|
||||
"test":"hourly_clock_time",
|
||||
"operator":">=",
|
||||
"value":21000
|
||||
},
|
||||
{
|
||||
"test":"hourly_clock_time",
|
||||
"operator":"<",
|
||||
"value":24000
|
||||
}
|
||||
]
|
||||
},
|
||||
"event":"gather"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The events section looks something like this:
|
||||
|
||||
<CodeHeader></CodeHeader>
|
||||
|
||||
```json
|
||||
"events":{
|
||||
"work":{
|
||||
"remove":{
|
||||
"component_groups":[
|
||||
"gather_schedule"
|
||||
]
|
||||
},
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"work_schedule"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gather":{
|
||||
"remove":{
|
||||
"component_groups":[
|
||||
"work_schedule"
|
||||
]
|
||||
},
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"gather_schedule"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Open your world, spawn entity then put a bed and you should see green particle.
|
||||
|
||||
## Other Behavior
|
||||
|
||||
All of this is usable by custom entities:
|
||||
- `minecraft:behavior.move_to_village`
|
||||
Used by Pillager this may keep the entity to stay in the village.
|
||||
- `minecraft:behavior.stroll_towards_village`
|
||||
Used by fox to search a village and go there.
|
||||
- `minecraft:behavior.inspect_bookshelf`
|
||||
Used by librarian villager allows an entity to look at and inspect a bookshelf.
|
||||
- `minecraft:behavior.explore_outskirts`
|
||||
Allows entity to explore beyond the bounds of village (use schedule and component group to keep the entity return to the village).
|
||||
- `minecraft:behavior.defend_village_target`
|
||||
Use this on melee attack. Ranged attack can accidentally shoot any entity with inhabitant dwelling role.
|
||||
|
||||
All of this can be used by custom entities and have relation to villager or village:
|
||||
| Behavior | Uses | Note |
|
||||
| ------------------------------------------ | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| `minecraft:behavior.defend_village_target` | Allows entity to attack other entity that hurt the entity who had "dweller_role": "inhabitant". | Recommended to use only on entities with melee attack. |
|
||||
| `minecraft:behavior.hide` | Used by villager to hide and stay at defined POI. | Currently, there is no documentation for the POI type that's why I recommend not to change `"poi_type": "bed"`. |
|
||||
| `minecraft:behavior.move_to_village` | Used by Illager and also witch. Allows entity to travel to a random x,y,z coordinate in a village. | - |
|
||||
| `"minecraft:behavior.nap"` | Used by Fox to take a nap. | Similar with sleep but offers more flexibility also has built-in wake up system by detecting specific entity. |
|
||||
80
docs/wiki/3-实体/3-文档/dummy-components.md
Normal file
80
docs/wiki/3-实体/3-文档/dummy-components.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: 虚拟组件
|
||||
category: 文档
|
||||
mentions:
|
||||
- SirLich
|
||||
- jigarbov
|
||||
- MedicalJewel105
|
||||
- StealthyExpertX
|
||||
- TheItsNameless
|
||||
---
|
||||
|
||||
# 虚拟组件
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::warning 弃用警告
|
||||
|
||||
'虚拟组件'是一个旧版概念,现已被[实体属性](https://learn.microsoft.com/en-us/minecraft/creator/documents/introductiontoentityproperties)取代。建议尽可能使用实体属性代替。
|
||||
:::
|
||||
|
||||
虚拟组件是仅用于数据存储的"无功能"组件。它们本身**不会**产生任何实际效果,需要配合其他机制才能发挥作用。这类组件的主要价值在于可将数据存储在实体上,并通过Molang查询来驱动图形/游戏机制。
|
||||
|
||||
典型案例包括 `variant`(变种)和 `mark_variant`(标记变种)。这些组件接受整数值设置,在原版资源包中用于定义猫和马匹的贴图选择。另一个典型案例是 `is_tamed`(驯服状态),用于控制马匹能否被骑乘。
|
||||
|
||||
虚拟组件的优势在于能够将数据与实体绑定,并通过Molang查询调用这些信息。
|
||||
|
||||
## 整型虚拟组件
|
||||
|
||||
整型组件存储整数值(例如1、10、1423),可使用Molang查询进行读取,是最常用的虚拟组件类型。
|
||||
|
||||
## 布尔型虚拟组件
|
||||
|
||||
布尔型组件存储单一状态信息,包括 `True`(真)和 `False`(假)。以 `is_tamed` 为例,组件存在表示为 `True`(已驯服),不存在则为 `False`(未驯服)。
|
||||
|
||||
## 组件列表
|
||||
|
||||
| 类型 | 查询语句 | 组件名称 | 备注 |
|
||||
| --------- | ------------------------------------------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **整型** | q.variant | minecraft:variant | |
|
||||
| **整型** | q.mark_variant | minecraft:mark_variant | |
|
||||
| **整型** | q.skin_id | minecraft:skin_id | |
|
||||
| **整型\*** | 使用类似 `"test": "is_color"` 的过滤器,下方提供颜色列表 | minecraft:color | 同时在材质系统中设置颜色 |
|
||||
| **整型\*** | 无对应过滤器语法,可使用 `"has_component"` | minecraft:color2 | 同时在材质系统中设置颜色 |
|
||||
| 布尔型 | q.is_illager_captain | minecraft:is_illager_captain | |
|
||||
| 布尔型 | q.is_baby | minecraft:is_baby | 禁用`minecraft:breedable`组件功能 |
|
||||
| 布尔型 | q.is_sheared | minecraft:is_sheared | |
|
||||
| 布尔型 | q.is_saddled | minecraft:is_saddled | |
|
||||
| 布尔型 | q.is_tamed | minecraft:is_tamed | |
|
||||
| 布尔型 | q.is_chested | minecraft:is_chested | 死亡时会掉落储存箱 |
|
||||
| 布尔型 | q.is_powered | minecraft:is_charged | |
|
||||
| 布尔型 | q.is_stunned | minecraft:is_stunned | |
|
||||
| 布尔型 | q.can_climb | minecraft:can_climb | 允许实体攀爬梯子 |
|
||||
| 布尔型 | q.can_fly | minecraft:can_fly | 标记实体具有飞行能力,路径查找器将不限于下方有固体方块的位置 |
|
||||
| 布尔型 | q.can_power_jump | minecraft:can_power_jump | 允许实体执行强力跳跃(如原版马匹动作) |
|
||||
| 布尔型 | q.is_ignited | minecraft:is_ignited | |
|
||||
| 布尔型 | q.out_of_control | minecraft:out_of_control | 新版功能,用于处理船体硬编码运动/粒子效果,Molang q查询可安全 |
|
||||
| 布尔型 | q.has_any_family('monster') | minecraft:type_family | 可检测指定Family类型(如'monster')返回布尔值
|
||||
|
||||
### color与color2组件颜色对照表
|
||||
|
||||
::: code-group
|
||||
```json [颜色代码]
|
||||
- black
|
||||
- blue
|
||||
- brown
|
||||
- cyan
|
||||
- gray
|
||||
- green
|
||||
- light_blue
|
||||
- light_green
|
||||
- magenta
|
||||
- orange
|
||||
- pink
|
||||
- purple
|
||||
- red
|
||||
- silver
|
||||
- white
|
||||
- yellow
|
||||
```
|
||||
:::
|
||||
140
docs/wiki/3-实体/3-文档/non-mob-runtime-identifiers.md
Normal file
140
docs/wiki/3-实体/3-文档/non-mob-runtime-identifiers.md
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: 非生物运行时标识符
|
||||
category: 文档
|
||||
mentions:
|
||||
- Ciosciaa
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# 非生物运行时标识符
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
_最后更新于1.19.10 版本_
|
||||
|
||||
非生物实体是用于游戏机制或实用功能的不常规实体。典型示例包括抛射物、运输类实体以及模拟方块的实体。这些运行时标识符的属性与普通生物实体有根本性不同,其特殊属性在某些场景下可能具有实用价值。
|
||||
|
||||
## 总览
|
||||
### 服务端属性
|
||||
| 属性 | 已注册 | 可配置行为 | 可配置碰撞箱 | 可配置方块碰撞 | 可配置重力 | 可配置实体推动性 | 可配置活塞推动性 | 支持传送门 | 生命值类型 | 可受伤害 | 可燃性 | 可击退 | 受效果影响 | 可选择 | 可挂钩 | 可锁定 | 可作为抛射体 | 可沿轨道移动 | 自动骑乘 | 可配置战利品 | 生成行为 |
|
||||
|------------------------------------------------------------|--------|------------|--------------|----------------|------------|------------------|------------------|------------|-------------------|----------|--------|--------|------------|--------|--------|--------|--------------|--------------|----------|--------------|----------------|
|
||||
| `minecraft:arrow` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:thrown_trident` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:snowball` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 抛射物 |
|
||||
| `minecraft:egg` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 抛射物 |
|
||||
| `minecraft:splash_potion` & `minecraft:lingering_potion` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 抛射物 |
|
||||
| `minecraft:ice_bomb` | ⚠️ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 抛射物 |
|
||||
| `minecraft:llama_spit` | ✅ | ❌ | ⚠️ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ⚠️ | ⚠️ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:fireball` | ✅ | ❌ | ⚠️ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ⚠️ | ⚠️ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:small_fireball` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:shulker_bullet` | ✅ | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ❌ | ❌ | ❌ | ⚠️ | ⚠️ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:dragon_fireball` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:wither_skull` & `minecraft:wither_skull_dangerous` | ✅ | ❌ | ⚠️ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ❌ | ❌ | ❌ | ⚠️ | ⚠️ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:ender_pearl` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 抛射物 |
|
||||
| `minecraft:fishing_hook` | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ | ❌ | 🐛 | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:xp_bottle` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 抛射物 |
|
||||
| `minecraft:boat` & `minecraft:chest_boat` | ✅ | ❌ | ✅ | ✅ | ⚠️ | ✅ | ❌ | ✅ | 结构完整性 | ✅ | ✅ | ❌ | ❌ | ✅ | ⚠️ | ❌ | ✅ | ⚠️ | ❌ | ⚠️ | 目标表面 |
|
||||
| `minecraft:minecart` & 变种 | ✅ | ❌ | ✅ | ❌ | ⚠️ | ❌ | ✅ | ✅ | 结构完整性 | ✅ | ✅ | ❌ | ❌ | ✅ | ⚠️ | ❌ | ⚠️ | ✅ | ❌ | ⚠️ | 轨道 |
|
||||
| `minecraft:balloon` | ⚠️ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:tnt` | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ⚠️ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:armor_stand` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 结构完整性 | ⚠️ | ✅ | ❌ | ✅ | ✅ | ✅ | ⚠️ | ✅ | ⚠️ | ✅ | ⚠️ | 目标表面 |
|
||||
| `minecraft:painting` | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ⚠️ | 无 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | 目标表面 |
|
||||
| `minecraft:falling_block` | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | 无 | ⚠️ | ✅ | ❌ | ❌ | ⚠️ | ⚠️ | ❌ | 🐛 | ❌ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:ender_crystal` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ⚠️ | ⚠️ | ❌ | ⚠️ | ❌ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:leash_knot` | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ⚠️ | 无 | ✅ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | 轨道 |
|
||||
| `minecraft:chalkboard` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 生命值 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ | 目标表面 |
|
||||
| `minecraft:tripod_camera` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 生命值 | ❌ | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ⚠️ | ✅ | ✅ | 目标表面 |
|
||||
| `minecraft:area_effect_cloud` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❓ | ❌ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:lightning_bolt` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:evocation_fang` | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:item` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | 物品 | ❌ | ⚠️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❓ | ⚠️ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:xp_orb` | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:fireworks_rocket` | ✅ | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ⚠️ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:eye_of_ender_signal` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | 无 | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ⚠️ | ✅ | ❌ | ✅ | 目标表面 |
|
||||
| `minecraft:elder_guardian_ghost` | ✅ | ⚠️ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 生命值 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 目标表面 |
|
||||
| `minecraft:npc` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 生命值 | ❌ | ✅ | ⚠️ | ❌ | ✅ | ❌ | ✅ | ✅ | ⚠️ | ❌ | ❌ | 目标表面 |
|
||||
| `minecraft:agent` | ❌ | ❌ | ⚠️ | ❌ | ❌ | ❌ | ✅ | ✅ | 生命值 | ✅ | ✅ | ❌ | ❌ | ⚠️ | ⚠️ | ✅ | ❌ | ✅ | ❌ | ⚠️ | 目标表面 |
|
||||
| `minecraft:shield` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | 生命值 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ | 目标表面 |
|
||||
|
||||
### 客户端属性
|
||||
| 属性 | 客户端实体 | 位置更新 | 插值移动 | 面向方向 | 阴影 | 死亡效果 | 踏步音效 |
|
||||
|------------------------------------------------------------|------------|----------|----------|----------|------|----------|----------|
|
||||
| `minecraft:arrow` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:thrown_trident` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
|
||||
| `minecraft:snowball` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:egg` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:splash_potion` & `minecraft:lingering_potion` | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:ice_bomb` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:llama_spit` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
|
||||
| `minecraft:fireball` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:small_fireball` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:shulker_bullet` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
|
||||
| `minecraft:dragon_fireball` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:wither_skull` & `minecraft:wither_skull_dangerous` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:ender_pearl` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:fishing_hook` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
|
||||
| `minecraft:xp_bottle` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:boat` & `minecraft:chest_boat` | ✅ | ✅ | ❌ | ❌ | ⚠️ | ❌ | ❌ |
|
||||
| `minecraft:minecart` & 变种 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:balloon` | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ |
|
||||
| `minecraft:tnt` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:armor_stand` | ✅ | ✅ | ✅ | ✅ | ❌ | ⚠️ | ✅ |
|
||||
| `minecraft:painting` | ❌ | ✅ | ❓ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:falling_block` | ⚠️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:ender_crystal` | ✅ | ❌ | ❌ | ❌ | ⚠️ | ❌ | ❌ |
|
||||
| `minecraft:leash_knot` | ✅ | ✅ | ❓ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:chalkboard` | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ | ✅ |
|
||||
| `minecraft:tripod_camera` | ✅ | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ |
|
||||
| `minecraft:area_effect_cloud` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:lightning_bolt` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:evocation_fang` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:item` | ❌ | ✅ | ✅ | ❌ | ⚠️ | ❌ | ❌ |
|
||||
| `minecraft:xp_orb` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:fireworks_rocket` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
||||
| `minecraft:eye_of_ender_signal` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
|
||||
| `minecraft:elder_guardian_ghost` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| `minecraft:npc` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| `minecraft:agent` | ⚠️ | ✅ | ❓ | ⚠️ | ⚠️ | ✅ | ✅ |
|
||||
| `minecraft:shield` | ✅ | ✅ | ✅ | ⚠️ | ✅ | ✅ | ✅ |
|
||||
|
||||
## 属性定义与章节说明
|
||||
本文档中使用的属性定义用于描述特定运行时标识符实体的行为特征。每个属性配有一个值及可能的附加说明,用以强调关联定义的异常情况。
|
||||
|
||||
大多数属性使用表情符号简短表达:
|
||||
| 值 | 说明 |
|
||||
|:---:|-------------------------------------------------------------------------|
|
||||
| ✅ | **激活/可用**<br>该属性在当前运行时标识符实体上通常处于活跃或可用状态。附加说明为特殊情况提供说明。 |
|
||||
| ⚠️ | **需警告**<br>该属性在特定条件下可用。标有此符号的属性可能需要特别处理。附加说明会细化具体例外情况。 |
|
||||
| ❌ | **未激活/不可用**<br>该属性在当前运行时标识符实体上不可用。附加说明会阐述实体如何处理该属性。 |
|
||||
| ❓ | **未知**<br>该属性的具体行为在当前上下文中尚未明确。 |
|
||||
| 🐛 | **存在漏洞**<br>该属性激活时会导致崩溃或其他错误。附加说明会具体描述漏洞触发条件。 |
|
||||
|
||||
### NBT扩展字段
|
||||
此部分列出该运行时标识符实体专用的NBT字段(其他实体不使用),字段用途通常在本体注释中说明。
|
||||
|
||||
### 特殊查询
|
||||
若Molang查询在当前运行时标识符上有特殊行为,则会在此说明。所有查询在服务端和客户端均可使用。
|
||||
|
||||
### 硬编码变量
|
||||
本节列出该运行时标识符绑定的硬编码Molang变量(若无声明则为未定义)。所有这些变量服务端和客户端均可使用。
|
||||
|
||||
### 特效
|
||||
本节描述与实体绑定的硬编码粒子或音效。除`minecraft:fireworks_rocket`外,其他效果可通过修改粒子/音效定义进行配置。
|
||||
|
||||
### 服务端属性
|
||||
服务端属性描述实体核心行为机制,包含位置、状态和交互等正规信息。
|
||||
|
||||
**已注册**
|
||||
当实体可通过`/summon`生成且`type`选择器能选中时视为已注册。只要`is_spawnable`为`true`,生成蛋始终可用。
|
||||
|
||||
**可配置行为**
|
||||
若为是,则该实体可使用通用行为组件(如`minecraft:behavior.panic`)。
|
||||
|
||||
**可配置碰撞箱**
|
||||
此属性激活时,`minecraft:collision_box`生效。某些运行时标识符会强制应用固定碰撞箱或修改碰撞箱计算方式。
|
||||
|
||||
**可配置方块碰撞**
|
||||
当激活时,`minecraft:physics`的`has_collision`生效。若实体声明了`minecraft:projectile`组件,此属性仍标记为活跃。
|
||||
|
||||
(由于长度限制,完整翻译内容超过单次响应限制,将分次响应。)
|
||||
422
docs/wiki/3-实体/3-文档/runtime-identifier.md
Normal file
422
docs/wiki/3-实体/3-文档/runtime-identifier.md
Normal file
@@ -0,0 +1,422 @@
|
||||
---
|
||||
title: 运行时标识符
|
||||
category: 文档
|
||||
mentions:
|
||||
- MedicalJewel105
|
||||
- aexer0e
|
||||
- Luthorius
|
||||
- SirLich
|
||||
- TheDoctor15
|
||||
- ChibiMango
|
||||
- stirante
|
||||
- epxzzy
|
||||
- IlkinQafarov
|
||||
- TheItsNameless
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
- Goatfu
|
||||
---
|
||||
|
||||
# 运行时标识符
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
`runtime_identifier` 是位于实体行为文件描述部分的可选参数,用于模拟原版实体的硬编码特性。
|
||||
它接受原版 Minecraft 标识符,例如 `minecraft:shulker`。
|
||||
|
||||
::: code-group
|
||||
```json [行为实体描述]
|
||||
"description": {
|
||||
"identifier": "wiki:my_box",
|
||||
"runtime_identifier": "minecraft:shulker", // 此运行时标识符会将潜影贝的硬编码行为附加到当前实体
|
||||
"is_spawnable": true,
|
||||
"is_summonable": true,
|
||||
"is_experimental": false
|
||||
}
|
||||
```
|
||||
|
||||
:::tip 注意
|
||||
需要注意 `runtime_identifier` **仅解析实体的硬编码特性**。这意味着使用100%数据驱动的生物作为运行时标识符不会给实体添加新特性。此外,某些实体运行时可能会覆盖组件部分定义的属性,例如潜影贝实体的碰撞箱尺寸。
|
||||
:::
|
||||
|
||||
:::warning 警告
|
||||
此处未列出所有运行时标识符效果。建议通过实验自行探索新效果,也欢迎在此补充发现。
|
||||
:::
|
||||
|
||||
## 已知的运行时标识符效果:
|
||||
|
||||
- 所有运行时ID都会将实体名称更改为对应原版实体的名称
|
||||
|
||||
### minecraft:area_effect_cloud
|
||||
|
||||
- 导致实体崩溃
|
||||
|
||||
---
|
||||
|
||||
### minecraft:armor_stand
|
||||
|
||||
- 禁用实体阴影
|
||||
- 击打时立即消失
|
||||
- 允许装备穿戴/卸除
|
||||
- 死亡时掉落盔甲架物品
|
||||
|
||||
---
|
||||
|
||||
### minecraft:arrow
|
||||
|
||||
- 为抛射物添加朝向玩家的动画
|
||||
- 禁用死亡动画/声音/粒子
|
||||
- 缩小实体阴影(但不会消失)
|
||||
- 不可交互
|
||||
- 通过生成蛋或/summon生成时,玩家接触后获得箭矢同时实体消失
|
||||
- 飞行物理特性和击退效果与箭矢一致
|
||||
|
||||
---
|
||||
|
||||
### minecraft:axolotl
|
||||
- 不影响游泳/移动/重力行为
|
||||
- 类似热带鱼,不同变种值影响水桶名称(如"亮蓝色美西螈桶"或"幼年黄色美西螈桶")
|
||||
年龄变种: 成年/幼年
|
||||
颜色变种: 亮色/野生/黄色/青色/蓝色
|
||||
|
||||
---
|
||||
|
||||
### minecraft:bee
|
||||
|
||||
- 添加蜜蜂音效
|
||||
|
||||
---
|
||||
|
||||
### minecraft:blaze
|
||||
|
||||
- 添加烈焰人燃烧音效和粒子
|
||||
- 实体将具有烈焰人飞行特性(即使未添加飞行行为)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:boat
|
||||
|
||||
- 骑乘时显示船型UI界面
|
||||
- 禁止实体旋转
|
||||
- 具有船形固体碰撞箱
|
||||
|
||||
---
|
||||
|
||||
### minecraft:chest_minecart
|
||||
|
||||
- 导致实体崩溃
|
||||
- 击打后立即消失
|
||||
- 生成状态异常
|
||||
- 掉落箱子和矿车
|
||||
|
||||
---
|
||||
|
||||
### minecraft:chicken
|
||||
|
||||
- 部分动画失效
|
||||
- 更新移动速度
|
||||
- 实体下落减缓但仍受掉落伤害
|
||||
- 生成时不携带装备(若原有)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:cod
|
||||
|
||||
- 脱离水体时扑腾
|
||||
- 使用水桶交互获得鳕鱼桶(放置时生成当前实体而非鳕鱼)
|
||||
- 赋予特殊游泳和重力特性
|
||||
|
||||
---
|
||||
|
||||
### minecraft:command_block_minecart
|
||||
|
||||
- 导致实体崩溃
|
||||
- 击打后立即消失
|
||||
- 生成状态异常
|
||||
- 掉落矿车
|
||||
|
||||
---
|
||||
|
||||
### minecraft:cow
|
||||
|
||||
- 部分动画失效
|
||||
- 更新移动速度
|
||||
- 生成时不携带装备(若原有)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:dolphin
|
||||
|
||||
- 添加 `minecraft:movement.dolphin` 组件
|
||||
|
||||
---
|
||||
|
||||
### minecraft:donkey
|
||||
|
||||
- 将纹理/模型/动画更换为驴子
|
||||
|
||||
---
|
||||
|
||||
### minecraft:dragon_fireball
|
||||
|
||||
- 完全破坏实体
|
||||
- 生成龙息火球尾迹粒子
|
||||
|
||||
---
|
||||
|
||||
### minecraft:egg
|
||||
|
||||
- 为抛射物添加朝向玩家的动画
|
||||
- 导致实体崩溃
|
||||
- 使用生成蛋生成时会出现在玩家位置而非指定位置,且面朝天空
|
||||
|
||||
---
|
||||
|
||||
### minecraft:elder_guardian
|
||||
|
||||
- 将纹理/模型/动画更换为远古守卫者
|
||||
- 改变部分行为特性
|
||||
|
||||
---
|
||||
|
||||
### minecraft:ender_crystal
|
||||
|
||||
- 实体将固定在生成方块的中央
|
||||
- 除传送外始终保持位置不变
|
||||
- 可放置于任何表面
|
||||
- 其他实体可穿透
|
||||
- 无法配置承受伤害
|
||||
- 无法改变朝向
|
||||
- 可复活末影龙
|
||||
- 生成时带火焰效果
|
||||
|
||||
---
|
||||
|
||||
### minecraft:ender_dragon
|
||||
|
||||
- 添加末影龙死亡特效
|
||||
- 继承末影龙碰撞箱
|
||||
- 破坏碰撞箱内所有方块(包括底部方块),建议在下方放置不可破坏方块/移除重力/禁用`mobGriefing`规则
|
||||
- 对碰撞箱2格范围内的玩家造成伤害
|
||||
- 增加渲染距离
|
||||
- 只能通过/kill指令消除
|
||||
|
||||
---
|
||||
|
||||
### minecraft:ender_pearl
|
||||
|
||||
- 破坏实体行为
|
||||
- 受伤时生成粒子
|
||||
|
||||
---
|
||||
|
||||
### minecraft:endermite
|
||||
|
||||
- 受伤时生成粒子
|
||||
- 导致旋转异常
|
||||
- 部分动画失效
|
||||
|
||||
---
|
||||
|
||||
### minecraft:evocation_fang
|
||||
|
||||
- 对接触实体造成伤害
|
||||
- 完全禁用碰撞
|
||||
|
||||
---
|
||||
|
||||
### minecraft:falling_block
|
||||
|
||||
- 导致实体崩溃并下落
|
||||
- 接触地面后无动画消失,掉落金合欢按钮
|
||||
- 移除效果附着能力
|
||||
|
||||
### minecraft:horse
|
||||
|
||||
- 将纹理/模型/动画更换为马匹
|
||||
|
||||
---
|
||||
|
||||
### minecraft:iron_golem
|
||||
|
||||
- 允许发动攻击(击退效果垂直增强)
|
||||
- 加速四肢动画(可手动修复为约1/4速度)
|
||||
- 可能与村庄/村民逻辑冲突
|
||||
|
||||
---
|
||||
|
||||
### minecraft:llama_spit
|
||||
|
||||
- 添加羊驼唾沫粒子
|
||||
|
||||
---
|
||||
|
||||
### minecraft:minecart
|
||||
|
||||
- 禁用实体阴影
|
||||
- 死亡时掉落矿车
|
||||
- 禁止实体旋转
|
||||
|
||||
---
|
||||
|
||||
### minecraft:panda
|
||||
|
||||
- 使`q.is_grazing`和`q.sit_mount`能与`minecraft:behavior.random_sitting`组件协同工作
|
||||
|
||||
---
|
||||
|
||||
### minecraft:parrot
|
||||
|
||||
- 启用翅膀扇动动画
|
||||
- 缓慢降落
|
||||
- 跟随音乐唱片跳舞
|
||||
|
||||
---
|
||||
|
||||
### minecraft:piglin
|
||||
|
||||
- 启用`minecraft:celebrate_hunt`功能(激活 q.is_celebrating)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:player
|
||||
|
||||
- 激活`q.movement_direction`
|
||||
|
||||
---
|
||||
|
||||
### minecraft:pufferfish
|
||||
|
||||
- 脱离水体时扑腾
|
||||
- 使用水桶交互获得河豚桶(放置时生成当前实体而非河豚)
|
||||
- 赋予特殊游泳和重力特性
|
||||
|
||||
---
|
||||
|
||||
### minecraft:salmon
|
||||
|
||||
- 脱离水体时扑腾
|
||||
- 使用水桶交互获得鲑鱼桶(放置时生成当前实体而非鲑鱼)
|
||||
- 赋予特殊游泳和重力特性
|
||||
|
||||
---
|
||||
|
||||
### minecraft:sheep
|
||||
|
||||
- 使`q.is_grazing`能与`behavior.eat_block`组件协同工作
|
||||
|
||||
---
|
||||
|
||||
### minecraft:shulker
|
||||
|
||||
冒险模式玩家的方块拟态神器
|
||||
|
||||
- 1x1x1固体碰撞箱
|
||||
- 固定于生成方块的中央
|
||||
- 附着方块被破坏后传送至附近可用位置
|
||||
- 在非完整方块(床/台阶等)上生成时自动传送
|
||||
- 无法修改碰撞箱尺寸
|
||||
|
||||
---
|
||||
|
||||
### minecraft:shulker_bullet
|
||||
|
||||
- 生成潜影贝导弹尾迹粒子
|
||||
|
||||
---
|
||||
|
||||
### minecraft:slime
|
||||
|
||||
- 下落时生成黏液粒子
|
||||
- 根据变体值分裂(1-5为史莱姆常规尺寸,5以上视为中型)
|
||||
- 允许攻击同时保持史莱姆跳跃机制(无此标识符时攻击状态无法转向)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:snowball
|
||||
|
||||
- 移除碰撞箱
|
||||
- 不可交互
|
||||
- 生成于玩家头部位置
|
||||
- 无视重力
|
||||
- 移除实体阴影
|
||||
- 恒定面朝南方
|
||||
- 无法发出踏步音效
|
||||
|
||||
---
|
||||
|
||||
### minecraft:spider
|
||||
|
||||
- 蛛网减速失效
|
||||
|
||||
---
|
||||
|
||||
### minecraft:skeleton
|
||||
|
||||
- 治疗效果造成伤害/瞬间伤害效果恢复生命
|
||||
- 亡灵杀手附魔增伤
|
||||
- 变体≥1时近战与远程攻击附加凋零效果
|
||||
|
||||
---
|
||||
|
||||
### minecraft:stray
|
||||
|
||||
- 治疗效果造成伤害/瞬间伤害效果恢复生命
|
||||
- 亡灵杀手附魔增伤
|
||||
- 免疫冰冻伤害
|
||||
|
||||
---
|
||||
|
||||
### minecraft:squid
|
||||
|
||||
- 支持特殊行为组件(参考squid.json)
|
||||
- 受伤时生成墨汁粒子
|
||||
|
||||
---
|
||||
|
||||
### minecraft:thrown_trident
|
||||
|
||||
- 为抛射物添加朝向玩家的动画
|
||||
- 禁用死亡动画/声音/粒子
|
||||
- 缩小实体阴影(但不会消失)
|
||||
- 不可交互
|
||||
- 飞行物理特性和击退效果与三叉戟一致
|
||||
|
||||
---
|
||||
|
||||
### minecraft:tropicalfish
|
||||
|
||||
- 脱离水体时扑腾
|
||||
- 赋予特殊游泳和重力特性
|
||||
- 使用水桶获得热带鱼桶(若无variant/mark_variant/color定义则为白色考伯鱼规格,含相关组件时桶名与实体规格对应)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:wither_skull_dangerous
|
||||
|
||||
- 死亡时掉落凋零玫瑰
|
||||
- 被击杀实体会在原地生成凋零玫瑰(僵尸类异常掉落)
|
||||
- 持续生成基础烟雾粒子
|
||||
- 无视重力(使projectile组件实体直线运动)
|
||||
- 免疫所有伤害
|
||||
- 仅对无AI目标的实体生效(适用于假人实体和弹射物)
|
||||
|
||||
---
|
||||
|
||||
### minecraft:xp_orb
|
||||
|
||||
- 完全禁用碰撞
|
||||
- 接触玩家增加经验值
|
||||
|
||||
### minecraft:zombie
|
||||
|
||||
- 治疗效果造成伤害/瞬间伤害效果恢复生命
|
||||
- 亡灵杀手附魔增伤
|
||||
|
||||
---
|
||||
|
||||
### minecraft:wither
|
||||
|
||||
- 死亡时爆炸
|
||||
|
||||
---
|
||||
194
docs/wiki/3-实体/3-文档/spawning-tamed-entities.md
Normal file
194
docs/wiki/3-实体/3-文档/spawning-tamed-entities.md
Normal file
@@ -0,0 +1,194 @@
|
||||
---
|
||||
title: 生成已驯服的实体
|
||||
category: 教程
|
||||
tags:
|
||||
- 中级
|
||||
mentions:
|
||||
- Axelpvz2030
|
||||
- aexer0e
|
||||
- SirLich
|
||||
- MedicalJewel105
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# 生成已驯服的实体
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
在本教程中,您将学习如何通过向特定玩家触发事件来生成预驯服的实体,以及如何投掷在撞击时变形为已驯服实体的物品。
|
||||
|
||||
## 概述
|
||||
|
||||
传统方式中,若要让玩家驯服实体,必须通过 `minecraft:tameable` 强制玩家与实体互动。但我们也可以利用原版弹射物会记录生成者*\*的特性来实现预驯服实体的生成。
|
||||
|
||||
具体实现步骤:
|
||||
1. 通过 `minecraft:spawn_entity` 生成一个中间态弹射物实体
|
||||
2. 该实体将立即转换为预驯服的目标实体(本教程以原版狼为例)
|
||||
3. 在 `minecraft:transformation` 组件中将 `keep_owner` 设置为 `true`
|
||||
|
||||
\*: 需要区分 _Spawn(生成)_ 和 _Summon(召唤)_ 的区别。只有通过生成蛋或 `minecraft:spawn_entity` 组件生成的弹射物才会记录玩家信息,使用 `/summon` 命令生成的则不会。
|
||||
|
||||
## player.json
|
||||
|
||||
我们需要对玩家行为文件进行微调,添加一个事件来激活组件组用于生成中间态实体。
|
||||
|
||||
您可以在 Mojang 提供的[原版行为包模板](https://aka.ms/behaviorpacktemplate)中找到玩家实体的行为文件。
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/player.json]
|
||||
{
|
||||
"format_version":"1.16.0",
|
||||
"minecraft:entity":{
|
||||
"description":{
|
||||
"identifier":"minecraft:player",
|
||||
"is_spawnable":false,
|
||||
"is_summonable":false,
|
||||
"is_experimental":false
|
||||
},
|
||||
"component_groups":{ // 组件组定义
|
||||
"wiki:spawn_tamed_wolf":{
|
||||
"minecraft:spawn_entity":{
|
||||
"entities":{
|
||||
"min_wait_time":0,
|
||||
"max_wait_time":0,
|
||||
"spawn_entity":"wiki:pretamed_wolf",
|
||||
"single_use":true,
|
||||
"num_to_spawn":1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
...
|
||||
"events":{ // 事件定义
|
||||
"wiki:spawn_tamed_wolf":{
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"wiki:spawn_tamed_wolf"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## pretamed_wolf.json
|
||||
|
||||
创建一个使用 `minecraft:arrow` 作为运行时标识符(也可选用其他弹射物标识符)的自定义实体,包含空白弹射物组件和用于转换为驯服狼的变形组件。
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/pretamed_wolf.json]
|
||||
{
|
||||
"format_version": "1.16.0",
|
||||
"minecraft:entity": {
|
||||
"description": {
|
||||
"identifier": "wiki:pretamed_wolf",
|
||||
"runtime_identifier": "minecraft:arrow",
|
||||
"is_spawnable": false,
|
||||
"is_summonable": true,
|
||||
"is_experimental": false
|
||||
},
|
||||
"components": { // 组件配置
|
||||
"minecraft:projectile": {}, // 弹射物组件
|
||||
"minecraft:transformation": { // 变形组件
|
||||
"into": "minecraft:wolf<minecraft:on_tame>",
|
||||
"keep_owner": true // 保持归属关系
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
现在即可通过命令 `/event entity @p wiki:spawn_tamed_wolf` 在玩家身边生成驯服的狼。若将 `is_spawnable` 设为 `true` 还可通过生成蛋调用!
|
||||
|
||||
:::warning 重要提示
|
||||
如需生成自定义实体而非原版狼:
|
||||
1. 必须为实体添加 `minecraft:is_tamed` 组件
|
||||
2. 未被驯服的实体可能出现预期外的行为
|
||||
:::
|
||||
|
||||
## 集成物品抛射物(替代方法)
|
||||
|
||||
利用 [1.16 实验性物品特性](/items/item-components) 中的 `shoot` 事件属性,可制作碰撞时转换为已驯服实体的弹射物。
|
||||
|
||||
::: code-group
|
||||
```json [BP/items/throwable_pretamed_wolf.json]
|
||||
{
|
||||
"format_version":"1.16.100",
|
||||
"minecraft:item":{
|
||||
"description":{
|
||||
"identifier":"wiki:throwable_pretamed_wolf"
|
||||
},
|
||||
"components":{ // 物品组件
|
||||
"minecraft:on_use":{
|
||||
"on_use":{
|
||||
"event":"wiki:on_use" // 使用事件触发
|
||||
}
|
||||
}
|
||||
},
|
||||
"events":{ // 事件配置
|
||||
"wiki:on_use":{
|
||||
"shoot":{
|
||||
"projectile":"wiki:pretamed_wolf" // 发射自定义弹射物
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
同时需修改弹射物实体的转化逻辑以避免即时变形:
|
||||
|
||||
::: code-group
|
||||
```json [BP/entities/pretamed_wolf.json]
|
||||
{
|
||||
"minecraft:entity":{
|
||||
"description":{
|
||||
"identifier":"wiki:pretamed_wolf",
|
||||
"runtime_identifier":"minecraft:arrow",
|
||||
"is_spawnable":false,
|
||||
"is_summonable":true,
|
||||
"is_experimental":false
|
||||
},
|
||||
"component_groups":{ // 组件组定义
|
||||
"wiki:transform_to_entity":{
|
||||
"minecraft:transformation":{
|
||||
"into":"minecraft:wolf<minecraft:on_tame>",
|
||||
"keep_owner":true
|
||||
}
|
||||
}
|
||||
},
|
||||
"components":{ // 组件配置
|
||||
"minecraft:projectile":{
|
||||
"on_hit":{ // 碰撞触发配置
|
||||
"impact_damage":{
|
||||
"damage":0 // 禁用伤害
|
||||
},
|
||||
"stick_in_ground":{}, // 插入地面
|
||||
"definition_event":{
|
||||
"event_trigger":{
|
||||
"event":"wiki:on_hit" // 碰撞事件触发
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"events":{ // 事件响应
|
||||
"wiki:on_hit":{
|
||||
"add":{
|
||||
"component_groups":[
|
||||
"wiki:transform_to_entity" // 添加变形组件组
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
特别感谢 [Zarkmend ZAN](https://twitter.com/Zarkmend_ZAN) 发现这一方法 :)
|
||||
20969
docs/wiki/3-实体/3-文档/vanilla-usage-components.md
Normal file
20969
docs/wiki/3-实体/3-文档/vanilla-usage-components.md
Normal file
File diff suppressed because it is too large
Load Diff
1383
docs/wiki/3-实体/3-文档/vanilla-usage-spawn-rules.md
Normal file
1383
docs/wiki/3-实体/3-文档/vanilla-usage-spawn-rules.md
Normal file
File diff suppressed because it is too large
Load Diff
47771
docs/wiki/3-实体/3-文档/vuc-full.md
Normal file
47771
docs/wiki/3-实体/3-文档/vuc-full.md
Normal file
File diff suppressed because it is too large
Load Diff
4500
docs/wiki/3-实体/3-文档/vusr-full.md
Normal file
4500
docs/wiki/3-实体/3-文档/vusr-full.md
Normal file
File diff suppressed because it is too large
Load Diff
155
docs/wiki/4-Json-UI/1-基础/best-practices.md
Normal file
155
docs/wiki/4-Json-UI/1-基础/best-practices.md
Normal file
@@ -0,0 +1,155 @@
|
||||
---
|
||||
title: 最佳实践
|
||||
category: 通用指南
|
||||
nav_order: 2
|
||||
tags:
|
||||
- 指南
|
||||
mentions:
|
||||
- LukasPAH
|
||||
- SmokeyStack
|
||||
- TheItsNameless
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# 最佳实践
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
:::tip 提示
|
||||
本文内容假定您已对JSON-UI系统有一定了解。如果您是JSON-UI的新手,请务必先阅读[JSON-UI介绍](/json-ui/json-ui-intro)和[JSON-UI文档](/json-ui/json-ui-documentation)。
|
||||
:::
|
||||
|
||||
## 最大化兼容性并减少UI崩溃的可能性
|
||||
|
||||
JSON-UI与其他附加包系统不同,因为**JSON-UI没有版本控制**。随着Mojang更新和修复JSON-UI系统,您对UI所做的任何修改都可能失效。幸运的是,您可以通过以下几种方法在Mojang更新原版UI时保持自定义UI的稳定性。
|
||||
|
||||
### 仅修改必要内容
|
||||
最有效的防崩溃策略是只修改需要调整的部分。例如若只需要禁用经验条阴影,正确做法应是在资源包中向`hud_screen.json`文件添加:
|
||||
|
||||
```json
|
||||
{
|
||||
"progress_text_label": {
|
||||
"shadow": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
这种极简修改方式能显著降低未来更新导致UI崩溃的风险,同时保持文件整洁并大幅缩小体积。**若您将整个原版UI文件复制到资源包中进行修改,说明您错误理解了JSON-UI的工作机制**。
|
||||
|
||||
### 善用修改策略
|
||||
使用[wiki文档中的修改策略](/json-ui/json-ui-intro#modifications)能有效降低更新风险。例如在HUD中添加自定义元素时,推荐使用修改数组操作而非直接插入控件:
|
||||
|
||||
::: code-group
|
||||
```json [正确做法]
|
||||
{
|
||||
"root_panel": {
|
||||
"modifications": [
|
||||
{
|
||||
"array_name": "controls",
|
||||
"operation": "insert_front",
|
||||
"value": [
|
||||
{
|
||||
"custom_ui@namespace.custom_ui": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
这种策略性合并方式能提升与其他资源包的兼容性,并减少因原版控件结构调整导致的崩溃风险。
|
||||
|
||||
### 避免修改深层嵌套控件
|
||||
修改嵌套层级过深的控件容易引发问题。推荐优先修改基础元素定义,必要时使用斜杠语法定位子控件:
|
||||
|
||||
::: code-group
|
||||
```json [推荐修改方式]
|
||||
{
|
||||
"panel_with_label_and_bg/bg_image": {
|
||||
"size": ["100%c", "100%c"]
|
||||
},
|
||||
"panel_with_label_and_bg/bg_image/label": {
|
||||
"layer": -5
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 使用单一入口点
|
||||
合并自定义UI时建议集中到单个入口点。例如将多个自定义控件统一插入`root_panel`:
|
||||
|
||||
::: code-group
|
||||
```json [优化后]
|
||||
{
|
||||
"root_panel": {
|
||||
"modifications": [
|
||||
{
|
||||
"array_name": "controls",
|
||||
"operation": "insert_front",
|
||||
"value": [
|
||||
{"custom_ui_1@ns1.control1": {}},
|
||||
{"custom_ui_2@ns1.control2": {}}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 避免使用原版命名空间
|
||||
开发大规模UI修改时,建议创建自定义[命名空间](/json-ui/json-ui-intro#namespaces)并使用前缀(如`wiki:namespace`)来防止命名冲突。通过`element@namespace.element`语法引用其他命名空间的元素。
|
||||
|
||||
## 性能优化指南
|
||||
|
||||
JSON-UI是仅次于实体的性能消耗大户。以下策略可帮助提升UI性能表现:
|
||||
|
||||
### 减少操作符使用
|
||||
[操作符](/json-ui/json-ui-intro#using-operators)会显著增加计算开销。优化示例:
|
||||
|
||||
```json
|
||||
"$var": "(-2 * $number)" // 优于 "(2 * (-1 * $number))"
|
||||
```
|
||||
|
||||
### 精简绑定数量
|
||||
每个[绑定](/json-ui/json-ui-intro#bindings)都会产生性能开销。建议:
|
||||
- 移除无效绑定
|
||||
- 合并相似功能绑定
|
||||
- 避免重复绑定相同数据
|
||||
|
||||
### 优化控件结构
|
||||
通过以下方式减少控件数量:
|
||||
1. 删除无用控件或添加`"ignored": true`
|
||||
2. 合并相似控件
|
||||
3. 使用条件渲染替代多个独立控件
|
||||
|
||||
::: code-group
|
||||
```json [优化前]
|
||||
// 5个独立图像控件
|
||||
"image_1@image_template": {
|
||||
"$texture": "textures/ui/example_1",
|
||||
"$binding_text": "1"
|
||||
}
|
||||
...
|
||||
```
|
||||
```json [优化后]
|
||||
// 单个动态图像控件
|
||||
"image": {
|
||||
"type": "image",
|
||||
"texture": "#texture",
|
||||
"bindings": [
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "('textures/ui/example_' + #hud_title_text_string)",
|
||||
"target_property_name": "#texture"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
**注意**:`"visible": false`不会阻止控件计算,应优先使用`"ignored": true`彻底禁用控件。
|
||||
|
||||
通过系统性优化,可显著提升UI响应速度并降低资源消耗,为玩家提供更流畅的游戏体验。
|
||||
837
docs/wiki/4-Json-UI/1-基础/json-ui-intro.md
Normal file
837
docs/wiki/4-Json-UI/1-基础/json-ui-intro.md
Normal file
@@ -0,0 +1,837 @@
|
||||
---
|
||||
title: JSON UI 入门指南
|
||||
category: 通用
|
||||
nav_order: 1
|
||||
tags:
|
||||
- guide
|
||||
mentions:
|
||||
- sermah
|
||||
- KalmeMarq
|
||||
- SirLich
|
||||
- solvedDev
|
||||
- Joelant05
|
||||
- GTB3NW
|
||||
- stirante
|
||||
- MedicalJewel105
|
||||
- r4isen1920
|
||||
- shanewolf38
|
||||
- LeGend077
|
||||
- mark-wiemer
|
||||
- TheItsNameless
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# JSON UI 入门指南
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
## 简介
|
||||
|
||||
:::warning
|
||||
JSON UI 已进入弃用阶段,推荐使用 [Ore UI](https://github.com/Mojang/ore-ui) 替代。请注意,任何使用 JSON UI 的附加包将在未来几年内失效。
|
||||
:::
|
||||
|
||||
:::tip
|
||||
本文概述了 JSON UI 的基础知识。如需更详细的文档,请查阅 [JSON UI 文档](/json-ui/json-ui-documentation)。
|
||||
:::
|
||||
|
||||
游戏用户界面采用数据驱动模式,支持自定义修改。通过 JSON UI 系统,我们可以调整用户界面的渲染方式及部分交互行为。所有原版 UI 文件均存储在 `RP/ui/...` 文件夹中。
|
||||
|
||||
JSON UI 可能包含以下文件类型:
|
||||
|
||||
### 系统文件
|
||||
|
||||
这些是 JSON UI 的内置文件:
|
||||
|
||||
- `_global_variables.json` - 存储全局变量定义
|
||||
- `_ui_defs.json` - 管理 UI 文件引用清单
|
||||
|
||||
### 屏幕文件
|
||||
|
||||
用于定义特定界面布局的文件:
|
||||
|
||||
- `hud_screen.json` - 显示包含快捷栏等游戏元素的 HUD 界面
|
||||
- `inventory_screen.json` - 玩家背包界面
|
||||
- 其他屏幕文件
|
||||
|
||||
### 模板文件
|
||||
|
||||
存储可复用 UI 组件的文件:
|
||||
|
||||
- `ui_common.json` - 包含通用组件(如设置界面的按钮模板)
|
||||
- `ui_template_*.json` - 模块化组织的组件集合
|
||||
|
||||
## UI 定义文件
|
||||
|
||||
`_ui_defs.json` 通过数组形式引用所有 JSON UI 文件。
|
||||
|
||||
例如新增 `RP/ui/button.json` 和 `RP/my_ui/main_menu.json` 时,应如下配置:
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/_ui_defs.json]
|
||||
{
|
||||
"ui_defs": ["ui/button.json", "my_ui/main_menu.json"]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
- 必须包含从资源包根目录开始的完整文件路径(包括 `.json` 扩展名)
|
||||
- 只需声明自建文件,无需包含原版或其他第三方文件
|
||||
- 支持非 `RP/ui/...` 路径的文件引用
|
||||
- 可使用非 `.json` 扩展名,但文件内容必须为合法 JSON
|
||||
|
||||
## 全局变量
|
||||
|
||||
在 `_global_variables.json` 中定义变量 `"$info_text_color"`:
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/_global_variables.json]
|
||||
{
|
||||
"$info_text_color": [0.8, 0.8, 0.8]
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
其他 UI 文件可调用此变量:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/my_ui/file1.json]
|
||||
{
|
||||
"some_info": {
|
||||
...
|
||||
"text": "Hey",
|
||||
"color": "$info_text_color"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json [vanilla/my_ui/file2.json]
|
||||
{
|
||||
"info": {
|
||||
...
|
||||
"text": "Information",
|
||||
"color": "$info_text_color"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
- 支持定义多个变量(逗号分隔)
|
||||
- 全局变量为单向常量,不可跨文件修改
|
||||
|
||||
## 命名空间
|
||||
|
||||
命名空间是 UI 文件的唯一标识符,用于跨文件引用元素。每个命名空间必须具有唯一名称。
|
||||
|
||||
示例命名空间 `one` 中的元素:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/file_a.json]
|
||||
{
|
||||
"namespace": "one",
|
||||
"foobar": {...}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
在命名空间 `two` 中引用:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/file_b.json]
|
||||
{
|
||||
"namespace": "two",
|
||||
"fizzbuzz@one.foobar": {...}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
跨命名空间引用格式:
|
||||
```json
|
||||
"[元素名称]@[命名空间].[被引用元素]"
|
||||
```
|
||||
|
||||
## 屏幕系统
|
||||
|
||||
屏幕文件包含游戏在特定场景调用的界面布局(如背包界面)。每个屏幕文件必须包含根元素供游戏直接访问。
|
||||
|
||||
屏幕文件具有数据访问隔离特性。
|
||||
|
||||
## UI 元素
|
||||
|
||||
UI 元素是 JSON UI 的基本组成单元,每个命名空间内的元素名称必须唯一。
|
||||
|
||||
示例文本元素:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/example_file.json]
|
||||
{
|
||||
"test_element": {
|
||||
"type": "label",
|
||||
"text": "Hello World"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 元素类型
|
||||
|
||||
常用元素类型 (`type` 属性值):
|
||||
|
||||
- `label` - 文本对象
|
||||
- `image` - 图像渲染
|
||||
- `button` - 交互按钮
|
||||
- `panel` - 层叠容器
|
||||
- `stack_panel` - 流式布局容器
|
||||
- `grid` - 网格模板渲染
|
||||
- `factory` - 动态元素生成器
|
||||
- `custom` - 自定义渲染器
|
||||
- `screen` - 根屏幕元素
|
||||
|
||||
## 动画系统
|
||||
|
||||
使用 `anim_type` 属性创建动画元素,可通过 `anims` 数组应用于其他元素。
|
||||
|
||||
示例动画元素:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/example_file.json]
|
||||
{
|
||||
"namespace": "example_nm",
|
||||
|
||||
"anim_size": {
|
||||
"anim_type": "size",
|
||||
"easing": "linear",
|
||||
"from": [ "100%", 27 ],
|
||||
"to": [ "100% + 3px", 30 ],
|
||||
"duration": 1.25
|
||||
},
|
||||
|
||||
"anim_alpha": {
|
||||
"anim_type": "alpha",
|
||||
"easing": "linear",
|
||||
"from": 1,
|
||||
"to": 0.5,
|
||||
"duration": 2
|
||||
},
|
||||
|
||||
"test_animated_element": {
|
||||
...
|
||||
"anims": [
|
||||
"@example_nm.anim_size",
|
||||
"@example_nm.anim_alpha"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 动画类型
|
||||
|
||||
支持动画类型 (`anim_type`):
|
||||
|
||||
- `alpha` - 透明度动画
|
||||
- `offset` - 位移动画
|
||||
- `size` - 尺寸动画
|
||||
- `flip_book` - 翻页动画
|
||||
- `uv` - UV 贴图动画
|
||||
- `color` - 颜色过渡
|
||||
- `wait` - 等待延时
|
||||
- `aseprite_flip_book` - 精灵表动画
|
||||
- `clip` - 裁剪动画
|
||||
|
||||
## 操作符系统
|
||||
|
||||
支持在属性中使用运算符,结合 `$变量` 和 `#绑定` 实现动态计算。
|
||||
|
||||
| 运算符 | 符号 | 示例 |
|
||||
|----------------------|------|----------------------------------------------------------------------|
|
||||
| 加法 | + | `"100% + 420px"` `($text + ' my')` |
|
||||
| 减法 | - | `"100% - 69px"` `($index - 13)` |
|
||||
| 乘法 | * | `($var * 9)` |
|
||||
| 除法 | / | `(#value / 2)` |
|
||||
| 等于 | = | `($var = 'text')` |
|
||||
| 大于 | > | `(#value > 13)` |
|
||||
| 小于 | < | `($var < 4)` |
|
||||
| 大于等于 | >= | `(#value >= 2)` |
|
||||
| 小于等于 | <= | `(#value <= 2)` |
|
||||
| 逻辑与 | and | `($cond1 and $cond2)` |
|
||||
| 逻辑或 | or | `($condA or $condB)` |
|
||||
| 逻辑非 | not | `(not #flag)` |
|
||||
|
||||
## 变量系统
|
||||
|
||||
除全局变量外,支持在元素内定义局部变量。
|
||||
|
||||
### 变量定义
|
||||
|
||||
使用 `$` 前缀定义变量,支持多种数据类型:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/example_file.json]
|
||||
{
|
||||
"test_element": {
|
||||
// 定义变量
|
||||
"$array_var": [10, 10],
|
||||
"$str_var": "foobar",
|
||||
|
||||
// 使用变量
|
||||
"size": "$array_var",
|
||||
"text": "$str_var",
|
||||
|
||||
// 动态引用模板
|
||||
"controls": [
|
||||
{ "foobar@$str_var": {} }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 变量继承
|
||||
|
||||
支持通过元素继承覆盖变量:
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/example_file.json]
|
||||
{
|
||||
"base_element": {
|
||||
"$var1": 1,
|
||||
"$var2": false
|
||||
},
|
||||
|
||||
"derived_element@base_element": {
|
||||
"$var1": 2 // 覆盖父元素变量
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 数据绑定
|
||||
|
||||
通过 `bindings` 实现数据源与元素的动态关联。
|
||||
|
||||
### 简单绑定
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/example_file.json]
|
||||
{
|
||||
"label": {
|
||||
"type": "label",
|
||||
"text": "#hardtext",
|
||||
"bindings": [
|
||||
{
|
||||
"binding_name": "#hardtext"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 重定向绑定
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/example_file.json]
|
||||
{
|
||||
"label": {
|
||||
"type": "label",
|
||||
"text": "#display_text",
|
||||
"bindings": [
|
||||
{
|
||||
"binding_name": "#source_data",
|
||||
"binding_name_override": "#display_text"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 跨元素绑定
|
||||
|
||||
::: code-group
|
||||
```json
|
||||
{
|
||||
"status_panel": {
|
||||
"bindings": [
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_control_name": "my_toggle",
|
||||
"source_property_name": "#state",
|
||||
"target_property_name": "#visible"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 条件渲染
|
||||
|
||||
通过变量和绑定实现动态显示控制。
|
||||
|
||||
### 变量条件
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/hud_screen.json]
|
||||
{
|
||||
"hud_actionbar_text/actionbar_message": {
|
||||
"$atext": "$actionbar_text",
|
||||
"visible": "(not ($atext = 'hello world'))"
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
### 工厂条件
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/hud_screen.json]
|
||||
{
|
||||
"conditional_image": {
|
||||
"type": "image",
|
||||
"texture": "textures/ui/Black",
|
||||
"$atext": "$actionbar_text",
|
||||
"visible": "($atext = 'show_image')"
|
||||
},
|
||||
|
||||
"image_factory": {
|
||||
"type": "panel",
|
||||
"factory": {
|
||||
"name": "hud_actionbar_text_factory",
|
||||
"control_ids": {
|
||||
"hud_actionbar_text": "conditional_image@hud.conditional_image"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
通过结合操作符系统,可实现复杂的条件逻辑判断,为界面交互提供灵活的控制能力。
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/hud_screen.json]
|
||||
```
|
||||
:::
|
||||
|
||||
### 使用绑定的条件渲染
|
||||
|
||||
根据上文提到的操作栏示例,你可能会认为标题也使用变量。但实际情况并非如此。标题使用绑定(bindings)来获取数据,如下所示。
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/hud_screen.json]
|
||||
{
|
||||
...
|
||||
"hud_title_text": {
|
||||
"type": "stack_panel",
|
||||
"orientation": "vertical", // 垂直排列
|
||||
"offset": [ 0, -19 ], // 位置偏移
|
||||
"layer": 1, // 渲染层级
|
||||
"alpha": "@hud.anim_title_text_alpha_in", // 透明度动画
|
||||
"propagate_alpha": true, // 透明度继承
|
||||
"controls": [ // 子控件集合
|
||||
{
|
||||
"title_frame": {
|
||||
"type": "panel", // 面板类型
|
||||
"size": [ "100%", "100%cm" ], // 尺寸设置
|
||||
"controls": [
|
||||
{
|
||||
"title_background": {
|
||||
"type": "image", // 图像类型
|
||||
"size": [ "100%sm + 30px", "100%sm + 6px" ], // 动态尺寸计算
|
||||
"texture": "textures/ui/hud_tip_text_background", // 纹理路径
|
||||
"alpha": "@hud.anim_title_background_alpha_in" // 背景透明度动画
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": {
|
||||
"type": "label", // 文本标签类型
|
||||
"anchor_from": "top_middle", // 锚点起始位置
|
||||
"anchor_to": "top_middle", // 锚点目标位置
|
||||
"color": "$title_command_text_color", // 文字颜色变量
|
||||
"text": "#text", // 文本内容绑定
|
||||
"layer": 1, // 渲染层级
|
||||
"localize": false, // 关闭本地化
|
||||
"font_size": "extra_large", // 超大字号
|
||||
"variables": [ // 条件变量组
|
||||
{
|
||||
"requires": "(not $title_shadow)", // 无阴影条件
|
||||
"$show_shadow": false // 关闭阴影显示
|
||||
},
|
||||
{
|
||||
"requires": "$title_shadow", // 启用阴影条件
|
||||
"$show_shadow": true // 启用阴影显示
|
||||
}
|
||||
],
|
||||
"shadow": "$show_shadow", // 阴影状态绑定
|
||||
"text_alignment": "center", // 文本居中
|
||||
"offset": [ 0, 6 ], // 位置微调
|
||||
"bindings": [ // 数据绑定组
|
||||
{
|
||||
"binding_name": "#hud_title_text_string", // 原始绑定名
|
||||
"binding_name_override": "#text", // 覆盖目标属性
|
||||
"binding_type": "global" // 全局绑定类型
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
我们需要在文本组件中添加另一个绑定对象来控制可见性。注意`#visible`属性会通过绑定直接控制元素可见性。以下示例将不会渲染"hello world"标题,但会显示其他所有标题。可在游戏中输入`/title @s title hello world`观察效果。
|
||||
|
||||
::: code-group
|
||||
```json [vanilla/ui/hud_screen.json]
|
||||
{
|
||||
...
|
||||
"hud_title_text": {
|
||||
"type": "stack_panel",
|
||||
"orientation": "vertical",
|
||||
"offset": [ 0, -19 ],
|
||||
"layer": 1,
|
||||
"alpha": "@hud.anim_title_text_alpha_in",
|
||||
"propagate_alpha": true,
|
||||
"controls": [
|
||||
{
|
||||
"title_frame": {
|
||||
"type": "panel",
|
||||
"size": [ "100%", "100%cm" ],
|
||||
"controls": [
|
||||
{
|
||||
"title_background": {
|
||||
"type": "image",
|
||||
"size": [ "100%sm + 30px", "100%sm + 6px" ],
|
||||
"texture": "textures/ui/hud_tip_text_background",
|
||||
"alpha": "@hud.anim_title_background_alpha_in"
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": {
|
||||
"type": "label",
|
||||
"anchor_from": "top_middle",
|
||||
"anchor_to": "top_middle",
|
||||
"color": "$title_command_text_color",
|
||||
"text": "#text",
|
||||
"layer": 1,
|
||||
"localize": false,
|
||||
"font_size": "extra_large",
|
||||
"variables": [
|
||||
{
|
||||
"requires": "(not $title_shadow)",
|
||||
"$show_shadow": false
|
||||
},
|
||||
{
|
||||
"requires": "$title_shadow",
|
||||
"$show_shadow": true
|
||||
}
|
||||
],
|
||||
"shadow": "$show_shadow",
|
||||
"text_alignment": "center",
|
||||
"offset": [ 0, 6 ],
|
||||
"bindings": [
|
||||
{
|
||||
"binding_name": "#hud_title_text_string",
|
||||
"binding_name_override": "#text",
|
||||
"binding_type": "global"
|
||||
},
|
||||
{
|
||||
"binding_type": "view", // 将此设为视图绑定
|
||||
"source_property_name": "(not (#text = 'hello world'))", // 当标题文本不等于"hello world"时触发
|
||||
"target_property_name": "#visible" // 根据条件覆盖可见性属性
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
在资源包中使用非侵入式UI文件修改时,应保持如下格式:
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
{
|
||||
"hud_title_text/title_frame/title": {
|
||||
"modifications": [
|
||||
{
|
||||
"array_name": "bindings", // 目标数组名
|
||||
"operation": "insert_back", // 末尾插入操作
|
||||
"value": { // 新增绑定对象
|
||||
"binding_type": "view",
|
||||
"source_property_name": "(not (#text = 'hello world'))",
|
||||
"target_property_name": "#visible"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
下面是一个更复杂的条件渲染示例。16x16的黑色图片仅在标题文本等于"hello world"时显示。虽然在此案例中不需要使用标题工厂(title factory),但如需使用UI动画则建议采用。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
{
|
||||
"black_conditional_image": {
|
||||
"type": "image",
|
||||
"texture": "textures/ui/Black", // 黑色纹理
|
||||
"size": [16, 16], // 固定尺寸
|
||||
"layer": 10, // 较高渲染层级
|
||||
"bindings": [
|
||||
{
|
||||
"binding_name": "#hud_title_text_string" // 标题文本绑定
|
||||
},
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "(#hud_title_text_string = 'hello world')", // 条件判断
|
||||
"target_property_name": "#visible" // 可见性控制
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"black_conditional_image_factory": {
|
||||
"type": "panel",
|
||||
"factory": {
|
||||
"name": "hud_title_text_factory", // 使用标题工厂
|
||||
"control_ids": {
|
||||
"hud_title_text": "black_conditional_image@hud.black_conditional_image" // 控件ID映射
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"root_panel": {
|
||||
"modifications": [
|
||||
{
|
||||
"array_name": "controls", // 根面板控件数组
|
||||
"operation": "insert_front", // 前置插入
|
||||
"value": {
|
||||
"black_conditional_image_factory@hud.black_conditional_image_factory": {} // 工厂实例
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
## 字符串格式化
|
||||
|
||||
使用`%.#s`格式可以从字符串中截取指定长度的部分,其中`#`代表字符数量。示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"label_element": {
|
||||
"type": "label",
|
||||
"text": "#text", // 文本绑定
|
||||
"layer": 2,
|
||||
"bindings": [
|
||||
{
|
||||
"binding_type": "global",
|
||||
"binding_name": "#hud_title_text_string" // 全局标题绑定
|
||||
},
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "('%.3s' * #hud_title_text_string)", // 截取前3个字符
|
||||
"target_property_name": "#text" // 输出结果
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
假设变量`"$var": "abcdefghijklmn"`,则:
|
||||
- `'%.5s' * $var` 返回 `abcde`
|
||||
- `$var - ('%.7s' * $var)` 返回 `hijklm`
|
||||
|
||||
注意该格式的使用场景较为有限。
|
||||
|
||||
## 按钮映射
|
||||
|
||||
`button_mappings`允许重新定义控件输入与按钮行为的对应关系,支持键鼠、触屏和手柄输入。
|
||||
|
||||
按钮元素配置示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"sample_button@common.button": {
|
||||
"$pressed_button_name": "button_id", // 按钮ID变量
|
||||
"button_mappings": [
|
||||
{
|
||||
"to_button_id": "$pressed_button_name",
|
||||
"mapping_type": "pressed" // 按压映射
|
||||
},
|
||||
{
|
||||
"from_button_id": "button.menu_ok", // 来源按钮
|
||||
"to_button_id": "$pressed_button_name", // 目标按钮
|
||||
"mapping_type": "focused" // 焦点状态映射
|
||||
},
|
||||
{
|
||||
"from_button_id": "button.menu_select", // 选择按钮
|
||||
"to_button_id": "$pressed_button_name",
|
||||
"mapping_type": "pressed"
|
||||
},
|
||||
{
|
||||
"from_button_id": "button.menu_up", // 上方向键
|
||||
"to_button_id": "$pressed_button_name",
|
||||
"mapping_type": "global" // 全局映射
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 映射类型
|
||||
|
||||
定义按钮映射的作用范围:
|
||||
|
||||
- `focused` - 控件获得焦点时生效
|
||||
- `pressed` - 控件被点击/按压时生效
|
||||
- `global` - 控件存在时全局生效
|
||||
|
||||
条件触发示例:
|
||||
```json
|
||||
{
|
||||
"sample_button@common.button": {
|
||||
"$pressed_button_name": "button_id",
|
||||
"button_mappings": [
|
||||
// 鼠标悬停时触发
|
||||
{
|
||||
"from_button_id": "button.menu_ok",
|
||||
"to_button_id": "$pressed_button_name",
|
||||
"mapping_type": "focused"
|
||||
},
|
||||
// 点击时触发
|
||||
{
|
||||
"from_button_id": "button.menu_select",
|
||||
"to_button_id": "$pressed_button_name",
|
||||
"mapping_type": "pressed"
|
||||
},
|
||||
// 全局响应上方向键
|
||||
{
|
||||
"from_button_id": "button.menu_up",
|
||||
"to_button_id": "$pressed_button_name",
|
||||
"mapping_type": "global"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 常用按钮ID
|
||||
|
||||
**键鼠映射表:**
|
||||
| 按钮ID | 说明 |
|
||||
|-----------------------------|---------------|
|
||||
| `button.menu_select` | 鼠标左键 |
|
||||
| `button.menu_secondary_select` | 鼠标右键 |
|
||||
| `button.menu_ok` | 回车键 |
|
||||
| `button.menu_exit` | ESC键 |
|
||||
| `button.menu_cancel` | ESC键 |
|
||||
| `button.menu_up` | 上方向键 |
|
||||
| `button.menu_down` | 下方向键 |
|
||||
| `button.menu_left` | 左方向键 |
|
||||
| `button.menu_right` | 右方向键 |
|
||||
| `button.menu_autocomplete` | Tab键 |
|
||||
|
||||
**手柄映射表:**
|
||||
| 按钮ID | 说明 |
|
||||
|-----------------------------|-------------|
|
||||
| `button.controller_select` | X/A键 |
|
||||
| `button.menu_secondary_select` | Y键 |
|
||||
| `button.menu_exit` | B键 |
|
||||
| `button.menu_cancel` | B键 |
|
||||
| `button.menu_up` | 方向键上 |
|
||||
| `button.menu_down` | 方向键下 |
|
||||
| `button.menu_left` | 方向键左 |
|
||||
| `button.menu_right` | 方向键右 |
|
||||
|
||||
建议在设计UI时兼容多种输入设备。
|
||||
|
||||
## 修改操作
|
||||
|
||||
使用`modifications`属性可以非侵入式地修改现有JSON UI元素,提升资源包兼容性。
|
||||
|
||||
| 操作类型 | 描述 |
|
||||
|------------------|-----------------------|
|
||||
| `insert_back` | 在数组末尾插入 |
|
||||
| `insert_front` | 在数组开头插入 |
|
||||
| `insert_after` | 在目标元素后插入 |
|
||||
| `insert_before` | 在目标元素前插入 |
|
||||
| `move_back` | 移动元素到数组末尾 |
|
||||
| `move_front` | 移动元素到数组开头 |
|
||||
| `move_after` | 移动元素到目标之后 |
|
||||
| `move_before` | 移动元素到目标之前 |
|
||||
| `swap` | 交换两个元素位置 |
|
||||
| `replace` | 替换目标元素 |
|
||||
| `remove` | 移除目标元素 |
|
||||
|
||||
### 操作示例
|
||||
|
||||
#### 首尾操作
|
||||
```json
|
||||
// 在控件列表开头插入新元素
|
||||
{
|
||||
"array_name": "controls",
|
||||
"operation": "insert_front",
|
||||
"value": [{"foo@example.bar": {}}]
|
||||
}
|
||||
|
||||
// 将现有元素移至末尾
|
||||
{
|
||||
"array_name": "controls",
|
||||
"operation": "move_back",
|
||||
"value": [{"foo@example.bar": {}}]
|
||||
}
|
||||
```
|
||||
|
||||
#### 相对定位操作
|
||||
```json
|
||||
// 在指定绑定后插入新绑定
|
||||
{
|
||||
"array_name": "bindings",
|
||||
"operation": "insert_after",
|
||||
"where": {"binding_name": "#example_binding_2"},
|
||||
"value": [{"binding_name": "#my_binding_1"}]
|
||||
}
|
||||
|
||||
// 移动绑定到指定位置前
|
||||
{
|
||||
"array_name": "bindings",
|
||||
"operation": "move_before",
|
||||
"where": {"binding_name": "#example_binding_1"},
|
||||
"target": {"binding_name": "#example_binding_2"}
|
||||
}
|
||||
```
|
||||
|
||||
#### 替换与删除
|
||||
```json
|
||||
// 替换现有绑定
|
||||
{
|
||||
"array_name": "bindings",
|
||||
"operation": "replace",
|
||||
"where": {"binding_name": "#example_binding_1"},
|
||||
"value": {"binding_name": "#replacement_binding"}
|
||||
}
|
||||
|
||||
// 删除指定绑定
|
||||
{
|
||||
"array_name": "bindings",
|
||||
"operation": "remove",
|
||||
"where": {"binding_name": "#example_binding_1"}
|
||||
}
|
||||
```
|
||||
89
docs/wiki/4-Json-UI/2-巧思案例/add-hud-elements.md
Normal file
89
docs/wiki/4-Json-UI/2-巧思案例/add-hud-elements.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
title: 添加HUD元素
|
||||
category: 教程
|
||||
tags:
|
||||
- 初学者
|
||||
mentions:
|
||||
- shanewolf38
|
||||
- SmokeyStack
|
||||
---
|
||||
|
||||
# 添加HUD元素
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
在本教程中,你将学习如何向HUD界面添加元素。
|
||||
|
||||
## 概述
|
||||
|
||||
HUD界面在游戏中大部分时间都会显示,为玩家提供关键信息。很多时候你需要在界面上添加元素,比如在完成特定事件后弹出文字、显示玩家体力的耐力条、显示玩家速度的时速表等等!
|
||||
|
||||
要将创建的元素添加到HUD界面,需要使用`modification`参数在`root_panel`中添加新的`control`(界面元素)。Root_panel是一个面板类型的元素,包含了HUD界面上几乎所有显示的元素。
|
||||
|
||||
## 单个元素添加
|
||||
|
||||
下面这段代码会在屏幕顶部创建一个显示黑色方块的图像元素,在屏幕右上角创建显示文字"HUD文本"的标签元素,并通过修改`root_panel`将它们添加到HUD界面。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
"hud_square": {
|
||||
"type": "image",
|
||||
"texture": "textures/ui/Black", // 原版纹理
|
||||
"anchor_from": "top_middle",
|
||||
"anchor_to": "top_middle",
|
||||
"size": [ 64, 64 ],
|
||||
"offset": [ 0, 4 ]
|
||||
},
|
||||
|
||||
"hud_text": {
|
||||
"type": "label",
|
||||
"text": "HUD文本",
|
||||
"anchor_from": "top_right",
|
||||
"anchor_to": "top_right",
|
||||
"offset": [ -4, 4 ]
|
||||
},
|
||||
|
||||
"root_panel": {
|
||||
"modifications": [
|
||||
{
|
||||
"array_name": "controls",
|
||||
"operation": "insert_front",
|
||||
"value": [
|
||||
{ "hud_square@hud.hud_square": {} },
|
||||
{ "hud_text@hud.hud_text": {} }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
需要添加到HUD界面上的所有元素都列举在root_panel的`modifications`->`value`部分。在添加元素时使用的命名空间标识(例如`@hud.hud_square`)可以根据实际模块进行调整。比如当`hud_square`元素是创建在`scoreboard`命名空间的scoreboards.json界面文件中时,添加时应使用`@scoreboard.hud_square`。
|
||||
|
||||
## 组合元素添加
|
||||
|
||||
出于组织结构考虑,通常不建议将大量元素直接逐个添加到根面板中。以下代码将之前定义的`hud_square`和`hud_text`元素(示例中未展示)包裹在名为`hud_elements_panel`的面板元素中,然后将该面板整体添加到HUD的根面板。最终效果与单个元素添加方式相同。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
"hud_elements_panel": {
|
||||
"type": "panel",
|
||||
"controls": [
|
||||
{ "hud_square@hud_square": {} },
|
||||
{ "hud_text@hud_text": {} }
|
||||
]
|
||||
},
|
||||
|
||||
"root_panel": {
|
||||
"modifications": [
|
||||
{
|
||||
"array_name": "controls",
|
||||
"operation": "insert_front",
|
||||
"value": [
|
||||
{ "hud_elements_panel@hud.hud_elements_panel": {} }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
此处`hud_elements_panel`没有直接定义尺寸参数,因此将继承其父元素(`root_panel`)的尺寸。这使得子元素的锚点定位、百分比尺寸等效果能相对于HUD屏幕进行适配。
|
||||
64
docs/wiki/4-Json-UI/2-巧思案例/aseprite-animations.md
Normal file
64
docs/wiki/4-Json-UI/2-巧思案例/aseprite-animations.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
title: Aseprite动画
|
||||
category: 教程
|
||||
mentions:
|
||||
- TheDataLioness
|
||||
- shanewolf38
|
||||
- TheItsNameless
|
||||
- LeGend077
|
||||
- stirante
|
||||
---
|
||||
|
||||
# Aseprite动画
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
## Aseprite简介
|
||||
|
||||
[Aseprite](https://www.aseprite.org/) 是一款付费像素艺术软件,专门用于轻松创建皮肤和资源包。它提供丰富的工具、详尽的文档和教程,适合不同水平的艺术家使用。
|
||||
|
||||
[LibreSprite](https://libresprite.github.io/) 是Aseprite的免费开源替代品。它基于Aseprite最后一个开源许可版本进行分支开发,本教程中的操作同样适用于LibreSprite。
|
||||
|
||||
## 在Aseprite中创建动画
|
||||
|
||||
假设你有一组按数字1到5顺序命名的"frameimage"系列帧图像。导入第一张图像后,Aseprite会自动识别同名但编号不同的其他图片,将它们按正确顺序排列并创建动画。
|
||||
|
||||
<FolderView
|
||||
:paths="[
|
||||
'frameimage1.png',
|
||||
'frameimage2.png',
|
||||
'frameimage3.png',
|
||||
'frameimage4.png',
|
||||
'frameimage5.png'
|
||||
]"
|
||||
></FolderView>
|
||||
|
||||
使用`箭头键`在帧间导航,`Enter键`控制动画的播放/暂停。按下`Tab键`可打开时间轴选择单帧,右键点击时间轴上的帧可设置各种参数。
|
||||
|
||||
通过快捷键`Ctrl + E`或菜单`文件 -> 导出到精灵表`进行导出操作。在输出设置中选择输出文件和JSON数据格式,出现包含哈希(Hash)和数组(Array)两种选项的下拉菜单时,请确保选择数组(Array)模式,否则会导致异常。
|
||||
|
||||
最终将生成两个文件:SpriteSheet图像和JSON文件。请确保这两个文件主文件名相同且扩展名不同。
|
||||
|
||||
## 在JSON-UI中使用Aseprite动画
|
||||
|
||||
`aseprite_flip_book`动画类型专用于`image`类型元素的`uv`属性配置。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/example_file.json]
|
||||
{
|
||||
"image_element": { // 此处为动画元素
|
||||
"type": "image",
|
||||
"texture": "textures/ui/my_sprite_file",
|
||||
"uv_size": [32, 32],
|
||||
"uv": "@example_namespace.image_uv_animation"
|
||||
},
|
||||
|
||||
"image_uv_animation": { // 此处为动画控制参数
|
||||
"anim_type": "aseprite_flip_book",
|
||||
"initial_uv": [0, 0]
|
||||
}
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
将`texture`字段设置为导出文件的路径(不包含扩展名)。`uv_size`字段应设置为单帧的宽高尺寸。
|
||||
78
docs/wiki/4-Json-UI/2-巧思案例/preserve-title-texts.md
Normal file
78
docs/wiki/4-Json-UI/2-巧思案例/preserve-title-texts.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: 保留标题文本
|
||||
category: 教程分类
|
||||
tags:
|
||||
- 中级
|
||||
mentions:
|
||||
- shanewolf38
|
||||
- SmokeyStack
|
||||
---
|
||||
|
||||
# 保留标题文本
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
在本教程中,您将学习如何保存绑定数据并根据含有特定字符串的标题更新界面元素。
|
||||
|
||||
## 概述
|
||||
|
||||
标题是向UI系统传递数据的常用方法。当标题包含特定字符串时才更新相关数据元素,而忽略所有不含该字符串的标题数据非常有用。尽管本教程以标题为例,但该方法适用于所有通过绑定传递的数据(如副标题、玩家记分板名称等)。
|
||||
|
||||
要保存特定字符串,我们需要组合使用 `visibility_changed` 绑定更新条件和 `source_control_name`,从而仅在包含特定字符串时更新绑定,并将该绑定传递给另一个元素。
|
||||
|
||||
## 标题指令
|
||||
|
||||
以下代码创建了一个标签元素,当将其添加到根面板时,可以在屏幕显示包含字符串"update"的标题(显示文本中会移除"update"部分)。后续传入的标题信息只有包含"update"时才会更新显示文本。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
"preserved_title_display": {
|
||||
"$update_string": "update", // 标题必须包含此字符串才触发元素更新
|
||||
"type": "label",
|
||||
"text": "#text",
|
||||
"controls": [
|
||||
{
|
||||
"data_control": {
|
||||
"type": "panel",
|
||||
"size": [ 0, 0 ],
|
||||
"bindings": [
|
||||
{
|
||||
"binding_name": "#hud_title_text_string" // 读取当前标题字符串
|
||||
},
|
||||
{
|
||||
"binding_name": "#hud_title_text_string",
|
||||
"binding_name_override": "#preserved_text", // 元素可见性变化时更新#preserved_text
|
||||
"binding_condition": "visibility_changed"
|
||||
},
|
||||
// 当包含更新字符的标题传入后,元素会短暂可见后立即隐藏
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "(not (#hud_title_text_string = #preserved_text) and not ((#hud_title_text_string - $update_string) = #hud_title_text_string))",
|
||||
"target_property_name": "#visible"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"bindings": [
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_control_name": "data_control", // 从"data_control"子元素读取绑定
|
||||
//"resolve_sibling_scope": true, // 当"data_control"与绑定调用元素为同级时需启用
|
||||
"source_property_name": "(#preserved_text - $update_string)", // 从显示文本中移除更新字符串
|
||||
"target_property_name": "#text"
|
||||
}
|
||||
]
|
||||
},
|
||||
```
|
||||
|
||||
变量 `$update_string` 定义了触发元素更新的标题必须包含的特定字符串。子元素 `data_control` 用于在标题包含更新字符串时存储标题文本。`data_control` 必须是要传递保留文本元素的子级或同级元素,因为其可见性变化会触发文本保存。该元素的三个绑定分别实现:
|
||||
1. 首绑定:持续追踪当前标题文本
|
||||
2. 次绑定:在元素可见性变化时将当前标题保存至 `#preserved_text`
|
||||
3. 末绑定:当传入含更新字符串的标题时短暂显示元素后立即隐藏
|
||||
|
||||
在 `data_control` 元素的第三个绑定中,需同时满足两个条件才可见:
|
||||
1. `not (#hud_title_text_string = #preserved_text)` - 当前标题与保存标题不一致时成立
|
||||
2. `not ((#hud_title_text_string - $update_string)` - 当前标题含有更新字符串时成立
|
||||
|
||||
当含有更新字符串且与已存文本不同的标题传入时,两条件同时触发,元素更新数据后立即重新隐藏自身。
|
||||
80
docs/wiki/4-Json-UI/2-巧思案例/string-to-number.md
Normal file
80
docs/wiki/4-Json-UI/2-巧思案例/string-to-number.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: 字符串转数值
|
||||
category: 教程
|
||||
tags:
|
||||
- 中级
|
||||
mentions:
|
||||
- shanewolf38
|
||||
- SmokeyStack
|
||||
- ThomasOrs
|
||||
---
|
||||
|
||||
# 字符串转数值
|
||||
|
||||
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
|
||||
|
||||
在本教程中,您将学习如何将数字字符串转换为数值,以及如何将数值转换为文本字符串。
|
||||
|
||||
## 概述
|
||||
|
||||
在许多情况下会有文本字符串通过标题、操作栏、记分板或其他来源传递到用户界面中。当我们希望根据输入的字符串动态调整UI元素时,能够进行数字比较就显得非常重要。但类似于"34"或"89"这样的数值型字符串通常会被视为普通文本,既无法与数值进行比较,也难以直接作为运算数据使用。此时我们需要将这类字符串转换为数值。
|
||||
|
||||
要实现字符串到数值的转换,我们可以利用乘法运算特性。任何包含数字的字符串与数值相乘,或者通过去除字符串中的非数字部分,都能使游戏引擎将该值作为数值而非字符串处理。
|
||||
|
||||
## 字符串转数值
|
||||
|
||||
以下代码创建了一个标签元素,当添加到主面板时,可在记分板侧栏的最高分值处于100-999范围内时显示该数值。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
"string_to_number": {
|
||||
"type": "label",
|
||||
"text": "#player_score_sidebar",
|
||||
"bindings": [
|
||||
{
|
||||
"binding_name": "#player_score_sidebar",
|
||||
"binding_type": "collection",
|
||||
"binding_collection_name": "scoreboard_scores"
|
||||
},
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "(#player_score_sidebar * 1)", // 将分数从字符串转换为数值
|
||||
"target_property_name": "#score"
|
||||
},
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "((#score > 99) and (#score < 1000))", // 仅在100-999范围内可见
|
||||
"target_property_name": "#visible"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
第一个绑定从记分板侧栏读取最大数值(该绑定值以字符串形式固定传输),第二个绑定通过将分数乘以1将其转换为数值(也可以通过减法操作去除字符串中的文本),第三个绑定设置元素仅在分数大于99且小于1000时可见。
|
||||
|
||||
**注意:** 如果需要将数值识别为浮点类型而非整数,可在等式运算中引入浮点变量或绑定,例如除以1.0(必须通过变量或绑定实现——直接插入浮点数无法生效)。这在处理`#clip-ratio`绑定时尤为实用。
|
||||
|
||||
## 数值转字符串
|
||||
|
||||
以下代码创建了一个标签元素,当添加到主面板时,可将"Strength: #"格式标题中的数字部分单独显示。
|
||||
|
||||
::: code-group
|
||||
```json [RP/ui/hud_screen.json]
|
||||
"number_to_string": {
|
||||
"type": "label",
|
||||
"text": "#text",
|
||||
"bindings": [
|
||||
{
|
||||
"binding_type": "global",
|
||||
"binding_name": "#hud_title_text_string"
|
||||
},
|
||||
{
|
||||
"binding_type": "view",
|
||||
"source_property_name": "('§z' + (#hud_title_text_string - 'strength: '))",
|
||||
"target_property_name": "#text"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
当使用标题、副标题等方式传递包含数字的文本时,此方法可单独显示数值。通过减法运算去除多余文本后,需在数值前添加文本使其转换为字符串类型(`text`参数无法直接读取纯数值型绑定)。此例中的括号并非必需,主要用于区分数值转换操作。添加的`§z`字符是无效的Minecraft格式代码,既不显示也不影响标签颜色参数。若需要去除显示中无法通过减法处理的文本,推荐将元素嵌套在设置`"clips_children": true`和适当尺寸的容器面板中实现遮挡效果。
|
||||
2067
docs/wiki/4-Json-UI/3-文档/json-ui-documentation.md
Normal file
2067
docs/wiki/4-Json-UI/3-文档/json-ui-documentation.md
Normal file
File diff suppressed because it is too large
Load Diff
7
docs/wiki/bedrock-wiki-mirror.md
Normal file
7
docs/wiki/bedrock-wiki-mirror.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
hidden: true
|
||||
---
|
||||
|
||||
:::details 本页面镜像自 <div style="display:inline-block; width: 16px; height: 16px; background-image:url(https://wiki.bedrock.dev/assets/images/homepage/wikilogo.png); background-size: contain; background-position: center; background-repeat: no-repeat; vertical-align: middle;"></div> [BedrockWiki](https://wiki.bedrock.dev)
|
||||
根据原始项目协议授权。本文经过AI翻译处理,如有内容遗漏,可以提交PR进行补充。
|
||||
:::
|
||||
Reference in New Issue
Block a user