Skip to content

为生成器做好准备

扩展音符盒(Extended Note Block)拥有许多自定义 NBT 标签,利用这些标签可以实现比传统音符盒更丰富的音乐效果。这对于通过命令方块或外部生成器批量生成音符盒非常有用。

NBT 结构概览

扩展音符盒的 NBT 数据主要分为基础属性高级数据 (AdvancedData) 两部分。

基础属性 (Root)

这些属性直接位于 NBT 的根节点下:

标签名类型描述范围/单位默认值
noteIntMIDI 音高0-127 (60 为中央C)60
velocityIntMIDI 力度 (基础音量)0-127100
sustainTimeInt音符持续时间游戏刻 (Ticks, 20 ticks = 1s)40
delayedPlayingTimeInt延迟播放时间毫秒 (ms)0
fadeInTimeInt淡入时间游戏刻 (Ticks)0
fadeOutTimeInt淡出时间游戏刻 (Ticks)0

方块状态 (Block States)

除了 NBT 数据,扩展音符盒还使用 BlockStates 来处理红石信号和视觉表现。

状态名类型可选值描述
pitchEnumc, cs, d, ds, e, f, fs, g, gs, a, as, b对应当前音符在一个八度内的音高(Note % 12)。主要用于资源包更改方块纹理。例如 cs 代表 C#。
poweredBooleantrue, false标记方块是否被红石信号激活。用于检测信号边缘(上升沿/下降沿)。

注意

当你使用 setblock 放置方块时,通常不需要手动指定 pitch,因为方块在被红石激活时,会根据 NBT 中的 note 值自动计算并更新这个状态。

高级数据 (AdvancedData Compound)

所有高级功能的数据都存储在一个名为 AdvancedData 的复合标签内。生成器需要构造精确的 List 数据结构。

1. 弯音曲线 (PitchBendPoints)

  • 类型: List<Compound>
  • 元素结构: {t: <float>, v: <float>}
    • t (Time): 时间点,范围 0.0 (开始) 到 1.0 (结束)。
    • v (Value): 半音 (Semitones) 偏移量。
      • 0.0: 无偏移(原音高)。
      • 12.0: 升高一个八度。
      • -12.0: 降低一个八度。
      • 支持小数,例如 0.5 半音(50 音分)。
  • 插值行为: 游戏会在两个关键点之间进行线性插值

2. 音量包络 (VolumePoints)

  • 类型: List<Compound>
  • 元素结构: {t: <float>, v: <float>}
    • t (Time): 时间点,范围 0.01.0
    • v (Value): 音量倍率 (Multiplier)
      • 1.0: 标准音量(由 velocity 决定)。
      • 0.0: 静音。
      • 2.0: 两倍标准音量。
  • 插值行为: 游戏会在两个关键点之间进行线性插值
  • 覆盖规则: 一旦此列表非空,NBT 根节点的 fadeInTime/fadeOutTime 将失效。

3. 声源移动路径 (SoundPath)

  • 类型: List<Compound>
  • 元素结构: {x: <double>, y: <double>, z: <double>}
    • 这组坐标是相对于音符盒中心的偏移量。例如 {x:0, y:1, z:0} 表示在音符盒上方 1 格处。
  • 采样行为: 与曲线不同,SoundPath 不进行线性插值
    • 游戏会根据当前播放进度,计算出索引 Index = Progress * (Size - 1),直接取对应点的位置。
    • 建议: 如果需要平滑移动,生成器应生成足够密集的点(例如,如果 sustainTime 为 40 ticks,建议生成 40 个路径点,每 tick 一个点)。

4. GUI 表达式缓存 (ExpressionX/Y/Z)

  • 类型: String
  • 这些仅字符串用于在 GUI 中回显用户输入的公式(如 sin(t * pi))。

重要

游戏核心逻辑完全忽略这些字符串。如果你是一个外部生成器,不需要生成这些字符串,除非你想让玩家打开 GUI 时看到特定的公式。你需要生成的是上方的 SoundPath 列表。

Setblock 命令示例

你可以使用 /setblock 命令来放置一个带有预设 NBT 数据的扩展音符盒。

基础示例:

mcfunction
setblock ~ ~1 ~ extendednoteblock:extended_note_block{note:64, velocity:120, sustainTime:10}

高级示例(包含弯音):

mcfunction
setblock ~ ~1 ~ extendednoteblock:extended_note_block{note:60, sustainTime:40, AdvancedData:{PitchBendPoints:[{t:0.0f, v:0.0f}, {t:1.0f, v:12.0f}]}}

注意事项

SoundPath 与 Expression 的关系

AdvancedData 中,你可能会发现同时存在 SoundPathExpressionX/Y/Z

  • Expr (表达式):仅用于GUI 界面显示和编辑。游戏在运行时不会计算这些表达式。
  • SoundPath (路径):这是游戏实际播放声音时使用的路径数据。

关键点: 如果你编写生成器,必须直接生成 SoundPath 列表数据。仅仅写入 Expression 字符串是无效的,声音不会移动,除非玩家手动打开 GUI 并保存,此时客户端才会根据表达式计算出路径点并写入 SoundPath

音量控制优先权

音量主要由以下两个属性控制:

  1. velocity (基础力度):决定全曲的基础音量。
  2. VolumePoints (高级音量曲线):如果 AdvancedData 中存在非空的 VolumePoints 列表,它将完全覆盖 (Override) 基础 velocity 的效果。

这意味着,如果你想使用动态的音量包络(ADSR等),应使用 VolumePoints;如果是简单的固定音量,使用 velocity 即可。