IdleGirl/Assets/Plugins/Editor/RelationsInspector/Backends/MasterAudioEventBackend.cs

1058 lines
49 KiB
C#
Raw Normal View History

using System.Text;
using UnityEngine;
using RelationsInspector.Backend;
using RelationsInspector;
using System.Collections.Generic;
using DarkTonic.MasterAudio;
using System;
using System.Linq;
using UnityEditor;
using UnityEditor.Animations;
// ReSharper disable once CheckNamespace
public class MasterAudioEventBackend : MinimalBackend<object, string> {
public const string AllBusesOrGroupsWord = "All";
public class AudioEventGroupNode {
public EventSounds.EventType type;
public string name;
public bool useGroup;
public AudioEventGroup group;
}
public class AmbientSoundNode {
public string _groupName;
public AmbientSoundNode(string groupName) {
_groupName = groupName;
}
}
public class FootstepSoundsNode
{
public string _groupName;
public FootstepSoundsNode(string groupName)
{
_groupName = groupName;
}
}
public class LinkedGroupNode {
public List<string> parentLinkedGroups { get; set; }
public string groupName;
public bool hasLinkedGroupLoop;
public string linkedGroupLoopName;
public LinkedGroupNode(string groupName, List<string> parentLinkedGroups)
{
this.groupName = groupName;
this.parentLinkedGroups = new List<string>(parentLinkedGroups);
}
}
public class EndLinkedGroupNode {
public List<string> parentLinkedGroups { get; set; }
public string groupName;
public bool hasLinkedGroupLoop;
public string linkedGroupLoopName;
public EndLinkedGroupNode(string groupName, List<string> parentLinkedGroups) {
this.groupName = groupName;
this.parentLinkedGroups = new List<string>(parentLinkedGroups);
}
}
public class EventGroupData {
public EventSounds.EventType type;
public Func<EventSounds, AudioEventGroup> getGroup;
public Func<EventSounds, bool> useGroup;
public string name;
}
public class MechanimEventSound {
public string group;
public string type;
public MechanimEventSound(string group, string type) { this.group = group; this.type = type; }
}
public class MechanimEventCustomEvent {
public string customEvent;
public string type;
public MechanimEventCustomEvent(string customEvent, string type) { this.customEvent = customEvent; this.type = type; }
}
public static List<EventGroupData> namedEventGroups = new List<EventGroupData>()
{
new EventGroupData() {type = EventSounds.EventType.OnStart, getGroup = es=> es.startSound, useGroup = es => es.useStartSound, name = "Start" },
new EventGroupData() {type = EventSounds.EventType.OnVisible, getGroup = es=> es.visibleSound, useGroup = es => es.useVisibleSound, name = "Visible" },
new EventGroupData() {type = EventSounds.EventType.OnInvisible, getGroup = es=> es.invisibleSound, useGroup = es => es.useInvisibleSound, name = "Invisible" },
new EventGroupData() {type = EventSounds.EventType.OnCollision, getGroup = es=> es.collisionSound, useGroup = es => es.useCollisionSound, name = "Collision Enter" },
new EventGroupData() {type = EventSounds.EventType.OnCollisionExit, getGroup = es=> es.collisionExitSound, useGroup = es => es.useCollisionExitSound, name = "Collision Exit" },
new EventGroupData() {type = EventSounds.EventType.OnTriggerEnter, getGroup = es=> es.triggerSound, useGroup = es => es.useTriggerEnterSound, name = "Trigger Enter" },
new EventGroupData() {type = EventSounds.EventType.OnTriggerExit, getGroup = es=> es.triggerExitSound, useGroup = es => es.useTriggerExitSound, name = "Trigger Exit" },
new EventGroupData() {type = EventSounds.EventType.OnMouseEnter, getGroup = es=> es.mouseEnterSound, useGroup = es => es.useMouseEnterSound, name = "Mouse Enter (Legacy)" },
new EventGroupData() {type = EventSounds.EventType.OnMouseExit, getGroup = es=> es.mouseExitSound, useGroup = es => es.useMouseExitSound, name = "Mouse Exit (Legacy)" },
new EventGroupData() {type = EventSounds.EventType.OnMouseClick, getGroup = es=> es.mouseClickSound, useGroup = es => es.useMouseClickSound, name = "Mouse Down (Legacy)" },
new EventGroupData() {type = EventSounds.EventType.OnMouseUp, getGroup = es=> es.mouseUpSound, useGroup = es => es.useMouseUpSound, name = "Mouse Up (Legacy)" },
new EventGroupData() {type = EventSounds.EventType.OnMouseDrag, getGroup = es=> es.mouseDragSound, useGroup = es => es.useMouseDragSound, name = "Mouse Drag (Legacy)" },
new EventGroupData() {type = EventSounds.EventType.OnSpawned, getGroup = es=> es.spawnedSound, useGroup = es => es.useSpawnedSound, name = "Spawned (Pooling)" },
new EventGroupData() {type = EventSounds.EventType.OnDespawned, getGroup = es=> es.despawnedSound, useGroup = es => es.useDespawnedSound, name = "Despawned (Pooling)" },
new EventGroupData() {type = EventSounds.EventType.OnEnable, getGroup = es=> es.enableSound, useGroup = es => es.useEnableSound, name = "Enable" },
new EventGroupData() {type = EventSounds.EventType.OnDisable, getGroup = es=> es.disableSound, useGroup = es => es.useDisableSound, name = "Disable" },
new EventGroupData() {type = EventSounds.EventType.OnCollision2D, getGroup = es=> es.collision2dSound, useGroup = es => es.useCollision2dSound, name = "2D Collision Enter" },
new EventGroupData() {type = EventSounds.EventType.OnCollisionExit2D, getGroup = es=> es.collisionExit2dSound, useGroup = es => es.useCollisionExit2dSound, name = "2D Collision Exit" },
new EventGroupData() {type = EventSounds.EventType.OnTriggerEnter2D, getGroup = es=> es.triggerEnter2dSound, useGroup = es => es.useTriggerEnter2dSound, name = "2D Trigger Enter" },
new EventGroupData() {type = EventSounds.EventType.OnTriggerExit2D, getGroup = es=> es.triggerExit2dSound, useGroup = es => es.useTriggerExit2dSound, name = "2D Trigger Exit" },
new EventGroupData() {type = EventSounds.EventType.OnParticleCollision, getGroup = es=> es.particleCollisionSound, useGroup = es => es.useParticleCollisionSound, name = "Particle Collision" },
new EventGroupData() {type = EventSounds.EventType.NGUIOnClick, getGroup = es=> es.nguiOnClickSound, useGroup = es => es.useNguiOnClickSound, name = "NGUI Mouse Click" },
new EventGroupData() {type = EventSounds.EventType.NGUIMouseDown, getGroup = es=> es.nguiMouseDownSound, useGroup = es => es.useNguiMouseDownSound, name = "NGUI Mouse Down" },
new EventGroupData() {type = EventSounds.EventType.NGUIMouseUp, getGroup = es=> es.nguiMouseUpSound, useGroup = es => es.useNguiMouseUpSound, name = "NGUI Mouse Up" },
new EventGroupData() {type = EventSounds.EventType.NGUIMouseEnter, getGroup = es=> es.nguiMouseEnterSound, useGroup = es => es.useNguiMouseEnterSound, name = "NGUI Mouse Enter" },
new EventGroupData() {type = EventSounds.EventType.NGUIMouseExit, getGroup = es=> es.nguiMouseExitSound, useGroup = es => es.useNguiMouseExitSound, name = "NGUI Mouse Exit" },
new EventGroupData() {type = EventSounds.EventType.UnitySliderChanged, getGroup = es=> es.unitySliderChangedSound, useGroup = es => es.useUnitySliderChangedSound, name = "Slider Changed (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityButtonClicked, getGroup = es=> es.unityButtonClickedSound, useGroup = es => es.useUnityButtonClickedSound, name = "Button Click (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityPointerDown, getGroup = es=> es.unityPointerDownSound, useGroup = es => es.useUnityPointerDownSound, name = "Pointer Down (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityDrag, getGroup = es=> es.unityDragSound, useGroup = es => es.useUnityDragSound, name = "Drag (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityPointerUp, getGroup = es=> es.unityPointerUpSound, useGroup = es => es.useUnityPointerUpSound, name = "Pointer Up (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityPointerEnter, getGroup = es=> es.unityPointerEnterSound, useGroup = es => es.useUnityPointerEnterSound, name = "Pointer Enter (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityPointerExit, getGroup = es=> es.unityPointerExitSound, useGroup = es => es.useUnityPointerExitSound, name = "Pointer Exit (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityDrop, getGroup = es=> es.unityDropSound, useGroup = es => es.useUnityDropSound, name = "Drop (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityScroll, getGroup = es=> es.unityScrollSound, useGroup = es => es.useUnityScrollSound, name = "Scroll (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityUpdateSelected, getGroup = es=> es.unityUpdateSelectedSound, useGroup = es => es.useUnityUpdateSelectedSound, name = "Update Slected (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnitySelect, getGroup = es=> es.unitySelectSound, useGroup = es => es.useUnitySelectSound, name = "Select (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityDeselect, getGroup = es=> es.unityDeselectSound, useGroup = es => es.useUnityDeselectSound, name = "Deselect (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityMove, getGroup = es=> es.unityMoveSound, useGroup = es => es.useUnityMoveSound, name = "Move (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityInitializePotentialDrag, getGroup = es=> es.unityInitializePotentialDragSound, useGroup = es => es.useUnityInitializePotentialDragSound, name = "Initialize Potential Drag (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityBeginDrag, getGroup = es=> es.unityBeginDragSound, useGroup = es => es.useUnityBeginDragSound, name = "Begin Drag (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityEndDrag, getGroup = es=> es.unityEndDragSound, useGroup = es => es.useUnityEndDragSound, name = "End Drag (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnitySubmit, getGroup = es=> es.unitySubmitSound, useGroup = es => es.useUnitySubmitSound, name = "Submit (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityCancel, getGroup = es=> es.unityCancelSound, useGroup = es => es.useUnityCancelSound, name = "Cancel (uGUI)" },
new EventGroupData() {type = EventSounds.EventType.UnityToggle, getGroup = es=> es.unityToggleSound, useGroup = es => es.useUnityToggleSound, name = "Toggle (uGUI)" }
};
const string busFilterPrefsKey = "MasterAudioEventBackend" + "busFilter";
static string busFilter;
public static string BusFilter {
get {
busFilter = EditorPrefs.GetString(busFilterPrefsKey, string.Empty);
return busFilter;
}
set {
busFilter = value;
EditorPrefs.SetString(busFilterPrefsKey, busFilter);
}
}
const string groupFilterPrefsKey = "MasterAudioEventBackend" + "groupFilter";
static string groupFilter;
public static string GroupFilter {
get {
groupFilter = EditorPrefs.GetString(groupFilterPrefsKey, string.Empty);
return groupFilter;
}
set {
groupFilter = value;
EditorPrefs.SetString(groupFilterPrefsKey, groupFilter);
}
}
public override void Awake(GetAPI getAPI) {
base.Awake(getAPI);
var targets = api.GetTargets();
if (targets.Length == 1 && (targets[0] as string == "currentScene"))
ResetGraph();
busFilter = EditorPrefs.GetString(busFilterPrefsKey, string.Empty);
groupFilter = EditorPrefs.GetString(groupFilterPrefsKey, string.Empty);
}
public override IEnumerable<Relation<object, string>> GetRelations(object entity) {
var asAmbientSound = entity as DarkTonic.MasterAudio.AmbientSound;
if (asAmbientSound != null) {
yield return new Relation<object, string>(asAmbientSound, new AmbientSoundNode(asAmbientSound.AmbientSoundGroup), "Ambient Sound");
}
var asFootstepSound = entity as DarkTonic.MasterAudio.FootstepSounds;
if (asFootstepSound != null)
{
foreach (var stepGroup in asFootstepSound.footstepGroups)
{
yield return new Relation<object, string>(asFootstepSound, new FootstepSoundsNode(stepGroup.soundType), "Footstep Sound");
}
}
var asEndLinkedGroupNode = entity as EndLinkedGroupNode;
if (asEndLinkedGroupNode != null) {
foreach (var linkedGroupName in GetStartLinkedGroups(asEndLinkedGroupNode.groupName)) {
if (asEndLinkedGroupNode.parentLinkedGroups.Contains(linkedGroupName)) {
asEndLinkedGroupNode.hasLinkedGroupLoop = true;
asEndLinkedGroupNode.linkedGroupLoopName = linkedGroupName;
continue;
}
yield return
new Relation<object, string>(asEndLinkedGroupNode, new LinkedGroupNode(linkedGroupName, asEndLinkedGroupNode.parentLinkedGroups),
GetGroupLinkLabel(asEndLinkedGroupNode.groupName, false));
}
foreach (var endLinkedGroupName in GetStopLinkedGroups(asEndLinkedGroupNode.groupName)) {
if (asEndLinkedGroupNode.parentLinkedGroups.Contains(endLinkedGroupName)) {
asEndLinkedGroupNode.hasLinkedGroupLoop = true;
asEndLinkedGroupNode.linkedGroupLoopName = endLinkedGroupName;
continue;
}
yield return
new Relation<object, string>(asEndLinkedGroupNode, new EndLinkedGroupNode(endLinkedGroupName, asEndLinkedGroupNode.parentLinkedGroups),
GetGroupLinkLabel(asEndLinkedGroupNode.groupName, true));
}
yield break;
}
var asLinkedGroupNode = entity as LinkedGroupNode;
if (asLinkedGroupNode != null) {
foreach (var linkedGroupName in GetStartLinkedGroups(asLinkedGroupNode.groupName)) {
if (asLinkedGroupNode.parentLinkedGroups.Contains(linkedGroupName)) {
asLinkedGroupNode.hasLinkedGroupLoop = true;
asLinkedGroupNode.linkedGroupLoopName = linkedGroupName;
continue;
}
yield return
new Relation<object, string>(asLinkedGroupNode, new LinkedGroupNode(linkedGroupName, asLinkedGroupNode.parentLinkedGroups),
GetGroupLinkLabel(asLinkedGroupNode.groupName, false));
}
foreach (var startLinkedGroupName in GetStopLinkedGroups(asLinkedGroupNode.groupName)) {
if (asLinkedGroupNode.parentLinkedGroups.Contains(startLinkedGroupName)) {
asLinkedGroupNode.hasLinkedGroupLoop = true;
asLinkedGroupNode.linkedGroupLoopName = startLinkedGroupName;
continue;
}
yield return
new Relation<object, string>(asLinkedGroupNode, new EndLinkedGroupNode(startLinkedGroupName, asLinkedGroupNode.parentLinkedGroups),
GetGroupLinkLabel(asLinkedGroupNode.groupName, true));
}
yield break;
}
var asAmbientSoundNode = entity as AmbientSoundNode;
if (asAmbientSoundNode != null) {
foreach (var linkedGroupName in GetStartLinkedGroups(asAmbientSoundNode._groupName)) {
yield return
new Relation<object, string>(asAmbientSoundNode, new LinkedGroupNode(linkedGroupName, new List<string> { asAmbientSoundNode._groupName }),
GetGroupLinkLabel(asAmbientSoundNode._groupName, false));
}
foreach (var endLinkedGroupName in GetStopLinkedGroups(asAmbientSoundNode._groupName)) {
yield return
new Relation<object, string>(asAmbientSoundNode, new EndLinkedGroupNode(endLinkedGroupName, new List<string> { asAmbientSoundNode._groupName }),
GetGroupLinkLabel(asAmbientSoundNode._groupName, true));
}
yield break;
}
// connect EventSounds components to their AudioEventGroups that contain actions
var asEventSounds = entity as EventSounds;
if (asEventSounds != null) {
foreach (var groupNode in GetGroupNodes(asEventSounds))
yield return new Relation<object, string>(asEventSounds, groupNode, "handles event");
yield break;
}
// connect AudioEventGroups to their actions
var asGroupNode = entity as AudioEventGroupNode;
if (asGroupNode != null) {
foreach (var audioEvent in GetAudioEvents(asGroupNode.group))
yield return new Relation<object, string>(asGroupNode, audioEvent, "invokes action");
yield break;
}
// connect PlaySound actions to their linked groups
var asAction = entity as AudioEvent;
if (asAction != null) {
if (asAction.currentSoundFunctionType == MasterAudio.EventSoundFunctionType.PlaySound) {
foreach (var linkedGroupName in GetStartLinkedGroups(asAction.soundType)) {
yield return
new Relation<object, string>(asAction, new LinkedGroupNode(linkedGroupName, new List<string> { asAction.soundType }),
GetGroupLinkLabel(asAction.soundType, true));
}
foreach (var endLinkedGroupName in GetStopLinkedGroups(asAction.soundType)) {
yield return
new Relation<object, string>(asAction, new EndLinkedGroupNode(endLinkedGroupName, new List<string> { asAction.soundType }),
GetGroupLinkLabel(asAction.soundType, false));
}
}
yield break;
}
var asAnimator = entity as Animator;
if (asAnimator != null) {
var controller = asAnimator.runtimeAnimatorController as AnimatorController;
if (controller != null) {
foreach (var layer in controller.layers) {
if (GetSoundGroups(layer).Any())
yield return new Relation<object, string>(asAnimator, layer, "contains layer");
}
}
yield break;
}
var asLayer = entity as AnimatorControllerLayer;
if (asLayer != null) {
foreach (var state in asLayer.stateMachine.states) {
if (GetSoundGroups(state.state).Any())
yield return new Relation<object, string>(asLayer, state.state, "contains state");
}
yield break;
}
var asAnimState = entity as AnimatorState;
if (asAnimState != null) {
foreach (var behaviour in asAnimState.behaviours) {
var asStateSounds = behaviour as MechanimStateSounds;
if (asStateSounds != null) {
if (!string.IsNullOrEmpty(asStateSounds.enterSoundGroup) && !FilterSoundGroup(asStateSounds.enterSoundGroup)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventSound(asStateSounds.enterSoundGroup, "On Enter"),
"plays on state entry");
}
if (!string.IsNullOrEmpty(asStateSounds.exitSoundGroup) && !FilterSoundGroup(asStateSounds.exitSoundGroup)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventSound(asStateSounds.exitSoundGroup, "On Exit"),
"plays on state exit");
}
if (!string.IsNullOrEmpty(asStateSounds.TimedSoundGroup) && !FilterSoundGroup(asStateSounds.TimedSoundGroup)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventSound(asStateSounds.TimedSoundGroup, "Anim-Timed"),
"plays on animation timeline");
}
if (!string.IsNullOrEmpty(asStateSounds.MultiSoundsTimedGroup) && !FilterSoundGroup(asStateSounds.MultiSoundsTimedGroup)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventSound(asStateSounds.MultiSoundsTimedGroup, "Multi Anim-Timed"),
"plays on animation timeline 0-4 times");
}
}
var asStateEvents = behaviour as MechanimStateCustomEvents;
if (asStateEvents != null) {
if (!string.IsNullOrEmpty(asStateEvents.enterCustomEvent) && !FilterCustomEvent(asStateEvents.enterCustomEvent)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventCustomEvent(asStateEvents.enterCustomEvent, "On Enter"),
"plays on state entry");
}
if (!string.IsNullOrEmpty(asStateEvents.exitCustomEvent) && !FilterCustomEvent(asStateEvents.exitCustomEvent)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventCustomEvent(asStateEvents.exitCustomEvent, "On Exit"),
"plays on state exit");
}
if (!string.IsNullOrEmpty(asStateEvents.timedCustomEvent) && !FilterCustomEvent(asStateEvents.timedCustomEvent)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventCustomEvent(asStateEvents.timedCustomEvent, "Anim-Timed"),
"plays on animation timeline");
}
if (!string.IsNullOrEmpty(asStateEvents.MultiTimedEvent) && !FilterCustomEvent(asStateEvents.MultiTimedEvent)) {
yield return new Relation<object, string>(
asAnimState,
new MechanimEventCustomEvent(asStateEvents.MultiTimedEvent, "Multi Anim-Timed"),
"plays on animation timeline");
}
}
}
yield break;
}
var asMechanimEventSound = entity as MechanimEventSound;
if (asMechanimEventSound != null) {
foreach (var linkedGroupName in GetStartLinkedGroups(asMechanimEventSound.group)) {
yield return
new Relation<object, string>(asMechanimEventSound, new LinkedGroupNode(linkedGroupName, new List<string> { asMechanimEventSound.group }),
GetGroupLinkLabel(asMechanimEventSound.group, true));
}
foreach (var linkedGroupName in GetStopLinkedGroups(asMechanimEventSound.group)) {
yield return
new Relation<object, string>(asMechanimEventSound, new EndLinkedGroupNode(linkedGroupName, new List<string> { asMechanimEventSound.group }),
GetGroupLinkLabel(asMechanimEventSound.group, false));
}
yield break;
}
}
public override Rect OnGUI() {
GUILayout.BeginHorizontal(EditorStyles.toolbar);
{
// regenerate the graph
if (GUILayout.Button("Show active scene", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
ResetGraph();
// filter actions by group
GUILayout.Space(20);
string[] groupNames;
if (MasterAudio.SafeInstance != null) {
groupNames = new string[] { AllBusesOrGroupsWord }.Concat(MasterAudio.Instance.GroupNames.Skip(2)).ToArray();
} else {
groupNames = new string[] { AllBusesOrGroupsWord };
}
int groupFilterIndex = Mathf.Max(0, Array.IndexOf(groupNames, groupFilter)); // short for: if(id==-1) id = 0;
GUILayout.Label("Filter by group", EditorStyles.miniLabel);
int newGroupFilterIndex = EditorGUILayout.Popup(groupFilterIndex, groupNames, EditorStyles.toolbarPopup, GUILayout.Width(70));
string newGroupFilter = newGroupFilterIndex <= 0 ? string.Empty : groupNames[newGroupFilterIndex];
if (newGroupFilter != groupFilter) {
groupFilter = newGroupFilter;
EditorPrefs.SetString(groupFilterPrefsKey, groupFilter);
ResetGraph();
}
// filter actions by bus
GUILayout.Space(20);
string[] busNames;
if (MasterAudio.SafeInstance != null) {
busNames = new string[] { AllBusesOrGroupsWord }.Concat(MasterAudio.Instance.BusNames.Skip(2)).ToArray();
} else {
busNames = new string[] { AllBusesOrGroupsWord };
}
int busFilterIndex = Mathf.Max(0, Array.IndexOf(busNames, busFilter));
GUILayout.Label("Filter by bus", EditorStyles.miniLabel);
int newBusFilterIndex = EditorGUILayout.Popup(busFilterIndex, busNames, EditorStyles.toolbarPopup, GUILayout.Width(70));
string newBusFilter = newBusFilterIndex <= 0 ? string.Empty : busNames[newBusFilterIndex];
if (newBusFilter != busFilter) {
busFilter = newBusFilter;
EditorPrefs.SetString(busFilterPrefsKey, busFilter);
ResetGraph();
}
// fill up the toolbar
GUILayout.FlexibleSpace();
}
GUILayout.EndHorizontal();
return base.OnGUI();
}
void ResetGraph() {
var eventSoundsComponents = UnityEngine.Object
.FindObjectsOfType<EventSounds>()
.Where(comp => GetGroupNodes(comp).Any());
var newTargets = eventSoundsComponents
.Cast<object>();
var mechanimStateSoundsObjects = UnityEngine.Object
.FindObjectsOfType<Animator>()
.Where(animator => GetSoundGroups(animator).Any());
newTargets = newTargets.Concat(mechanimStateSoundsObjects.Cast<object>());
var mechanimStateCustomEventObjects = UnityEngine.Object
.FindObjectsOfType<Animator>()
.Where(animator => GetCustomEvents(animator).Any());
newTargets = newTargets.Concat(mechanimStateCustomEventObjects.Cast<object>());
var ambientSoundsComponents = UnityEngine.Object
.FindObjectsOfType<DarkTonic.MasterAudio.AmbientSound>()
.Where(f => IncludeAmbientSound(f))
.ToArray();
newTargets = newTargets.Concat(ambientSoundsComponents);
// put all components in an object array
var footstepSoundsComponents = UnityEngine.Object
.FindObjectsOfType<DarkTonic.MasterAudio.FootstepSounds>()
.Where(f => IncludeFootstepSounds(f))
.ToArray();
newTargets = newTargets.Concat(footstepSoundsComponents);
var newTargetList = newTargets.ToArray();
api.ResetTargets(newTargetList);
}
public override GUIContent GetContent(object entity) {
var asEventSounds = entity as EventSounds;
if (asEventSounds != null) {
return base.GetContent(asEventSounds.gameObject);
}
var asFootstepSounds = entity as FootstepSounds;
if (asFootstepSounds != null)
{
return base.GetContent(asFootstepSounds.gameObject);
}
var asFootstepNode = entity as FootstepSoundsNode;
if (asFootstepNode != null)
{
return new GUIContent(GetFoostepSoundNodeLabel(asFootstepNode));
}
var asGroupNode = entity as AudioEventGroupNode;
if (asGroupNode != null) {
return new GUIContent(asGroupNode.name);
}
var asAmbientSound = entity as AmbientSound;
if (asAmbientSound != null) {
return base.GetContent(asAmbientSound.gameObject);
}
var asAmbientSoundNode = entity as AmbientSoundNode;
if (asAmbientSoundNode != null) {
return new GUIContent(GetAmbientSoundNodeLabel(asAmbientSoundNode));
}
var asAudioEvent = entity as AudioEvent;
if (asAudioEvent != null) {
return new GUIContent(GetAudioEventLabel(asAudioEvent));
}
var asLinkedGroupNode = entity as LinkedGroupNode;
if (asLinkedGroupNode != null) {
var label = "Play 'Start' Linked\nGroup: " + asLinkedGroupNode.groupName;
if (asLinkedGroupNode.hasLinkedGroupLoop) {
label += "\n-Linked Group Loop to '" + asLinkedGroupNode.linkedGroupLoopName + "'-";
}
return new GUIContent(label);
}
var asStopLinkedGroupNode = entity as EndLinkedGroupNode;
if (asStopLinkedGroupNode != null) {
var label = "Play 'Stop' Linked\nGroup: " + asStopLinkedGroupNode.groupName;
if (asStopLinkedGroupNode.hasLinkedGroupLoop) {
label += "\n-Linked Group Loop to '" + asStopLinkedGroupNode.linkedGroupLoopName + "'-";
}
return new GUIContent(label);
}
var asAnimator = entity as Animator;
if (asAnimator != null) {
return base.GetContent(asAnimator.gameObject);
}
var asLayer = entity as AnimatorControllerLayer;
if (asLayer != null) {
return new GUIContent("Mechanim Layer\n" + asLayer.name);
}
var asState = entity as AnimatorState;
if (asState != null) {
return new GUIContent("State\n" + asState.name);
}
var asMechanimEventSound = entity as MechanimEventSound;
if (asMechanimEventSound != null) {
return new GUIContent(asMechanimEventSound.type + "\n" + "Play Sound Group\n" + asMechanimEventSound.group);
}
var asMechanimCustomEvent = entity as MechanimEventCustomEvent;
if (asMechanimCustomEvent != null) {
return new GUIContent(asMechanimCustomEvent.type + "\n" + "Fire Custom Event\n" + asMechanimCustomEvent.customEvent);
}
return base.GetContent(entity);
}
public override string GetEntityTooltip(object entity) {
var asAudioEvent = entity as AudioEvent;
if (asAudioEvent != null)
return GetAudioEventTooltip(asAudioEvent);
var asAnimator = entity as Animator;
if (asAnimator != null)
return asAnimator.name + " Animator";
return base.GetEntityTooltip(entity);
}
// handles node selection changes:
// when a EventSounds node is selected, its GameObject should be be selected other Unity windows
public override void OnEntitySelectionChange(object[] selection) {
if (selection.Count() == 1) {
var single = selection.First();
var asAmbientSoundNode = single as AmbientSoundNode;
if (asAmbientSoundNode != null) {
var groupTransform = MasterAudio.FindGroupTransform(asAmbientSoundNode._groupName);
if (groupTransform != null) {
Selection.activeObject = groupTransform.gameObject;
}
return;
}
var asFootstepSoundNode = single as FootstepSoundsNode;
if (asFootstepSoundNode != null)
{
var groupTransform = MasterAudio.FindGroupTransform(asFootstepSoundNode._groupName);
if (groupTransform != null)
{
Selection.activeObject = groupTransform.gameObject;
}
return;
}
// action nodes are handled depending on their action type
var asAudioEvent = single as AudioEvent;
if (asAudioEvent != null) {
// PlaySound: the played group should be selected in other Unity windows
// GroupControl: if only a single group is affected, it should be selected in other unity windows
switch (asAudioEvent.currentSoundFunctionType) {
case MasterAudio.EventSoundFunctionType.PlaySound: {
var groupTransform = MasterAudio.FindGroupTransform(asAudioEvent.soundType);
if (groupTransform != null)
Selection.activeObject = groupTransform;
}
break;
case MasterAudio.EventSoundFunctionType.GroupControl: {
if (!asAudioEvent.allSoundTypesForGroupCmd) {
var groupTransform = MasterAudio.FindGroupTransform(asAudioEvent.soundType);
if (groupTransform != null)
Selection.activeObject = groupTransform;
}
}
break;
case MasterAudio.EventSoundFunctionType.PlaylistControl: {
if (!asAudioEvent.allPlaylistControllersForGroupCmd) {
var controller = PlaylistController.InstanceByName(asAudioEvent.playlistControllerName);
if (controller != null)
Selection.activeObject = controller;
}
}
break;
case MasterAudio.EventSoundFunctionType.UnityMixerControl: {
if (asAudioEvent.currentMixerCommand == MasterAudio.UnityMixerCommand.TransitionToSnapshot) {
if (asAudioEvent.snapshotToTransitionTo != null) {
// run AudioMixerWindow.Create
// Selection.activeObject = asAudioEvent.snapshotToTransitionTo.audioMixer;
}
}
}
break;
case MasterAudio.EventSoundFunctionType.PersistentSettingsControl: {
if (asAudioEvent.currentPersistentSettingsCommand == MasterAudio.PersistentSettingsCommand.SetGroupVolume) {
if (!asAudioEvent.allSoundTypesForGroupCmd) {
var groupTransform = MasterAudio.FindGroupTransform(asAudioEvent.soundType);
if (groupTransform != null)
Selection.activeObject = groupTransform;
}
}
}
break;
}
return;
}
// AudioEventGroup: don't do anything
var asGroupNode = single as AudioEventGroupNode;
if (asGroupNode != null)
return;
var asLinkedGroup = single as LinkedGroupNode;
if (asLinkedGroup != null) {
var groupTransform = MasterAudio.FindGroupTransform(asLinkedGroup.groupName);
if (groupTransform != null) {
Selection.activeObject = groupTransform;
}
return;
}
var asStopLinkedGroup = single as EndLinkedGroupNode;
if (asStopLinkedGroup != null) {
var groupTransform = MasterAudio.FindGroupTransform(asStopLinkedGroup.groupName);
if (groupTransform != null) {
Selection.activeObject = groupTransform;
}
return;
}
var asAnimatorState = single as AnimatorState;
if (asAnimatorState != null) {
Selection.activeObject = asAnimatorState;
return;
}
var asMechanimEventSound = single as MechanimEventSound;
if (asMechanimEventSound != null) {
var groupTransform = MasterAudio.FindGroupTransform(asMechanimEventSound.group);
if (groupTransform != null) {
Selection.activeObject = groupTransform;
}
return;
}
var asMechanimCustomEvent = single as MechanimEventCustomEvent;
if (asMechanimCustomEvent != null) {
var mago = MasterAudio.SafeInstance;
if (mago != null) {
Selection.activeObject = mago;
}
return;
}
}
base.OnEntitySelectionChange(selection);
}
// returns all actions of the given AudioEventGroup that pass the group- and bus filters
static IEnumerable<AudioEvent> GetAudioEvents(AudioEventGroup group) {
return group.SoundEvents.Where(IncludeAudioEvent);
}
static bool IncludeAmbientSound(DarkTonic.MasterAudio.AmbientSound ambient) {
if (MasterAudio.SoundGroupHardCodedNames.Contains(ambient.AmbientSoundGroup)) {
return false;
}
if (FilterSoundGroup(ambient.AmbientSoundGroup)) {
return false;
}
return true;
}
static bool IncludeFootstepSounds(DarkTonic.MasterAudio.FootstepSounds footstepSounds)
{
if (footstepSounds.footstepGroups.Count == 0)
{
return false;
}
foreach (var footstep in footstepSounds.footstepGroups)
{
if (!FilterSoundGroup(footstep.soundType))
{
return true;
}
}
return false;
}
static bool IncludeAudioEvent(AudioEvent ev) {
switch (ev.currentSoundFunctionType) {
case MasterAudio.EventSoundFunctionType.PlaySound:
case MasterAudio.EventSoundFunctionType.GroupControl:
return !FilterSoundGroup(ev.soundType);
case MasterAudio.EventSoundFunctionType.BusControl:
if (!string.IsNullOrEmpty(groupFilter)) {
return false;
}
return ev.allSoundTypesForBusCmd || string.IsNullOrEmpty(busFilter) || ev.busName == busFilter;
case MasterAudio.EventSoundFunctionType.PlaylistControl:
case MasterAudio.EventSoundFunctionType.UnityMixerControl:
case MasterAudio.EventSoundFunctionType.CustomEventControl:
case MasterAudio.EventSoundFunctionType.PersistentSettingsControl:
return string.IsNullOrEmpty(busFilter) && string.IsNullOrEmpty(groupFilter);
}
return true;
}
static IEnumerable<string> GetSoundGroups(Animator animator) {
var controller = animator.runtimeAnimatorController as AnimatorController;
if (controller == null)
return Enumerable.Empty<string>();
return controller.layers.SelectMany(layer => GetSoundGroups(layer));
}
static IEnumerable<string> GetSoundGroups(AnimatorControllerLayer layer) {
return layer.stateMachine.states.SelectMany(state => GetSoundGroups(state.state));
}
static IEnumerable<string> GetSoundGroups(AnimatorState animatorState) {
return animatorState.behaviours
.OfType<MechanimStateSounds>()
.SelectMany(stateSound => GetSoundGroups(stateSound));
}
static IEnumerable<string> GetSoundGroups(MechanimStateSounds behaviour) {
var groups = new[] { behaviour.enterSoundGroup, behaviour.exitSoundGroup, behaviour.TimedSoundGroup, behaviour.MultiSoundsTimedGroup };
return groups.Where(name => !string.IsNullOrEmpty(name) && !FilterSoundGroup(name));
}
static IEnumerable<string> GetCustomEvents(Animator animator) {
var controller = animator.runtimeAnimatorController as AnimatorController;
if (controller == null)
return Enumerable.Empty<string>();
return controller.layers.SelectMany(layer => GetCustomEvents(layer));
}
static IEnumerable<string> GetCustomEvents(AnimatorControllerLayer layer) {
return layer.stateMachine.states.SelectMany(state => GetCustomEvents(state.state));
}
static IEnumerable<string> GetCustomEvents(AnimatorState animatorState) {
return animatorState.behaviours
.OfType<MechanimStateCustomEvents>()
.SelectMany(stateEvents => GetCustomEvents(stateEvents));
}
static IEnumerable<string> GetCustomEvents(MechanimStateCustomEvents behaviour) {
var customEvents = new[] { behaviour.enterCustomEvent, behaviour.exitCustomEvent, behaviour.timedCustomEvent, behaviour.MultiTimedEvent };
return customEvents.Where(name => !string.IsNullOrEmpty(name) && !FilterCustomEvent(name));
}
static bool FilterSoundGroup(string name) {
if (!string.IsNullOrEmpty(groupFilter) && groupFilter != name) {
return true;
}
if (MasterAudio.SoundGroupHardCodedNames.Contains(name)) {
return true;
}
if (!string.IsNullOrEmpty(busFilter)) {
var bus = GetGroupBus(name);
if (bus == null || bus.busName != busFilter) {
return true;
}
}
return false;
}
static bool FilterCustomEvent(string customEventName) {
if (MasterAudio.SoundGroupHardCodedNames.Contains(customEventName)) {
return true;
}
return !string.IsNullOrEmpty(groupFilter) || !string.IsNullOrEmpty(busFilter);
}
// returns nodes for all AudioEventGroups of the given component which are in use and contain actions
static IEnumerable<AudioEventGroupNode> GetGroupNodes(EventSounds esComponent) {
var customGroupNodes = esComponent.userDefinedSounds.Select(
element => new AudioEventGroupNode() {
type = 0,
group = element,
useGroup = true,
name = "Custom event\n" + element.customEventName
}
);
var componentGroups = GetNamedEventGroupNodes(esComponent).Concat(customGroupNodes);
foreach (var node in componentGroups) {
if (!node.useGroup)
continue;
if (!GetAudioEvents(node.group).Any())
continue;
yield return node;
}
}
static string GetAudioEventTooltip(AudioEvent ev) {
switch (ev.currentSoundFunctionType) {
case MasterAudio.EventSoundFunctionType.PlaySound: {
var bus = GetGroupBus(ev.soundType);
if (bus != null)
return "Bus: " + bus.busName;
}
break;
case MasterAudio.EventSoundFunctionType.GroupControl: {
if (ev.allSoundTypesForGroupCmd)
return string.Empty;
var bus = GetGroupBus(ev.soundType);
if (bus != null)
return "Bus: " + bus.busName;
}
break;
default:
return string.Empty;
}
return string.Empty;
}
static GroupBus GetGroupBus(string groupName) {
var groupComponent = GetGroupComponent(groupName);
if (groupComponent == null)
return null;
var index = groupComponent.busIndex - MasterAudio.HardCodedBusOptions;
if (index < 0 || index >= MasterAudio.GroupBuses.Count)
return null;
return MasterAudio.GroupBuses[index];
}
static string GetFoostepSoundNodeLabel(FootstepSoundsNode node)
{
var sb = new StringBuilder("Footstep Sound");
sb.Append("\nGroup: " + node._groupName);
return sb.ToString();
}
static string GetAmbientSoundNodeLabel(AmbientSoundNode node) {
var sb = new StringBuilder("Ambient Sound");
sb.Append("\nGroup: " + node._groupName);
return sb.ToString();
}
// returns a node label text for the given action
static string GetAudioEventLabel(AudioEvent ev) {
var sb = new System.Text.StringBuilder(ev.currentSoundFunctionType.ToString());
switch (ev.currentSoundFunctionType) {
case MasterAudio.EventSoundFunctionType.PlaySound:
sb.Append("\nGroup: " + ev.soundType);
break;
case MasterAudio.EventSoundFunctionType.GroupControl:
sb.Append("\nCmd: " + ev.currentSoundGroupCommand);
sb.Append("\nGroup: " + (ev.allSoundTypesForGroupCmd ? "all" : ev.soundType));
break;
case MasterAudio.EventSoundFunctionType.BusControl:
sb.Append("\nCmd: " + ev.currentBusCommand);
sb.Append("\nBus: " + (ev.allSoundTypesForBusCmd ? "all" : ev.busName));
break;
case MasterAudio.EventSoundFunctionType.PlaylistControl:
sb.Append("\nCmd: " + ev.currentPlaylistCommand);
sb.Append("\nController: " + (ev.allPlaylistControllersForGroupCmd ? "all" : ev.playlistControllerName));
break;
case MasterAudio.EventSoundFunctionType.CustomEventControl:
sb.Append("\nCmd: " + ev.currentCustomEventCommand);
sb.Append("\nName: " + ev.theCustomEventName);
break;
case MasterAudio.EventSoundFunctionType.GlobalControl:
sb.Append("\nCmd: " + ev.currentGlobalCommand);
break;
case MasterAudio.EventSoundFunctionType.UnityMixerControl:
sb.Append("\nCmd: " + ev.currentMixerCommand);
switch (ev.currentMixerCommand) {
case MasterAudio.UnityMixerCommand.TransitionToSnapshot:
sb.Append("\nSnapshot: " + (ev.snapshotToTransitionTo == null ? "" : ev.snapshotToTransitionTo.name));
break;
}
break;
case MasterAudio.EventSoundFunctionType.PersistentSettingsControl:
sb.Append("\nCmd: " + ev.currentPersistentSettingsCommand);
switch (ev.currentPersistentSettingsCommand) {
case MasterAudio.PersistentSettingsCommand.SetBusVolume:
sb.Append("\nBus: " + (ev.allSoundTypesForBusCmd ? "all" : ev.busName));
break;
case MasterAudio.PersistentSettingsCommand.SetGroupVolume:
sb.Append("\nGroup: " + (ev.allSoundTypesForGroupCmd ? "all" : ev.soundType));
break;
}
break;
default:
break;
}
return sb.ToString();
}
// returns nodes for all AudioEventGroups of the given component which are in use
static IEnumerable<AudioEventGroupNode> GetNamedEventGroupNodes(EventSounds es) {
return namedEventGroups
.Select(
item => new AudioEventGroupNode() {
type = item.type,
group = item.getGroup(es),
useGroup = item.useGroup(es),
name = item.name
}
);
}
static MasterAudioGroup GetGroupComponent(string groupName) {
var groupTransform = MasterAudio.FindGroupTransform(groupName);
if (groupTransform == null)
return null;
return groupTransform.GetComponent<MasterAudioGroup>();
}
// returns a label for a group link relation comming from the given group
private string GetGroupLinkLabel(string groupName, bool isStartLinkedGroup) {
var component = MasterAudio.Instance.Trans.GetChildTransform(groupName);
if (component == null) {
return string.Empty;
}
var group = component.GetComponent<MasterAudioGroup>();
if (group == null) {
return string.Empty;
}
if (isStartLinkedGroup) {
if (group.childSoundGroups.Count <= 1 || group.linkedStartGroupSelectionType == MasterAudio.LinkedGroupSelectionType.All) {
return "plays when linker group\nstarts playing";
}
return "may play when linker group\nstarts playing (random selection)";
}
if (group.endLinkedGroups.Count <= 1 || group.linkedStopGroupSelectionType == MasterAudio.LinkedGroupSelectionType.All) {
return "plays when linker group\nfinishes playing";
}
return "may play when linker group\nfinishes playing (random selection)";
}
// returns the names of all groups that the given group links to
static IEnumerable<string> GetStartLinkedGroups(string groupName) {
var grpTrans = MasterAudio.Instance.Trans.GetChildTransform(groupName);
if (grpTrans == null) {
return Enumerable.Empty<string>();
}
var component = grpTrans.GetComponent<MasterAudioGroup>();
if (component == null) {
return Enumerable.Empty<string>();
}
return component.childSoundGroups;
}
static IEnumerable<string> GetStopLinkedGroups(string groupName) {
var grpTrans = MasterAudio.Instance.Trans.GetChildTransform(groupName);
if (grpTrans == null) {
return Enumerable.Empty<string>();
}
var component = grpTrans.GetComponent<MasterAudioGroup>();
if (component == null) {
return Enumerable.Empty<string>();
}
return component.endLinkedGroups;
}
}