1. Wiki
  2. /粒子
  3. /粒子组件

粒子组件

详解 Minecraft 基岩版的每一个粒子组件:初始速度和旋转、运动、碰撞、广告牌外观、颜色、光照和寿命。

粒子组件描述的是每一个粒子:它如何开始、如何移动、长什么样,以及何时消失。它们放在粒子文件的 components 块中,旁边是负责生成粒子的发射器组件。

刚接触粒子?你的第一个粒子从零开始做了一个红宝石闪光效果,用到了下面大部分组件。

每个粒子都需要什么

实际上,每个效果都需要 particle_lifetime_expression(否则粒子永远不会消失)和 particle_appearance_billboard(否则什么都看不见)。其他组件都是可选的,可以随意组合。

数字字段可以填普通数字,也可以填 Molang 字符串。在 Molang 里,你可以使用 variable.particle_age、variable.particle_lifetime 以及 variable.particle_random_1 到 _4,让每个粒子都有自己的个性。

初始状态

这些在粒子诞生时设置一次。

组件作用主要字段
minecraft:particle_initial_speed粒子开始移动时有多快一个数字(每秒格数,沿发射器形状给出的方向),或者一个 [x, y, z] 速度
minecraft:particle_initial_spin图片的初始角度以及旋转的快慢rotation:角度(默认 0)。rotation_rate:每秒旋转的角度(默认 0)
minecraft:particle_initialization为每个粒子运行你自己的 Molang,设置其他字段要读取的变量per_update_expression:每次更新时运行。per_render_expression:每次绘制时运行

速度

在 components 内部
"minecraft:particle_initial_speed": "math.random(1, 2)"

只写一个数字时,粒子会朝发射器形状给出的方向飞出。写三个数字时,由你自己设定速度,比如 [0, 2, 0] 表示笔直向上。不写这个组件的话,粒子一开始是静止的。

旋转

在 components 内部
"minecraft:particle_initial_spin": {
  "rotation": "math.random(0, 360)",
  "rotation_rate": "math.random(-90, 90)"
}

旋转会让平面图片像车轮一样绕中心转动。随机的初始角度是让一大群粒子看起来不像复制品的最简单方法。

你自己的变量

在 components 内部
"minecraft:particle_initialization": {
  "per_render_expression": "variable.twinkle = math.sin(variable.particle_age * 720) * 0.5 + 0.5;"
}

现在 variable.twinkle 每秒在 0 和 1 之间来回摆动两次,你可以用它来控制大小或颜色。如果想让某个值在整个生命周期中按某种形状变化,使用曲线通常更简单。

运动

这些组件在粒子诞生后的每一帧移动它。

组件作用主要字段
minecraft:particle_motion_dynamic带有力的真实运动:重力、风、空气阻力、旋转加速linear_acceleration、linear_drag_coefficient、rotation_acceleration、rotation_drag_coefficient
minecraft:particle_motion_parametric用 Molang 精确设置每一帧的位置,忽略所有的力relative_position、direction、rotation
minecraft:particle_motion_collision让粒子能撞到方块:弹起、滑行、停下或消失enabled、collision_radius、coefficient_of_restitution、collision_drag、expire_on_contact、events

动态运动

在 components 内部
"minecraft:particle_motion_dynamic": {
  "linear_acceleration": [0, -9.8, 0],
  "linear_drag_coefficient": 0.5,
  "rotation_acceleration": 0,
  "rotation_drag_coefficient": 0
}
字段作用
linear_acceleration每秒施加的推力,写成 [x, y, z],单位是格每二次方秒。[0, -9.8, 0] 感觉像是在下落。y 为正数时会像烟一样往上飘
linear_drag_coefficient空气阻力。粒子越快,减速越厉害。0 表示没有阻力
rotation_acceleration让旋转加速(负值则减速),单位是度每二次方秒
rotation_drag_coefficient让旋转慢下来,这样旋转的粒子最终会稳定住

动态运动作用于粒子的速度,所以它可以和 particle_initial_speed 配合:一开始很快,然后交给重力和阻力接管。

参数化运动

在 components 内部
"minecraft:particle_motion_parametric": {
  "relative_position": [
    "math.cos(variable.particle_age * 360) * 0.8",
    "variable.particle_age",
    "math.sin(variable.particle_age * 360) * 0.8"
  ]
}

这里你跳过物理计算,直接说明粒子在哪里,以发射器为原点来测量。这个例子每秒绕一圈,同时每秒上升一格:形成一道红宝石螺旋。direction 和 rotation 也可以用同样的方式设置。

参数化运动需要普通发射器

参数化运动对 emitter_rate_manual 生成的粒子无效。对于附着在生物身上的效果,只有当发射器的位置使用局部空间时它才有效。

碰撞

在 components 内部
"minecraft:particle_motion_collision": {
  "collision_radius": 0.1,
  "coefficient_of_restitution": 0.4,
  "collision_drag": 2,
  "events": { "event": "pop", "min_speed": 2 }
}

没有这个组件的话,粒子会直接穿过方块。

字段作用
enabled开启或关闭碰撞。可以是 Molang,每帧检查一次。默认开启
collision_radius粒子在碰撞方块时有多大。必须不超过半格。大致与广告牌的大小保持一致
coefficient_of_restitution弹性。0 会直接停住,1 会弹回同样的高度,介于两者之间时每次弹跳都会损失一些高度
collision_drag粒子接触表面时的减速,单位是每秒格数。让它滑行一段后停下
expire_on_contact设为 true 时,粒子一碰到方块就消失。很适合做雨滴
events撞到东西时触发你的某个事件,比如溅起水花。可以是一个事件对象,也可以是一个列表。min_speed(至少每秒 2 格)会忽略轻微的触碰

碰撞会消耗性能

为每个粒子检测方块对游戏来说是不小的工作量。只在能看出区别的地方添加碰撞,并且让这些效果的 max_particles 保持在较低水平。

外观

这些组件决定粒子在屏幕上的样子。

组件作用主要字段
minecraft:particle_appearance_billboard把粒子绘制成一张平面图片,并决定它的大小、朝向以及显示纹理的哪一部分size、facing_camera_mode、direction、uv
minecraft:particle_appearance_tinting给图片着色,可以是单一颜色,也可以是随时间变化的渐变color
minecraft:particle_appearance_lighting像方块一样,让粒子在暗处变暗、在亮处变亮无:写 {} 即可

广告牌

在 components 内部
"minecraft:particle_appearance_billboard": {
  "size": [0.1, 0.1],
  "facing_camera_mode": "lookat_xyz",
  "uv": {
    "texture_width": 32,
    "texture_height": 8,
    "uv": [0, 0],
    "uv_size": [8, 8]
  }
}

size 是 [宽度, 高度],每帧都会检查一次,所以在这里写 Molang 可以让粒子变大或变小。每个值都是从中心开始测量的,所以 0.5 会形成一个一格宽的正方形。

facing_camera_mode 决定平面图片朝向哪里:

模式图片
lookat_xyz始终面向相机,但保持竖直。最常用的选择
rotate_xyz平贴在屏幕上,随相机一起转动
lookat_y / rotate_y面向相机,但只左右转动,就像立在地上的纸板人
lookat_direction面向相机,同时与粒子的方向对齐。适合做拖尾
direction_x / direction_y / direction_z让图片的 x 边、y 边或正面沿粒子的方向
emitter_transform_xy / _xz / _yz平躺在发射器的某个平面上。_xz 可以在地面上做出平贴的贴花

方向类模式需要知道粒子指向哪里。用 direction 来设置:

在 minecraft:particle_appearance_billboard 内部
"direction": {
  "mode": "derive_from_velocity",
  "min_speed_threshold": 0.01
}

derive_from_velocity 使用粒子的运动方向,但只在它的速度高于 min_speed_threshold 时生效。如果想自己设置,就用 "mode": "custom_direction" 配合 "custom_direction": [x, y, z]。

uv 选择要显示纹理的哪一部分。texture_width 和 texture_height 是你的 PNG 的像素尺寸,uv 是左上角,uv_size 是你想要的那部分的宽和高。上面的例子显示的是一条 32x8 图片带中的第一个 8x8 帧。

翻页动画

把几帧图片并排放在一起,广告牌就能像翻页书一样播放它们。把 uv 和 uv_size 换成 flipbook:

在 uv 块内部
"uv": {
  "texture_width": 32,
  "texture_height": 8,
  "flipbook": {
    "base_UV": [0, 0],
    "size_UV": [8, 8],
    "step_UV": [8, 0],
    "max_frame": 4,
    "stretch_to_lifetime": true,
    "loop": false
  }
}
字段作用
base_UV第一帧的左上角
size_UV一帧的宽和高
step_UV移到下一帧要移动多远。[8, 0] 表示向右移
max_frame一共有多少帧(第一帧是第 1 帧)
frames_per_second播放速度
stretch_to_lifetime设为 true 时会忽略速度,在粒子的整个生命周期内把所有帧恰好播放一遍
loop设为 true 时,播完最后一帧后从第一帧重新开始

一个 4 帧的红宝石闪光,先张开、再闪耀、然后合上,比单张图片要生动得多。

着色

在 components 内部
"minecraft:particle_appearance_tinting": {
  "color": [1, 0.15, 0.3, 1]
}

颜色会和纹理相乘,所以粒子纹理要画成白色或灰色,再让着色来添加颜色。颜色可以用以下任意一种方式书写:

形式示例
[r, g, b] 或 [r, g, b, a],每个值 0 到 1[1, 0.15, 0.3, 1]
"#RRGGBB""#FF2650"
"#AARRGGBB"(alpha 在前)"#80FF2650" 是半透明的
每个位置写 Molang["variable.tint.r", "variable.tint.g", "variable.tint.b", 1]

