Adding sound thanks to Event Adio plugin
55
addons/event_audio/EventAudio.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
public partial class EventAudio : Node {
|
||||||
|
static private EventAudio _instance;
|
||||||
|
private GodotObject _eventAudio;
|
||||||
|
private Callable _play3DMethod;
|
||||||
|
private Callable _play2DMethod;
|
||||||
|
private Callable _stopMethod;
|
||||||
|
|
||||||
|
// Simple 'handle' class for managing Godot audio emitters.
|
||||||
|
public class EventAudioEmitter {
|
||||||
|
public GodotObject Emitter;
|
||||||
|
|
||||||
|
public EventAudioEmitter(GodotObject emitter) {
|
||||||
|
Emitter = emitter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Ready() {
|
||||||
|
base._Ready();
|
||||||
|
_eventAudio = GetParent().GetNode("EventAudio");
|
||||||
|
_play3DMethod = _eventAudio.Get("play_3d").AsCallable();
|
||||||
|
_play2DMethod = _eventAudio.Get("play_2d").AsCallable();
|
||||||
|
_stopMethod = _eventAudio.Get("stop").AsCallable();
|
||||||
|
_instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EventAudio Instance {
|
||||||
|
get {
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventAudioEmitter Play2D(string trigger, Node3D source) {
|
||||||
|
var result = _play2DMethod.Call(trigger, source);
|
||||||
|
var godotEmitter = result.AsGodotObject();
|
||||||
|
if (godotEmitter != null) {
|
||||||
|
return new EventAudioEmitter(godotEmitter);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EventAudioEmitter Play3D(string trigger, Node3D source) {
|
||||||
|
var result = _play3DMethod.Call(trigger, source);
|
||||||
|
var godotEmitter = result.AsGodotObject();
|
||||||
|
if (godotEmitter != null) {
|
||||||
|
return new EventAudioEmitter(godotEmitter);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop(EventAudioEmitter emitter) {
|
||||||
|
_stopMethod.Call(emitter.Emitter);
|
||||||
|
}
|
||||||
|
}
|
207
addons/event_audio/event_audio.gd
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
# Ideally this would be called just EventAudio, but that would class with the autoload
|
||||||
|
class_name EventAudioAPI
|
||||||
|
static var _separator := "+"
|
||||||
|
static var instance : EventAudioAPI
|
||||||
|
|
||||||
|
@export var log_lookups := false
|
||||||
|
@export var log_deaths := false
|
||||||
|
@export var log_registrations := false
|
||||||
|
|
||||||
|
var _trigger_map: Dictionary
|
||||||
|
var _rng: RandomNumberGenerator
|
||||||
|
var _audio_banks: Array[EAEventBank]
|
||||||
|
|
||||||
|
class AudioEmitter2D:
|
||||||
|
var source: Node2D
|
||||||
|
var player: AudioStreamPlayer2D
|
||||||
|
var event: EAEvent
|
||||||
|
|
||||||
|
var _active_emitters_2d = Array()
|
||||||
|
|
||||||
|
class AudioEmitter3D:
|
||||||
|
var source: Node3D
|
||||||
|
var player: AudioStreamPlayer3D
|
||||||
|
var event: EAEvent
|
||||||
|
|
||||||
|
var _active_emitters_3d = Array()
|
||||||
|
|
||||||
|
#---------------------------------------------------------
|
||||||
|
# API
|
||||||
|
#---------------------------------------------------------
|
||||||
|
static func get_instance() -> EventAudioAPI:
|
||||||
|
return instance
|
||||||
|
|
||||||
|
func play_2d(trigger: String, source: Node2D) -> AudioEmitter2D:
|
||||||
|
var event := _find_event_for_trigger(trigger)
|
||||||
|
if event == null:
|
||||||
|
return null
|
||||||
|
|
||||||
|
var stream_player = AudioStreamPlayer2D.new()
|
||||||
|
return _play_event(event, stream_player, source)
|
||||||
|
|
||||||
|
func play_3d(trigger: String, source: Node3D) -> AudioEmitter3D:
|
||||||
|
var event := _find_event_for_trigger(trigger)
|
||||||
|
if event == null:
|
||||||
|
return null
|
||||||
|
|
||||||
|
var stream_player = AudioStreamPlayer3D.new()
|
||||||
|
return _play_event(event, stream_player, source)
|
||||||
|
|
||||||
|
func stop(emitter):
|
||||||
|
if emitter.player != null:
|
||||||
|
emitter.player.stop()
|
||||||
|
|
||||||
|
func register_event_bank(bank: EAEventBank):
|
||||||
|
if log_registrations:
|
||||||
|
print("Registering bank: " + bank.resource_path)
|
||||||
|
_audio_banks.append(bank)
|
||||||
|
_invalidate_trigger_map()
|
||||||
|
|
||||||
|
func unregister_event_bank(bank: EAEventBank):
|
||||||
|
if log_registrations:
|
||||||
|
print("Unregistering bank: " + bank.resource_name)
|
||||||
|
var idx := _audio_banks.find(bank)
|
||||||
|
if idx >= 0:
|
||||||
|
_audio_banks.remove_at(idx)
|
||||||
|
_invalidate_trigger_map()
|
||||||
|
|
||||||
|
static func init_player_from_playback_settings(rng, stream_player, settings: EAEventPlaybackSettings):
|
||||||
|
var min_pitch := min(settings.min_pitch, settings.max_pitch) as float
|
||||||
|
var max_pitch := max(settings.min_pitch, settings.max_pitch) as float
|
||||||
|
var pitch = rng.randf_range(min_pitch, max_pitch)
|
||||||
|
stream_player.pitch_scale = pitch
|
||||||
|
stream_player.volume_db = settings.volume_db
|
||||||
|
|
||||||
|
if stream_player is AudioStreamPlayer3D:
|
||||||
|
stream_player.unit_size = settings.unit_size
|
||||||
|
stream_player.max_db = settings.max_db
|
||||||
|
stream_player.panning_strength = settings.panning_strength
|
||||||
|
|
||||||
|
elif stream_player is AudioStreamPlayer2D:
|
||||||
|
stream_player.max_distance = settings.max_distance
|
||||||
|
stream_player.attenuation = settings.attenuation
|
||||||
|
stream_player.panning_strength = settings.panning_strength
|
||||||
|
|
||||||
|
#---------------------------------------------------------
|
||||||
|
func _init():
|
||||||
|
_rng = RandomNumberGenerator.new()
|
||||||
|
|
||||||
|
func _process(_delta: float):
|
||||||
|
_active_emitters_2d = _process_active_audio(_active_emitters_2d)
|
||||||
|
_active_emitters_3d = _process_active_audio(_active_emitters_3d)
|
||||||
|
|
||||||
|
func _process_active_audio(active_audio):
|
||||||
|
var new_active_audio := Array()
|
||||||
|
|
||||||
|
# TODO - find a better way of modifying the list of active audio emitters
|
||||||
|
for audio in active_audio:
|
||||||
|
var alive := true
|
||||||
|
if audio.player == null:
|
||||||
|
alive = false
|
||||||
|
elif not audio.player.playing:
|
||||||
|
audio.player.queue_free()
|
||||||
|
audio.player = null
|
||||||
|
alive = false
|
||||||
|
elif audio.source == null:
|
||||||
|
if audio.event.playback_settings.stop_when_source_dies:
|
||||||
|
audio.player.stop()
|
||||||
|
alive = false
|
||||||
|
|
||||||
|
# Update the position
|
||||||
|
if not audio.event.playback_settings.stationary and alive and audio.source != null:
|
||||||
|
audio.player.global_position = audio.source.global_position
|
||||||
|
|
||||||
|
if alive:
|
||||||
|
new_active_audio.append(audio)
|
||||||
|
else:
|
||||||
|
_log_death(audio.event.trigger_tags)
|
||||||
|
return new_active_audio
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
instance = self
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
instance = null
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
# Internals
|
||||||
|
#---------------------------------------------------------------------------------
|
||||||
|
func _play_event(event: EAEvent, stream_player, source: Node):
|
||||||
|
var stream := event.get_weighted_random_stream(_rng.randf())
|
||||||
|
stream_player.name = "AudioPlayback"
|
||||||
|
add_child(stream_player)
|
||||||
|
stream_player.stream = stream
|
||||||
|
|
||||||
|
EventAudioAPI.init_player_from_playback_settings(_rng, stream_player, event.playback_settings)
|
||||||
|
|
||||||
|
if source:
|
||||||
|
stream_player.global_position = source.global_position
|
||||||
|
|
||||||
|
stream_player.play()
|
||||||
|
|
||||||
|
if stream_player is AudioStreamPlayer2D:
|
||||||
|
var emitter := AudioEmitter2D.new()
|
||||||
|
emitter.player = stream_player
|
||||||
|
emitter.source = source
|
||||||
|
emitter.event = event
|
||||||
|
_active_emitters_2d.append(emitter)
|
||||||
|
return emitter
|
||||||
|
else:
|
||||||
|
var emitter = AudioEmitter3D.new()
|
||||||
|
emitter.player = stream_player
|
||||||
|
emitter.source = source
|
||||||
|
emitter.event = event
|
||||||
|
_active_emitters_3d.append(emitter)
|
||||||
|
return emitter
|
||||||
|
|
||||||
|
|
||||||
|
func _invalidate_trigger_map():
|
||||||
|
_trigger_map = {}
|
||||||
|
|
||||||
|
func _make_trigger_map():
|
||||||
|
_trigger_map = {}
|
||||||
|
for bank: EAEventBank in _audio_banks:
|
||||||
|
for entry in bank.entries:
|
||||||
|
var key = entry.trigger_tags
|
||||||
|
_trigger_map[key] = entry
|
||||||
|
|
||||||
|
func _find_event_for_trigger(trigger: String) -> EAEvent:
|
||||||
|
if _trigger_map.size() == 0:
|
||||||
|
_make_trigger_map()
|
||||||
|
|
||||||
|
var current_trigger := trigger
|
||||||
|
|
||||||
|
while current_trigger != "":
|
||||||
|
_log_lookup(current_trigger)
|
||||||
|
var found_entry := _trigger_map.get(current_trigger) as EAEvent
|
||||||
|
if found_entry:
|
||||||
|
_log_found(found_entry.trigger_tags)
|
||||||
|
return found_entry
|
||||||
|
var tag_pos := current_trigger.rfind(_separator)
|
||||||
|
if tag_pos >= 0:
|
||||||
|
current_trigger = current_trigger.substr(0, tag_pos)
|
||||||
|
else:
|
||||||
|
current_trigger = ""
|
||||||
|
return null
|
||||||
|
|
||||||
|
func _log_lookup(msg: String):
|
||||||
|
if log_lookups:
|
||||||
|
print("Trying " + msg)
|
||||||
|
|
||||||
|
func _log_found(msg: String):
|
||||||
|
if log_lookups:
|
||||||
|
print("Found " + msg)
|
||||||
|
|
||||||
|
func _log_bank_add(msg: String):
|
||||||
|
if log_registrations:
|
||||||
|
print("Registering Bank " + msg)
|
||||||
|
|
||||||
|
func _log_bank_remove(msg: String):
|
||||||
|
if log_registrations:
|
||||||
|
print("Unregistering Bank " + msg)
|
||||||
|
|
||||||
|
func _log_death(msg: String):
|
||||||
|
if log_deaths:
|
||||||
|
print("Killing " + msg)
|
59
addons/event_audio/example/ExampleEmitter3D.cs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
|
||||||
|
public partial class ExampleEmitter3D : Node3D {
|
||||||
|
[Export]
|
||||||
|
float Speed = 1.0f;
|
||||||
|
[Export]
|
||||||
|
Node3D OrbitNode;
|
||||||
|
EventAudio.EventAudioEmitter _loopEmitter;
|
||||||
|
float _orbitRadius = 1.0f;
|
||||||
|
|
||||||
|
public override void _Ready() {
|
||||||
|
_orbitRadius = (GlobalPosition - OrbitNode.GlobalPosition).Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Process(double _delta) {
|
||||||
|
float orbitAngle = (Time.GetTicksMsec() / 1000.0f % Speed) * 2.0f * 3.14159f;
|
||||||
|
float offset_x = _orbitRadius * Mathf.Cos(orbitAngle);
|
||||||
|
float offset_y = _orbitRadius * Mathf.Sin(orbitAngle);
|
||||||
|
|
||||||
|
var new_position = OrbitNode.GlobalPosition;
|
||||||
|
new_position.X += offset_x;
|
||||||
|
new_position.Z += offset_y;
|
||||||
|
|
||||||
|
GlobalPosition = new_position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _Input(InputEvent ev_) {
|
||||||
|
if (!(ev_ is InputEventKey) || !ev_.IsPressed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ev = ev_ as InputEventKey;
|
||||||
|
if (ev.Keycode == Key.Key1) {
|
||||||
|
EventAudio.Instance.Play3D("hit", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.Keycode == Key.Key2) {
|
||||||
|
EventAudio.Instance.Play3D("hit+large", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.Keycode == Key.Key3) {
|
||||||
|
EventAudio.Instance.Play3D("hit+nonexistent", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.Keycode == Key.Key4) {
|
||||||
|
EventAudio.Instance.Play3D("random_shoot", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev.Keycode == Key.Key5) {
|
||||||
|
if (_loopEmitter != null) {
|
||||||
|
EventAudio.Instance.Stop(_loopEmitter);
|
||||||
|
_loopEmitter = null;
|
||||||
|
} else {
|
||||||
|
_loopEmitter = EventAudio.Instance.Play3D("loop", this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
addons/event_audio/example/csharp_example_3D.tscn
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
[gd_scene load_steps=6 format=3 uid="uid://fk1nqp2seuw6"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_bank_mounter.gd" id="1_0y6i8"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cfxmacq8po281" path="res://addons/event_audio/example/example_audio_bank.tres" id="2_qo1e5"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/example/ExampleEmitter3D.cs" id="3_w1shi"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://kjsaalyhmkc5" path="res://addons/event_audio/example/example_ui.tscn" id="4_e42vy"]
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_3bdsu"]
|
||||||
|
|
||||||
|
[node name="Example3d" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D" parent="." node_paths=PackedStringArray("OrbitNode")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -4.70263)
|
||||||
|
script = ExtResource("3_w1shi")
|
||||||
|
OrbitNode = NodePath("../Camera3D")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D"]
|
||||||
|
mesh = SubResource("SphereMesh_3bdsu")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.176947, 0.98422, 0, -0.98422, 0.176947, 0, 1.9958, 0)
|
||||||
|
|
||||||
|
[node name="ExampleAudioBank" type="Node" parent="."]
|
||||||
|
script = ExtResource("1_0y6i8")
|
||||||
|
_audio_bank_resource = ExtResource("2_qo1e5")
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="ExampleUi" parent="CanvasLayer" instance=ExtResource("4_e42vy")]
|
33
addons/event_audio/example/example2D.tscn
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
[gd_scene load_steps=6 format=3 uid="uid://konnaekcsk2e"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/example/example_emitter_2d.gd" id="1_7u4pm"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cfxmacq8po281" path="res://addons/event_audio/example/example_audio_bank.tres" id="3_kb4ey"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_bank_mounter.gd" id="3_q1afy"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://kjsaalyhmkc5" path="res://addons/event_audio/example/example_ui.tscn" id="4_kisj8"]
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_7scev"]
|
||||||
|
radius = 10.0
|
||||||
|
height = 20.0
|
||||||
|
|
||||||
|
[node name="Example2d" type="Node2D"]
|
||||||
|
|
||||||
|
[node name="Emitter" type="MeshInstance2D" parent="."]
|
||||||
|
position = Vector2(2.08165e-12, 175.95)
|
||||||
|
mesh = SubResource("SphereMesh_7scev")
|
||||||
|
script = ExtResource("1_7u4pm")
|
||||||
|
|
||||||
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
|
position = Vector2(578, 324)
|
||||||
|
|
||||||
|
[node name="AudioListener2D" type="AudioListener2D" parent="Camera2D"]
|
||||||
|
current = true
|
||||||
|
|
||||||
|
[node name="TestAudioBank" type="Node" parent="."]
|
||||||
|
script = ExtResource("3_q1afy")
|
||||||
|
_audio_bank_resource = ExtResource("3_kb4ey")
|
||||||
|
|
||||||
|
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="ExampleUi" parent="CanvasLayer" instance=ExtResource("4_kisj8")]
|
31
addons/event_audio/example/example3D.tscn
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
[gd_scene load_steps=6 format=3 uid="uid://b12tpedbx38u7"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_bank_mounter.gd" id="1_ncilt"]
|
||||||
|
[ext_resource type="Resource" uid="uid://cfxmacq8po281" path="res://addons/event_audio/example/example_audio_bank.tres" id="2_nj06b"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/example/example_emitter_3d.gd" id="3_wpepl"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://kjsaalyhmkc5" path="res://addons/event_audio/example/example_ui.tscn" id="4_sw6y2"]
|
||||||
|
|
||||||
|
[sub_resource type="SphereMesh" id="SphereMesh_3bdsu"]
|
||||||
|
|
||||||
|
[node name="Example3d" type="Node3D"]
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
|
||||||
|
[node name="Node3D" type="Node3D" parent="." node_paths=PackedStringArray("OrbitNode")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -4.70263)
|
||||||
|
script = ExtResource("3_wpepl")
|
||||||
|
OrbitNode = NodePath("../Camera3D")
|
||||||
|
|
||||||
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D"]
|
||||||
|
mesh = SubResource("SphereMesh_3bdsu")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.176947, 0.98422, 0, -0.98422, 0.176947, 0, 1.9958, 0)
|
||||||
|
|
||||||
|
[node name="TestAudioBank" type="Node" parent="."]
|
||||||
|
script = ExtResource("1_ncilt")
|
||||||
|
_audio_bank_resource = ExtResource("2_nj06b")
|
||||||
|
|
||||||
|
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="ExampleUi" parent="CanvasLayer" instance=ExtResource("4_sw6y2")]
|
94
addons/event_audio/example/example_audio_bank.tres
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
[gd_resource type="Resource" script_class="EAEventBank" load_steps=17 format=3 uid="uid://cfxmacq8po281"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event.gd" id="1_fy8lm"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://7ncmg0ox4nxr" path="res://addons/event_audio/example/sounds/loop.wav" id="2_fyotq"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_bank.gd" id="2_rbntb"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_playback_settings.gd" id="3_fy5gc"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://byg26ypxea5qh" path="res://addons/event_audio/example/sounds/laser1.wav" id="3_nyuuq"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://ftyi4ikfmbii" path="res://addons/event_audio/example/sounds/laser2.wav" id="4_ahbca"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://cqo6bi2ygpwbu" path="res://addons/event_audio/example/sounds/shot1.wav" id="4_fpv34"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://cultflwybpfo1" path="res://addons/event_audio/example/sounds/shot2.wav" id="5_1yf0v"]
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_dd35s"]
|
||||||
|
script = ExtResource("3_fy5gc")
|
||||||
|
stop_when_source_dies = false
|
||||||
|
stationary = true
|
||||||
|
volume_db = 0.0
|
||||||
|
min_pitch = 0.8
|
||||||
|
max_pitch = 1.2
|
||||||
|
panning_strength = 1.0
|
||||||
|
attenuation = 1.0
|
||||||
|
max_distance = 2000
|
||||||
|
unit_size = 10.0
|
||||||
|
max_db = 3.0
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_lfo5e"]
|
||||||
|
script = ExtResource("1_fy8lm")
|
||||||
|
audio_streams = Array[AudioStream]([ExtResource("4_fpv34")])
|
||||||
|
probability_weights = Array[float]([1.0])
|
||||||
|
trigger_tags = "hit"
|
||||||
|
playback_settings = SubResource("Resource_dd35s")
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_j54ca"]
|
||||||
|
script = ExtResource("3_fy5gc")
|
||||||
|
stop_when_source_dies = false
|
||||||
|
stationary = true
|
||||||
|
volume_db = 0.0
|
||||||
|
min_pitch = 0.9
|
||||||
|
max_pitch = 1.2
|
||||||
|
panning_strength = 1.0
|
||||||
|
attenuation = 1.0
|
||||||
|
max_distance = 2000
|
||||||
|
unit_size = 10.0
|
||||||
|
max_db = 3.0
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_d2op2"]
|
||||||
|
script = ExtResource("1_fy8lm")
|
||||||
|
audio_streams = Array[AudioStream]([ExtResource("5_1yf0v")])
|
||||||
|
probability_weights = Array[float]([1.0])
|
||||||
|
trigger_tags = "hit+large"
|
||||||
|
playback_settings = SubResource("Resource_j54ca")
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_ljdcd"]
|
||||||
|
script = ExtResource("3_fy5gc")
|
||||||
|
stop_when_source_dies = false
|
||||||
|
stationary = false
|
||||||
|
volume_db = 0.0
|
||||||
|
min_pitch = 0.8
|
||||||
|
max_pitch = 1.2
|
||||||
|
panning_strength = 2.0
|
||||||
|
attenuation = 1.0
|
||||||
|
max_distance = 2000
|
||||||
|
unit_size = 10.0
|
||||||
|
max_db = 3.0
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_ps0cx"]
|
||||||
|
script = ExtResource("1_fy8lm")
|
||||||
|
audio_streams = Array[AudioStream]([ExtResource("2_fyotq")])
|
||||||
|
probability_weights = Array[float]([1.0])
|
||||||
|
trigger_tags = "loop"
|
||||||
|
playback_settings = SubResource("Resource_ljdcd")
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_1xrvu"]
|
||||||
|
script = ExtResource("3_fy5gc")
|
||||||
|
stop_when_source_dies = false
|
||||||
|
stationary = true
|
||||||
|
volume_db = 0.0
|
||||||
|
min_pitch = 0.8
|
||||||
|
max_pitch = 1.2
|
||||||
|
panning_strength = 1.0
|
||||||
|
attenuation = 1.0
|
||||||
|
max_distance = 2000
|
||||||
|
unit_size = 10.0
|
||||||
|
max_db = 3.0
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_xjlcv"]
|
||||||
|
script = ExtResource("1_fy8lm")
|
||||||
|
audio_streams = Array[AudioStream]([ExtResource("3_nyuuq"), ExtResource("4_ahbca")])
|
||||||
|
probability_weights = Array[float]([1.0, 1.0])
|
||||||
|
trigger_tags = "random_shoot"
|
||||||
|
playback_settings = SubResource("Resource_1xrvu")
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("2_rbntb")
|
||||||
|
entries = Array[ExtResource("1_fy8lm")]([SubResource("Resource_lfo5e"), SubResource("Resource_d2op2"), SubResource("Resource_ps0cx"), SubResource("Resource_xjlcv")])
|
48
addons/event_audio/example/example_emitter_2d.gd
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
extends Node2D
|
||||||
|
class_name ExampleEmitter2D
|
||||||
|
|
||||||
|
@export var Speed := 1.0
|
||||||
|
var _loop_emitter : EventAudioAPI.AudioEmitter2D
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
EventAudio.log_lookups = true
|
||||||
|
EventAudio.log_registrations = true
|
||||||
|
EventAudio.log_deaths = true
|
||||||
|
|
||||||
|
func _process(delta: float):
|
||||||
|
var screen_width := get_viewport_rect().size.x
|
||||||
|
|
||||||
|
var step := Speed * screen_width * delta
|
||||||
|
var new_position := global_position
|
||||||
|
new_position.x += step
|
||||||
|
if new_position.x < 0:
|
||||||
|
new_position.x = 0
|
||||||
|
Speed = -Speed
|
||||||
|
elif new_position.x >= screen_width:
|
||||||
|
new_position.x = screen_width
|
||||||
|
Speed = -Speed
|
||||||
|
|
||||||
|
global_position = new_position
|
||||||
|
|
||||||
|
func _input(event: InputEvent):
|
||||||
|
if not event is InputEventKey or not event.is_pressed():
|
||||||
|
return
|
||||||
|
|
||||||
|
if event.keycode == KEY_1:
|
||||||
|
EventAudio.play_2d("hit", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_2:
|
||||||
|
EventAudio.play_2d("hit+large", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_3:
|
||||||
|
EventAudio.play_2d("hit+nonexistent", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_4:
|
||||||
|
EventAudio.play_2d("random_shoot", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_5:
|
||||||
|
if _loop_emitter:
|
||||||
|
EventAudio.stop(_loop_emitter)
|
||||||
|
_loop_emitter = null
|
||||||
|
else:
|
||||||
|
_loop_emitter = EventAudio.play_2d("loop", self)
|
50
addons/event_audio/example/example_emitter_3d.gd
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
extends Node3D
|
||||||
|
class_name ExampleEmitter3D
|
||||||
|
|
||||||
|
@export var Speed := 1.0
|
||||||
|
@export var OrbitNode : Node3D
|
||||||
|
var _loop_emitter : EventAudioAPI.AudioEmitter3D
|
||||||
|
var _orbit_radius := 1.0
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
EventAudio.log_lookups = true
|
||||||
|
EventAudio.log_registrations = true
|
||||||
|
EventAudio.log_deaths = true
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
_orbit_radius = (global_position - OrbitNode.global_position).length()
|
||||||
|
|
||||||
|
func _process(_delta: float):
|
||||||
|
var orbit_angle = fmod(Time.get_ticks_msec() / 1000.0, Speed) * 2 * PI
|
||||||
|
|
||||||
|
var offset_x = _orbit_radius * cos(orbit_angle)
|
||||||
|
var offset_y = _orbit_radius * sin(orbit_angle)
|
||||||
|
|
||||||
|
var new_position := OrbitNode.global_position
|
||||||
|
new_position.x += offset_x
|
||||||
|
new_position.z += offset_y
|
||||||
|
|
||||||
|
global_position = new_position
|
||||||
|
|
||||||
|
func _input(event: InputEvent):
|
||||||
|
if not event is InputEventKey or not event.is_pressed():
|
||||||
|
return
|
||||||
|
|
||||||
|
if event.keycode == KEY_1:
|
||||||
|
EventAudio.play_3d("hit", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_2:
|
||||||
|
EventAudio.play_3d("hit+large", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_3:
|
||||||
|
EventAudio.play_3d("hit+nonexistent", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_4:
|
||||||
|
EventAudio.play_3d("random_shoot", self)
|
||||||
|
|
||||||
|
if event.keycode == KEY_5:
|
||||||
|
if _loop_emitter:
|
||||||
|
EventAudio.stop(_loop_emitter)
|
||||||
|
_loop_emitter = null
|
||||||
|
else:
|
||||||
|
_loop_emitter = EventAudio.play_3d("loop", self)
|
24
addons/event_audio/example/example_ui.tscn
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[gd_scene format=3 uid="uid://kjsaalyhmkc5"]
|
||||||
|
|
||||||
|
[node name="ExampleUi" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 2
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_vertical = 0
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 2
|
||||||
|
anchor_top = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = -127.0
|
||||||
|
offset_right = 196.0
|
||||||
|
grow_vertical = 0
|
||||||
|
text = "1 - Play \"hit\"
|
||||||
|
2 - Play \"hit+large\"
|
||||||
|
3 - Play \"hit+nonexistent\"
|
||||||
|
4 - Play \"random_shoot\"
|
||||||
|
5 - Toggle \"loop\""
|
||||||
|
vertical_alignment = 2
|
||||||
|
justification_flags = 161
|
BIN
addons/event_audio/example/sounds/laser1.wav
Normal file
24
addons/event_audio/example/sounds/laser1.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://byg26ypxea5qh"
|
||||||
|
path="res://.godot/imported/laser1.wav-7c7bf6a86d0428120783ce6ae72e8afb.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/example/sounds/laser1.wav"
|
||||||
|
dest_files=["res://.godot/imported/laser1.wav-7c7bf6a86d0428120783ce6ae72e8afb.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=0
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=0
|
BIN
addons/event_audio/example/sounds/laser2.wav
Normal file
24
addons/event_audio/example/sounds/laser2.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://ftyi4ikfmbii"
|
||||||
|
path="res://.godot/imported/laser2.wav-396964f333f7fcbda54278f155b07608.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/example/sounds/laser2.wav"
|
||||||
|
dest_files=["res://.godot/imported/laser2.wav-396964f333f7fcbda54278f155b07608.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=0
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=0
|
BIN
addons/event_audio/example/sounds/loop.wav
Normal file
24
addons/event_audio/example/sounds/loop.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://7ncmg0ox4nxr"
|
||||||
|
path="res://.godot/imported/loop.wav-fa3b1ef3ac7c882255ced1130766deef.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/example/sounds/loop.wav"
|
||||||
|
dest_files=["res://.godot/imported/loop.wav-fa3b1ef3ac7c882255ced1130766deef.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=2
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=0
|
BIN
addons/event_audio/example/sounds/shot1.wav
Normal file
24
addons/event_audio/example/sounds/shot1.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://cqo6bi2ygpwbu"
|
||||||
|
path="res://.godot/imported/shot1.wav-d93bbca9f7efde511f9d9572265cbb25.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/example/sounds/shot1.wav"
|
||||||
|
dest_files=["res://.godot/imported/shot1.wav-d93bbca9f7efde511f9d9572265cbb25.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=0
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=0
|
BIN
addons/event_audio/example/sounds/shot2.wav
Normal file
24
addons/event_audio/example/sounds/shot2.wav.import
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="wav"
|
||||||
|
type="AudioStreamWAV"
|
||||||
|
uid="uid://cultflwybpfo1"
|
||||||
|
path="res://.godot/imported/shot2.wav-ac04745e5c74f182ec001473606b2120.sample"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/example/sounds/shot2.wav"
|
||||||
|
dest_files=["res://.godot/imported/shot2.wav-ac04745e5c74f182ec001473606b2120.sample"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
force/8_bit=false
|
||||||
|
force/mono=false
|
||||||
|
force/max_rate=false
|
||||||
|
force/max_rate_hz=44100
|
||||||
|
edit/trim=false
|
||||||
|
edit/normalize=false
|
||||||
|
edit/loop_mode=0
|
||||||
|
edit/loop_begin=0
|
||||||
|
edit/loop_end=-1
|
||||||
|
compress/mode=0
|
BIN
addons/event_audio/icon.png
Normal file
After Width: | Height: | Size: 35 KiB |
34
addons/event_audio/icon.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://d3rrns80mmgqo"
|
||||||
|
path="res://.godot/imported/icon.png-5ff47921d459c4c7814e206e0a2e0cc0.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icon.png"
|
||||||
|
dest_files=["res://.godot/imported/icon.png-5ff47921d459c4c7814e206e0a2e0cc0.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
1
addons/event_audio/icons/Add.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m7 1v6h-6v2h6v6h2v-6h6v-2h-6v-6z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 149 B |
37
addons/event_audio/icons/Add.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dqg7mfau2g7ck"
|
||||||
|
path="res://.godot/imported/Add.svg-219bdd038475c83ffbebee883f646de0.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icons/Add.svg"
|
||||||
|
dest_files=["res://.godot/imported/Add.svg-219bdd038475c83ffbebee883f646de0.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
addons/event_audio/icons/Close.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3 10 10M3 13 13 3" fill="none" stroke="#e0e0e0" stroke-width="2"/></svg>
|
After Width: | Height: | Size: 168 B |
37
addons/event_audio/icons/Close.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://pad8hlsq2shw"
|
||||||
|
path="res://.godot/imported/Close.svg-326dec14804498c2ab2273a4a572c2e2.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icons/Close.svg"
|
||||||
|
dest_files=["res://.godot/imported/Close.svg-326dec14804498c2ab2273a4a572c2e2.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
addons/event_audio/icons/Play.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 12a1 1 0 0 0 1.555.832l6-4a1 1 0 0 0 0-1.664l-6-4A1 1 0 0 0 4 4z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 184 B |
37
addons/event_audio/icons/Play.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://byclw0utbwbam"
|
||||||
|
path="res://.godot/imported/Play.svg-33c5bae738cb342d56c12b8caaf4909d.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icons/Play.svg"
|
||||||
|
dest_files=["res://.godot/imported/Play.svg-33c5bae738cb342d56c12b8caaf4909d.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
addons/event_audio/icons/RandomNumberGenerator.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1C1 1 1 1 1 8s0 7 7 7 7 0 7-7 0-7-7-7zM4.25 2.25a1 1 0 0 1 0 4 1 1 0 0 1 0-4zM8 6a1 1 0 0 1 0 4 1 1 0 0 1 0-4zm3.75 3.75a1 1 0 0 1 0 4 1 1 0 0 1 0-4z" fill="#fff"/></svg>
|
After Width: | Height: | Size: 266 B |
37
addons/event_audio/icons/RandomNumberGenerator.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dcbbwdp16tdns"
|
||||||
|
path="res://.godot/imported/RandomNumberGenerator.svg-307a8ce8bcb247fd591f4766aea337ae.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icons/RandomNumberGenerator.svg"
|
||||||
|
dest_files=["res://.godot/imported/RandomNumberGenerator.svg-307a8ce8bcb247fd591f4766aea337ae.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
addons/event_audio/icons/Remove.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1v1h-4v2h14v-2h-4v-1zm-3 4v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-8zm1 2h2v6h-2zm4 0h2v6h-2zm4 0h2v6h-2z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 218 B |
37
addons/event_audio/icons/Remove.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://djgktanb5swk6"
|
||||||
|
path="res://.godot/imported/Remove.svg-dad4f6b2d936a8b9536e5322302cb088.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icons/Remove.svg"
|
||||||
|
dest_files=["res://.godot/imported/Remove.svg-dad4f6b2d936a8b9536e5322302cb088.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
1
addons/event_audio/icons/Tools.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4 1 3 3l1 2v4H2v3.5a2.5 2.5 0 0 0 5 0V9H5V5l1-2-1-2zm6 .174a3 3 0 0 0 0 5.652V14a1 1 0 0 0 2 0V6.824a3 3 0 0 0 0-5.648V4a1 1 0 0 1-2 0z" fill="#e0e0e0"/></svg>
|
After Width: | Height: | Size: 253 B |
37
addons/event_audio/icons/Tools.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://i4qa40akvjaa"
|
||||||
|
path="res://.godot/imported/Tools.svg-4c4437be5a640503622d98eb51e3bd18.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://addons/event_audio/icons/Tools.svg"
|
||||||
|
dest_files=["res://.godot/imported/Tools.svg-4c4437be5a640503622d98eb51e3bd18.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
||||||
|
svg/scale=2.0
|
||||||
|
editor/scale_with_editor_scale=false
|
||||||
|
editor/convert_colors_with_editor_theme=false
|
6
addons/event_audio/plugin.cfg
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[plugin]
|
||||||
|
name="EventAudio"
|
||||||
|
description=""
|
||||||
|
author="Simon Carter"
|
||||||
|
version="1.0.1"
|
||||||
|
script="plugin.gd"
|
33
addons/event_audio/plugin.gd
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
@tool
|
||||||
|
extends EditorPlugin
|
||||||
|
|
||||||
|
var _editor_plugin = preload("res://addons/event_audio/src/ea_event_bank_inspector.gd").new()
|
||||||
|
var _runtime_scene = "res://addons/event_audio/scenes/event_audio_autoload.tscn"
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
|
||||||
|
var mono_supported = ClassDB.class_exists("CSharpScript")
|
||||||
|
|
||||||
|
if mono_supported:
|
||||||
|
print ("Mono supported")
|
||||||
|
else:
|
||||||
|
print ("Mono unsupported")
|
||||||
|
|
||||||
|
add_inspector_plugin(_editor_plugin)
|
||||||
|
|
||||||
|
if not ProjectSettings.has_setting("autoload/EventAudio"):
|
||||||
|
add_autoload_singleton("EventAudio", _runtime_scene)
|
||||||
|
|
||||||
|
if mono_supported:
|
||||||
|
if not ProjectSettings.has_setting("autoload/EventAudioCSharp"):
|
||||||
|
var _cs_script = "res://addons/event_audio/EventAudio.cs"
|
||||||
|
add_autoload_singleton("EventAudioCSharp", _cs_script)
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
if _editor_plugin != null:
|
||||||
|
remove_inspector_plugin(_editor_plugin)
|
||||||
|
if ProjectSettings.has_setting("autoload/EventAudio"):
|
||||||
|
remove_autoload_singleton("EventAudio")
|
||||||
|
|
||||||
|
if ProjectSettings.has_setting("autoload/EventAudioCSharp"):
|
||||||
|
remove_autoload_singleton("EventAudioCSharp")
|
68
addons/event_audio/scenes/bank_line.tscn
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
[gd_scene load_steps=6 format=3 uid="uid://co2eglljfwoxo"]
|
||||||
|
|
||||||
|
[ext_resource type="Texture2D" uid="uid://pad8hlsq2shw" path="res://addons/event_audio/icons/Close.svg" id="1_2kmlt"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_edit_control.gd" id="1_melcq"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://i4qa40akvjaa" path="res://addons/event_audio/icons/Tools.svg" id="2_31ihp"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dcbbwdp16tdns" path="res://addons/event_audio/icons/RandomNumberGenerator.svg" id="3_ikqib"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b84km51g3vs0n" path="res://addons/event_audio/scenes/bank_resource_line.tscn" id="5_nou6o"]
|
||||||
|
|
||||||
|
[node name="TriggerLine" type="HBoxContainer" node_paths=PackedStringArray("delete_trigger_button", "play_random_button", "trigger_name_edit", "settings_button", "stream_settings_list")]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_top = -38.0
|
||||||
|
offset_bottom = -655.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
script = ExtResource("1_melcq")
|
||||||
|
delete_trigger_button = NodePath("HBoxContainer/DeleteButton")
|
||||||
|
play_random_button = NodePath("HBoxContainer/RandomButton")
|
||||||
|
trigger_name_edit = NodePath("HBoxContainer/TriggerEdit")
|
||||||
|
settings_button = NodePath("HBoxContainer/SettingsButton")
|
||||||
|
stream_settings_list = NodePath("BoxContainer/ResourceList")
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 0
|
||||||
|
|
||||||
|
[node name="DeleteButton" type="Button" parent="HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Delete this event."
|
||||||
|
icon = ExtResource("1_2kmlt")
|
||||||
|
|
||||||
|
[node name="TriggerEdit" type="LineEdit" parent="HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
tooltip_text = "The string that will trigger this audio event.
|
||||||
|
Trigger strings are chopped right-to-left at the seperator character until a match is found."
|
||||||
|
placeholder_text = "trigger string"
|
||||||
|
|
||||||
|
[node name="SettingsButton" type="Button" parent="HBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(16, 16)
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Playback settings."
|
||||||
|
icon = ExtResource("2_31ihp")
|
||||||
|
icon_alignment = 1
|
||||||
|
|
||||||
|
[node name="RandomButton" type="Button" parent="HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Trigger this audio. Plays back a random audio variant, taking into account the variant weights."
|
||||||
|
icon = ExtResource("3_ikqib")
|
||||||
|
|
||||||
|
[node name="BoxContainer" type="BoxContainer" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="ResourceList" type="VBoxContainer" parent="BoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="ResourceLine" parent="BoxContainer/ResourceList" instance=ExtResource("5_nou6o")]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="ResourceLine2" parent="BoxContainer/ResourceList" instance=ExtResource("5_nou6o")]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
76
addons/event_audio/scenes/bank_resource_line.tscn
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
[gd_scene load_steps=5 format=3 uid="uid://b84km51g3vs0n"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_stream_edit_control.gd" id="1_fwtai"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://byclw0utbwbam" path="res://addons/event_audio/icons/Play.svg" id="2_jis6r"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dqg7mfau2g7ck" path="res://addons/event_audio/icons/Add.svg" id="3_aknch"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://djgktanb5swk6" path="res://addons/event_audio/icons/Remove.svg" id="4_il77p"]
|
||||||
|
|
||||||
|
[node name="ResourceLine" type="HBoxContainer" node_paths=PackedStringArray("delete_event_button", "add_stream_button", "play_button", "audio_label")]
|
||||||
|
offset_right = 328.0
|
||||||
|
offset_bottom = 40.0
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_vertical = 3
|
||||||
|
script = ExtResource("1_fwtai")
|
||||||
|
delete_event_button = NodePath("DeleteButton")
|
||||||
|
add_stream_button = NodePath("AddButton")
|
||||||
|
play_button = NodePath("PlayButton")
|
||||||
|
audio_label = NodePath("ResourcePicker/ResourceLabel")
|
||||||
|
|
||||||
|
[node name="PlayButton" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Play this audio variant."
|
||||||
|
icon = ExtResource("2_jis6r")
|
||||||
|
|
||||||
|
[node name="WeightSliderContainer" type="FlowContainer" parent="."]
|
||||||
|
custom_minimum_size = Vector2(64, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_stretch_ratio = 0.5
|
||||||
|
tooltip_text = "The weighted probabily this variant will play.
|
||||||
|
Only used when there is more than one variant."
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="ResourcePicker" type="Control" parent="."]
|
||||||
|
clip_contents = true
|
||||||
|
custom_minimum_size = Vector2(128, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="ResourcePickerContainer" type="BoxContainer" parent="ResourcePicker"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
alignment = 1
|
||||||
|
vertical = true
|
||||||
|
|
||||||
|
[node name="ResourceLabel" type="Label" parent="ResourcePicker"]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = -1
|
||||||
|
anchor_left = 0.234
|
||||||
|
anchor_right = 0.703
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 0.0479984
|
||||||
|
offset_right = 0.0159988
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
clip_text = true
|
||||||
|
text_overrun_behavior = 1
|
||||||
|
|
||||||
|
[node name="AddButton" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
tooltip_text = "Add an audio variant to the trigger."
|
||||||
|
icon = ExtResource("3_aknch")
|
||||||
|
|
||||||
|
[node name="DeleteButton" type="Button" parent="."]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_vertical = 3
|
||||||
|
tooltip_text = "Delete this variant."
|
||||||
|
icon = ExtResource("4_il77p")
|
8
addons/event_audio/scenes/event_audio_autoload.tscn
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://be741v81fj3xc"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/event_audio.gd" id="1_75kvd"]
|
||||||
|
|
||||||
|
[node name="EventAudio" type="Node"]
|
||||||
|
script = ExtResource("1_75kvd")
|
||||||
|
|
||||||
|
[node name="EventAudioAutoload" type="Node" parent="."]
|
201
addons/event_audio/src/ea_editor_tools.gd
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
class_name EAEditorTools
|
||||||
|
static var _editor_stream_player : AudioStreamPlayer
|
||||||
|
static var _global_rng : RandomNumberGenerator
|
||||||
|
|
||||||
|
static func get_global_rng() -> RandomNumberGenerator:
|
||||||
|
if _global_rng == null:
|
||||||
|
_global_rng = RandomNumberGenerator.new()
|
||||||
|
return _global_rng
|
||||||
|
|
||||||
|
static func play_sound(entry: EAEvent, stream: AudioStream):
|
||||||
|
var main_screen = EditorInterface.get_editor_main_screen()
|
||||||
|
var audio = _editor_stream_player
|
||||||
|
if audio == null:
|
||||||
|
audio = AudioStreamPlayer.new()
|
||||||
|
audio.name = "_EditorAudio"
|
||||||
|
main_screen.add_child(audio)
|
||||||
|
_editor_stream_player = audio
|
||||||
|
|
||||||
|
EventAudioAPI.init_player_from_playback_settings(get_global_rng(), audio, entry.playback_settings)
|
||||||
|
|
||||||
|
audio.stop()
|
||||||
|
audio.stream = stream
|
||||||
|
audio.play()
|
||||||
|
|
||||||
|
static func stop_sound():
|
||||||
|
var audio := _editor_stream_player
|
||||||
|
if audio != null:
|
||||||
|
print("Stopping audio")
|
||||||
|
audio.stop()
|
||||||
|
audio.stream = null
|
||||||
|
|
||||||
|
static func make_property_panel(obj: Object, title: String, excludes : Dictionary, change_callback : Callable) -> Container:
|
||||||
|
var panel := PanelContainer.new()
|
||||||
|
panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
panel.modulate = Color(0.8, 0.8, 1)
|
||||||
|
|
||||||
|
var property_container := VBoxContainer.new()
|
||||||
|
property_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
panel.add_child(property_container)
|
||||||
|
|
||||||
|
if title != "":
|
||||||
|
var title_label := Label.new()
|
||||||
|
title_label.text = title
|
||||||
|
title_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
property_container.add_child(title_label)
|
||||||
|
|
||||||
|
for prop in obj.get_property_list():
|
||||||
|
if not prop.name in excludes:
|
||||||
|
var val = obj.get(prop.name)
|
||||||
|
var property_control := _make_property_control(prop, val, change_callback.bind(obj, prop.name))
|
||||||
|
if property_control != null:
|
||||||
|
property_container.add_child(property_control)
|
||||||
|
|
||||||
|
return panel
|
||||||
|
|
||||||
|
static func _make_property_control(prop, initial_value, update_callback: Callable) -> Control:
|
||||||
|
# print(prop)
|
||||||
|
var control : Control
|
||||||
|
|
||||||
|
if prop.usage & PROPERTY_USAGE_STORAGE:
|
||||||
|
control = HBoxContainer.new()
|
||||||
|
control.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
var text_label = Label.new()
|
||||||
|
text_label.text = _property_name_to_display_name(prop.name)
|
||||||
|
|
||||||
|
text_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
control.add_child(text_label)
|
||||||
|
|
||||||
|
var prop_type: Variant.Type = prop["type"]
|
||||||
|
var prop_range : Dictionary = _parse_range(prop)
|
||||||
|
|
||||||
|
match prop_type:
|
||||||
|
TYPE_BOOL:
|
||||||
|
var prop_editor = CheckBox.new()
|
||||||
|
prop_editor.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
if initial_value != null:
|
||||||
|
prop_editor.button_pressed = initial_value
|
||||||
|
|
||||||
|
prop_editor.toggled.connect(update_callback)
|
||||||
|
control.add_child(prop_editor)
|
||||||
|
|
||||||
|
TYPE_INT, TYPE_FLOAT:
|
||||||
|
var prop_editor := EditorSpinSlider.new()
|
||||||
|
var default_step = null
|
||||||
|
if prop_range.has("step"):
|
||||||
|
default_step = prop_range["step"]
|
||||||
|
|
||||||
|
# For floats, show a normal input box if the step has been set to 1.
|
||||||
|
# For ints, show a normal input box if the step has been set to 1, or left out.
|
||||||
|
# Otherwise show a slider
|
||||||
|
if prop_type == TYPE_FLOAT:
|
||||||
|
if default_step == null:
|
||||||
|
prop_editor.hide_slider = false
|
||||||
|
prop_editor.step = 0.0001
|
||||||
|
elif default_step == 1:
|
||||||
|
prop_editor.step = 1
|
||||||
|
else:
|
||||||
|
prop_editor.step = default_step
|
||||||
|
prop_editor.hide_slider = false
|
||||||
|
else:
|
||||||
|
if default_step == null or default_step == 1:
|
||||||
|
prop_editor.step = 1
|
||||||
|
else:
|
||||||
|
prop_editor.step = default_step
|
||||||
|
prop_editor.hide_slider = false
|
||||||
|
|
||||||
|
|
||||||
|
prop_editor.allow_lesser = prop_range.has("or_lesser")
|
||||||
|
prop_editor.allow_greater = prop_range.has("or_greater")
|
||||||
|
|
||||||
|
if prop_range.has("min"):
|
||||||
|
prop_editor.min_value = prop_range["min"]
|
||||||
|
|
||||||
|
if prop_range.has("max"):
|
||||||
|
prop_editor.max_value = prop_range["max"]
|
||||||
|
|
||||||
|
prop_editor.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
if initial_value != null:
|
||||||
|
prop_editor.value = initial_value
|
||||||
|
|
||||||
|
prop_editor.value_changed.connect(update_callback)
|
||||||
|
control.add_child(prop_editor)
|
||||||
|
|
||||||
|
TYPE_STRING, TYPE_STRING_NAME, TYPE_NODE_PATH:
|
||||||
|
var prop_editor = LineEdit.new()
|
||||||
|
prop_editor.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
if initial_value != null:
|
||||||
|
prop_editor.text = initial_value
|
||||||
|
|
||||||
|
prop_editor.text_changed.connect(update_callback)
|
||||||
|
control.add_child(prop_editor)
|
||||||
|
|
||||||
|
_:
|
||||||
|
pass
|
||||||
|
elif prop.usage & PROPERTY_USAGE_GROUP:
|
||||||
|
var group_label := Label.new()
|
||||||
|
group_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
group_label.text = prop.name
|
||||||
|
control = group_label
|
||||||
|
|
||||||
|
return control
|
||||||
|
|
||||||
|
static func _parse_range(prop) -> Dictionary:
|
||||||
|
if prop["hint"] != PROPERTY_HINT_RANGE:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
var prop_range := {}
|
||||||
|
var parts := prop["hint_string"].split(",") as PackedStringArray
|
||||||
|
var is_float : bool = prop["type"] == TYPE_FLOAT
|
||||||
|
|
||||||
|
if parts.size() > 0:
|
||||||
|
if is_float:
|
||||||
|
prop_range["min"] = parts[0].to_float()
|
||||||
|
else:
|
||||||
|
prop_range["min"] = parts[0].to_int()
|
||||||
|
|
||||||
|
if parts.size() > 1:
|
||||||
|
if is_float:
|
||||||
|
prop_range["max"] = parts[1].to_float()
|
||||||
|
else:
|
||||||
|
prop_range["max"] = parts[1].to_int()
|
||||||
|
|
||||||
|
if parts.size() > 2:
|
||||||
|
if is_float:
|
||||||
|
prop_range["step"] = parts[2].to_float()
|
||||||
|
else:
|
||||||
|
prop_range["step"] = parts[2].to_int()
|
||||||
|
|
||||||
|
if parts.size() > 3:
|
||||||
|
match parts[3]:
|
||||||
|
"or_lesser":
|
||||||
|
prop_range["or_lesser"] = true
|
||||||
|
"or_greater":
|
||||||
|
prop_range["or_greater"] = true
|
||||||
|
|
||||||
|
if parts.size() > 4:
|
||||||
|
match parts[4]:
|
||||||
|
"or_lesser":
|
||||||
|
prop_range["or_lesser"] = true
|
||||||
|
"or_greater":
|
||||||
|
prop_range["or_greater"] = true
|
||||||
|
_:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return prop_range
|
||||||
|
|
||||||
|
|
||||||
|
static func _property_name_to_display_name(name: String):
|
||||||
|
var name_snake := name.to_snake_case()
|
||||||
|
var parts := name_snake.split("_")
|
||||||
|
var display_name := ""
|
||||||
|
|
||||||
|
for c1 : int in parts.size():
|
||||||
|
var part := parts[c1]
|
||||||
|
display_name += part.to_pascal_case()
|
||||||
|
if c1 < parts.size() - 1:
|
||||||
|
display_name += " "
|
||||||
|
|
||||||
|
return display_name
|
||||||
|
|
||||||
|
|
40
addons/event_audio/src/ea_event.gd
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
@tool
|
||||||
|
extends Resource
|
||||||
|
class_name EAEvent
|
||||||
|
|
||||||
|
@export var audio_streams : Array[AudioStream] = []
|
||||||
|
@export var probability_weights : Array[float] = []
|
||||||
|
@export var trigger_tags: String = ""
|
||||||
|
@export var playback_settings: EAEventPlaybackSettings
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
if audio_streams.size() == 0:
|
||||||
|
audio_streams.push_front(null)
|
||||||
|
probability_weights.push_front(1.0)
|
||||||
|
playback_settings = EAEventPlaybackSettings.new()
|
||||||
|
|
||||||
|
func add_stream(index: int):
|
||||||
|
audio_streams.insert(index+1, null)
|
||||||
|
probability_weights.insert(index+1, 1.0)
|
||||||
|
|
||||||
|
func remove_stream(index: int):
|
||||||
|
audio_streams.remove_at(index)
|
||||||
|
probability_weights.remove_at(index)
|
||||||
|
|
||||||
|
func get_weighted_random_stream(random: float) -> AudioStream:
|
||||||
|
var total_weight := 0.0
|
||||||
|
for w : float in probability_weights:
|
||||||
|
total_weight = total_weight + w
|
||||||
|
|
||||||
|
var r := random * total_weight
|
||||||
|
var num_entries := probability_weights.size()
|
||||||
|
var weight_count := 0.0
|
||||||
|
for i in num_entries:
|
||||||
|
if i + 1 == num_entries:
|
||||||
|
return audio_streams[i]
|
||||||
|
elif r <= weight_count + probability_weights[i]:
|
||||||
|
return audio_streams[i]
|
||||||
|
weight_count += probability_weights[i]
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
27
addons/event_audio/src/ea_event_bank.gd
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
@tool
|
||||||
|
extends Resource
|
||||||
|
class_name EAEventBank
|
||||||
|
|
||||||
|
@export var entries: Array[EAEvent]
|
||||||
|
|
||||||
|
func add_entry():
|
||||||
|
entries.insert(0, EAEvent.new())
|
||||||
|
|
||||||
|
func delete_entry(entry: EAEvent):
|
||||||
|
var entry_idx := entries.find(entry)
|
||||||
|
if entry_idx >= 0:
|
||||||
|
entries.remove_at(entry_idx)
|
||||||
|
|
||||||
|
func find_entry_with_trigger(trigger: String) -> EAEvent:
|
||||||
|
for entry: EAEvent in entries:
|
||||||
|
if entry.trigger_tags == trigger:
|
||||||
|
return entry
|
||||||
|
|
||||||
|
return null
|
||||||
|
|
||||||
|
func _sort_func(a: EAEvent, b: EAEvent) -> bool:
|
||||||
|
return a.trigger_tags < b.trigger_tags
|
||||||
|
|
||||||
|
func sort_by_trigger():
|
||||||
|
entries.sort_custom(_sort_func)
|
||||||
|
|
11
addons/event_audio/src/ea_event_bank_inspector.gd
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
@tool
|
||||||
|
extends EditorInspectorPlugin
|
||||||
|
|
||||||
|
func _can_handle(object):
|
||||||
|
return object is EAEventBank
|
||||||
|
|
||||||
|
func _parse_property(_object, _type, name, _hint_type, _hint_string, _usage_flags, _wide):
|
||||||
|
if name == "entries":
|
||||||
|
add_property_editor(name, EAEventBankProperty.new())
|
||||||
|
return true
|
||||||
|
return false
|
13
addons/event_audio/src/ea_event_bank_mounter.gd
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
extends Node
|
||||||
|
class_name EAEventBankMounter
|
||||||
|
@export var _audio_bank_resource : EAEventBank
|
||||||
|
# @export var audioBankResources: Array[EAEventBank]
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
var player := EventAudio.instance
|
||||||
|
player.register_event_bank(_audio_bank_resource)
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
var player := EventAudio.instance
|
||||||
|
player.unregister_event_bank(_audio_bank_resource)
|
||||||
|
|
109
addons/event_audio/src/ea_event_bank_property.gd
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
@tool
|
||||||
|
extends EditorProperty
|
||||||
|
|
||||||
|
class_name EAEventBankProperty
|
||||||
|
|
||||||
|
var _audio_bank_line_scene := preload("res://addons/event_audio/scenes/bank_line.tscn")
|
||||||
|
var _audio_bank_resource_line_scene := preload("res://addons/event_audio/scenes/bank_resource_line.tscn")
|
||||||
|
|
||||||
|
var _resource: EAEventBank
|
||||||
|
var _property_name: StringName
|
||||||
|
var _entries: Array[EAEvent]
|
||||||
|
var _root_container := VBoxContainer.new()
|
||||||
|
var _focus_on_trigger : String = ""
|
||||||
|
|
||||||
|
#----------------------------------------------
|
||||||
|
# Godot call to update rendering
|
||||||
|
func _update_property():
|
||||||
|
# print("updating property")
|
||||||
|
var open_settings := {}
|
||||||
|
|
||||||
|
for control : Node in _root_container.get_children():
|
||||||
|
if control is EAEventEditControl and control.is_settings_open():
|
||||||
|
open_settings[control.get_event()] = true
|
||||||
|
|
||||||
|
_root_container.remove_child(control)
|
||||||
|
control.queue_free()
|
||||||
|
|
||||||
|
_make_lines(open_settings)
|
||||||
|
|
||||||
|
# Search for the trigger we were looking at previously.
|
||||||
|
if _focus_on_trigger == "":
|
||||||
|
return
|
||||||
|
|
||||||
|
await get_tree().process_frame
|
||||||
|
|
||||||
|
# Find the trigger we were editing previously and select it.
|
||||||
|
for control : Control in _root_container.get_children():
|
||||||
|
if control is not EAEventEditControl:
|
||||||
|
continue
|
||||||
|
var line = control as EAEventEditControl
|
||||||
|
if line.trigger_name_edit.text == _focus_on_trigger:
|
||||||
|
EditorInterface.get_inspector().ensure_control_visible(line.trigger_name_edit)
|
||||||
|
break
|
||||||
|
|
||||||
|
_focus_on_trigger = ""
|
||||||
|
|
||||||
|
func _enter_tree():
|
||||||
|
_property_name = get_edited_property()
|
||||||
|
_resource = get_edited_object() as EAEventBank
|
||||||
|
_entries = _resource.entries
|
||||||
|
|
||||||
|
_root_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
|
||||||
|
_make_lines()
|
||||||
|
add_child(_root_container)
|
||||||
|
set_bottom_editor(_root_container)
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
EAEditorTools.stop_sound()
|
||||||
|
|
||||||
|
func sort_bank():
|
||||||
|
_resource.sort_by_trigger()
|
||||||
|
|
||||||
|
func signal_entry_changed(update_ui: bool):
|
||||||
|
emit_changed(_property_name, _entries, "", not update_ui)
|
||||||
|
|
||||||
|
func set_focus_on_trigger(trigger: String):
|
||||||
|
_focus_on_trigger = trigger
|
||||||
|
|
||||||
|
func delete_event(event: EAEvent):
|
||||||
|
_resource.delete_entry(event)
|
||||||
|
signal_entry_changed(true)
|
||||||
|
|
||||||
|
#--------------------------------------
|
||||||
|
func _make_lines(setting_to_restore = {}):
|
||||||
|
var add_button := Button.new()
|
||||||
|
add_button.text = "Add Entry"
|
||||||
|
add_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
add_button.pressed.connect(_on_add_entry_button_clicked)
|
||||||
|
_root_container.add_child(add_button)
|
||||||
|
|
||||||
|
var stop_button := Button.new()
|
||||||
|
stop_button.text = "Stop playback"
|
||||||
|
stop_button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
stop_button.pressed.connect(_on_stop_button_clicked)
|
||||||
|
_root_container.add_child(stop_button)
|
||||||
|
|
||||||
|
for entry : EAEvent in _resource.entries:
|
||||||
|
var settings_open := setting_to_restore.has(entry)
|
||||||
|
_makeEntryLine(entry, settings_open)
|
||||||
|
|
||||||
|
func _makeEntryLine(entry: EAEvent, settings_open: bool):
|
||||||
|
var line := _audio_bank_line_scene.instantiate() as EAEventEditControl
|
||||||
|
_root_container.add_child(line)
|
||||||
|
line.create(self, entry, settings_open)
|
||||||
|
|
||||||
|
for c1: int in entry.audio_streams.size():
|
||||||
|
var resource_line := _audio_bank_resource_line_scene.instantiate() as EAStreamEditControl
|
||||||
|
line.stream_settings_list.add_child(resource_line)
|
||||||
|
resource_line.create(self, entry, c1, entry.audio_streams.size() == 1)
|
||||||
|
|
||||||
|
func _on_add_entry_button_clicked():
|
||||||
|
_resource.add_entry()
|
||||||
|
signal_entry_changed(true)
|
||||||
|
|
||||||
|
func _on_stop_button_clicked():
|
||||||
|
EAEditorTools.stop_sound()
|
||||||
|
|
||||||
|
|
91
addons/event_audio/src/ea_event_edit_control.gd
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
@tool
|
||||||
|
extends Container
|
||||||
|
class_name EAEventEditControl
|
||||||
|
|
||||||
|
@export var delete_trigger_button : BaseButton
|
||||||
|
@export var play_random_button : BaseButton
|
||||||
|
@export var trigger_name_edit : LineEdit
|
||||||
|
@export var settings_button : BaseButton
|
||||||
|
@export var stream_settings_list : Container
|
||||||
|
var _exclude_props = {"resource_local_to_scene": true, "Resource": true, "resource_name": true, "script": true}
|
||||||
|
var _settings_panel : Control
|
||||||
|
var _event : EAEvent
|
||||||
|
var _bank_inspector : EAEventBankProperty
|
||||||
|
|
||||||
|
func create(bank_inspector: EAEventBankProperty, event: EAEvent, open_settings: bool) -> void:
|
||||||
|
_event = event
|
||||||
|
_bank_inspector = bank_inspector
|
||||||
|
|
||||||
|
delete_trigger_button.pressed.connect(_on_delete_entry_button_clicked)
|
||||||
|
trigger_name_edit.set_text(_event.trigger_tags)
|
||||||
|
trigger_name_edit.text_submitted.connect(_on_trigger_submitted)
|
||||||
|
trigger_name_edit.text_changed.connect(_on_trigger_changed)
|
||||||
|
settings_button.pressed.connect(_on_settings_button_clicked)
|
||||||
|
play_random_button.pressed.connect(_on_play_random_button_clicked)
|
||||||
|
|
||||||
|
if open_settings:
|
||||||
|
var panel := _make_settings_panel()
|
||||||
|
self.add_sibling(panel)
|
||||||
|
_settings_panel = panel
|
||||||
|
|
||||||
|
func is_settings_open():
|
||||||
|
return _settings_panel != null
|
||||||
|
|
||||||
|
func get_event():
|
||||||
|
return _event
|
||||||
|
|
||||||
|
func _on_settings_button_clicked():
|
||||||
|
_toggle_settings_panel()
|
||||||
|
|
||||||
|
func _on_settings_entry_changed(val, settings: EAEventPlaybackSettings, member: StringName):
|
||||||
|
settings.set(member, val)
|
||||||
|
_bank_inspector.signal_entry_changed(false)
|
||||||
|
|
||||||
|
func _on_delete_entry_button_clicked():
|
||||||
|
_bank_inspector.delete_event(_event)
|
||||||
|
|
||||||
|
func _check_trigger_name(entry: EAEvent, trigger: String) -> bool:
|
||||||
|
var bank_entry := _bank_inspector._resource.find_entry_with_trigger(trigger)
|
||||||
|
|
||||||
|
if bank_entry and bank_entry != entry:
|
||||||
|
return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
func _on_trigger_changed(trigger: String):
|
||||||
|
# If the trigger isn't valid, show an error color
|
||||||
|
if _check_trigger_name(_event, trigger):
|
||||||
|
trigger_name_edit.modulate = Color.WHITE
|
||||||
|
else:
|
||||||
|
trigger_name_edit.modulate = Color.RED
|
||||||
|
|
||||||
|
func _on_trigger_submitted(trigger: String):
|
||||||
|
if _check_trigger_name(_event, trigger):
|
||||||
|
_event.trigger_tags = trigger
|
||||||
|
trigger_name_edit.release_focus()
|
||||||
|
|
||||||
|
# Re-sort the bank - this may trigger a UI update, so make sure we focus on the right control
|
||||||
|
_bank_inspector.set_focus_on_trigger(trigger)
|
||||||
|
_bank_inspector.sort_bank()
|
||||||
|
_bank_inspector.signal_entry_changed(true)
|
||||||
|
|
||||||
|
func _on_play_random_button_clicked():
|
||||||
|
var roll := EAEditorTools.get_global_rng().randf_range(0, 1.0)
|
||||||
|
var stream := _event.get_weighted_random_stream(roll)
|
||||||
|
if stream:
|
||||||
|
EAEditorTools.play_sound(_event, stream)
|
||||||
|
|
||||||
|
func _toggle_settings_panel():
|
||||||
|
if _settings_panel:
|
||||||
|
_settings_panel.get_parent().remove_child(_settings_panel)
|
||||||
|
_settings_panel.queue_free()
|
||||||
|
_settings_panel = null
|
||||||
|
else:
|
||||||
|
var panel := _make_settings_panel()
|
||||||
|
_settings_panel = panel
|
||||||
|
self.add_sibling(panel)
|
||||||
|
|
||||||
|
func _make_settings_panel() -> Container:
|
||||||
|
return EAEditorTools.make_property_panel(
|
||||||
|
_event.playback_settings, "Playback Settings", _exclude_props, _on_settings_entry_changed)
|
||||||
|
|
22
addons/event_audio/src/ea_event_playback_settings.gd
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
class_name EAEventPlaybackSettings
|
||||||
|
|
||||||
|
## The factor for the attenuation effect. Higher values make the sound audible over a larger distance.
|
||||||
|
@export_group("Behaviour")
|
||||||
|
@export var stop_when_source_dies := false
|
||||||
|
@export var stationary := false
|
||||||
|
|
||||||
|
@export_group("Shared Playback")
|
||||||
|
@export_range(-10.0, 10.0, 0.1) var volume_db := 0.0
|
||||||
|
@export_range(0.1, 2.0, 0.1) var min_pitch := 1.0
|
||||||
|
@export_range(0.1, 2.0, 0.1) var max_pitch := 1.0
|
||||||
|
@export_range(0.0, 3.0, 0.1) var panning_strength := 1.0
|
||||||
|
|
||||||
|
@export_group("2D Playback")
|
||||||
|
@export_range(0.0, 3.0, 0.1) var attenuation := 1.0
|
||||||
|
@export_range(0, 9999999) var max_distance := 2000
|
||||||
|
|
||||||
|
@export_group("3D Playback")
|
||||||
|
@export_range(0, 1000) var unit_size := 10.0
|
||||||
|
@export_range(-10.0, 10.0, 0.1) var max_db := 3.0
|
131
addons/event_audio/src/ea_stream_edit_control.gd
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
@tool
|
||||||
|
extends Container
|
||||||
|
class_name EAStreamEditControl
|
||||||
|
|
||||||
|
@export var delete_event_button : Button
|
||||||
|
@export var add_stream_button : Button
|
||||||
|
@export var play_button : Button
|
||||||
|
@export var audio_label : Label
|
||||||
|
var weight_editor : EditorSpinSlider
|
||||||
|
var audio_selector : EditorResourcePicker
|
||||||
|
|
||||||
|
var _stream_id : int
|
||||||
|
var _event : EAEvent
|
||||||
|
var _bank_inspector : EAEventBankProperty
|
||||||
|
|
||||||
|
func create(bank_inspector: EAEventBankProperty, event: EAEvent, stream_id: int, primary: bool) -> void:
|
||||||
|
# When this is the primary resource, we don't want to delete it.
|
||||||
|
# add_stream_button.visible = true
|
||||||
|
_stream_id = stream_id
|
||||||
|
_event = event
|
||||||
|
_bank_inspector = bank_inspector
|
||||||
|
|
||||||
|
if primary:
|
||||||
|
delete_event_button.disabled = true
|
||||||
|
else:
|
||||||
|
delete_event_button.disabled = false
|
||||||
|
|
||||||
|
play_button.pressed.connect(_on_play_button_clicked)
|
||||||
|
|
||||||
|
audio_selector.resource_changed.connect(_on_stream_changed)
|
||||||
|
audio_selector.edited_resource = _event.audio_streams[_stream_id]
|
||||||
|
|
||||||
|
add_stream_button.pressed.connect(_on_add_resource_button_clicked)
|
||||||
|
delete_event_button.pressed.connect(_on_delete_resource_button_clicked)
|
||||||
|
|
||||||
|
weight_editor.value_changed.connect(_on_stream_weight_changed)
|
||||||
|
weight_editor.value = _event.probability_weights[_stream_id]
|
||||||
|
_make_audio_picker_pretty()
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
get_node("WeightSliderContainer").add_child(weight_editor)
|
||||||
|
get_node("ResourcePicker/ResourcePickerContainer").add_child(audio_selector)
|
||||||
|
# if _event:
|
||||||
|
# audio_selector.edited_resource = _event.audio_streams[_stream_id]
|
||||||
|
|
||||||
|
_make_audio_picker_pretty()
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
weight_editor = EditorSpinSlider.new()
|
||||||
|
weight_editor.label = "weight"
|
||||||
|
weight_editor.step = 0.05
|
||||||
|
weight_editor.hide_slider = false
|
||||||
|
weight_editor.allow_lesser = false
|
||||||
|
weight_editor.allow_greater = false
|
||||||
|
weight_editor.min_value = 0
|
||||||
|
weight_editor.max_value = 1.0
|
||||||
|
weight_editor.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
|
||||||
|
audio_selector = EditorResourcePicker.new()
|
||||||
|
audio_selector.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||||
|
audio_selector.base_type = "AudioStream"
|
||||||
|
# audio_selector.edited_resource = _event.audio_streams[_stream_id]
|
||||||
|
|
||||||
|
audio_selector.resource_changed.connect(_on_resource_changed)
|
||||||
|
audio_selector.resource_selected.connect(_on_resource_clicked)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_resource_clicked(res: Resource, _inspect: bool):
|
||||||
|
# When the resource picker is clicked, visit the resource.
|
||||||
|
# Do it the next frame, however, in case the controls are being updated.
|
||||||
|
if res != null:
|
||||||
|
await get_tree().process_frame
|
||||||
|
EditorInterface.edit_resource(res)
|
||||||
|
|
||||||
|
func _on_resource_changed(_res: Resource):
|
||||||
|
# When the resource is changed, update the prettification of the resource picker.
|
||||||
|
_make_audio_picker_pretty()
|
||||||
|
|
||||||
|
# The default resource picker has several drawbacks when used in a custom inspector.
|
||||||
|
# - It draws double-height, to show an audio preview; even when there is no preview.
|
||||||
|
# - When audio is assigned it stops showing the path name.
|
||||||
|
# This function 'fixes' that, somewhat hackily.
|
||||||
|
func _make_audio_picker_pretty():
|
||||||
|
# In certain circumstances, show a custom label with the resources file path.
|
||||||
|
# Otherwise, hide it and rely on the default control.
|
||||||
|
var res := audio_selector.edited_resource
|
||||||
|
|
||||||
|
if res == null:
|
||||||
|
# If no resource, show the default button text
|
||||||
|
audio_label.visible = false
|
||||||
|
else:
|
||||||
|
# Otherwise, try to show the file name
|
||||||
|
if FileAccess.file_exists(res.resource_path):
|
||||||
|
audio_label.text = res.resource_path.get_file()
|
||||||
|
audio_label.visible = true
|
||||||
|
else:
|
||||||
|
audio_label.text = res.get_class()
|
||||||
|
# TODO - can't tell when the button is rendering at the moment, so this shows on top, sometimes.
|
||||||
|
# Until we can, make the label invisible
|
||||||
|
audio_label.visible = false
|
||||||
|
|
||||||
|
# This is the only way we found to get the ResourcePicker smaller.
|
||||||
|
# It's not ideal, as it depends on the internals of the resource picker.
|
||||||
|
# Search for the texture rect that shows the preview and detach it.
|
||||||
|
var children := audio_selector.get_children()
|
||||||
|
while not children.is_empty():
|
||||||
|
var child := children.pop_back() as Node
|
||||||
|
children.append_array(child.get_children())
|
||||||
|
if child is TextureRect:
|
||||||
|
child.get_parent().remove_child(child)
|
||||||
|
|
||||||
|
func _on_play_button_clicked():
|
||||||
|
var stream := _event.audio_streams[_stream_id]
|
||||||
|
if stream:
|
||||||
|
EAEditorTools.play_sound(_event, stream)
|
||||||
|
|
||||||
|
func _on_stream_weight_changed(val):
|
||||||
|
_event.probability_weights[_stream_id] = val
|
||||||
|
_bank_inspector.signal_entry_changed(false)
|
||||||
|
|
||||||
|
func _on_add_resource_button_clicked():
|
||||||
|
_event.add_stream(_stream_id)
|
||||||
|
_bank_inspector.signal_entry_changed(true)
|
||||||
|
|
||||||
|
func _on_delete_resource_button_clicked():
|
||||||
|
_event.remove_stream(_stream_id)
|
||||||
|
_bank_inspector.signal_entry_changed(true)
|
||||||
|
|
||||||
|
func _on_stream_changed(res: Resource):
|
||||||
|
_event.audio_streams[_stream_id] = res as AudioStream
|
||||||
|
_bank_inspector.signal_entry_changed(false)
|
10
main.gd
|
@ -7,6 +7,7 @@ extends Control
|
||||||
@onready var trueview: int = 0
|
@onready var trueview: int = 0
|
||||||
|
|
||||||
# variables for nodes
|
# variables for nodes
|
||||||
|
@onready var sound: Node2D = $Sounds
|
||||||
@onready var roll_dice: TextureButton = $Roll/Roll_dice
|
@onready var roll_dice: TextureButton = $Roll/Roll_dice
|
||||||
@onready var psyline_other: Control = $Psy_line_other
|
@onready var psyline_other: Control = $Psy_line_other
|
||||||
@onready var psyline_self: Control = $Psy_line_self
|
@onready var psyline_self: Control = $Psy_line_self
|
||||||
|
@ -15,10 +16,11 @@ extends Control
|
||||||
@onready var keep_psy: CheckBox = $Roll/Keep_psy
|
@onready var keep_psy: CheckBox = $Roll/Keep_psy
|
||||||
@onready var keep_traits: CheckBox = $Roll/Keep_traits
|
@onready var keep_traits: CheckBox = $Roll/Keep_traits
|
||||||
@onready var language_choice: MenuButton = $Language
|
@onready var language_choice: MenuButton = $Language
|
||||||
|
@onready var soundplayer: EAEventBankMounter = $SoundPlayer
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
lets_roll(seed)
|
lets_roll(seed, 0)
|
||||||
roll_dice.pressed.connect(_on_roll_dice_pressed)
|
roll_dice.pressed.connect(_on_roll_dice_pressed)
|
||||||
|
|
||||||
language_choice.get_popup().connect("id_pressed", _on_menu_language_selected)
|
language_choice.get_popup().connect("id_pressed", _on_menu_language_selected)
|
||||||
|
@ -35,13 +37,17 @@ func _process(delta: float) -> void:
|
||||||
func _on_roll_dice_pressed() -> void:
|
func _on_roll_dice_pressed() -> void:
|
||||||
lets_roll(seed)
|
lets_roll(seed)
|
||||||
|
|
||||||
func lets_roll(chosen_seed: int) -> void:
|
func lets_roll(chosen_seed: int, noise: bool = 1) -> void:
|
||||||
# Random psy profiles
|
# Random psy profiles
|
||||||
var possible_psy: int = $Psy_line_other.resources.size()
|
var possible_psy: int = $Psy_line_other.resources.size()
|
||||||
|
|
||||||
var random = RandomNumberGenerator.new()
|
var random = RandomNumberGenerator.new()
|
||||||
random.seed = chosen_seed
|
random.seed = chosen_seed
|
||||||
|
|
||||||
|
# Play sound if wanted
|
||||||
|
if noise:
|
||||||
|
EventAudio.play_2d("DICEROLL", sound)
|
||||||
|
|
||||||
# Randomize psychology
|
# Randomize psychology
|
||||||
if not keep_psy.button_pressed:
|
if not keep_psy.button_pressed:
|
||||||
random.randomize()
|
random.randomize()
|
||||||
|
|
10
main.tscn
|
@ -1,10 +1,12 @@
|
||||||
[gd_scene load_steps=6 format=3 uid="uid://d14wihi8i46og"]
|
[gd_scene load_steps=8 format=3 uid="uid://d14wihi8i46og"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bff864odl7vlj" path="res://psyline.tscn" id="1_03r8p"]
|
[ext_resource type="PackedScene" uid="uid://bff864odl7vlj" path="res://psyline.tscn" id="1_03r8p"]
|
||||||
[ext_resource type="Script" path="res://main.gd" id="1_gqole"]
|
[ext_resource type="Script" path="res://main.gd" id="1_gqole"]
|
||||||
[ext_resource type="Theme" uid="uid://qsom67gcgupx" path="res://themes/base.tres" id="2_vc4v2"]
|
[ext_resource type="Theme" uid="uid://qsom67gcgupx" path="res://themes/base.tres" id="2_vc4v2"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cl5wswke7jxpi" path="res://traits.tscn" id="3_t3gol"]
|
[ext_resource type="PackedScene" uid="uid://cl5wswke7jxpi" path="res://traits.tscn" id="3_t3gol"]
|
||||||
[ext_resource type="Texture2D" uid="uid://b7fg7g42642p" path="res://textures/dices.png" id="5_rsth0"]
|
[ext_resource type="Texture2D" uid="uid://b7fg7g42642p" path="res://textures/dices.png" id="5_rsth0"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_bank_mounter.gd" id="6_im5e0"]
|
||||||
|
[ext_resource type="Resource" uid="uid://c51i5hutfhrsx" path="res://sounds/eventbanks/UI_sounds.tres" id="7_6knbw"]
|
||||||
|
|
||||||
[node name="Main" type="Control"]
|
[node name="Main" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
@ -239,3 +241,9 @@ item_count = 2
|
||||||
popup/item_0/text = "FRENCH"
|
popup/item_0/text = "FRENCH"
|
||||||
popup/item_1/text = "ENGLISH"
|
popup/item_1/text = "ENGLISH"
|
||||||
popup/item_1/id = 1
|
popup/item_1/id = 1
|
||||||
|
|
||||||
|
[node name="SoundPlayer" type="Node" parent="."]
|
||||||
|
script = ExtResource("6_im5e0")
|
||||||
|
_audio_bank_resource = ExtResource("7_6knbw")
|
||||||
|
|
||||||
|
[node name="Sounds" type="Node2D" parent="."]
|
||||||
|
|
|
@ -15,6 +15,14 @@ run/main_scene="res://main.tscn"
|
||||||
config/features=PackedStringArray("4.3", "Forward Plus")
|
config/features=PackedStringArray("4.3", "Forward Plus")
|
||||||
config/icon="res://textures/icon.png"
|
config/icon="res://textures/icon.png"
|
||||||
|
|
||||||
|
[autoload]
|
||||||
|
|
||||||
|
EventAudio="*res://addons/event_audio/scenes/event_audio_autoload.tscn"
|
||||||
|
|
||||||
|
[editor_plugins]
|
||||||
|
|
||||||
|
enabled=PackedStringArray("res://addons/event_audio/plugin.cfg")
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
ui_accept={
|
ui_accept={
|
||||||
|
|
19
sounds/assets/dieShuffle1.ogg.import
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="oggvorbisstr"
|
||||||
|
type="AudioStreamOggVorbis"
|
||||||
|
uid="uid://bbsb62p7ci00d"
|
||||||
|
path="res://.godot/imported/dieShuffle1.ogg-dcb2d2e1f13163ad0879571ecc9e036c.oggvorbisstr"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://sounds/assets/dieShuffle1.ogg"
|
||||||
|
dest_files=["res://.godot/imported/dieShuffle1.ogg-dcb2d2e1f13163ad0879571ecc9e036c.oggvorbisstr"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
loop=false
|
||||||
|
loop_offset=0
|
||||||
|
bpm=0
|
||||||
|
beat_count=0
|
||||||
|
bar_beats=4
|
|
@ -1,19 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="oggvorbisstr"
|
|
||||||
type="AudioStreamOggVorbis"
|
|
||||||
uid="uid://bbsb62p7ci00d"
|
|
||||||
path="res://.godot/imported/dieShuffle1.ogg-839321e52515a7254293b5f786bc71b8.oggvorbisstr"
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://sounds/dieShuffle1.ogg"
|
|
||||||
dest_files=["res://.godot/imported/dieShuffle1.ogg-839321e52515a7254293b5f786bc71b8.oggvorbisstr"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
loop=false
|
|
||||||
loop_offset=0
|
|
||||||
bpm=0
|
|
||||||
beat_count=0
|
|
||||||
bar_beats=4
|
|
30
sounds/eventbanks/UI_sounds.tres
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
[gd_resource type="Resource" script_class="EAEventBank" load_steps=7 format=3 uid="uid://c51i5hutfhrsx"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event.gd" id="1_kbnqw"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_bank.gd" id="2_jlkrc"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bbsb62p7ci00d" path="res://sounds/assets/dieShuffle1.ogg" id="2_uyd46"]
|
||||||
|
[ext_resource type="Script" path="res://addons/event_audio/src/ea_event_playback_settings.gd" id="3_dcij5"]
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_odclp"]
|
||||||
|
script = ExtResource("3_dcij5")
|
||||||
|
stop_when_source_dies = false
|
||||||
|
stationary = false
|
||||||
|
volume_db = 0.0
|
||||||
|
min_pitch = 1.0
|
||||||
|
max_pitch = 1.0
|
||||||
|
panning_strength = 1.0
|
||||||
|
attenuation = 1.0
|
||||||
|
max_distance = 2000
|
||||||
|
unit_size = 10.0
|
||||||
|
max_db = 3.0
|
||||||
|
|
||||||
|
[sub_resource type="Resource" id="Resource_5ogac"]
|
||||||
|
script = ExtResource("1_kbnqw")
|
||||||
|
audio_streams = Array[AudioStream]([ExtResource("2_uyd46")])
|
||||||
|
probability_weights = Array[float]([1.0])
|
||||||
|
trigger_tags = "DICEROLL"
|
||||||
|
playback_settings = SubResource("Resource_odclp")
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("2_jlkrc")
|
||||||
|
entries = Array[ExtResource("1_kbnqw")]([SubResource("Resource_5ogac")])
|