index

This is a basic audio manager global script to be used in Godot 4.x.
Example useage:
AudioManager.play("res://assets/audio/explosion.wav", 0.9, 1.1, "", self)

    
        extends Node

        var num_players = 8
        var bus = "master"

        var available_3d = []
        var available_2d = []
        var queue = []

        func _ready():
            # Create AudioStreamPlayer3D pool
            for i in num_players:
                var player3d = AudioStreamPlayer3D.new()
                add_child(player3d)
                available_3d.append(player3d)
                player3d.finished.connect(_on_stream_finished_3d.bind(player3d))
                player3d.bus = bus
            # Create AudioStreamPlayer pool for 2D sounds
            for i in num_players:
                var player2d = AudioStreamPlayer.new()
                add_child(player2d)
                available_2d.append(player2d)
                player2d.finished.connect(_on_stream_finished_2d.bind(player2d))
                player2d.bus = bus


        func _on_stream_finished_3d(player):
            available_3d.append(player)


        func _on_stream_finished_2d(player):
            available_2d.append(player)


        func play(
            sound_path: String,
            min_pitch: float = 0.95,
            max_pitch: float = 1.05,
            bus_override: String = "",
            source = null
            ):
            var is_3d = false
            var source_pos: Vector3 = Vector3.ZERO
            if source != null:
                if typeof(source) == TYPE_OBJECT and source is Node3D:
                    is_3d = true
                    source_pos = source.global_transform.origin
                elif typeof(source) == TYPE_VECTOR3:
                    is_3d = true
                    source_pos = source
                else:
                    push_warning(
                        "AudioManager.play() called with unsupported source type: %s" % typeof(source))
            queue.append({
                "path": sound_path,
                "min_pitch": min_pitch,
                "max_pitch": max_pitch,
                "bus": bus_override,
                "is_3d": is_3d,
                "source_pos": source_pos
            })


        func _process(delta):
            if queue.size() == 0:
                return
            var item = queue[0]
            if item.is_3d and available_3d.size() > 0:
                queue.pop_front()
                var player = available_3d.pop_front()
                player.global_transform.origin = item.source_pos
                player.stream = load(item.path)
                player.pitch_scale = randf_range(item.min_pitch, item.max_pitch)
                player.bus = item.bus if item.bus != "" else bus
                player.play()
            elif not item.is_3d and available_2d.size() > 0:
                queue.pop_front()
                var player = available_2d.pop_front()
                player.stream = load(item.path)
                player.pitch_scale = randf_range(item.min_pitch, item.max_pitch)
                player.bus = item.bus if item.bus != "" else bus
                player.play()