Files
Nitrox/NitroxClient/Debuggers/SoundDebugger.cs
2025-07-06 00:23:46 +02:00

226 lines
8.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using FMOD.Studio;
using FMODUnity;
using NitroxClient.Unity.Helper;
using NitroxModel.GameLogic.FMOD;
using UnityEngine;
#pragma warning disable 618
namespace NitroxClient.Debuggers;
[ExcludeFromCodeCoverage]
public class SoundDebugger : BaseDebugger
{
private readonly ReadOnlyDictionary<string, SoundData> assetList;
private readonly Dictionary<string, bool> assetIs3D = new();
private readonly Dictionary<string, EventInstance> eventInstancesByPath = new();
private Vector2 scrollPosition;
private string searchText;
private string searchCategory;
private float volume = 1f;
private float distance;
private bool displayIsWhitelisted = true;
private bool displayIsGlobal;
private bool displayWithRadius;
public SoundDebugger(FMODWhitelist fmodWhitelist) : base(700, null, KeyCode.F, true, false, false, GUISkinCreationOptions.DERIVEDCOPY)
{
assetList = fmodWhitelist.GetWhitelist();
foreach (KeyValuePair<string,SoundData> pair in assetList)
{
EventInstance evt = FMODUWE.GetEvent(pair.Key);
evt.getDescription(out EventDescription description);
description.is3D(out bool is3D);
assetIs3D[pair.Key] = is3D;
evt.release();
evt.clearHandle();
}
ActiveTab = AddTab("Sounds", RenderTabAllSounds);
}
protected override void OnSetSkin(GUISkin skin)
{
base.OnSetSkin(skin);
skin.SetCustomStyle("soundKeyLabel",
skin.label,
s =>
{
s.fontSize = 15;
});
skin.SetCustomStyle("enabled",
skin.label,
s =>
{
s.normal = new GUIStyleState { textColor = Color.green };
});
skin.SetCustomStyle("disabled",
skin.label,
s =>
{
s.normal = new GUIStyleState { textColor = Color.red };
});
}
private void RenderTabAllSounds()
{
using (new GUILayout.VerticalScope("Box"))
{
using (new GUILayout.VerticalScope("Box"))
{
using (new GUILayout.HorizontalScope("Box"))
{
searchText = GUILayout.TextField(searchText);
if (GUILayout.Button("Stop all", GUILayout.MaxWidth(60f)))
{
eventInstancesByPath.Values.ForEach(evt => evt.stop(FMOD.Studio.STOP_MODE.IMMEDIATE));
eventInstancesByPath.Clear();
}
}
using (new GUILayout.HorizontalScope())
{
if (GUILayout.Button("Creature"))
{
searchCategory = "event:/creature";
}
if (GUILayout.Button("Environment"))
{
searchCategory = "event:/env";
}
if (GUILayout.Button("Player"))
{
searchCategory = "event:/player";
}
if (GUILayout.Button("Vehicles"))
{
searchCategory = "event:/sub";
}
if (GUILayout.Button("Tools"))
{
searchCategory = "event:/tools";
}
if (GUILayout.Button("Clear"))
{
searchCategory = string.Empty;
}
}
}
using (new GUILayout.HorizontalScope("Box"))
{
using (new GUILayout.VerticalScope(GUILayout.Width(325f)))
{
displayIsWhitelisted = GUILayout.Toggle(displayIsWhitelisted, "Whitelisted sounds");
displayWithRadius = GUILayout.Toggle(displayWithRadius, "Sounds with radius");
displayIsGlobal = GUILayout.Toggle(displayIsGlobal, "Global sounds");
}
using (new GUILayout.VerticalScope(GUILayout.Width(325f)))
{
using (new GUILayout.HorizontalScope())
{
GUILayout.Label($"Volume: {NitroxModel.Helper.Mathf.Round(volume, 2)}");
volume = GUILayout.HorizontalSlider(volume, 0f, 1f, GUILayout.Width(240f));
}
GUILayout.Space(5f);
using (new GUILayout.HorizontalScope())
{
GUILayout.Label($"Distance: {NitroxModel.Helper.Mathf.Round(distance)}");
distance = GUILayout.HorizontalSlider(distance, 0f, 500f, GUILayout.Width(240f));
}
}
}
}
using (new GUILayout.VerticalScope("Box"))
{
scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Height(500f));
foreach (KeyValuePair<string, SoundData> sound in assetList)
{
if (displayIsWhitelisted && !sound.Value.IsWhitelisted ||
displayIsGlobal && !sound.Value.IsGlobal ||
displayWithRadius && sound.Value.Radius <= 0.1f ||
!string.IsNullOrWhiteSpace(searchText) && sound.Key.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) == -1 ||
!string.IsNullOrWhiteSpace(searchCategory) && !sound.Key.StartsWith(searchCategory))
{
continue;
}
using (new GUILayout.VerticalScope("Box", GUILayout.MaxHeight(16f)))
{
using (new GUILayout.HorizontalScope())
{
GUILayout.Label(sound.Key, "soundKeyLabel", GUILayout.MaxWidth(370f));
GUILayout.FlexibleSpace();
GUILayout.Label("Is3D", assetIs3D[sound.Key] ? "enabled" : "disabled");
GUILayout.Space(7f);
GUILayout.Label("Whitelisted", sound.Value.IsWhitelisted ? "enabled" : "disabled", GUILayout.MinWidth(70));
GUILayout.Space(7f);
GUILayout.Label("Global", sound.Value.IsGlobal ? "enabled" : "disabled");
GUILayout.Space(7f);
GUILayout.Label($"Radius: {sound.Value.Radius}", GUILayout.Width(70f));
if (GUILayout.Button("Play"))
{
PlaySound(sound.Key);
}
if (GUILayout.Button("Stop"))
{
StopSound(sound.Key);
}
}
}
}
GUILayout.EndScrollView();
}
}
private void PlaySound(string eventPath)
{
Camera camera = Camera.main;
if (!camera)
{
Log.InGame("Camera.main not found");
return;
}
Vector3 position = camera.transform.position + new Vector3(distance, 0, 0);
if (!eventInstancesByPath.TryGetValue(eventPath, out EventInstance instance))
{
instance = FMODUWE.GetEvent(eventPath);
eventInstancesByPath.Add(eventPath, instance);
}
else
{
instance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
}
instance.setVolume(volume);
instance.set3DAttributes(position.To3DAttributes());
instance.setProperty(EVENT_PROPERTY.MINIMUM_DISTANCE, 0f);
instance.setProperty(EVENT_PROPERTY.MAXIMUM_DISTANCE, 100f);
instance.start();
instance.release();
}
private void StopSound(string eventPath)
{
if (eventInstancesByPath.TryGetValue(eventPath, out EventInstance instance))
{
instance.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
eventInstancesByPath.Remove(eventPath);
}
}
}