add music and synchronize animation to it

This commit is contained in:
Teatov 2025-02-27 18:53:22 +10:00
parent e4ea6eb904
commit 5498b3dc21
13 changed files with 3792 additions and 81 deletions

File diff suppressed because it is too large Load Diff

BIN
assets/music/test.mp3 Normal file

Binary file not shown.

View File

@ -0,0 +1,19 @@
[remap]
importer="mp3"
type="AudioStreamMP3"
uid="uid://dkk50judgj5ky"
path="res://.godot/imported/test.mp3-570869566ae53ec072dfce8ac7fafc25.mp3str"
[deps]
source_file="res://assets/music/test.mp3"
dest_files=["res://.godot/imported/test.mp3-570869566ae53ec072dfce8ac7fafc25.mp3str"]
[params]
loop=true
loop_offset=0.0
bpm=90.0
beat_count=0
bar_beats=4

16
default_bus_layout.tres Normal file
View File

@ -0,0 +1,16 @@
[gd_resource type="AudioBusLayout" format=3 uid="uid://c7ofyshumd62f"]
[resource]
bus/0/volume_db = -34.9953
bus/1/name = &"Music"
bus/1/solo = false
bus/1/mute = false
bus/1/bypass_fx = false
bus/1/volume_db = 0.0
bus/1/send = &"Master"
bus/2/name = &"SFX"
bus/2/solo = false
bus/2/mute = false
bus/2/bypass_fx = false
bus/2/volume_db = 0.0
bus/2/send = &"Master"

View File

@ -27,6 +27,7 @@ Inputer="*res://scripts/globals/inputer.gd"
Debugger="*res://scenes/debugger.tscn"
Settings="*res://scripts/globals/settings.gd"
Cursor="*res://scenes/ui/cursor.tscn"
Music="*res://scenes/music.tscn"
[debug]

BIN
resources/animations/batrix/+idle_L.res (Stored with Git LFS) Normal file

Binary file not shown.

BIN
resources/animations/batrix/+idle_R.res (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -0,0 +1,40 @@
[gd_resource type="AnimationNodeBlendTree" load_steps=8 format=3 uid="uid://dhclwpxlgqerd"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_tes4q"]
animation = &"+idle_L"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_rdhgj"]
animation = &"+idle_R"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_tdamk"]
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_gk5g1"]
reset = false
switch_mode = 1
advance_mode = 2
advance_condition = &"side_L"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_v3m8c"]
reset = false
switch_mode = 1
advance_mode = 2
advance_condition = &"side_R"
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_yk01a"]
states/+idle_L/node = SubResource("AnimationNodeAnimation_tes4q")
states/+idle_L/position = Vector2(351, 62)
states/+idle_R/node = SubResource("AnimationNodeAnimation_rdhgj")
states/+idle_R/position = Vector2(351, 169)
transitions = ["Start", "+idle_L", SubResource("AnimationNodeStateMachineTransition_tdamk"), "+idle_R", "+idle_L", SubResource("AnimationNodeStateMachineTransition_gk5g1"), "+idle_L", "+idle_R", SubResource("AnimationNodeStateMachineTransition_v3m8c")]
[sub_resource type="AnimationNodeTimeScale" id="AnimationNodeTimeScale_5rfjp"]
[resource]
graph_offset = Vector2(-257.59, 46.1947)
nodes/idle_machine/node = SubResource("AnimationNodeStateMachine_yk01a")
nodes/idle_machine/position = Vector2(240, 120)
nodes/main_time_scale/node = SubResource("AnimationNodeTimeScale_5rfjp")
nodes/main_time_scale/position = Vector2(540, 80)
nodes/output/position = Vector2(780, 100)
node_connections = [&"main_time_scale", 0, &"idle_machine", &"output", 0, &"main_time_scale"]

View File

@ -1,37 +0,0 @@
[gd_resource type="AnimationLibrary" load_steps=3 format=3 uid="uid://81cl401rtu7a"]
[sub_resource type="Animation" id="Animation_ni72j"]
resource_name = "+idle_L"
length = 1.2
loop_mode = 1
tracks/0/type = "animation"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Model/AnimationPlayer")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"clips": PackedStringArray("+idle_L"),
"times": PackedFloat32Array(0)
}
[sub_resource type="Animation" id="Animation_tn82g"]
resource_name = "+idle_R"
length = 1.2
loop_mode = 1
tracks/0/type = "animation"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Model/AnimationPlayer")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"clips": PackedStringArray("+idle_R"),
"times": PackedFloat32Array(0)
}
[resource]
_data = {
"+idle_L": SubResource("Animation_ni72j"),
"+idle_R": SubResource("Animation_tn82g")
}

