动画不只能让骨骼动起来。在动画的任意时刻,你都可以生成粒子、播放声音、修改变量,甚至运行一条命令。在本指南中,我们的红宝石傀儡每走一步都会冒出红色闪光并发出沉重的脚步声,受了重伤还会暴怒。
文件一览
RP/
animations/
ruby_golem.animation.json
entity/
ruby_golem.entity.json
models/
entity/
ruby_golem.geo.json
BP/
animations/
ruby_golem.animation.json
animation_controllers/
ruby_golem.animation_controllers.json
entities/
ruby_golem.json没错,行为包也可以有动画。第 3 部分会解释原因。
哪个包能做什么
| 事件 | 资源包 | 行为包 |
|---|---|---|
粒子(particle_effects) | 可以 | 不可以 |
声音(sound_effects) | 可以 | 不可以 |
Molang,例如 variable.x = 1; | 可以 | 可以 |
命令,例如 /say hi | 不可以 | 可以 |
实体事件,例如 @s wiki:enrage | 不可以 | 可以 |
简单记法:资源包负责每个玩家屏幕上的画面和声音;行为包负责所有人共享的、真正改变游戏的内容。
第 1 部分:粒子
给粒子起个简称
客户端实体会列出生物可以使用的粒子,每个粒子都有一个简称:
"particle_effects": {
"sparkle": "wiki:ruby_sparkle",
"dust": "minecraft:villager_happy"
}右边是粒子效果的标识符。可以是原版粒子,也可以是你自己做的(见粒子)。
在动画中生成粒子
在动画里添加 particle_effects。键是以秒为单位的时间,和关键帧一样:
"animation.ruby_golem.walk": {
"loop": true,
"animation_length": 1.0,
"bones": { },
"particle_effects": {
"0.0": { "effect": "sparkle", "locator": "left_foot" },
"0.5": { "effect": "sparkle", "locator": "right_foot" }
}
}行走动画每循环一次,左脚下会先出现一团闪光,接着是右脚。
| 字段 | 作用 |
|---|---|
effect | 客户端实体中的简称。必填。 |
locator | 粒子在模型上的起始位置。不填则使用生物的位置。 |
bind_to_actor | 设为 false 时粒子留在世界中,不会跟着生物移动 |
pre_effect_script | 在粒子开始前运行的 Molang,用来设置粒子会读取的变量 |
要同时生成多个粒子,可以用列表:"0.0": [ { ... }, { ... } ]。
定位器
定位器是模型某根骨骼里一个带名字的点。在几何文件中添加:
{
"name": "left_leg",
"parent": "body",
"pivot": [3, 12, 0],
"locators": {
"left_foot": [3, 0, 0]
},
"cubes": [ ]
}因为定位器位于骨骼中,骨骼动它也跟着动。left_foot 处的粒子会跟随摆动的腿。
第 2 部分:声音
声音的用法完全一样。先在客户端实体中定义简称:
"sound_effects": {
"thud": "mob.wiki.ruby_golem.step"
}右边是 RP/sounds/sound_definitions.json 中的声音事件名。然后在动画中添加 sound_effects:
"sound_effects": {
"0.0": { "effect": "thud" },
"0.5": { "effect": "thud" }
}每个声音条目都有 effect 和可选的 locator,和粒子一样。
脚步对准节奏
把声音的键放在动画中脚落地的那些时刻。如果行走动画使用了带 query.modified_distance_moved 的 anim_time_update,脚步声会自动随傀儡的速度加快或放慢。
从控制器状态触发
控制器状态也可以有 particle_effects 和 sound_effects。它们没有时间,因为状态没有时间轴,而是在生物进入该状态时触发:
"alert": {
"animations": ["fists_up"],
"particle_effects": [{ "effect": "sparkle", "locator": "head" }],
"sound_effects": [{ "effect": "roar" }],
"transitions": [{ "idle": "!query.has_target" }]
}时间轴
除了粒子和声音,动画还可以有一个 timeline:在指定时间运行的内容列表。在资源包中,时间轴运行的是 Molang:
"animation.ruby_golem.blink": {
"animation_length": 4.0,
"loop": true,
"timeline": {
"0.0": "variable.eyes_closed = 0;",
"3.8": "variable.eyes_closed = 1;"
}
}傀儡每四秒会闭一下眼。渲染控制器可以读取 variable.eyes_closed,显示另一张纹理或隐藏眼睛骨骼(见渲染控制器)。
一个键可以放一个字符串,也可以放字符串列表:"1.0": ["variable.a = 1;", "variable.b = 2;"]。
第 3 部分:行为包动画
接下来是最妙的部分。服务端也能运行动画和控制器。它不能移动骨骼(服务端没有模型可动),但能运行时间轴和控制器状态。这就让它们成了生物体内的一个小型脚本工具,完全不需要 JavaScript。
在行为包中,事件可以是三种东西:
| 事件字符串 | 作用 |
|---|---|
"/say Hello" | 运行一条命令,就像生物自己输入的一样。@s 就是生物本身。 |
"@s wiki:enrage" | 运行生物自身 events 列表中的一个事件 |
"variable.rage = 1;" | 运行 Molang |
实体事件只能作用于生物自己,所以写法永远是 @s 加事件名。
第 1 步:监视生命值的控制器
让傀儡在生命值低于 20 时暴怒,恢复后再平静下来:
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.ruby_golem.rage": {
"initial_state": "calm",
"states": {
"calm": {
"transitions": [
{ "enraged": "query.health < 20" }
]
},
"enraged": {
"on_entry": [
"/say The ruby golem is cracking!",
"/particle minecraft:lava_particle ~ ~1 ~",
"@s wiki:enrage"
],
"on_exit": [
"@s wiki:calm_down"
],
"transitions": [
{ "calm": "query.health >= 20" }
]
}
}
}
}
}on_entry 列表会在傀儡进入 enraged 时运行一次。命令从傀儡的位置执行,所以 ~ ~1 ~ 表示它上方一格。
第 2 步:循环计时动画
循环播放的行为包动画是个方便的计时器。下面这个会在每 10 秒循环开始时给傀儡短暂回血:
{
"format_version": "1.10.0",
"animations": {
"animation.ruby_golem.regen": {
"loop": true,
"animation_length": 10.0,
"timeline": {
"0.0": "/effect @s regeneration 3 0 true"
}
}
}
}第 3 步:在实体中启用
在行为包的实体文件中,把它们列在 description 下,并用 scripts.animate 播放,和客户端实体的做法一样:
{
"format_version": "1.21.0",
"minecraft:entity": {
"description": {
"identifier": "wiki:ruby_golem",
"is_spawnable": true,
"is_summonable": true,
"animations": {
"rage": "controller.animation.ruby_golem.rage",
"regen": "animation.ruby_golem.regen"
},
"scripts": {
"animate": ["rage", "regen"]
}
},
"component_groups": {
"wiki:enraged": {
"minecraft:movement": { "value": 0.35 },
"minecraft:attack": { "damage": 12 }
}
},
"components": { },
"events": {
"wiki:enrage": {
"add": { "component_groups": ["wiki:enraged"] }
},
"wiki:calm_down": {
"remove": { "component_groups": ["wiki:enraged"] }
}
}
}
}现在受伤的傀儡会跑得更快、打得更狠,等生命恢复效果让它回到 20 以上后就恢复正常。
命令会频繁运行
on_entry 中的命令在每次进入该状态时都会运行,而且世界里的每个傀儡都会运行。二十个傀儡切换状态,就会刷出二十条 /say 消息。聊天类命令只在测试时用,正式发布的附加包里请用不会刷屏的命令。
出问题时
| 你看到的现象 | 最可能的原因 |
|---|---|
| 没有粒子 | 简称不在客户端实体的 particle_effects 中,或粒子标识符写错了 |
| 粒子出现在生物脚下而不是定位器处 | 定位器名称拼错了,或它在另一根骨骼中 |
| 没有声音 | 声音事件名在 sound_definitions.json 中不存在 |
| 资源包里的命令没有效果 | 命令只在行为包动画中有效 |
| 行为包控制器从不运行 | 它写在了 description.animations 中,但没有写进 description.scripts.animate |
@s wiki:enrage 没有效果 | 实体的 events 中缺少该事件,或事件名拼错了 |
更多帮助见故障排查。