Last active
March 17, 2023 02:13
-
-
Save afk-mario/c6ce7768fca750b0efafd3eae1999271 to your computer and use it in GitHub Desktop.
SFX Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tool | |
extends Resource | |
class_name SfxEvent, "res://ui/editor_icons/sfx.svg" | |
const PROPERTY_HINT_TYPE_STRING := PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS + 2 | |
enum SEQUENCE_TYPE { RANDOM, LOOP, HOLD } | |
enum SEQUENCE_RESET { TIME, NEVER } | |
var audio_streams: Array | |
var sequence_type: int setget _set_sequence_type | |
var sequence_reset: int setget _set_sequence_reset | |
var sequence_reset_time := 1.0 | |
var volume_randomize := false setget _set_volume_random | |
var volume_db := 0.0 | |
var volume_min := 0.0 | |
var volume_max := 0.0 | |
var pitch_randomize := false setget _set_pitch_random | |
var pitch_scale := 1.0 | |
var pitch_min := 0.01 | |
var pitch_max := 4.0 | |
func _set_volume_random(value: bool) -> void: | |
volume_randomize = value | |
property_list_changed_notify() | |
func _set_pitch_random(value: bool) -> void: | |
pitch_randomize = value | |
property_list_changed_notify() | |
func _set_sequence_type(value: int) -> void: | |
sequence_type = value | |
property_list_changed_notify() | |
func _set_sequence_reset(value: int) -> void: | |
sequence_reset = value | |
property_list_changed_notify() | |
func property_can_revert(property): | |
if property == "volume_db": | |
return true | |
if property == "sequence_reset_time": | |
return true | |
return false | |
func property_get_revert(property): | |
if property == "volume_db": | |
return 0.0 | |
if property == "sequence_reset_time": | |
return 1.0 | |
func _get_property_list() -> Array: | |
var properties = [] | |
#https://stackoverflow.com/questions/71175503/how-to-add-array-with-hint-and-hint-string | |
properties.append( | |
{ | |
name = "audio_streams", | |
type = TYPE_ARRAY, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_TYPE_STRING, | |
hint_string = str(TYPE_OBJECT) + ":" | |
} | |
) | |
properties.append( | |
{ | |
name = "Sequence", | |
type = TYPE_NIL, | |
hint_string = "sequence_", | |
usage = PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SCRIPT_VARIABLE | |
} | |
) | |
properties.append( | |
{ | |
name = "sequence_type", | |
type = TYPE_INT, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_ENUM, | |
hint_string = PoolStringArray(SEQUENCE_TYPE.keys()).join(",").capitalize() | |
} | |
) | |
if sequence_type != SEQUENCE_TYPE.RANDOM: | |
properties.append( | |
{ | |
name = "sequence_reset", | |
type = TYPE_INT, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_ENUM, | |
hint_string = PoolStringArray(SEQUENCE_RESET.keys()).join(",").capitalize() | |
} | |
) | |
if sequence_reset == SEQUENCE_RESET.TIME: | |
properties.append( | |
{ | |
name = "sequence_reset_time", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_RANGE, | |
hint_string = "0.0,10.0,.01" | |
} | |
) | |
properties.append( | |
{ | |
name = "Volume", | |
type = TYPE_NIL, | |
hint_string = "volume_", | |
usage = PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SCRIPT_VARIABLE | |
} | |
) | |
properties.append({name = "volume_randomize", type = TYPE_BOOL}) | |
if not volume_randomize: | |
properties.append( | |
{ | |
name = "volume_db", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_EXP_RANGE, | |
hint_string = "-80.0,24.0,.001" | |
} | |
) | |
else: | |
properties.append( | |
{ | |
name = "volume_min", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_EXP_RANGE, | |
hint_string = "-80.0,24.0,.001" | |
} | |
) | |
properties.append( | |
{ | |
name = "volume_max", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_EXP_RANGE, | |
hint_string = "-80.0,24.0,.001" | |
} | |
) | |
properties.append( | |
{ | |
name = "Pitch", | |
type = TYPE_NIL, | |
hint_string = "pitch_", | |
usage = PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SCRIPT_VARIABLE | |
} | |
) | |
properties.append({name = "pitch_randomize", type = TYPE_BOOL}) | |
if not pitch_randomize: | |
properties.append( | |
{ | |
name = "pitch_scale", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_RANGE, | |
hint_string = "0.01,4.0" | |
} | |
) | |
else: | |
properties.append( | |
{ | |
name = "pitch_min", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_RANGE, | |
hint_string = "0.01,4.0" | |
} | |
) | |
properties.append( | |
{ | |
name = "pitch_max", | |
type = TYPE_REAL, | |
usage = PROPERTY_USAGE_DEFAULT, | |
hint = PROPERTY_HINT_RANGE, | |
hint_string = "0.01,4.0" | |
} | |
) | |
return properties |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends Node | |
# Using this addon as a base for sound busses | |
# https://github.com/nathanhoad/godot_sound_manager | |
const events_dir := "res://sfx/events/" | |
var events_dict := {} | |
var events_sequence := {} | |
var events_timers := {} | |
func _init() -> void: | |
var dir = Directory.new() | |
assert(dir.open(events_dir) == OK) | |
dir.list_dir_begin(true, true) | |
var filename = dir.get_next() | |
while filename != "": | |
var name: String = filename.get_file().split(".")[0] | |
events_dict[name] = load(events_dir + filename) | |
filename = dir.get_next() | |
func _ready() -> void: | |
SoundManager.set_sound_volume(SettingsSaved.data.get("sfx_volume", 1.0)) | |
func play(event_name: String) -> AudioStreamPlayer: | |
var event: SfxEvent = events_dict.get(event_name, null) | |
if event == null: | |
push_warning("No sfx event named " + event_name) | |
return null | |
return play_event(event) | |
func play_event(event: SfxEvent) -> AudioStreamPlayer: | |
var event_name := event.get_path().get_file().split(".")[0] | |
if event.audio_streams.size() < 1: | |
push_warning("Sfx event " + event_name + " has empty audio_streams") | |
return null | |
var index: int = events_sequence.get(event_name, 0) | |
if event.sequence_type == SfxEvent.SEQUENCE_TYPE.RANDOM: | |
index = randi() % event.audio_streams.size() | |
var audio: AudioStream = event.audio_streams[index] | |
var player := SoundManager.play_sound(audio) | |
if event.pitch_randomize: | |
player.pitch_scale = rand_range(event.pitch_min, event.pitch_max) | |
else: | |
player.pitch_scale = event.pitch_scale | |
if event.volume_randomize: | |
player.volume_db = rand_range(event.volume_min, event.volume_max) | |
else: | |
player.volume_db = event.volume_db | |
if event.sequence_type != SfxEvent.SEQUENCE_TYPE.RANDOM: | |
if event.sequence_type == SfxEvent.SEQUENCE_TYPE.LOOP: | |
index = (index + 1) % event.audio_streams.size() | |
elif event.sequence_type == SfxEvent.SEQUENCE_TYPE.HOLD: | |
index = int(min(index + 1, event.audio_streams.size() - 1)) | |
if event.sequence_reset == SfxEvent.SEQUENCE_RESET.TIME: | |
var timer: SceneTreeTimer = events_timers.get(event_name, null) | |
if timer != null: | |
timer.disconnect("timeout", self, "_on_timer_timeout") | |
timer.emit_signal("timeout") | |
timer = null | |
timer = get_tree().create_timer(event.sequence_reset_time) | |
events_timers[event_name] = timer | |
assert(timer.connect("timeout", self, "_on_timer_timeout", [event_name]) == OK) | |
events_sequence[event_name] = index | |
return player | |
func _on_timer_timeout(event_name: String) -> void: | |
events_sequence[event_name] = 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment