37 lines
1.1 KiB
GDScript
37 lines
1.1 KiB
GDScript
@tool
|
|
class_name BeatMeasurer
|
|
extends Node
|
|
|
|
|
|
@export var path: Path3D
|
|
@export var track_duration: float = 1.0
|
|
@export var track_bpm: int = 120
|
|
@export var track_bars: int = 4
|
|
@export_tool_button("Force Update") var editor_force_update: Callable = _update_measurement
|
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
func _ready() -> void:
|
|
path.curve_changed.connect(_update_measurement)
|
|
_update_measurement.call_deferred()
|
|
|
|
|
|
func _update_measurement() -> void:
|
|
for child: Node in get_children():
|
|
if child.owner == null:
|
|
child.queue_free()
|
|
|
|
var path_length: float = path.curve.get_baked_length()
|
|
var beat_time: float = track_bpm / 60.0
|
|
var beats := int(path_length / beat_time)
|
|
|
|
for beat: int in range(beats):
|
|
var progress: float = beat_time * beat
|
|
var position: Vector3 = path.global_position + path.curve.sample_baked(progress)
|
|
DebugDraw3D.draw_sphere(position, 0.15, Color.WHITE, 5.0 if Engine.is_editor_hint() else 500.0)
|
|
|
|
var label := Label3D.new()
|
|
label.text = str(beat)
|
|
label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
|
add_child(label)
|
|
label.global_position = position + Vector3.UP
|