5.2. Sync API 参考

以下 19 个类 由同一个 GDExtension(addons/sync,入口 sync_library_init)注册。所有类名称以 Sync 为前缀: 13 个共享数据类继承自 ResourceRefCounted,3 个编辑器组件、 2 个运行时类与对象池 SyncNodePool 继承自 NodeRefCounted


5.2.1. SyncBeat

继承:

Resource

由整数拍数、分子和分母组成的音乐时间值资源。

描述:

使用 beat + numerator/denominator 表示音乐时间中的一个点。例如 (1, 2, 4) 表示 1+2/4 拍 = 1.5 拍。在 Sync 系统中用于标记音符打击时间、HOLD 结束时间、关键帧位置和拍号变化的位置。

5.2.1.1. 方法

SyncBeat from_array(Array array) static

[beat, numerator, denominator] 格式的数组创建 SyncBeat。

float to_ms(SyncBpmAxis bpm_axis)

通过 bpm_axis 将此拍点转换为绝对毫秒时间。如果 bpm_axis 为 null 则返回 0.0。

5.2.1.2. 属性

beat (int, 默认 0)

整数拍数。可以为负数,表示时间线原点之前的位置。

numerator (int, 默认 0)

一拍细分内的分数分子。推荐范围为 [0, denominator)。若大于等于 denominator,构造时会自动归一化到下一拍;负值可能导致非预期行为,不建议使用。

denominator (int, 默认 1)

细分分母。必须为正数。常用值为 4、8、16、480。


5.2.2. SyncBpmAxis

继承:

Resource

定义谱面速度曲线的 BPM 关键帧集合。

描述:

通过 BPM 关键帧列表定义谱面的速度曲线。关键帧为空时,自动使用 init_value 作为 (0, 0, 1) 处的默认 BPM 值。

5.2.2.1. 方法

void add_keyframe(SyncBeat start, float bpm)

在指定的音乐时间位置添加一个 BPM 关键帧。关键帧会自动按时间排序。bpm 必须为正数。

float beat_to_ms(SyncBeat beat) const

beat 通过此 BPM 轴转换为绝对毫秒时间。若 beat 为 null 则返回 0.0。

SyncBeat ms_to_beat(float ms, int denominator=480) const

将毫秒时间 ms 通过此 BPM 轴转换为指定 denominator 分母的 SyncBeat。常用于编辑器中的时间显示。

void remove_keyframe_at(int index)

移除指定索引处的 BPM 关键帧。索引越界时不执行任何操作。

void update_keyframe_at(int index, float bpm)

更新指定索引处关键帧的 BPM 值。索引越界时不执行任何操作。

Dictionary get_keyframe_at(int index) const

返回指定索引处的关键帧字典。索引越界时返回空字典。字典包含 "start" (SyncBeat 资源)和 "bpm" (浮点数)。

5.2.2.2. 属性

init_value (float, 默认 120.0)

关键帧为空时使用的默认 BPM 值。必须为正数。

keyframes (Array, 默认 [])

关键帧字典数组,每个字典包含 "start" (SyncBeat 资源)和 "bpm" (浮点数)。


5.2.3. SyncDocumentChart

继承:

Resource

用于编辑、保存、加载和编译谱面的顶层文档资源。

描述:

SyncDocumentChart 是编辑谱面的根对象,以可编辑的树状结构保存所有谱面数据。编译后的运行时谱面经 SyncChartPlayer.set_document_chart 获得。

