更新文档导航顺序,添加新页面和翻译内容

This commit is contained in:
boybook
2025-03-26 10:59:30 +08:00
parent 7de24ab663
commit 5382f625fc
41 changed files with 3591 additions and 3119 deletions

View File

@@ -0,0 +1,72 @@
---
title: AFK检测器
tags:
- 配方
mentions:
- SirLich
- BlueFrog130
- SmokeyStack
- Keyyard
- Ultr4Anubis
---
# AFK检测器
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
### AFK检测动画控制器
<BButton color="blue" link="animation-controllers-intro">了解更多动画控制器知识</BButton>
这是一个用于检测挂机玩家的示例实现。
::: code-group
```json [BP/animation_controllers/afk.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.player.afk": {
"states": {
"default": {
"transitions": [
{
"stands_still": "!q.is_moving"
}
]
},
"stands_still": {
"on_entry": [
"v.afk = q.life_time;"
],
"transitions": [
{
"afk": "(q.life_time - v.afk) >= 30 && !q.is_moving"
},
{
"default": "q.is_moving"
}
]
},
"afk": {
"on_entry": ["/tag @s add AFK", "/say 我现在处于挂机状态"],
"animations": ["afk_animation"],
"transitions": [
{
"default": "q.is_moving"
}
],
"on_exit": ["/tag @s remove AFK", "/say 我已结束挂机状态"]
}
}
}
}
}
```
:::
- `controller.animation.player.afk` 是该控制器的唯一标识符
- 当[Molang](https://bedrock.dev/zh/MoLang)查询`!q.is_moving`返回false时表示玩家未移动状态会切换到"stands_still"
- "stands_still"状态会持续检测若玩家30秒内无移动则进入"afk"状态,否则返回"default"状态
- 进入"afk"状态时,会触发"on_entry"中的命令
- "animations"字段包含该状态激活期间持续播放的行为动画简称(用法与[资源动画控制器](#animation-controller)相同)
- 当玩家恢复移动时,状态将转回"default"状态,并执行"on_exit"中的命令

View File

@@ -0,0 +1,310 @@
---
title: 动画控制器入门
nav_order: 1
tags:
- 指南
mentions:
- SirLich
- solvedDev
- Joelant05
- MedicalJewel105
- stirante
- cda94581
- ThijsHankelMC
- MetalManiacMc
- ThomasOrs
---
# 动画控制器入门
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
动画控制器AC是一种可在资源包RP和行为包BP中使用的状态机。在资源包中动画控制器RPAC用于播放动画在行为包中BPAC它们用于执行命令和"动画"指令。
## 什么是状态机?
状态机是一种特殊的逻辑管理方式,它依赖于一系列状态。每个状态具有两个属性:
- 当前状态下执行的操作
- 如何转移到其他状态
状态机在各类系统中广泛应用尤其在传统编程领域。它们不仅存在于Minecraft中您可以通过[此链接](https://www.itemis.com/en/yakindu/state-machine/documentation/user-guide/overview_what_are_state_machines)深入了解状态机。
状态机同一时间只能处于**一个**状态。当状态机"运行"时,可以理解为它在不同状态间转移,执行其中的逻辑,并遵循`transitions`规则转移到其他状态。
## 状态机示例
状态机的优势在于能够将动画自然分解为逻辑流程,每个状态独立处理自身动画**和**逻辑。
例如,假设您想为直升机螺旋桨制作动画,但仅在地面时停止旋转。这里有两个状态:
- `地面状态`
- `飞行状态`
我们可以用前文提到的两个属性来注解这些状态:
- `地面状态`
- 不播放动画
- 若处于空中则转移到`飞行状态`
- `飞行状态`
- 播放飞行动画
- 若着陆则返回`地面状态`
以下是状态机的流程图表示:
![](/assets/images/concepts/animation-controllers/two_state_FSM.png)
在流程图中,状态用矩形表示,箭头表示状态间的**转移**。让我们看一个更复杂的示例,新增了`爆炸状态`
![](/assets/images/concepts/animation-controllers/three_state_FSM.png)
可见,一个状态可同时转移到多个状态。状态也可以是终止状态(直升机损毁后无需继续动画)。这种分支流程体现了动画控制器的强大之处。
## 什么是动画控制器?
动画控制器是Minecraft中用于播放动画和执行指令的状态机。动画控制器文件必须存放在资源包或行为包的`animation_controllers`文件夹中。
### 将控制器附加到实体
动画控制器需在实体文件中进行"附加"才能生效。附加AC需要完成两个步骤
1. 为动画控制器定义简称
2. 通过`scripts`运行动画控制器
以下示例展示了如何在`animations`中定义AC并通过`scripts/animate`播放:
::: code-group
```json [RP/entity/helicopter.ce.json 或 BP/entities/helicopter.se.json]
"description": {
"identifier": "wiki:helicopter",
"animations": {
"blade_controller": "controller.animation.helicopter.blade"
},
"scripts": {
"animate": [
"blade_controller"
]
}
}
```
:::
若需要条件触发动画控制器可添加Molang参数。当参数为真时控制器才会运行
::: code-group
```json [RP/entity/helicopter.ce.json 或 BP/entities/helicopter.se.json]
"scripts": {
"animate": [
{
// 仅在直升机有骑手时播放blade_controller
"blade_controller": "q.has_rider"
}
]
}
```
:::
### RP动画控制器
资源包动画控制器位于RP中可附加到RP实体。用于播放骨骼动画。
### BP动画控制器
行为包动画控制器位于BP中可附加到BP实体。用于执行命令和向实体发送事件。
## 动画控制器示例
### 基础示例
::: code-group
```json [RP/animation_controllers/helicopter.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.helicopter.blade": {
"initial_state": "ground",
"states": {
"ground": {
"transitions": [
{
"flying": "!q.is_on_ground"
}
]
},
"flying": {
"animations": ["flying"],
"transitions": [
{
"ground": "q.is_on_ground"
}
]
}
}
}
}
}
```
:::
解析关键点:
- `initial_state`: "ground" 表示初始状态
- `ground`状态包含转移到"flying"状态的逻辑
- `flying`状态播放"flying"动画并包含返回逻辑
### 完整示例
::: code-group
```json [RP/animation_controllers/helicopter.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.helicopter.blade": {
"initial_state": "ground",
"states": {
"ground": {
"transitions": [
{"flying": "!q.is_on_ground"},
{"explode": "!q.is_alive"}
]
},
"flying": {
"animations": ["flying"],
"transitions": [
{"ground": "q.is_on_ground"},
{"explode": "!q.is_alive"}
]
},
"explode": {
"animations": ["explode"]
}
}
}
}
}
```
:::
## RP动画控制器扩展功能
资源包动画控制器可触发音效和粒子效果。使用前需在客户端实体文件中预先定义:
::: code-group
```json [RP/entities/custom_tnt.json#minecraft:client_entity/description]
"sound_effects": {
"explosion": "wiki.custom_tnt.explosion" // 其中wiki.custom_tnt.explosion是在sound_definitions中定义的声音
},
"particle_effects": {
"fuse_lit": "wiki:tnt_fuse_lit_particle"
}
```
:::
::: code-group
```json [RP/animation_controllers/custom_tnt.animation_controllers.json#controller.animation.custom_tnt]
"states":{
"default":{
"transitions":[
{"explode_state":"q.mark_variant == 1"}
]
},
"explode_state":{
"sound_effects":[{"effect":"explosion"}],
"particle_effects": [
{
"effect": "fuse_lit"
// "locator": "<骨骼名称>" 此处也可指定定位器
}
],
"transitions":[
{"default":"q.mark_variant == 0"}
]
}
}
```
:::
:::warning
警告!并非所有粒子效果在此处都有效。若遇到问题,建议尝试其他粒子效果(例如参考烈焰人动画控制器中的示例)。
:::
## BP动画控制器功能
行为包动画控制器支持两个新字段:
- `on_entry`: 进入状态时执行的命令
- `on_exit`: 退出状态时执行的命令
命令类型包含:
- 斜杠命令:`/say Hello!`
- 实体事件:`@s wiki:transform_into_plane`
- Molang表达式`v.tickets += 1;`
示例:
::: code-group
```json [BP/animation_controllers/helicopter.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.helicopter.commands": {
"initial_state": "ground",
"states": {
"ground": {
"on_entry": ["/say 当前处于地面状态!"],
"transitions": [
{"flying": "!q.is_on_ground"}
]
},
"flying": {
"on_entry": ["/say 当前处于空中状态!"],
"transitions": [
{"ground": "q.is_on_ground"}
]
}
}
}
}
}
```
:::
## 动画控制器执行流程
### 加载阶段
- 实体加载时进入初始状态(未定义时使用"default"
- 每Tick执行
1. 播放当前状态动画(循环或单次)
2. 检查转移条件,执行首个有效转移
### 重置机制
实体重载时(玩家进出、区块重载等)会重置到初始状态
## 高级功能
动画控制器支持变量重映射:
```json
{
"format_version": "1.17.30",
"animation_controllers": {
"controller.animation.sheep.move": {
"states": {
"default": {
"variables": {
"ground_speed_curve": {
"input": "q.ground_speed",
"remap_curve": {
"0.0": 0.2,
"1.0": 0.7
}
}
},
"animations": [
"wiggle_nose",
{"walk": "v.ground_speed_curve"}
]
}
}
}
}
}
```

View File

@@ -0,0 +1,120 @@
---
title: 死亡命令
tags:
- 配方
mentions:
- SirLich
- BlueFrog130
- SmokeyStack
- cda94581
- MedicalJewel105
- Kaioga5
- TheItsNameless
---
# 死亡命令
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
<BButton color="blue" link="animation-controllers-intro">了解更多关于动画控制器的知识</BButton>
我将"死亡效果"定义为"当实体死亡时执行某些操作"。以下是几种应该避免的错误实现方式:
- **在实体文件中检测死亡**:通过添加组件然后尝试在动画控制器中检测该组件。这种方法是错误的,因为实体在被移除前动画控制器没有机会运行。
- **通过外部源检测死亡**:例如使用持续运行的命令方块。这种方法并非完全错误,在某些情况下甚至可能是优选方案,但存在性能损耗且容易出错。
## 使用 q.is_alive 查询
创建死亡效果的最佳方式是使用`is_alive`查询。只需在动画控制器中创建基于`is_alive`的状态过渡,`on_entry`中的命令会在实体被移除前执行。
示例动画控制器:
::: code-group
```json [BP/animation_controllers/death.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.death": {
"initial_state":"default",
"states": {
"default": {
"transitions": [
{
"dead": "!q.is_alive"
}
]
},
"dead": {
"on_entry": ["/say 我已死亡!"]
}
}
}
}
}
```
:::
## 在玩家实体上的应用
对于玩家实体,需要在死亡状态中添加额外过渡来确保状态重置:
::: code-group
```json [BP/animation_controllers/death.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.death": {
"initial_state":"default",
"states": {
"default": {
"transitions": [
{
"dead": "!q.is_alive"
}
]
},
"dead": {
"on_entry": ["/say 我已死亡!"],
"transitions": [
{
"default": "q.is_alive"
}
]
}
}
}
}
}
```
:::
:::warning
需要启用实验性玩法
:::
## 使用 minecraft:on_death 组件
通过在行为包的`entity.json`文件中使用`minecraft:on_death`组件,可以更直接地实现死亡命令:
1. 在组件部分添加触发逻辑:
```json
"minecraft:on_death" : {
"event" : "wiki:on_death",
"target" : "self"
}
```
2. 在事件部分定义执行内容:
```json
"wiki:on_death": {
"run_command": {
"command": [
"say 我已经死了!"
]
}
}
```
:::tip
使用此方法可以在实体死亡后仍然为其添加计分板分数和标签
:::

View File

@@ -0,0 +1,275 @@
---
title: 实体命令
nav_order: 2
tags:
- 中级
mentions:
- SirLich
- solvedDev
- Joelant05
- destruc7i0n
- Dreamedc2015
- MedicalJewel105
- aexer0e
- cda94581
- ThijsHankelMC
---
# 实体命令
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
:::warning
通过`run_command`事件响应来执行实体命令是更简单的方法,但目前该功能仍处于实验性阶段。
:::
## 动画控制器
要触发斜杠命令,我们将使用行为包动画控制器。动画控制器应放置在`animation_controllers/some_controller.json`路径下。你可以在[bedrock.dev的实体事件章节](https://bedrock.dev/docs/stable/Entity%20Events)了解更多关于动画控制器的知识。
简而言之,动画控制器允许我们从行为包中触发事件:
- 斜杠命令(如`/say`
- Molang表达式`v.foo += 1;`
- 实体事件(如`@s wiki:my_event`
以下是一个动画控制器示例:
::: code-group
```json [BP/animation_controllers/entity_commands.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.sirlich_entity_commands": {
"states": {
"default": {
"transitions": [
{
"on_summon": "1" // 1表示真值
}
]
},
"on_summon": {
"on_entry": ["/say I have been summoned"]
}
}
}
}
}
```
:::
当实体被召唤到世界时,这个动画控制器会立即执行`/say I have been summoned`命令。如果对工作原理有疑问请复习Molang、动画和实体事件相关内容。
简单来说,`states`可以通过`on_entry`子句触发事件。我们使用查询条件在不同状态间切换。除非定义了`initial_state`值,否则实体默认处于`default`状态。
:::warning
当世界/区块重新加载时,查询会重新运行。这意味着`"/say I have been summoned"`命令实际上会在每次实体"加载"时执行——而不仅在被召唤时。
:::
如果需要避免这种情况,需要添加额外查询条件,例如使用`skin_id`查询。首次生成实体时检查`skin_id = 0`,然后将其设置为更高的值如`skin_id = 1`。这样当实体重新加载时就不会再次触发命令。下文将展示具体实现方法。
## 使用动画控制器
要将动画控制器添加到实体中,可以在实体定义描述中使用以下代码:
::: code-group
```json [BP/entities/entity_commands.se.json]
"description": {
"identifier": "wiki:entity_commands",
"scripts": {
"animate": [
"wiki:entity_commands"
]
},
"animations": {
"wiki:entity_commands": "controller.animation.wiki_entity_commands"
}
}
```
:::
如果对步骤有疑问,请再次查阅[实体事件文档](https://bedrock.dev/r/Entity%20Events)。
## 通过事件触发命令
动画状态过渡使用查询条件实现。可查阅[实体查询列表](https://bedrock.dev/docs/stable/MoLang#List%20of%20Entity%20Queries)。在第一个示例中,查询条件简化为`true`因此命令会自动执行。我们可以使用更复杂的查询条件实现更精细的控制其中通过组件作为Molang过滤器来触发命令是便捷的方法。
推荐使用[skin_id](https://docs.microsoft.com/en-us/minecraft/creator/reference/content/entityreference/examples/entityproperties/minecraftproperty_skin_id)组件。
更新后的动画控制器基于`skin_id`触发:
::: code-group
```json [BP/animation_controllers/entity_commands.ac.json]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.sirlich_entity_commands": {
"states": {
"default": {
"transitions": [
{
"command_example": "q.skin_id == 1"
},
{
"zombies": "q.skin_id == 2"
}
]
},
"command_example": {
"transitions": [
{
"default": "q.skin_id != 1"
}
],
"on_entry": ["/say Command One!", "@s execute_no_commands"]
},
"zombies": {
"transitions": [
{
"default": "q.skin_id != 2"
}
],
"on_entry": [
"/say AHH! Zombies everywhere!",
"/summon minecraft:zombie",
"/summon minecraft:zombie",
"/summon minecraft:zombie",
"/summon minecraft:zombie",
"@s execute_no_commands"
]
}
}
}
}
}
```
:::
现在这个动画控制器有两个命令状态:`skin_id = 1`触发第一个,`skin_id = 2`触发第二个。注意使用`==`和`!=`运算符(不要使用单个`=`)。`@s execute_no_commands`语法用于在命令列表末尾重置`skin_id`,下文将创建这个事件。
## 设置组件组
在实体文件中,可以通过`skin_id`组件设置值:
::: code-group
```json [BP/entities/entity_commands.se.json]
"component_groups": {
"execute_no_commands": {
"minecraft:skin_id": {
"value": 0
}
},
"command_example": {
"minecraft:skin_id": {
"value": 1
}
},
"command_zombies": {
"minecraft:skin_id": {
"value": 2
}
}
}
```
:::
## 添加事件
创建事件以便管理组件组:
::: code-group
```json [BP/entities/entity_commands.se.json]
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": [
"execute_no_commands"
]
}
},
"execute_no_commands": {
"add": {
"component_groups": [
"execute_no_commands"
]
}
},
"command_example": {
"add": {
"component_groups": [
"command_example"
]
}
},
"command_zombies": {
"add": {
"component_groups": [
"command_zombies"
]
}
}
}
```
:::
## 触发事件
Minecraft中有多种触发事件的方式以下是两个典型示例
### 交互组件
此组件会在点击实体时生成僵尸:
::: code-group
```json [BP/entities/entity_commands.se.json]
"minecraft:interact": {
"interactions": [{
"on_interact": {
"filters": {
"all_of": [{
"test": "is_family",
"subject": "other",
"value": "player"
}
]
},
"event": "command_zombies"
}
}]
}
```
:::
### 定时器
此组件每10秒触发示例命令
::: code-group
```json [BP/entities/entity_commands.se.json]
"minecraft:timer": {
"looping": true,
"time": 10,
"time_down_event": {
"event": "example_command"
}
}
```
:::
通过添加这些组件,我们可以控制`skin_id`的变化时机,从而决定哪些事件会被触发。
## 流程总结
完整工作流程如下:
1. 通过交互或定时器等组件触发`example_command`事件
2. 事件添加`example_command`组件组
3. 组件组设置实体的`skin_id`
4. 动画控制器检测到`skin_id`变化,切换到对应状态
5. 执行状态中的`/say`等命令
6. 执行`@s execute_no_command`事件重置`skin_id`
7. 动画控制器检测重置,返回默认状态
8. 等待新的`skin_id`触发新事件
通过这种机制,可以实现精准的实体行为控制。

View File

@@ -0,0 +1,4 @@
---
title: 动画控制器
nav_order: 6
---

View File

@@ -0,0 +1,84 @@
---
title: 将Molang数据导入记分板
mentions:
- SirLich
- MedicalJewel105
- shanewolf38
- Luthorius
- TheItsNameless
- ThomasOrs
---
# 将Molang数据导入记分板
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
以下提供了一种将任意Molang变量、查询等即时转换为记分板数值的方法。请确保控制器`convert`状态中调用的动画名称与实体定义中的动画名称animation.namespace.molang_to_score完全匹配。
**注意:** 需要先在游戏中执行以下两条命令进行初始化:
`/scoreboard objectives add MoLang dummy`
`/scoreboard players set "#10" MoLang 10`
::: code-group
```json [BP/animation_controllers/molang_to_score.animation_controllers.json]
"controller.animation.namespace.molang_to_score": {
"initial_state": "idle",
"states": {
"idle": {
"transitions": [ { "convert": "<转换启动条件>" } ],
"on_exit": [
"/scoreboard players set @s MoLang 0",
"/scoreboard players set \"#var\" MoLang 0",
"v.convert = <需要转换的变量>;",
"v.digit = 1000000000;"
]
},
"convert": {
"animations": [
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score",
"molang_to_score"
],
"transitions": [ { "idle": "1" } ]
}
}
}
```
:::
::: code-group
```json [BP/animations/molang_to_score.animation.json]
"animation.namespace.molang_to_score": {
"animation_length": 10.0,
"anim_time_update": "t.digit = Math.mod(Math.floor(v.convert / v.digit), 10) + 0.1; v.digit = v.digit / 10; return t.digit;",
"timeline": {
"0.0": [
"/scoreboard players operation @s MoLang *= \"#10\" MoLang",
"/scoreboard players operation @s MoLang += \"#var\" MoLang",
"/scoreboard players set \"#var\" MoLang 0"
],
"1.0": [ "/scoreboard players set \"#var\" MoLang 1" ],
"2.0": [ "/scoreboard players set \"#var\" MoLang 2" ],
"3.0": [ "/scoreboard players set \"#var\" MoLang 3" ],
"4.0": [ "/scoreboard players set \"#var\" MoLang 4" ],
"5.0": [ "/scoreboard players set \"#var\" MoLang 5" ],
"6.0": [ "/scoreboard players set \"#var\" MoLang 6" ],
"7.0": [ "/scoreboard players set \"#var\" MoLang 7" ],
"8.0": [ "/scoreboard players set \"#var\" MoLang 8" ],
"9.0": [ "/scoreboard players set \"#var\" MoLang 9" ]
}
}
```
:::
**实现原理:** 当转换启动时控制器会重置玩家的MoLang分数和`#var`虚拟玩家的MoLang分数。转换变量`v.convert`被初始化,数字位变量`v.digit`被设置为获取第十位数字10^10。第一个动画运行时会根据当前位数设置动画时间并将数字位变量调整为下一位第9位10^9。由于时间轴索引会持续运行到设定时间"0.0"时间点的事件总是会被触发。这会将玩家的MoLang分数乘以10来设置正确的位数然后加上最后获取的数字首次运行时由于控制器重置了`#var`该值始终为0。整个过程重复执行11次以获取转换变量的全部10位数字。需要注意的是每个动画处理的是前一个动画设置的数字位因此需要运行11次动画。
**游戏内测试方法:** 将`<转换启动条件>`设为`q.is_using_item``<需要转换的变量>`设为`Math.random_integer(0, 9999)`。手持苹果开始食用,即可观察数值转换过程。

View File

@@ -0,0 +1,68 @@
---
title: 重生命令
tags:
- recipe
mentions:
- SirLich
- solvedDev
- Joelant05
- BlueFrog130
- SmokeyStack
- MedicalJewel105
- cda94581
---
# 重生命令
<!--@include: @/wiki/bedrock-wiki-mirror.md-->
<BButton color="blue" link="animation-controllers-intro">了解更多关于动画控制器的信息</BButton>
这个动画控制器可用于在玩家重生时执行命令,例如重新添加药水效果或给予物品。
只需将动画控制器添加到 `player.json` 中,并
::: code-group
```json [原CodeHeader的值]
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.death": {
"initial_state": "initialization",
"states": {
"initialization": {
"transitions": [
{
"has_died": "!q.is_alive"
}
],
"on_exit": [
"v.delay = 0.2 + q.life_time;",
"/<死亡命令或动画>"
]
},
"has_died": {
"on_exit": ["/<重生命令或动画>"],
"transitions": [
{
"initialization": "q.is_alive && (q.life_time >= v.delay)"
}
]
}
}
}
}
}
```
:::
该控制器包含两个状态:
1. **初始化状态**:当玩家死亡时设置延迟计时器(`v.delay = 0.2 + q.life_time`
2. **死亡状态**:在延迟计时结束后触发重生命令
参数说明:
- `q.life_time`:玩家处于死亡状态的时间(秒)
- `v.delay`自定义延迟时间默认增加0.2秒容差)
- `/<>`:需要替换为实际执行的命令或动画
提示:可通过调整`v.delay`的公式来精确控制重生命令的触发时机。