要让颜色随时间变化,就使用渐变。各个颜色会均匀分布,interpolant 决定粒子此刻处于渐变上的哪个位置:

在 components 内部
"minecraft:particle_appearance_tinting": {
  "color": {
    "gradient": {
      "0.0": "#FFFFFFFF",
      "0.3": "#FFFF2650",
      "1.0": "#00600018"
    },
    "interpolant": "variable.particle_age / variable.particle_lifetime"
  }
}

像这样写成对象时,每个颜色都位于你指定的位置。如果写成普通列表,颜色则会从 0 到 1 均匀分布。这个闪光效果先闪一下白光,很快变成红宝石红,然后慢慢淡出。

透明度需要合适的材质

半透明颜色只有在使用 particles_blend 或 particles_add 材质时才会显示。使用 particles_alpha 时,像素要么完全显示,要么完全隐藏。

光照

在 components 内部
"minecraft:particle_appearance_lighting": {}

加上它之后,粒子在洞穴里和夜晚会显得更暗,从而与世界融为一体。对于应该在黑暗中发光的东西,比如魔法、火焰以及我们的红宝石闪光,就不要加它。

寿命

这些组件决定粒子何时消失。

组件作用主要字段
minecraft:particle_lifetime_expression主要的寿命设置:固定时间,或每帧检查一次的 Molang 条件max_lifetime、expiration_expression
minecraft:particle_lifetime_events在每个粒子生命中的某些时刻触发你的事件creation_event、expiration_event、timeline
minecraft:particle_kill_plane移除穿过一个看不见的平面的粒子[A, B, C, D]
minecraft:particle_expire_if_in_blocks移除位于列出的任意方块内部的粒子方块名称列表
minecraft:particle_expire_if_not_in_blocks移除离开列出的方块的粒子方块名称列表

寿命表达式

在 components 内部
"minecraft:particle_lifetime_expression": {
  "max_lifetime": "math.random(0.8, 1.5)"
}
  • max_lifetime 是以秒为单位的寿命,在粒子诞生时确定一次。
  • expiration_expression 每帧检查一次。当它不为 0 时,粒子就会消失。例如 "variable.particle_age > 1 && query.is_in_water" 可以让粒子提前结束。

两者可以同时使用:哪个先满足,粒子就在那时消失。

寿命事件

在 components 内部
"minecraft:particle_lifetime_events": {
  "creation_event": "flash",
  "expiration_event": "pop",
  "timeline": {
    "0.25": "twinkle"
  }
}

这些名称指向同一个文件中的 events 块,每个字段可以填一个名称或一个列表。和发射器版本不同,这些事件会为每一个粒子单独触发,所以一次爆发 12 个闪光就会触发 12 次 pop。事件能做什么,请参见事件。

消除平面

在 components 内部
"minecraft:particle_kill_plane": [0, 1, 0, 0.5]

这四个数字用数学方式描述一个平面:所有满足 A*x + B*y + C*z + D = 0 的点,以发射器为原点测量,但与世界坐标轴对齐。穿过它的粒子会消失。[0, 1, 0, 0.5] 是位于发射器下方半格处的一块地面。这是一种不用碰撞就能拦住下落粒子的低成本方法。

在方块内与不在方块内

在 components 内部
"minecraft:particle_expire_if_not_in_blocks": [
  "minecraft:water",
  "minecraft:flowing_water",
  "minecraft:bubble_column"
]

气泡到达水面时破裂就是这样实现的:它们只有在水里时才存活。相反的情况就用 particle_expire_if_in_blocks,比如灰尘一飘进水里就消失。两者都可以与 particle_lifetime_expression 一起使用。

一个完整的粒子

把四类组件放在一起。这是一块下落的红宝石碎片的粒子部分,它会弹跳并逐渐淡出:

RP/particles/ruby_shard.json(components 内部)
"minecraft:particle_initial_speed": "math.random(2, 3)",
"minecraft:particle_initial_spin": {
  "rotation": "math.random(0, 360)",
  "rotation_rate": 180
},
"minecraft:particle_motion_dynamic": {
  "linear_acceleration": [0, -9.8, 0],
  "rotation_drag_coefficient": 1
},
"minecraft:particle_motion_collision": {
  "collision_radius": 0.05,
  "coefficient_of_restitution": 0.3,
  "collision_drag": 4
},
"minecraft:particle_appearance_billboard": {
  "size": [0.06, 0.06],
  "facing_camera_mode": "lookat_xyz",
  "uv": {
    "texture_width": 8,
    "texture_height": 8,
    "uv": [0, 0],
    "uv_size": [8, 8]
  }
},
"minecraft:particle_appearance_tinting": {
  "color": "#FFE0204A"
},
"minecraft:particle_appearance_lighting": {},
"minecraft:particle_lifetime_expression": {
  "max_lifetime": 2
}

再从发射器组件中给它配一个发射器,比如从一个小球体中一次爆发 8 个,就能做出很棒的方块破坏效果。

We use cookies to improve your experience and analyse site traffic. Learn more