工作流程:

  1. 创建 SyncDocumentChart

  2. 添加轨道、音符和轴关键帧

  3. 交给 SyncChartPlayer 编译为运行时谱面(set_document_chart

  4. 通过 save_json / load_json 或 Godot 资源系统保存/加载

5.2.3.1. 方法

void add_root_track(SyncTrack track)

向谱面的顶层轨道列表添加一条轨道。

SyncChart compile()

编译为只读运行时谱面(SyncChart),不依赖任何节点生命周期。与 SyncChartPlayer.set_document_chart 的编译逻辑一致(含音乐时长注入)。

Array get_visible_note_ids(float chart_time_ms) const

返回在给定谱面时间所有根轨道中可见的音符信息。返回字典数组,每个字典包含 "track_id""local_id"

Array get_visible_notes(float chart_time_ms) const

返回在给定谱面时间所有根轨道中可见的 SyncNote 对象数组。

float get_duration_ms() const

返回编译后谱面的总时长(毫秒)。内部编译为 PlayChart 后计算,避免频繁调用。

int load_json(String path)

从指定路径的 JSON 文件加载谱面数据。成功返回 OK,失败返回错误码。

int load_json_string(String json_text)

从 JSON 字符串解析谱面数据。成功返回 OK,失败返回错误码。

int load_resource(String path)

从 Godot 二进制资源文件(.tres 或 .res)加载谱面数据,包括内嵌的音频和插图资源。

bool remove_root_track(SyncTrack track)

从根轨道列表中移除指定轨道。找到并移除后返回 true

void remove_root_track_at(int index)

移除指定索引处的根轨道。

int save_json(String path) const

将谱面保存为 JSON 文件到指定路径。成功返回 OK,失败返回错误码。

int save_resource(String path) const

将谱面保存为 Godot 二进制资源文件(.res),音频和插图数据内嵌保存。

int save_resource_split(String path, String music_path="", String illustration_path="") const

将谱面保存为 Godot 二进制资源文件,同时将音乐和插图保存到外部路径。

Dictionary to_json_dict() const

将谱面序列化为适合 JSON 导出的字典。字典结构与 Sync JSON 格式匹配。

String to_json_string() const

将谱面序列化为格式化的 JSON 字符串。

5.2.3.2. 属性

bpm (float, 默认 120.0)

谱面的默认 BPM(每分钟节拍数)。无 BPM 轴关键帧时作为备用值。

bpm_axis (SyncBpmAxis)

定义完整速度曲线的 BPM 轴。存在时优先于 bpm

illustration_texture (Texture2D)

谱面的插图/封面贴图。

illustration_texture_path (String, 默认 "")

插图/封面图片的文件路径。用于外部 JSON 序列化。

metadata (Dictionary, 默认 {})

谱面元数据字典。默认键为:music、musician、illustration、illustrator、creator、difficulty_label、difficulty_level。

music_audio (AudioStream)

谱面的音乐音频流。

music_audio_path (String, 默认 "")

音乐音频文件的路径。用于外部 JSON 序列化。

offset_ms (float, 默认 0.0)

音频偏移量(毫秒)。正值延迟音频,负值提前音频。

root_tracks (Array, 默认 [])

构成谱面顶层轨道的 SyncTrack 对象数组。

spec_name (String, 默认 "Sync/Generic")

谱面规格标识符。

spec_version (String, 默认 "0.1.0")

谱面规格版本号。

time_signature_map (SyncTimeSignatureMap)

定义谱面中节拍变化的拍号图。


5.2.4. SyncEase

继承:

RefCounted

关键帧缓动方向常量。

描述:

用于 SyncFloatAxis.add_keyframe 等方法的 ease 参数。

5.2.4.1. 常量

IN = 0

渐入。

OUT = 1

渐出。

IN_OUT = 2

渐入渐出。


5.2.5. SyncFloatAxis

继承:

Resource

浮点值关键帧动画轴。

描述:

通过关键帧提供浮点值的动画时间线。每个关键帧定义时间位置、目标值和过渡参数,可在任意谱面时间采样得到插值后的值。

过渡类型取值:0=STEP(阶跃)、1=LINEAR(线性)、2=SINE、3=QUAD、4=POLY、5=EXPO、6=CIRC、7=BACK、8=ELASTIC、9=BOUNCE。

缓动方向取值:0=IN(渐入)、1=OUT(渐出)、2=IN_OUT(渐入渐出)。

使用方法:

var axis = SyncFloatAxis.new()
axis.axis_name = "opacity"
axis.init_value = 0.5
axis.add_keyframe(beat_2s, 1.0, 0, 2)
var value = axis.sample(500.0, bpm_axis)  # 在 500ms 处采样

5.2.5.1. 方法

void add_keyframe(SyncBeat time, float value, int trans=0, int ease=2)

在指定的音乐时间添加一个关键帧。trans 控制插值曲线类型,ease 控制缓动方向。

void remove_keyframe_at(int index)

移除指定索引处的关键帧。

void update_keyframe_at(int index, float value, int trans=0, int ease=2)

更新指定索引处关键帧的值、过渡类型和缓动方向。索引越界时不执行任何操作。

Dictionary get_keyframe_at(int index) const

返回指定索引处的关键帧字典。索引越界时返回空字典。

float sample(float time_ms, SyncBpmAxis bpm_axis) const

在指定毫秒时间采样轴的值。需要传入 BPM 轴用于节拍→毫秒转换。在第一个关键帧之前返回 init_value

5.2.5.2. 属性

axis_name (String, 默认 "")

此轴在轨道中的唯一名称,运行时采样时用于查找。

init_value (float, 默认 0.0)

在第一个关键帧之前采样时返回的默认值。

keyframes (Array, 默认 [])

关键帧字典数组,每个字典包含 "time" (SyncBeat)、"value" (float)、"trans" (int)和 "ease" (int)。


5.2.6. SyncNote

继承:

Resource

谱面编辑器中的单个音符对象。

描述:

SyncNote 代表谱面中的单个音符。引擎只保留两种时间语义:

  • kind=0:TAP (单点击打;任何非 HOLD 的 kind 在引擎视角下都是 TAP)

  • kind=1:HOLD (长按),需设置 end_time 标记结束时间

游戏专属的音符种类(CATCH / VOID、自定义长按/滑键等)写在 metadata,例如 metadata["note_type"] = "catch",由你的 GDScript 判定逻辑按字符串分发——引擎不识别这些种类,但保证它们 的可见性、位置采样与序列化行为完全等价于 TAP。

5.2.6.1. 属性

kind (int, 默认 0)

音符种类。0=TAP,1=HOLD。任何非 HOLD 的 kind 在引擎视角下都被当作 TAP。 SyncNote.to_core()kind != 1 映射为 TAP。

local_id (String, 默认 "")

音符在轨道内的本地标识符。轨道内必须唯一。

time (SyncBeat)

音符打击的音乐时间。

end_time (SyncBeat)

HOLD 音符的长按结束时间。仅在 kind=1 时有效。

metadata (Dictionary, 默认 {})

可选的自定义元数据字典。游戏可在里面写 note_type 等自定义种类 (引擎不识别,按字符串由游戏判定代码分发);也用于附加任意键值 (如 x_pos / width / nodes 等附加几何数据—— 这些是特定作品的玩法层概念,不进入通用引擎)。


5.2.7. SyncSpeedAxis

继承:

Resource

控制轨道中音符滚动速度的关键帧动画轴。

描述:

SyncSpeedAxis 控制轨道上音符的视觉滚动速度。每个关键帧定义速度倍率(通常 1.0 = 正常速度),引擎对速度随时间积分以计算音符在画面上的滚动距离。

过渡类型仅支持:0=STEP(阶跃),1=LINEAR(线性渐变)。Speed 轴通常命名为 "speed"

5.2.7.1. 方法

void add_keyframe(SyncBeat time, float value, int trans=0)

在指定的音乐时间添加一个速度关键帧。value 为速度倍率,trans 为过渡类型(0=STEP,1=LINEAR)。

void remove_keyframe_at(int index)

移除指定索引处的关键帧。

void update_keyframe_at(int index, float value, int trans=0)

更新指定索引处关键帧的值和过渡类型。

Dictionary get_keyframe_at(int index) const

返回指定索引处的关键帧字典。

float sample_speed(float time_ms, SyncBpmAxis bpm_axis) const

在指定毫秒时间采样瞬时速度倍率。需要传入 BPM 轴。在第一个关键帧之前返回 init_value

float sample_position(float hit_time_ms, float chart_time_ms, SyncBpmAxis bpm_axis) const

计算参考时间点(hit_time_ms)在给定谱面时间(chart_time_ms)下的归一化位置。

  • 正值表示还未到达判定线

  • 0 表示正好在判定线上

  • 负值表示已越过

需要传入 BPM 轴。

5.2.7.2. 属性

axis_name (String, 默认 "speed")

此轴在轨道中的唯一名称。默认为 "speed"

init_value (float, 默认 1.0)

在第一个关键帧之前使用的默认速度倍率。

keyframes (Array, 默认 [])

关键帧字典数组,每个字典包含 "time" (SyncBeat)、"value" (float)和 "trans" (int)。


5.2.8. SyncTimeSignatureMap

继承:

Resource

定义谱面拍号变化的关键帧集合。

描述:

SyncTimeSignatureMap 定义谱面中音乐节拍的变化方式。每个关键帧指定一个音乐时间位置、分子(每小节拍数)和分母(节拍单位)。例如 4/4(默认)、3/4、6/8。

5.2.8.1. 方法

void add_keyframe(SyncBeat start, int numerator, int denominator)

在指定的音乐时间位置添加一个拍号关键帧。numerator 为每小节拍数,denominator 为节拍单位。

void remove_keyframe_at(int index)

移除指定索引处的拍号关键帧。索引越界时不执行任何操作。

void update_keyframe_at(int index, int numerator, int denominator)

更新指定索引处关键帧的分子和分母值。索引越界时不执行任何操作。

Dictionary get_keyframe_at(int index) const

返回指定索引处的拍号关键帧字典。索引越界时返回空字典。字典包含 "start" (SyncBeat)、"numerator" (int)和 "denominator" (int)。

5.2.8.2. 属性

keyframes (Array, 默认 [])

关键帧字典数组,每个字典包含 "start" (SyncBeat)、"numerator" (int)和 "denominator" (int)。


5.2.9. SyncTrack

继承:

Resource

谱面树中的轨道节点,包含音符、子轨道和动画轴。

描述:

SyncTrack 代表谱面层级树中的一条轨道。轨道包含音符(SyncNote)、子轨道和多种动画轴(Float、Vector2、Vector3、Vector4、Speed)。轨道以树状结构组织,每条轨道有一个唯一的 track_id

轨道中所有轴均可独立采样(无需编译为 PlayChart),通过 sample_float_axis 等系列方法按轴名查找并采样。

5.2.9.1. 方法

void add_child_track(SyncTrack track)

向此轨道的子树中添加一个子轨道。

void add_note(SyncNote note)

向此轨道添加一个音符。note.local_id 在轨道内必须唯一。

void add_float_axis(SyncFloatAxis axis)

向此轨道添加一个 Float 轴。轴名称在轨道内必须唯一。

void add_vector2_axis(SyncVector2Axis axis)

向此轨道添加一个 Vector2 轴。轴名称在轨道内必须唯一。

void add_vector3_axis(SyncVector3Axis axis)

向此轨道添加一个 Vector3 轴。轴名称在轨道内必须唯一。

void add_vector4_axis(SyncVector4Axis axis)

向此轨道添加一个 Vector4 轴。轴名称在轨道内必须唯一。

void add_speed_axis(SyncSpeedAxis axis)

向此轨道添加一个 Speed 轴。轴名称在轨道内必须唯一。

int get_note_count() const

返回此轨道中音符的数量。

Array get_note_position(String local_id, float chart_time_ms, SyncBpmAxis bpm_axis) const

根据 local_id 查找音符,返回其在给定谱面时间的归一化位置。返回 [head_pos, tail_pos] (HOLD 两个元素,TAP 一个元素)。内部使用 local_id → 索引哈希缓存与轴 to_core 缓存,重复调用为 O(1)。

Array get_note_position_fast(float hit_ms, float end_ms, int kind, float chart_time_ms, SyncBpmAxis bpm_axis) const

get_note_position 的免查找版本:直接传入音符的命中/结束毫秒与类型(0=TAP/1=HOLD;游戏专属种类写在 metadata),返回 [head_pos, tail_pos] (HOLD 且 end_ms > hit_ms 时两个元素,否则一个)。适合在调用方已缓存音符静态时间的每帧热路径中使用,避免任何查找与重复转换。

Array get_visible_note_ids(float chart_time_ms, SyncBpmAxis bpm_axis) const

返回在给定谱面时间可见的音符 local_id 数组。

Array get_visible_notes(float chart_time_ms, SyncBpmAxis bpm_axis) const

返回在给定谱面时间可见的 SyncNote 对象数组。

Array get_notes_in_time_range(float start_ms, float end_ms, SyncBpmAxis bpm_axis) const

返回时间范围 [start_ms, end_ms] 内与轨道音符时间区间有交集的 SyncNote 对象数组。不考虑 speed 轴,仅按绝对时间过滤。

bool remove_note(SyncNote note)

移除指定的音符。找到并移除后返回 true

void remove_note_at(int index)

移除指定索引处的音符。

bool remove_child_track(SyncTrack track)

移除指定的子轨道。找到并移除后返回 true

void remove_child_track_at(int index)

移除指定索引处的子轨道。

bool remove_float_axis(SyncFloatAxis axis)

移除指定的 Float 轴。找到并移除后返回 true

void remove_float_axis_at(int index)

移除指定索引处的 Float 轴。

bool remove_vector2_axis(SyncVector2Axis axis)

移除指定的 Vector2 轴。找到并移除后返回 true

void remove_vector2_axis_at(int index)

移除指定索引处的 Vector2 轴。

bool remove_vector3_axis(SyncVector3Axis axis)

移除指定的 Vector3 轴。找到并移除后返回 true

void remove_vector3_axis_at(int index)

移除指定索引处的 Vector3 轴。

bool remove_vector4_axis(SyncVector4Axis axis)

移除指定的 Vector4 轴。找到并移除后返回 true

void remove_vector4_axis_at(int index)

移除指定索引处的 Vector4 轴。

bool remove_speed_axis(SyncSpeedAxis axis)

移除指定的 Speed 轴。找到并移除后返回 true

void remove_speed_axis_at(int index)

移除指定索引处的 Speed 轴。

5.2.9.2. 采样方法(按轴名查找,带 fallback)

float sample_float_axis(String axis_name, float time_ms, SyncBpmAxis bpm_axis, float fallback=0.0) const

按轴名查找并采样 Float 轴。未找到时返回 fallback

Vector2 sample_vector2_axis(String axis_name, float time_ms, SyncBpmAxis bpm_axis, Vector2 fallback=Vector2(0, 0)) const

按轴名查找并采样 Vector2 轴。未找到时返回 fallback

Vector3 sample_vector3_axis(String axis_name, float time_ms, SyncBpmAxis bpm_axis, Vector3 fallback=Vector3(0, 0, 0)) const

按轴名查找并采样 Vector3 轴。未找到时返回 fallback

Vector4 sample_vector4_axis(String axis_name, float time_ms, SyncBpmAxis bpm_axis, Vector4 fallback=Vector4(0, 0, 0, 0)) const

按轴名查找并采样 Vector4 轴。未找到时返回 fallback

float sample_speed(String axis_name, float time_ms, SyncBpmAxis bpm_axis, float fallback=1.0) const

按轴名查找并采样 Speed 轴的瞬时速度倍率。未找到时返回 fallback

5.2.9.3. 属性

track_id (String, 默认 "")

此轨道的唯一标识符。在整个谱面中必须唯一。

notes (Array, 默认 [])

SyncNote 数组。

children (Array, 默认 [])

子轨道 SyncTrack 数组。

float_axes (Array, 默认 [])

SyncFloatAxis 数组。

vector2_axes (Array, 默认 [])

SyncVector2Axis 数组。

vector3_axes (Array, 默认 [])

SyncVector3Axis 数组。

vector4_axes (Array, 默认 [])

SyncVector4Axis 数组。

speed_axes (Array, 默认 [])

SyncSpeedAxis 数组。

metadata (Dictionary, 默认 {})

可选的自定义元数据字典。


5.2.10. SyncTrans

继承:

RefCounted

关键帧过渡类型常量。

描述:

用于 SyncFloatAxis.add_keyframe 等方法的 trans 参数。

5.2.10.1. 常量

STEP = 0

无插值阶跃。

LINEAR = 1

线性插值。

SINE = 2

正弦曲线缓动。

QUAD = 3

二次曲线缓动。

POLY = 4

四次曲线缓动(多项式,power=4)。

EXPO = 5

指数曲线缓动。

CIRC = 6

圆形曲线缓动。

BACK = 7

回弹缓动,超出目标后再回来。

ELASTIC = 8

弹性缓动。

BOUNCE = 9

弹跳缓动。


5.2.11. SyncVector2Axis

继承:

Resource

Vector2 值关键帧动画轴。

描述:

SyncVector2Axis 存储 Vector2 关键帧的时间线,在运行时进行插值。过渡类型与缓动方向取值同 SyncFloatAxis。

使用方法:

var axis = SyncVector2Axis.new()
axis.axis_name = "position"
axis.add_keyframe(beat_2s, Vector2(100, 200), 0, 2)
var pos = axis.sample(500.0, bpm_axis)

5.2.11.1. 方法

void add_keyframe(SyncBeat time, Vector2 value, int trans=0, int ease=2)

在指定的音乐时间添加一个 Vector2 关键帧。

void remove_keyframe_at(int index)

移除指定索引处的关键帧。

void update_keyframe_at(int index, Vector2 value, int trans=0, int ease=2)

更新指定索引处关键帧的值、过渡类型和缓动方向。

Dictionary get_keyframe_at(int index) const

返回指定索引处的关键帧字典。

Vector2 sample(float time_ms, SyncBpmAxis bpm_axis) const

在指定毫秒时间采样轴的值。需要传入 BPM 轴。在第一个关键帧之前返回 init_value

5.2.11.2. 属性

axis_name (String, 默认 "")

此轴在轨道中的唯一名称。

init_value (Vector2, 默认 Vector2(0, 0))

在第一个关键帧之前采样时返回的默认值。

keyframes (Array, 默认 [])

关键帧字典数组。


5.2.12. SyncVector3Axis

继承:

Resource

Vector3 值关键帧动画轴。

描述:

SyncVector3Axis 存储 Vector3 关键帧的时间线,在运行时进行插值。过渡类型与缓动方向取值同 SyncFloatAxis。

5.2.12.1. 方法

void add_keyframe(SyncBeat time, Vector3 value, int trans=0, int ease=2)

在指定的音乐时间添加一个 Vector3 关键帧。

void remove_keyframe_at(int index)

移除指定索引处的关键帧。

void update_keyframe_at(int index, Vector3 value, int trans=0, int ease=2)

更新指定索引处关键帧的值、过渡类型和缓动方向。

Dictionary get_keyframe_at(int index) const

返回指定索引处的关键帧字典。

Vector3 sample(float time_ms, SyncBpmAxis bpm_axis) const

在指定毫秒时间采样轴的值。需要传入 BPM 轴。在第一个关键帧之前返回 init_value

5.2.12.2. 属性

axis_name (String, 默认 "")

此轴在轨道中的唯一名称。

init_value (Vector3, 默认 Vector3(0, 0, 0))

在第一个关键帧之前采样时返回的默认值。

keyframes (Array, 默认 [])

关键帧字典数组。


5.2.13. SyncVector4Axis

继承:

Resource

Vector4 值关键帧动画轴。

描述:

SyncVector4Axis 存储 Vector4 关键帧的时间线,在运行时进行插值。过渡类型与缓动方向取值同 SyncFloatAxis。

5.2.13.1. 方法

void add_keyframe(SyncBeat time, Vector4 value, int trans=0, int ease=2)

在指定的音乐时间添加一个 Vector4 关键帧。

void remove_keyframe_at(int index)

移除指定索引处的关键帧。

void update_keyframe_at(int index, Vector4 value, int trans=0, int ease=2)

更新指定索引处关键帧的值、过渡类型和缓动方向。

Dictionary get_keyframe_at(int index) const

返回指定索引处的关键帧字典。

Vector4 sample(float time_ms, SyncBpmAxis bpm_axis) const

在指定毫秒时间采样轴的值。需要传入 BPM 轴。在第一个关键帧之前返回 init_value

5.2.13.2. 属性

axis_name (String, 默认 "")

此轴在轨道中的唯一名称。

init_value (Vector4, 默认 Vector4(0, 0, 0, 0))

在第一个关键帧之前采样时返回的默认值。

keyframes (Array, 默认 [])

关键帧字典数组。


5.2.14. SyncProgressManager

继承:

Node

配合 SyncDocumentChart 的进度管理节点,内置时钟、播放控制和节拍导航。

5.2.14.1. 描述

SyncProgressManager 配合 SyncDocumentChart 使用,内置时钟通过 _process 驱动进度推进。共享数据类由 Sync GDExtension 注册,bind_chart 直接传 chart 对象即可。

总时长模型:乐曲时长 + 开头留白(head_padding_ms)+ 结尾留白(tail_padding_ms),默认各 5 秒即"乐曲时长 + 10 秒";不编译谱面(音符内容不影响时长)。无音乐时由 set_duration_ms() 手动指定。

5.2.14.2. 方法

void bind_chart(Object chart)

绑定 DocumentChart,进度和播放状态重置。chart 须为 Sync 插件注册的 SyncDocumentChart。

SyncDocumentChart get_chart() const

返回当前绑定的谱面。

void play()

开始播放。内置时钟从当前进度继续推进。

void pause()

暂停播放,进度保持在当前位置。

void stop()

停止播放并重置进度到 0。

bool is_playing() const

返回是否正在播放。

void set_playback_rate(float rate)

设置播放速率(必须大于 0,1.0 为原速;非正值将被忽略,不支持倒放)。仅影响谱面毫秒时钟的推进速度;谱面毫秒到拍数、音频文件位置的换算与速率无关。音频侧需自行按同一速率变速播放。

float get_playback_rate() const

返回当前播放速率。

void set_audio_started()

标记音频已启动。调用后内部音频状态被视为 active,直到 pause、stop 或 seek 重置。

float get_audio_progress_ms() const

返回音频进度 = max(0, progress_ms - offset_ms - delay_ms)

float get_progress_ms() const

返回当前谱面进度(毫秒)。

float get_progress_beats() const

返回当前进度(拍数)。

float get_duration_ms() const

返回谱面总时长(毫秒)。

float get_duration_beats() const

返回谱面总时长(拍数)。

String get_beat_string() const

返回当前进度的节拍字符串,格式 "beat:numerator/denominator"

5.2.14.3. 进度跳转

void seek_ms(float time_ms)

跳转到指定毫秒位置,自动钳制到 [0, duration]。重置音频启动状态。

void seek_beats(float beats)

跳转到指定拍数位置。重置音频启动状态。

void seek_ratio(float ratio)

按比例跳转(0.0 到 1.0)。重置音频启动状态。

void jump_to_next_beat()

按当前 beat_division 精度向后跳转一拍。重置音频启动状态。

void jump_to_previous_beat()

按当前 beat_division 精度向前跳转一拍。重置音频启动状态。

void snap_to_nearest_beat()

吸附到最近的节拍网格线上。重置音频启动状态。

5.2.14.4. 细分精度

void set_beat_division(int division)

设置节拍细分精度。仅在可用值列表中有效。

int get_beat_division() const

返回当前节拍细分精度。

void cycle_beat_division_up()

切换到下一个更细的可用细分精度(循环)。

void cycle_beat_division_down()

切换到上一个更粗的可用细分精度(循环)。

Array get_available_divisions() const

返回所有可用细分精度的整数数组:[2, 3, 4, 6, 8, 12, 16, 24, 32]

5.2.14.5. 属性

beat_division (int, 默认 4)

当前节拍细分精度。可用值为 [2, 3, 4, 6, 8, 12, 16, 24, 32]

head_padding_ms (float, 默认 5000.0)

开头留白(毫秒)。总时长 = 乐曲时长 + 开头留白 + 结尾留白。

playback_rate (float, 默认 1.0)

播放速率。1.0 为原速;必须大于 0,不支持倒放。仅改变谱面时钟的推进速度,音频侧需自行同步变速。

tail_padding_ms (float, 默认 5000.0)

结尾留白(毫秒)。

5.2.14.6. 信号

信号: chart_changed()

绑定新谱面时发射。

信号: playback_rate_changed(float rate)

播放速率变更时发射,rate 为新速率。音频层应据此同步变速播放。

信号: seek_completed()

跳转操作完成后发射。

信号: playback_state_changed(bool playing)

播放状态变更时发射。play() 时 playing 为 true,pause() / stop() 时为 false。

信号: audio_state_changed(bool playing, float progress_ms)

音频状态变化时发射。play() 或 _process() 检测到音频进度大于等于 0 时发射 playing=true,progress_ms 为当前音频位置(毫秒);pause() / stop() 音频从 active 状态离开时发射 playing=false。seek 后会被重置,允许再次发射。


5.2.15. SyncTimeline

继承:

RefCounted

归一化时间轴坐标映射:谱面毫秒 ↔ 归一化位置双向换算 + 输入反推节拍。

5.2.15.1. 描述

把"谱面毫秒 ↔ 归一化位置(底部 0 / 顶部 1)"的双向换算与"归一化位置 → 节拍(含吸附)"的输入反推集中在一个无状态组件上。本类不做任何渲染:像素/控件坐标与归一化坐标的互转由调用方负责。

换算公式:

position = judge_line_position + (1 - judge_line_position) * (time_ms - progress_ms) / (base_visible_duration_ms * zoom)
  • 制谱器布局(判定线距顶 0.85)对应 judge_line_position = 0.15 (默认值)

  • 横向时间轴把同一 position 映射到 x 即可

  • 所有换算方法的 progress_ms 参数缺省为 -1.0:此时使用绑定的 progress_manager 的当前进度;未绑定则报错并返回安全值

  • BPM 来源优先级:bpm_axis > progress_manager 绑定谱面的 bpm_axis > 谱面 bpm 常量

5.2.15.2. 方法

float time_to_normalized(float time_ms, float progress_ms=-1.0)

谱面毫秒 → 归一化位置(可超出 [0,1],由调用方裁剪)。

float normalized_to_time(float position, float progress_ms=-1.0)

归一化位置 → 谱面毫秒(time_to_normalized 的逆映射)。

SyncBeat normalized_to_beat(float position, float progress_ms=-1.0)

归一化位置 → 节拍(按 beat_division 精度量化到最近网格)。输入映射入口:把点击的归一化坐标反推为节拍。

float beat_to_normalized(SyncBeat beat, float progress_ms=-1.0)

节拍 → 归一化位置。

SyncBeat time_to_beat(float time_ms)

谱面毫秒 → 节拍(按 beat_division 精度量化)。

float beat_to_time(SyncBeat beat)

节拍 → 谱面毫秒。

float snap_time_ms(float time_ms)

毫秒吸附到最近的 beat_division 网格线上。

float get_visible_duration_ms()

当前可见时长(毫秒)= base_visible_duration_ms * zoom

Array get_available_divisions()

全部可用节拍细分:[2, 3, 4, 6, 8, 12, 16, 24, 32]

5.2.15.3. 属性

judge_line_position (float, 默认 0.15)

判定线归一化位置(0=底部,1=顶部),clamp 到 [0.01, 0.99]。默认 0.15 对应判定线距顶 0.85 的制谱器布局。

zoom (float, 默认 1.0)

缩放倍率(>0)。可见时长 = base_visible_duration_ms * zoom

base_visible_duration_ms (float, 默认 1000.0)

zoom = 1 时的可见时长(毫秒),必须为正数。

beat_division (int, 默认 4)

节拍细分(吸附与网格密度),仅 [2, 3, 4, 6, 8, 12, 16, 24, 32] 表内值生效。绑定 progress_manager 时取其当前细分一次。

bpm_axis (Object)

BPM 轴(须为 Sync 插件注册的 SyncBpmAxis)。优先级最高的拍↔毫秒换算来源;不设置时从 progress_manager 的谱面解析。

progress_manager (SyncProgressManager)

可选进度管理器。绑定后所有 progress_ms 参数可缺省(-1.0 时取 PM 当前进度)。


5.2.16. SyncBeatGrid

继承:

RefCounted

节拍线数据提供器:输出可见窗口内全部节拍线的纯数据,不做任何渲染。

5.2.16.1. 描述

基于 timeline (SyncTimeline)的归一化坐标系,输出当前可见窗口内全部节拍线的位置/类型/颜色/拍号。绘制方式(draw_line / MultiMesh / 自定义节点)由调用方自行决定——本类只提供数据。

get_lines 返回 Array[Dictionary],每条线一个字典:

  • position: float,归一化位置(底部 0、顶部 1;含边距可略出界,调用方裁剪)

  • type: int,LineType(TYPE_WHOLE_BEAT=0 整拍线,TYPE_SUBDIVISION=1 细分线,TYPE_JUDGE=2 判定线)

  • color: Color,按 kind 映射的可调颜色(默认制谱器配色)

  • beat: int,所属第几拍(判定线为 -1)

  • is_whole_beat: bool,是否整数拍

  • kind: int,LineKind 细分分类(判定线为 -1)

  • label: String,整拍为拍号、判定线为 "JUDGE"、其余为空

  • thickness: float,参考线宽

节拍线过密时自动沿可用细分表向粗降级(阈值见 min_line_spacing)。

5.2.16.2. 方法

Array get_lines(float progress_ms=-1.0)

计算当前窗口全部节拍线(时间升序,判定线条目在末尾)。progress_ms 缺省走 timeline 绑定的 progress_manager。

5.2.16.3. 属性

timeline (SyncTimeline)

坐标系来源(必填)。判定线位置 / 缩放 / 细分 / 进度全部取自它。

show_judge_line (bool, 默认 true)

是否在输出末尾附带判定线条目。

min_line_spacing (float, 默认 0.004)

归一化最小线间距(0~1)。线距低于此值时自动向粗细分降级;默认 0.004 ≈ 1000px 视口下 4px。

5.2.16.4. 颜色属性(9 种可自定义)

color_whole_beat (Color, 默认 Color(0, 0.74902, 1, 1))

整拍线颜色(DEEP_SKY_BLUE)。

color_half (Color, 默认 Color(0.52941, 0.80784, 0.92157, 1))

半拍线颜色(SKY_BLUE)。

color_quarter (Color, 默认 Color(0.59608, 0.98431, 0.59608, 0.8))

1/4 位线颜色(PALE_GREEN a0.8)。

color_eighth (Color, 默认 Color(0.6902, 0.76863, 0.87059, 0.7))

1/8 位线颜色(LIGHT_STEEL_BLUE a0.7)。

color_finer (Color, 默认 Color(0.6902, 0.76863, 0.87059, 0.3))

更细分位线颜色(LIGHT_STEEL_BLUE a0.3)。

color_third (Color, 默认 Color(1, 0, 0, 1))

三连音主位线颜色(RED)。

color_triplet (Color, 默认 Color(1, 0.64706, 0, 1))

三连音其余位线颜色(ORANGE)。

color_other (Color, 默认 Color(0.6902, 0.76863, 0.87059, 1))

其它细分线颜色(LIGHT_STEEL_BLUE)。

color_judge (Color, 默认 Color(1, 1, 1, 0.95))

判定线颜色(白 a0.95)。

5.2.16.5. 常量

5.2.16.6. LineType

TYPE_WHOLE_BEAT = 0

整拍线(字典 type 键)。

TYPE_SUBDIVISION = 1

细分线(字典 type 键)。

TYPE_JUDGE = 2

判定线(字典 type 键)。

5.2.16.7. LineKind

KIND_WHOLE = 0

整拍(字典 kind 键)。

KIND_HALF = 1

半拍位(字典 kind 键)。

KIND_QUARTER = 2

1/4 位(字典 kind 键)。

KIND_EIGHTH = 3

1/8 位(字典 kind 键)。

KIND_FINER = 4

更细分位(字典 kind 键)。

KIND_THIRD = 5

三连音主位(字典 kind 键)。

KIND_TRIPLET_OTHER = 6

三连音其余位(字典 kind 键)。

KIND_OTHER = 7

其它细分(字典 kind 键)。


5.2.17. SyncChart

继承:

RefCounted

编译后的只读谱面对象,通过 SyncChartPlayer.set_document_chart 内部编译生成, 可从任意线程安全访问。按 hit 时间窗口查询免疫 speed 轴瞬移(如 speed=9999 传送谱),适合"音符提前 N 毫秒出现"的表演谱。

5.2.17.1. 查询类方法

float get_duration_ms() const

返回谱面总时长(毫秒)。

Dictionary get_metadata_dict() const

返回谱面元数据字典(创作者、难度标签等)。

Array get_note_ids_for_track(track_id: String) const

返回指定轨道的所有音符 logic_id 数组。

Array get_note_ids_in_time_window(String track_id, float from_ms, float to_ms)

返回指定轨道 hit_time 落在 [from_ms, to_ms] 区间内的音符 logic_id 数组(升序)。按 hit 时间查询,不受速度轴跳变影响;无该轨道返回空数组。

Array get_note_ids_in_time_window_all(float from_ms, float to_ms)

跨全部轨道返回 hit_time 落在 [from_ms, to_ms] 区间内的音符 logic_id 数组。

Dictionary get_note_info(note_id: String) const

返回音符详细信息字典,字段:

  • logic_id (String) — 音符唯一标识

  • kind (int) — 0=TAP 1=HOLD(游戏专属种类在 metadata

  • hit_time_ms (float) — 命中时间(毫秒)

  • end_time_ms (float) — 结束时间(毫秒,TAP 为 0)

  • is_hold (bool) — kind == 1 的便捷判断

  • track_id (String) — 所属轨道 ID

  • metadata (Dictionary) — 自定义元数据(含游戏专属种类标记,如 note_type

Array get_note_normalized_position(note_id: String, chart_time_ms: float) const

返回 [head_pos, tail_pos],表示音符头部和尾部在指定谱面时间下的归一化位置。 TAP 音符的数组只有一个元素。

float get_track_normalized_position_at(track_id: String, ref_time_ms: float, chart_time_ms: float) const

获取指定轨道上任意参考时间点 ref_time_ms 在给定谱面时间 chart_time_ms 下的归一化位置。 正值 = 未到判定线,0 = 在判定线上,负值 = 已越过。

float get_offset_ms() const

返回音频偏移量(毫秒)。

String get_spec_name() const

返回谱面规格名称。

String get_spec_version() const

返回谱面规格版本字符串。

int get_total_note_count() const

返回所有轨道音符总数。

int get_track_count() const

返回播放轨道总数。

Array get_track_ids() const

返回所有轨道 ID 字符串数组。

Dictionary get_track_info(track_id: String) const

返回轨道信息字典:track_idparent_idchild_track_idsnote_countmetadata

Array get_visible_note_ids(float chart_time_ms, float window_lo = -1.0, float window_hi = 1.0) const

返回指定谱面时间下可见音符的 logic_id 数组。位置窗口(归一化坐标)默认 [-1, 1],可通过 [param window_lo] / [param window_hi] 自定义。

5.2.17.2. 轴采样方法

float sample_track_float_axis(track_id: String, axis_name: String, chart_time_ms: float, fallback: float = 0.0) const

在给定谱面时间采样指定 Float 轴。未找到时返回 fallback

Vector2 sample_track_vector2_axis(track_id: String, axis_name: String, chart_time_ms: float, fallback: Vector2 = Vector2(0, 0)) const

在给定谱面时间采样指定 Vector2 轴。

Vector3 sample_track_vector3_axis(track_id: String, axis_name: String, chart_time_ms: float, fallback: Vector3 = Vector3(0, 0, 0)) const

在给定谱面时间采样指定 Vector3 轴。

Vector4 sample_track_vector4_axis(track_id: String, axis_name: String, chart_time_ms: float, fallback: Vector4 = Vector4(0, 0, 0, 0)) const

在给定谱面时间采样指定 Vector4 轴。


5.2.18. SyncChartPlayer

继承:

Node

墙钟驱动的谱面播放节点。管理播放状态、时间进度、音符可见性追踪和轴采样。

5.2.18.1. 播放控制

void play()

从当前谱面位置开始或恢复播放。

void pause()

暂停播放,进度冻结。再次调用 play() 恢复。

void stop()

停止播放并将谱面位置重置为 0。

bool is_playing() const

谱面正在播放时返回 true

5.2.18.2. 时间控制

void seek_ms(chart_time_ms: float)

将播放跳转到指定谱面时间(毫秒),目标时间会被钳制到 [0, duration_ms]

float get_chart_progress_ms() const

返回当前谱面进度(毫秒)。

float get_duration_ms() const

返回播放终点(毫秒):等于 max(谱面内容时长, 音乐时长 - delay) + tail_padding_ms

float get_delay_ms() const

返回设备延迟(毫秒),正数表示音频应提前播放以补偿设备延迟。

void set_delay_ms(delay_ms: float)

设置设备延迟(毫秒)。

void step_ms(float delta_ms)

显式推进谱面时间(外部时间源:每帧传入增量毫秒)。与 set_chart_time_ms 二选一;使用外部时间源时建议 set_process(false) 关闭自动时钟。

void set_chart_time_ms(float chart_time_ms)

直接设置谱面时间(毫秒,钳制到 [0, get_duration_ms])并立即刷新可见性/事件。供音乐播放器 / 渲染管理器等外部时钟驱动。

void set_event_window_ms(float ahead_ms)

设置事件/可见窗口的提前量(毫秒)。ahead_ms >= 0:时间窗口(hit_time 落在 [progress, progress + ahead_ms]),免疫速度轴跳变;ahead_ms < 0:位置窗口(归一化位置 [-1, 1],默认),由速度轴驱动。

float get_event_window_ms()

返回当前事件窗口提前量(毫秒);小于 0 表示位置窗口模式。

void set_position_window(float lo, float hi)

设置位置窗口边界(归一化坐标,默认 [-1, 1])。仅位置窗口模式(set_event_window_ms < 0)下生效;改变窗口后游标会重新定位。

float get_position_window_lo()

返回位置窗口下边界(归一化坐标)。

float get_position_window_hi()

返回位置窗口上边界(归一化坐标)。

void set_max_events(int max_events)

设置事件队列上限(默认 100)。超出上限时丢弃最旧事件。

int get_max_events()

返回当前事件队列上限。

5.2.18.3. 每帧事件

Array drain_events()

返回并清空本帧累积的播放器事件。每个元素为 Dictionary:

  • type (String) — "note_entered_view""note_left_view"

  • chart_time_ms (float)

  • track_id (String)

  • note_id (String)

事件队列最多累积 100 个事件,应在每帧 _process() 中调用以避免丢失。

5.2.18.4. 谱面加载

void set_document_chart(document_chart: SyncDocumentChart)

设置文档谱面,自动编译为 SyncChart 并加载。编译时会将 SyncDocumentChart 的音乐时长注入播放终点计算。

SyncChart get_play_chart()

返回当前加载的编译谱面。

void set_play_chart(play_chart: SyncChart)

直接设置已编译的谱面。

5.2.18.5. 查询方法

Array get_visible_note_ids() const

返回当前谱面时间下可见音符的 logic_id 数组。

Array get_visible_notes_info() const

返回所有当前可见音符的完整信息数组,每项包含 note_info 各字段外加 normalized_position

Array get_note_ids_for_track(track_id: String) const
Dictionary get_note_info(note_id: String) const
Array get_note_normalized_position(note_id: String) const
float get_track_normalized_position_at(track_id: String, ref_time_ms: float) const
int get_track_count() const
Array get_track_ids() const
Dictionary get_track_info(track_id: String) const
Dictionary get_metadata_dict() const
float get_offset_ms() const

(与 SyncChart 同名方法语义一致,查询对象为当前已加载谱面。)

5.2.18.6. 轴采样

float sample_track_float_axis(track_id: String, axis_name: String, fallback: float = 0.0) const
Vector2 sample_track_vector2_axis(track_id: String, axis_name: String, fallback: Vector2 = Vector2(0, 0)) const
Vector3 sample_track_vector3_axis(track_id: String, axis_name: String, fallback: Vector3 = Vector3(0, 0, 0)) const
Vector4 sample_track_vector4_axis(track_id: String, axis_name: String, fallback: Vector4 = Vector4(0, 0, 0, 0)) const

在当前谱面时间采样轴,无需手动传入 chart_time_ms

5.2.18.7. 音频

void set_audio_duration_ms(duration_ms: float)

外部注入音乐时长(毫秒,含 offset),与编译注入值取较大者生效。 传 0 清除。加载新谱面时自动清除。

float get_audio_duration_ms() const

返回当前生效的音乐时长(毫秒,含 offset)。

float get_audio_progress_ms() const

返回当前音频播放进度(毫秒),已应用偏移量和延迟。

5.2.18.8. 成员变量

play_chart (SyncChart)

当前加载用于播放的编译谱面。也可使用 set_document_chart 从文档谱面自动编译。

tail_padding_ms (float, 默认 5000.0)

结尾留白(毫秒):谱面内容/音乐结束后继续推进的时间。默认 5 秒。

5.2.18.9. 信号

信号: play_chart_changed()

通过 set_play_chartset_document_chart 加载新谱面时发射。

信号: playback_state_changed(playing: bool)

播放开始、暂停或停止时发射。

信号: seek_completed()

seek_ms 操作完成后发射。

信号: audio_state_changed(playing: bool, progress_ms: float)

音频播放状态变化时发射。playing=trueprogress_ms 为当前音频位置(毫秒), 是通知 Godot 侧开始或重新定位音频播放的时机。


5.2.19. SyncNodePool

继承:

Node

绑定 PackedScene 的节点对象池。

描述:

0.5.0 回归的通用组件,编辑与游玩侧共用。绑定一个 PackedScene 后,acquire() 从池中取出节点实例、 release() 归还复用,避免高频音符等节点的反复 instantiate / queue_free

5.2.19.1. 方法

void bind_scene(PackedScene scene)

绑定对象池的场景资源。绑定后 is_bound() 返回 trueacquire() 用该场景实例化节点。

PackedScene get_scene() const

返回当前绑定的场景资源。

bool is_bound() const

返回是否已绑定场景。

Node acquire()

从池中取出一个节点实例。池中有空闲实例时直接复用,否则按绑定的 场景新实例化一个。

void release(Node node)

把节点归还对象池,供后续 acquire() 复用。

void prewarm(int count)

预创建 count 个空闲实例,减少运行时首帧实例化的卡顿。

int get_active_count() const

返回当前已取出(活跃)的实例数量。

int get_free_count() const

返回当前空闲的实例数量。