From a533f93361ad2e5588014b2bc926404217775898 Mon Sep 17 00:00:00 2001 From: MaddoScientisto Date: Sat, 5 Apr 2025 18:46:20 +0200 Subject: [PATCH] Concurrent audio limit and volume limiter --- Cirno.sln.DotSettings.user | 1 + Resources/Bullets/Explosion.tres | 5 +- Resources/bus_layout.tres | 7 +- .../Autoclearing_Explosion_Bullet.tscn | 1 + Scenes/Weapons/Bullets/explosion.tscn | 7 +- Scenes/Weapons/bullet.tscn | 5 +- Scripts/GameManager.cs | 6 ++ Scripts/Misc/AudioManager.cs | 52 ++++++++++++ Scripts/Misc/AudioManager.cs.uid | 1 + Scripts/Misc/LimitedAudioPlayer.cs | 82 +++++++++++++++++++ Scripts/Misc/LimitedAudioPlayer.cs.uid | 1 + 11 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 Scripts/Misc/AudioManager.cs create mode 100644 Scripts/Misc/AudioManager.cs.uid create mode 100644 Scripts/Misc/LimitedAudioPlayer.cs create mode 100644 Scripts/Misc/LimitedAudioPlayer.cs.uid diff --git a/Cirno.sln.DotSettings.user b/Cirno.sln.DotSettings.user index c8698013..a96154b9 100644 --- a/Cirno.sln.DotSettings.user +++ b/Cirno.sln.DotSettings.user @@ -19,6 +19,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded \ No newline at end of file diff --git a/Resources/Bullets/Explosion.tres b/Resources/Bullets/Explosion.tres index 0601af65..257b79bd 100644 --- a/Resources/Bullets/Explosion.tres +++ b/Resources/Bullets/Explosion.tres @@ -9,8 +9,11 @@ BulletScene = ExtResource("1_bca33") BulletSpeed = 0.0 Direction = Vector2(1, 0) BulletDamage = 8.0 -LifeTime = 1.0 +LifeTime = 0.4 DestroyOnCollision = false Owner = 0 DamageType = 4 +Controllable = false +Grazeable = false +GrazeValue = 1.0 TimeModifiers = null diff --git a/Resources/bus_layout.tres b/Resources/bus_layout.tres index 7b6617f6..8e3ee784 100644 --- a/Resources/bus_layout.tres +++ b/Resources/bus_layout.tres @@ -1,7 +1,8 @@ [gd_resource type="AudioBusLayout" load_steps=2 format=3 uid="uid://clblu7fse2pjy"] -[sub_resource type="AudioEffectLimiter" id="AudioEffectLimiter_0f13h"] -resource_name = "Limiter" +[sub_resource type="AudioEffectHardLimiter" id="AudioEffectHardLimiter_0f13h"] +resource_name = "HardLimiter" +ceiling_db = -10.0 [resource] bus/1/name = &"Music" @@ -16,7 +17,7 @@ bus/2/mute = false bus/2/bypass_fx = false bus/2/volume_db = 0.0 bus/2/send = &"Master" -bus/2/effect/0/effect = SubResource("AudioEffectLimiter_0f13h") +bus/2/effect/0/effect = SubResource("AudioEffectHardLimiter_0f13h") bus/2/effect/0/enabled = true bus/3/name = &"Voice" bus/3/solo = false diff --git a/Scenes/Weapons/Bullets/Autoclearing_Explosion_Bullet.tscn b/Scenes/Weapons/Bullets/Autoclearing_Explosion_Bullet.tscn index f2181c18..75e0683b 100644 --- a/Scenes/Weapons/Bullets/Autoclearing_Explosion_Bullet.tscn +++ b/Scenes/Weapons/Bullets/Autoclearing_Explosion_Bullet.tscn @@ -6,6 +6,7 @@ [node name="AutoclearingExplosionBullet" type="Node2D"] script = ExtResource("1_5c773") +Timeout = 0.4 BulletResource = ExtResource("2_d2d24") EmitOnStart = true EmitCoolDown = 10.0 diff --git a/Scenes/Weapons/Bullets/explosion.tscn b/Scenes/Weapons/Bullets/explosion.tscn index 82900ef8..602909a0 100644 --- a/Scenes/Weapons/Bullets/explosion.tscn +++ b/Scenes/Weapons/Bullets/explosion.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=5 format=3 uid="uid://h11o0et1y54v"] +[gd_scene load_steps=6 format=3 uid="uid://h11o0et1y54v"] [ext_resource type="Script" uid="uid://dsa4b75hdig8p" path="res://Scripts/Bullet.cs" id="1_f0epf"] [ext_resource type="SpriteFrames" uid="uid://lh1q76788ixw" path="res://Resources/Sprites/explosion_proc_1.tres" id="2_wng0j"] [ext_resource type="AudioStream" uid="uid://ds84e0m5l4i5d" path="res://SFX/404752__owlstorm__retro-video-game-sfx-explode-3.wav" id="3_wng0j"] +[ext_resource type="Script" uid="uid://dwnqgkuj6bgay" path="res://Scripts/Misc/LimitedAudioPlayer.cs" id="4_0imfi"] [sub_resource type="CircleShape2D" id="CircleShape2D_jxptd"] radius = 28.0179 @@ -35,6 +36,10 @@ autoplay = true max_distance = 300.0 bus = &"Effects" area_mask = 8 +script = ExtResource("4_0imfi") +AudioName = &"EXPLOSION" +ReparentOnCreation = true +Duration = 0.55 [connection signal="area_entered" from="." to="." method="_on_area_entered"] [connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/Scenes/Weapons/bullet.tscn b/Scenes/Weapons/bullet.tscn index ddff4a62..a44c8dba 100644 --- a/Scenes/Weapons/bullet.tscn +++ b/Scenes/Weapons/bullet.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=5 format=3 uid="uid://b1qnfiuokpvsr"] +[gd_scene load_steps=6 format=3 uid="uid://b1qnfiuokpvsr"] [ext_resource type="Texture2D" uid="uid://cybpmpb0d8yva" path="res://Sprites/Projectile.png" id="1_2eu87"] [ext_resource type="Script" uid="uid://dsa4b75hdig8p" path="res://Scripts/Bullet.cs" id="1_jvxw3"] [ext_resource type="AudioStream" uid="uid://cjg8r7bthkfsy" path="res://SFX/Laser_shoot 11.wav" id="3_8bitv"] +[ext_resource type="Script" uid="uid://dwnqgkuj6bgay" path="res://Scripts/Misc/LimitedAudioPlayer.cs" id="4_jxgah"] [sub_resource type="CircleShape2D" id="CircleShape2D_jxptd"] radius = 2.23607 @@ -30,6 +31,8 @@ stream = ExtResource("3_8bitv") autoplay = true bus = &"Effects" area_mask = 8 +script = ExtResource("4_jxgah") +AudioName = &"ICE_BULLET" [connection signal="area_entered" from="." to="." method="_on_area_entered"] [connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/Scripts/GameManager.cs b/Scripts/GameManager.cs index 2e8cca70..e0a7af3b 100644 --- a/Scripts/GameManager.cs +++ b/Scripts/GameManager.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Cirno.Scripts; using Cirno.Scripts.Components.FSM; +using Cirno.Scripts.Misc; using Cirno.Scripts.Resources; using Godot.Collections; using Cirno.Scripts.Utils; @@ -60,6 +61,8 @@ public partial class GameManager : Node2D public delegate void PlayerRespawnedEventHandler(); public Vector2 LastCheckpointPosition { get; set; } + + private AudioManager _audioManager; [Export] public Node2D PlayerParentNode { get; set; } @@ -76,6 +79,9 @@ public partial class GameManager : Node2D GlobalState.Instance.SaveGame(); } + _audioManager = new AudioManager(); + this.AddChild(_audioManager); + _hud = GetNodeOrNull("HUD"); if (_hud == null) GD.Print("No HUD in scene."); diff --git a/Scripts/Misc/AudioManager.cs b/Scripts/Misc/AudioManager.cs new file mode 100644 index 00000000..c78d8b18 --- /dev/null +++ b/Scripts/Misc/AudioManager.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using Godot; + +namespace Cirno.Scripts.Misc; + +public partial class AudioManager : Node2D +{ + public static AudioManager Instance { get; private set; } + + [Export] + public int ConcurrentSounds { get; set; } = 3; + + private Dictionary _audioDict = new Dictionary(); + + public override void _Ready() + { + Instance = this; + } + + public bool CanPlay(string audioName) + { + var item = _audioDict.TryGetValue(audioName, out int amount); + if (item) return amount < ConcurrentSounds; + _audioDict.Add(audioName, 0); + return true; + } + + public bool Play(string audioName) + { + if (!CanPlay(audioName)) return false; + if (!_audioDict.ContainsKey(audioName)) + { + _audioDict.Add(audioName, 0); + } + _audioDict[audioName] += 1; + + return true; + } + + public void Stop(string audioName) + { + if (_audioDict.ContainsKey(audioName)) + { + _audioDict[audioName] -= 1; + + if (_audioDict[audioName] < 0) + { + _audioDict[audioName] = 0; + } + } + } +} \ No newline at end of file diff --git a/Scripts/Misc/AudioManager.cs.uid b/Scripts/Misc/AudioManager.cs.uid new file mode 100644 index 00000000..87d7052b --- /dev/null +++ b/Scripts/Misc/AudioManager.cs.uid @@ -0,0 +1 @@ +uid://ci2px8dicc0xx diff --git a/Scripts/Misc/LimitedAudioPlayer.cs b/Scripts/Misc/LimitedAudioPlayer.cs new file mode 100644 index 00000000..4a861d47 --- /dev/null +++ b/Scripts/Misc/LimitedAudioPlayer.cs @@ -0,0 +1,82 @@ +using Godot; + +namespace Cirno.Scripts.Misc; + +public partial class LimitedAudioPlayer : AudioStreamPlayer2D +{ + [Export] public StringName AudioName { get; private set; } + [Export] public bool ReparentOnCreation { get; private set; } = false; + [Export] public float Duration { get; private set; } = -1; + + private bool _finished = false; + + private double _timer = 0; + + public override void _Ready() + { + if (ReparentOnCreation) + { + CallDeferred(MethodName.ReparentDeferred); + } + + if (Duration >= 0) + { + + } + + // Check if it can play + if (IsAutoplayEnabled()) + { + TryPlay(); + } + + this.Finished += OnFinished; + } + + public override void _Process(double delta) + { + if (Duration >= 0 && IsPlaying()) + { + _timer += delta; + + if (_timer >= Duration) + { + this.Stop(); + } + } + } + + private void ReparentDeferred() + { + this.Reparent(GameManager.Instance.BulletsContainer); + } + + public override void _ExitTree() + { + this.Finished -= OnFinished; + + if (!_finished) + { + AudioManager.Instance.Stop(AudioName); + } + } + + public void TryPlay() + { + if (!AudioManager.Instance.Play(AudioName)) + { + this.SetVolumeDb(-100); + return; + } + else + { + this.SetVolumeDb(0); + } + } + + private void OnFinished() + { + AudioManager.Instance.Stop(AudioName); + _finished = true; + } +} \ No newline at end of file diff --git a/Scripts/Misc/LimitedAudioPlayer.cs.uid b/Scripts/Misc/LimitedAudioPlayer.cs.uid new file mode 100644 index 00000000..dc568ff5 --- /dev/null +++ b/Scripts/Misc/LimitedAudioPlayer.cs.uid @@ -0,0 +1 @@ +uid://dwnqgkuj6bgay