12
scenes/music.tscn Normal file
View File

@ -0,0 +1,12 @@
[gd_scene load_steps=3 format=3 uid="uid://d6i010g7vf62"]
[ext_resource type="AudioStream" uid="uid://dkk50judgj5ky" path="res://assets/music/test.mp3" id="1_xuvjf"]
[ext_resource type="Script" path="res://scripts/globals/music.gd" id="2_h5nik"]
[node name="Music" type="AudioStreamPlayer"]
process_mode = 3
process_priority = -100
process_physics_priority = -100
stream = ExtResource("1_xuvjf")
bus = &"Music"
script = ExtResource("2_h5nik")

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=32 format=3 uid="uid://b73y71y3efmv"]
[gd_scene load_steps=25 format=3 uid="uid://b73y71y3efmv"]
[ext_resource type="Script" path="res://scripts/player/player.gd" id="1_xt3i8"]
[ext_resource type="Material" uid="uid://cc18ee0wbfoud" path="res://resources/materials/debug/debug_player.tres" id="2_0p422"]
@ -7,41 +7,12 @@
[ext_resource type="Script" path="res://scripts/player/player_animator.gd" id="4_adlgp"]
[ext_resource type="Script" path="res://scripts/effects/discrete_animation_player.gd" id="4_i3gf3"]
[ext_resource type="Material" uid="uid://bdi02rpvdukem" path="res://resources/materials/debug/debug_attack.tres" id="4_ll2ct"]
[ext_resource type="AnimationLibrary" uid="uid://81cl401rtu7a" path="res://resources/animations/player_animations.tres" id="5_y0ods"]
[ext_resource type="AnimationNodeBlendTree" uid="uid://dhclwpxlgqerd" path="res://resources/animations/batrix_anim_tree.tres" id="5_mq40n"]
[ext_resource type="Script" path="res://scripts/effects/bone_to_flatten.gd" id="6_cumn2"]
[ext_resource type="Script" path="res://scripts/effects/bone_flattener.gd" id="6_iug5b"]
[ext_resource type="PackedScene" uid="uid://c8gqrealje3o" path="res://scenes/effects/shadow_decal.tscn" id="9_vgb3d"]
[ext_resource type="Script" path="res://scripts/effects/player_attack_effect.gd" id="11_1cf3j"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_tes4q"]
animation = &"+idle_L"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_rdhgj"]
animation = &"+idle_R"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_tdamk"]
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_gk5g1"]
advance_mode = 2
advance_condition = &"side_L"
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_v3m8c"]
advance_mode = 2
advance_condition = &"side_R"
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_yk01a"]
states/+idle_L/node = SubResource("AnimationNodeAnimation_tes4q")
states/+idle_L/position = Vector2(351, 62)
states/+idle_R/node = SubResource("AnimationNodeAnimation_rdhgj")
states/+idle_R/position = Vector2(351, 168)
transitions = ["Start", "+idle_L", SubResource("AnimationNodeStateMachineTransition_tdamk"), "+idle_R", "+idle_L", SubResource("AnimationNodeStateMachineTransition_gk5g1"), "+idle_L", "+idle_R", SubResource("AnimationNodeStateMachineTransition_v3m8c")]
[sub_resource type="AnimationNodeBlendTree" id="AnimationNodeBlendTree_f4bn3"]
nodes/StateMachine/node = SubResource("AnimationNodeStateMachine_yk01a")
nodes/StateMachine/position = Vector2(40, 140)
node_connections = [&"output", 0, &"StateMachine"]
[sub_resource type="Curve" id="Curve_03vie"]
_data = [Vector2(0.952555, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 2
@ -136,7 +107,6 @@ bones/46/rotation = Quaternion(-0.0181733, 2.38379e-07, 1.14098e-08, 0.999835)
bones/47/rotation = Quaternion(-1.20807e-07, 0.993087, -0.117383, 7.85287e-07)
bones/49/rotation = Quaternion(-0.034235, -3.57418e-07, 8.86969e-08, 0.999414)
bones/51/rotation = Quaternion(0.403888, -2.98082e-07, -3.85178e-07, 0.914808)
bones/51/scale = Vector3(1, 1, 1)
bones/52/rotation = Quaternion(-0.512846, 3.82068e-07, 4.27952e-07, 0.858481)
bones/52/scale = Vector3(1, 1, 1)
bones/53/rotation = Quaternion(0.0772044, -1.03801e-06, -1.2885e-07, 0.997015)
@ -260,19 +230,20 @@ layers = 32
cast_shadow = 0
[node name="AnimationPlayer" parent="Model" index="1"]
deterministic = true
autoplay = "RESET"
script = ExtResource("4_i3gf3")
[node name="OverrideAnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": ExtResource("5_y0ods")
}
[node name="AnimationTree" type="AnimationTree" parent="."]
tree_root = SubResource("AnimationNodeBlendTree_f4bn3")
anim_player = NodePath("../OverrideAnimationPlayer")
parameters/StateMachine/conditions/side_L = false
parameters/StateMachine/conditions/side_R = false
process_priority = 10
process_physics_priority = 10
root_node = NodePath("../Model")
callback_mode_process = 2
tree_root = ExtResource("5_mq40n")
anim_player = NodePath("../Model/AnimationPlayer")
parameters/idle_machine/conditions/side_L = false
parameters/idle_machine/conditions/side_R = false
parameters/main_time_scale/scale = 1.0
script = ExtResource("4_adlgp")
[node name="BoneFlattener" type="Node3D" parent="." node_paths=PackedStringArray("skeleton")]
@ -321,4 +292,10 @@ mesh = SubResource("SphereMesh_kqbjh")
skeleton = NodePath("../../Attack")
script = ExtResource("11_1cf3j")
[node name="Audio" type="Node3D" parent="."]
[node name="FootstepsPlayer" type="AudioStreamPlayer3D" parent="Audio"]
attenuation_model = 3
bus = &"SFX"
[editable path="Model"]

55
scripts/globals/music.gd Normal file
View File

@ -0,0 +1,55 @@
extends AudioStreamPlayer
signal track_started
var bpm: float
var bar_beats: float
var beat_length: float
var bar_length: float
var bpm_factor: float
var audio_delta: float
var track_time: float
var bar_time: float
func _ready() -> void:
_play_track()
func _process(_delta: float) -> void:
var time := get_playback_position() + AudioServer.get_time_since_last_mix()
time -= AudioServer.get_output_latency()
audio_delta = time - track_time
track_time = time
bar_time = wrapf(track_time, 0, bar_length)
Debugger.text("bpm", bpm)
Debugger.text("bar_beats", bar_beats)
Debugger.text("beat_length", beat_length)
Debugger.text("bar_length", bar_length)
Debugger.text("bpm_factor", bpm_factor)
Debugger.text("track_time", track_time)
Debugger.text("bar_time", bar_time)
Debugger.text("audio_delta", audio_delta)
func _play_track() -> void:
play()
_get_bpm_info()
track_started.emit()
func _get_bpm_info() -> void:
if stream is AudioStreamMP3:
var steam_file := stream as AudioStreamMP3
bpm = steam_file.bpm
bar_beats = steam_file.bar_beats
if stream is AudioStreamOggVorbis:
var steam_file := stream as AudioStreamOggVorbis
bpm = steam_file.bpm
bar_beats = steam_file.bar_beats
beat_length = 60 / bpm
bar_length = beat_length * bar_beats
bpm_factor = bpm / 100

View File

@ -4,22 +4,44 @@ const SUFFIX_LEFT := "_L"
const SUFFIX_RIGHT := "_R"
@onready var player: Player = $"../" as Player
@onready var attack: PlayerAttack = $"../Attack" as PlayerAttack
@onready var animation_player: AnimationPlayer = $"../Model/AnimationPlayer"
func _ready() -> void:
assert(player, "player missing!")
Music.track_started.connect(_on_music_track_started)
attack.attacked.connect(_on_player_attacked)
_set_bpm()
_set_side()
func _process(_delta: float) -> void:
set(&"parameters/StateMachine/conditions/side_L", _is_left())
set(&"parameters/StateMachine/conditions/side_R", not _is_left())
advance(Music.audio_delta as float)
func _is_left() -> bool:
return player.attack.side == PlayerAttack.Side.LEFT
return attack.side == PlayerAttack.Side.LEFT
func _suffix(invert: bool) -> String:
if not invert:
return SUFFIX_LEFT if _is_left() else SUFFIX_RIGHT
return SUFFIX_LEFT if not _is_left() else SUFFIX_RIGHT
func _set_bpm() -> void:
set(&"parameters/main_time_scale/scale", Music.bpm_factor)
func _set_side() -> void:
set(&"parameters/idle_machine/conditions/side_L", _is_left())
set(&"parameters/idle_machine/conditions/side_R", not _is_left())
func _on_music_track_started() -> void:
_set_bpm()
func _on_player_attacked() -> void:
_set_side()