|
|
|
|
@@ -1,228 +1,491 @@
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
using TMPro;
|
|
|
|
|
using HarmonyLib;
|
|
|
|
|
|
|
|
|
|
namespace HomuraHimeAudioMod.GUI
|
|
|
|
|
{
|
|
|
|
|
public class AudioMixerGUI : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
private GameObject canvasObject;
|
|
|
|
|
private GameObject panelObject;
|
|
|
|
|
private RectTransform panelRect;
|
|
|
|
|
private RectTransform contentRect;
|
|
|
|
|
private GameObject resizeHandle;
|
|
|
|
|
private bool isVisible = false;
|
|
|
|
|
private Vector2 scrollPosition;
|
|
|
|
|
private float margin = 10f;
|
|
|
|
|
private float labelWidth = 140f;
|
|
|
|
|
private float sliderWidth = 200f;
|
|
|
|
|
private float buttonHeight = 25f;
|
|
|
|
|
private float lineHeight = 30f;
|
|
|
|
|
private float windowWidth = 380f;
|
|
|
|
|
private float windowHeight = 450f;
|
|
|
|
|
private Rect windowRect = new Rect(10, 10, 380, 450);
|
|
|
|
|
private Vector2 minSize = new Vector2(350, 400);
|
|
|
|
|
private Vector2 maxSize = new Vector2(800, 900);
|
|
|
|
|
private Vector2 currentSize = new Vector2(420, 650);
|
|
|
|
|
|
|
|
|
|
private Toggle voiceLimitToggle;
|
|
|
|
|
private Slider maxVoicesSlider;
|
|
|
|
|
private Toggle duckingToggle;
|
|
|
|
|
private Slider duckFadeSlider;
|
|
|
|
|
private Slider duckVolumeSlider;
|
|
|
|
|
private Toggle enemyAudioToggle;
|
|
|
|
|
private Slider indicatorBoostSlider;
|
|
|
|
|
private Slider alertBoostSlider;
|
|
|
|
|
private Slider attackBoostSlider;
|
|
|
|
|
|
|
|
|
|
private void Start()
|
|
|
|
|
{
|
|
|
|
|
CreateGUI();
|
|
|
|
|
Plugin.Log.LogInfo("AudioMixerGUI Canvas created - Press F1");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateGUI()
|
|
|
|
|
{
|
|
|
|
|
canvasObject = new GameObject("AudioMixerCanvas");
|
|
|
|
|
Canvas canvas = canvasObject.AddComponent<Canvas>();
|
|
|
|
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
|
|
|
|
canvas.sortingOrder = 999;
|
|
|
|
|
canvasObject.AddComponent<UnityEngine.EventSystems.EventSystem>();
|
|
|
|
|
canvasObject.AddComponent<GraphicRaycaster>();
|
|
|
|
|
|
|
|
|
|
CreatePanel();
|
|
|
|
|
CreateContent();
|
|
|
|
|
CreateResizeHandle();
|
|
|
|
|
|
|
|
|
|
canvasObject.SetActive(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreatePanel()
|
|
|
|
|
{
|
|
|
|
|
panelObject = new GameObject("MixerPanel");
|
|
|
|
|
panelObject.transform.SetParent(canvasObject.transform);
|
|
|
|
|
|
|
|
|
|
panelRect = panelObject.AddComponent<RectTransform>();
|
|
|
|
|
panelRect.anchorMin = Vector2.zero;
|
|
|
|
|
panelRect.anchorMax = Vector2.zero;
|
|
|
|
|
panelRect.pivot = Vector2.zero;
|
|
|
|
|
panelRect.anchoredPosition = new Vector2(30, 30);
|
|
|
|
|
panelRect.sizeDelta = currentSize;
|
|
|
|
|
|
|
|
|
|
Image bg = panelObject.AddComponent<Image>();
|
|
|
|
|
bg.color = new Color(0.12f, 0.12f, 0.18f, 0.97f);
|
|
|
|
|
|
|
|
|
|
panelObject.AddComponent<Outline>().effectColor = new Color(0.3f, 0.3f, 0.4f);
|
|
|
|
|
|
|
|
|
|
DraggablePanel draggable = panelObject.AddComponent<DraggablePanel>();
|
|
|
|
|
draggable.Initialize(panelRect);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateContent()
|
|
|
|
|
{
|
|
|
|
|
GameObject contentObj = new GameObject("Content");
|
|
|
|
|
contentObj.transform.SetParent(panelObject.transform);
|
|
|
|
|
|
|
|
|
|
VerticalLayoutGroup layout = contentObj.AddComponent<VerticalLayoutGroup>();
|
|
|
|
|
layout.spacing = 8;
|
|
|
|
|
layout.padding = new RectOffset(15, 15, 15, 15);
|
|
|
|
|
layout.childAlignment = TextAnchor.UpperCenter;
|
|
|
|
|
layout.childControlWidth = true;
|
|
|
|
|
layout.childControlHeight = true;
|
|
|
|
|
layout.childForceExpandWidth = true;
|
|
|
|
|
layout.childForceExpandHeight = false;
|
|
|
|
|
|
|
|
|
|
ContentSizeFitter fitter = contentObj.AddComponent<ContentSizeFitter>();
|
|
|
|
|
fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
|
|
|
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
|
|
|
|
|
|
|
|
contentRect = contentObj.GetComponent<RectTransform>();
|
|
|
|
|
contentRect.anchorMin = Vector2.zero;
|
|
|
|
|
contentRect.anchorMax = Vector2.one;
|
|
|
|
|
contentRect.sizeDelta = new Vector2(-30, -50);
|
|
|
|
|
|
|
|
|
|
CreateHeader(contentObj.transform);
|
|
|
|
|
CreateVoiceSection(contentObj.transform);
|
|
|
|
|
CreateDuckingSection(contentObj.transform);
|
|
|
|
|
CreateEnemySection(contentObj.transform);
|
|
|
|
|
CreateCueSection(contentObj.transform);
|
|
|
|
|
CreateFooter(contentObj.transform);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateHeader(Transform parent)
|
|
|
|
|
{
|
|
|
|
|
AddSectionTitle(parent, "AUDIO MIXER", 18, new Color(1f, 0.8f, 0.2f));
|
|
|
|
|
AddSpacer(parent, 5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateVoiceSection(Transform parent)
|
|
|
|
|
{
|
|
|
|
|
AddSectionTitle(parent, "VOICE MANAGER", 14, new Color(0.7f, 0.9f, 1f));
|
|
|
|
|
|
|
|
|
|
voiceLimitToggle = AddToggle(parent, "Voice Limit Fix", ModConfig.EnableVoiceLimitFix.Value,
|
|
|
|
|
(v) => ModConfig.EnableVoiceLimitFix.Value = v);
|
|
|
|
|
|
|
|
|
|
CreateSliderRow(parent, "Max Voices:", 32, 256, ModConfig.MaxVoiceCount.Value,
|
|
|
|
|
out maxVoicesSlider, (v) => ModConfig.MaxVoiceCount.Value = (int)v);
|
|
|
|
|
|
|
|
|
|
AddSpacer(parent, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateDuckingSection(Transform parent)
|
|
|
|
|
{
|
|
|
|
|
AddSectionTitle(parent, "AUDIO DUCKING", 14, new Color(0.7f, 0.9f, 1f));
|
|
|
|
|
|
|
|
|
|
duckingToggle = AddToggle(parent, "Ducking Fix", ModConfig.EnableDuckingFix.Value,
|
|
|
|
|
(v) => ModConfig.EnableDuckingFix.Value = v);
|
|
|
|
|
|
|
|
|
|
CreateSliderRow(parent, "Duck Fade:", 0.01f, 0.3f, ModConfig.DuckFadeTime.Value,
|
|
|
|
|
out duckFadeSlider, (v) => ModConfig.DuckFadeTime.Value = v);
|
|
|
|
|
|
|
|
|
|
CreateSliderRow(parent, "Duck Volume:", 0.1f, 0.8f, ModConfig.DuckVolume.Value,
|
|
|
|
|
out duckVolumeSlider, (v) => ModConfig.DuckVolume.Value = v);
|
|
|
|
|
|
|
|
|
|
AddSpacer(parent, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateEnemySection(Transform parent)
|
|
|
|
|
{
|
|
|
|
|
AddSectionTitle(parent, "ENEMY AUDIO", 14, new Color(1f, 0.6f, 0.6f));
|
|
|
|
|
|
|
|
|
|
enemyAudioToggle = AddToggle(parent, "Enemy Audio Boost", ModConfig.EnableEnemyAudioBoost.Value,
|
|
|
|
|
(v) => ModConfig.EnableEnemyAudioBoost.Value = v);
|
|
|
|
|
|
|
|
|
|
CreateSliderRow(parent, "Indicator:", 0.5f, 2.0f, ModConfig.EnemyIndicatorBoost.Value,
|
|
|
|
|
out indicatorBoostSlider, (v) => ModConfig.EnemyIndicatorBoost.Value = v);
|
|
|
|
|
|
|
|
|
|
CreateSliderRow(parent, "Alert:", 0.5f, 2.0f, ModConfig.AlertSoundBoost.Value,
|
|
|
|
|
out alertBoostSlider, (v) => ModConfig.AlertSoundBoost.Value = v);
|
|
|
|
|
|
|
|
|
|
CreateSliderRow(parent, "Attack:", 0.5f, 2.0f, ModConfig.AttackSoundBoost.Value,
|
|
|
|
|
out attackBoostSlider, (v) => ModConfig.AttackSoundBoost.Value = v);
|
|
|
|
|
|
|
|
|
|
AddSpacer(parent, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateCueSection(Transform parent)
|
|
|
|
|
{
|
|
|
|
|
AddSectionTitle(parent, "TEST CUES", 14, new Color(0.6f, 1f, 0.6f));
|
|
|
|
|
|
|
|
|
|
GameObject grid = new GameObject("CueGrid");
|
|
|
|
|
grid.transform.SetParent(parent.transform);
|
|
|
|
|
|
|
|
|
|
HorizontalLayoutGroup hLayout = grid.AddComponent<HorizontalLayoutGroup>();
|
|
|
|
|
hLayout.spacing = 10;
|
|
|
|
|
hLayout.childAlignment = TextAnchor.MiddleCenter;
|
|
|
|
|
hLayout.childControlWidth = true;
|
|
|
|
|
hLayout.childControlHeight = true;
|
|
|
|
|
hLayout.childForceExpandWidth = true;
|
|
|
|
|
hLayout.childForceExpandHeight = false;
|
|
|
|
|
|
|
|
|
|
ContentSizeFitter cf = grid.AddComponent<ContentSizeFitter>();
|
|
|
|
|
cf.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
|
|
|
|
|
cf.verticalFit = ContentSizeFitter.FitMode.MinSize;
|
|
|
|
|
|
|
|
|
|
RectTransform gridRect = grid.GetComponent<RectTransform>();
|
|
|
|
|
gridRect.sizeDelta = new Vector2(0, 40);
|
|
|
|
|
|
|
|
|
|
AddCueButton(grid.transform, "Enemy_Idle", () => TestCue("Enemy_Idle"));
|
|
|
|
|
AddCueButton(grid.transform, "Enemy_Alert", () => TestCue("Enemy_Alert"));
|
|
|
|
|
AddCueButton(grid.transform, "Enemy_Attack", () => TestCue("Enemy_Attack"));
|
|
|
|
|
AddCueButton(grid.transform, "Enemy_Chase", () => TestCue("Enemy_Chase"));
|
|
|
|
|
AddCueButton(grid.transform, "Enemy_Death", () => TestCue("Enemy_Death"));
|
|
|
|
|
|
|
|
|
|
AddSpacer(parent, 10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateFooter(Transform parent)
|
|
|
|
|
{
|
|
|
|
|
AddLabel(parent, "F1: Toggle | Drag: Move | Corner: Resize", 11, Color.gray);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateResizeHandle()
|
|
|
|
|
{
|
|
|
|
|
resizeHandle = new GameObject("ResizeHandle");
|
|
|
|
|
resizeHandle.transform.SetParent(panelObject.transform);
|
|
|
|
|
|
|
|
|
|
RectTransform handleRect = resizeHandle.AddComponent<RectTransform>();
|
|
|
|
|
handleRect.anchorMin = new Vector2(1, 0);
|
|
|
|
|
handleRect.anchorMax = new Vector2(1, 0);
|
|
|
|
|
handleRect.pivot = new Vector2(1, 0);
|
|
|
|
|
handleRect.anchoredPosition = new Vector2(0, 0);
|
|
|
|
|
handleRect.sizeDelta = new Vector2(20, 20);
|
|
|
|
|
|
|
|
|
|
Image handleImage = resizeHandle.AddComponent<Image>();
|
|
|
|
|
handleImage.color = new Color(0.4f, 0.4f, 0.5f, 0.8f);
|
|
|
|
|
|
|
|
|
|
ResizeHandle resize = resizeHandle.AddComponent<ResizeHandle>();
|
|
|
|
|
resize.Initialize(panelRect, minSize, maxSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddSectionTitle(Transform parent, string text, int fontSize, Color color)
|
|
|
|
|
{
|
|
|
|
|
GameObject obj = new GameObject("Title");
|
|
|
|
|
obj.transform.SetParent(parent);
|
|
|
|
|
|
|
|
|
|
LayoutElement le = obj.AddComponent<LayoutElement>();
|
|
|
|
|
le.minHeight = 25;
|
|
|
|
|
le.preferredHeight = 25;
|
|
|
|
|
le.flexibleWidth = 1;
|
|
|
|
|
|
|
|
|
|
TextMeshProUGUI txt = obj.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
txt.text = text;
|
|
|
|
|
txt.fontSize = fontSize;
|
|
|
|
|
txt.fontStyle = FontStyles.Bold;
|
|
|
|
|
txt.color = color;
|
|
|
|
|
txt.alignment = TextAlignmentOptions.Center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddSpacer(Transform parent, float height)
|
|
|
|
|
{
|
|
|
|
|
GameObject spacer = new GameObject("Spacer");
|
|
|
|
|
spacer.transform.SetParent(parent);
|
|
|
|
|
|
|
|
|
|
LayoutElement le = spacer.AddComponent<LayoutElement>();
|
|
|
|
|
le.minHeight = height;
|
|
|
|
|
le.preferredHeight = height;
|
|
|
|
|
le.flexibleWidth = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Toggle AddToggle(Transform parent, string label, bool defaultValue, Action<bool> onChanged)
|
|
|
|
|
{
|
|
|
|
|
GameObject obj = new GameObject("Toggle_" + label);
|
|
|
|
|
obj.transform.SetParent(parent);
|
|
|
|
|
|
|
|
|
|
LayoutElement le = obj.AddComponent<LayoutElement>();
|
|
|
|
|
le.minHeight = 25;
|
|
|
|
|
le.preferredHeight = 25;
|
|
|
|
|
le.flexibleWidth = 1;
|
|
|
|
|
|
|
|
|
|
Toggle toggle = obj.AddComponent<Toggle>();
|
|
|
|
|
toggle.isOn = defaultValue;
|
|
|
|
|
toggle.onValueChanged.AddListener((UnityEngine.Events.UnityAction<bool>)(v => onChanged(v)));
|
|
|
|
|
|
|
|
|
|
GameObject labelObj = new GameObject("Label");
|
|
|
|
|
labelObj.transform.SetParent(obj.transform);
|
|
|
|
|
|
|
|
|
|
TextMeshProUGUI txt = labelObj.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
txt.text = label;
|
|
|
|
|
txt.fontSize = 12;
|
|
|
|
|
txt.color = Color.white;
|
|
|
|
|
txt.alignment = TextAlignmentOptions.Left;
|
|
|
|
|
|
|
|
|
|
return toggle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateSliderRow(Transform parent, string label, float min, float max, float defaultVal,
|
|
|
|
|
out Slider slider, Action<float> onChanged)
|
|
|
|
|
{
|
|
|
|
|
GameObject row = new GameObject("Slider_" + label);
|
|
|
|
|
row.transform.SetParent(parent);
|
|
|
|
|
|
|
|
|
|
LayoutElement le = row.AddComponent<LayoutElement>();
|
|
|
|
|
le.minHeight = 30;
|
|
|
|
|
le.preferredHeight = 30;
|
|
|
|
|
le.flexibleWidth = 1;
|
|
|
|
|
|
|
|
|
|
GameObject labelObj = new GameObject("Label");
|
|
|
|
|
labelObj.transform.SetParent(row.transform);
|
|
|
|
|
|
|
|
|
|
TextMeshProUGUI labelTxt = labelObj.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
labelTxt.text = label;
|
|
|
|
|
labelTxt.fontSize = 11;
|
|
|
|
|
labelTxt.color = Color.white;
|
|
|
|
|
labelTxt.alignment = TextAlignmentOptions.Left;
|
|
|
|
|
|
|
|
|
|
RectTransform labelRect = labelObj.GetComponent<RectTransform>();
|
|
|
|
|
labelRect.anchorMin = new Vector2(0, 0);
|
|
|
|
|
labelRect.anchorMax = new Vector2(0.35f, 1);
|
|
|
|
|
labelRect.pivot = new Vector2(0, 0.5f);
|
|
|
|
|
labelRect.offsetMin = new Vector2(0, 0);
|
|
|
|
|
labelRect.offsetMax = new Vector2(0, 0);
|
|
|
|
|
labelRect.sizeDelta = new Vector2(0, 0);
|
|
|
|
|
|
|
|
|
|
GameObject sliderObj = new GameObject("Slider");
|
|
|
|
|
sliderObj.transform.SetParent(row.transform);
|
|
|
|
|
|
|
|
|
|
slider = sliderObj.AddComponent<Slider>();
|
|
|
|
|
slider.minValue = min;
|
|
|
|
|
slider.maxValue = max;
|
|
|
|
|
slider.value = defaultVal;
|
|
|
|
|
slider.onValueChanged.AddListener((UnityEngine.Events.UnityAction<float>)(v => onChanged(v)));
|
|
|
|
|
|
|
|
|
|
RectTransform sliderRect = sliderObj.GetComponent<RectTransform>();
|
|
|
|
|
sliderRect.anchorMin = new Vector2(0.35f, 0);
|
|
|
|
|
sliderRect.anchorMax = new Vector2(0.75f, 1);
|
|
|
|
|
sliderRect.pivot = new Vector2(0.5f, 0.5f);
|
|
|
|
|
sliderRect.offsetMin = new Vector2(5, 3);
|
|
|
|
|
sliderRect.offsetMax = new Vector2(-5, -3);
|
|
|
|
|
|
|
|
|
|
GameObject valueObj = new GameObject("Value");
|
|
|
|
|
valueObj.transform.SetParent(row.transform);
|
|
|
|
|
|
|
|
|
|
TextMeshProUGUI valueTxt = valueObj.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
valueTxt.text = defaultVal.ToString("F2");
|
|
|
|
|
valueTxt.fontSize = 11;
|
|
|
|
|
valueTxt.color = Color.yellow;
|
|
|
|
|
valueTxt.alignment = TextAlignmentOptions.Left;
|
|
|
|
|
|
|
|
|
|
RectTransform valueRect = valueObj.GetComponent<RectTransform>();
|
|
|
|
|
valueRect.anchorMin = new Vector2(0.75f, 0);
|
|
|
|
|
valueRect.anchorMax = new Vector2(1, 1);
|
|
|
|
|
valueRect.pivot = new Vector2(0, 0.5f);
|
|
|
|
|
valueRect.offsetMin = new Vector2(5, 0);
|
|
|
|
|
valueRect.offsetMax = new Vector2(0, 0);
|
|
|
|
|
valueRect.sizeDelta = new Vector2(0, 0);
|
|
|
|
|
|
|
|
|
|
slider.onValueChanged.AddListener((UnityEngine.Events.UnityAction<float>)(v => valueTxt.text = v.ToString("F2")));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddCueButton(Transform parent, string label, Action onClick)
|
|
|
|
|
{
|
|
|
|
|
GameObject btnObj = new GameObject("CueBtn_" + label);
|
|
|
|
|
btnObj.transform.SetParent(parent);
|
|
|
|
|
|
|
|
|
|
LayoutElement le = btnObj.AddComponent<LayoutElement>();
|
|
|
|
|
le.minWidth = 70;
|
|
|
|
|
le.preferredWidth = 80;
|
|
|
|
|
le.minHeight = 30;
|
|
|
|
|
le.preferredHeight = 30;
|
|
|
|
|
|
|
|
|
|
Button btn = btnObj.AddComponent<Button>();
|
|
|
|
|
btn.onClick.AddListener(() => onClick());
|
|
|
|
|
|
|
|
|
|
TextMeshProUGUI txt = btnObj.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
txt.text = label.Replace("Enemy_", "");
|
|
|
|
|
txt.fontSize = 10;
|
|
|
|
|
txt.color = Color.white;
|
|
|
|
|
txt.alignment = TextAlignmentOptions.Center;
|
|
|
|
|
|
|
|
|
|
ColorBlock colors = btn.colors;
|
|
|
|
|
colors.normalColor = new Color(0.25f, 0.35f, 0.45f);
|
|
|
|
|
colors.highlightedColor = new Color(0.35f, 0.5f, 0.6f);
|
|
|
|
|
colors.pressedColor = new Color(0.15f, 0.25f, 0.35f);
|
|
|
|
|
btn.colors = colors;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddLabel(Transform parent, string text, int fontSize, Color color)
|
|
|
|
|
{
|
|
|
|
|
GameObject obj = new GameObject("Label");
|
|
|
|
|
obj.transform.SetParent(parent);
|
|
|
|
|
|
|
|
|
|
LayoutElement le = obj.AddComponent<LayoutElement>();
|
|
|
|
|
le.minHeight = 20;
|
|
|
|
|
le.preferredHeight = 20;
|
|
|
|
|
le.flexibleWidth = 1;
|
|
|
|
|
|
|
|
|
|
TextMeshProUGUI txt = obj.AddComponent<TextMeshProUGUI>();
|
|
|
|
|
txt.text = text;
|
|
|
|
|
txt.fontSize = fontSize;
|
|
|
|
|
txt.color = color;
|
|
|
|
|
txt.alignment = TextAlignmentOptions.Center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Update()
|
|
|
|
|
{
|
|
|
|
|
if (UnityEngine.Input.GetKeyDown(KeyCode.F1))
|
|
|
|
|
if (Input.GetKeyDown(KeyCode.F1))
|
|
|
|
|
{
|
|
|
|
|
isVisible = !isVisible;
|
|
|
|
|
UpdateCursorState();
|
|
|
|
|
Plugin.Log.LogDebug($"Audio Mixer GUI: {(isVisible ? "VISIBLE" : "HIDDEN")}");
|
|
|
|
|
}
|
|
|
|
|
canvasObject.SetActive(isVisible);
|
|
|
|
|
|
|
|
|
|
if (UnityEngine.Input.GetKeyDown(KeyCode.F2) && isVisible)
|
|
|
|
|
Cursor.lockState = isVisible ? CursorLockMode.None : CursorLockMode.Locked;
|
|
|
|
|
Cursor.visible = isVisible;
|
|
|
|
|
|
|
|
|
|
Plugin.Log.LogDebug($"AudioMixer: {(isVisible ? "ON" : "OFF")}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void TestCue(string cueName)
|
|
|
|
|
{
|
|
|
|
|
Plugin.Log.LogDebug($"[GUI] Test cue: {cueName}");
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
isVisible = false;
|
|
|
|
|
UpdateCursorState();
|
|
|
|
|
var cfVoiceType = FindTypeByName("CFVoiceEventUtility");
|
|
|
|
|
if (cfVoiceType != null)
|
|
|
|
|
{
|
|
|
|
|
var method = AccessTools.Method(cfVoiceType, "PlayCFVoice");
|
|
|
|
|
if (method != null)
|
|
|
|
|
{
|
|
|
|
|
method.Invoke(null, new object[] { cueName });
|
|
|
|
|
Plugin.Log.LogDebug($"[GUI] Triggered: {cueName}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateCursorState()
|
|
|
|
|
{
|
|
|
|
|
if (isVisible)
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Cursor.lockState = CursorLockMode.None;
|
|
|
|
|
Cursor.visible = true;
|
|
|
|
|
Plugin.Log.LogWarning($"[GUI] Cue error: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Type FindTypeByName(string name)
|
|
|
|
|
{
|
|
|
|
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
|
|
|
{
|
|
|
|
|
Cursor.lockState = CursorLockMode.Locked;
|
|
|
|
|
Cursor.visible = false;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
foreach (var type in assembly.GetTypes())
|
|
|
|
|
{
|
|
|
|
|
if (type.Name.Contains(name))
|
|
|
|
|
return type;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class DraggablePanel : MonoBehaviour, IDragHandler
|
|
|
|
|
{
|
|
|
|
|
private RectTransform rectTransform;
|
|
|
|
|
|
|
|
|
|
public void Initialize(RectTransform rt)
|
|
|
|
|
{
|
|
|
|
|
rectTransform = rt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnGUI()
|
|
|
|
|
public void OnDrag(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
if (!isVisible) return;
|
|
|
|
|
if (rectTransform == null) return;
|
|
|
|
|
|
|
|
|
|
windowRect.x = Mathf.Clamp(windowRect.x, 0, Screen.width - windowWidth - 10);
|
|
|
|
|
windowRect.y = Mathf.Clamp(windowRect.y, 0, Screen.height - windowHeight - 10);
|
|
|
|
|
Vector2 delta = eventData.delta;
|
|
|
|
|
Vector2 newPos = rectTransform.anchoredPosition + delta;
|
|
|
|
|
|
|
|
|
|
windowRect = UnityEngine.GUI.Window(0, windowRect, DrawMainWindow, "HomuraHime Audio Mixer");
|
|
|
|
|
rectTransform.anchoredPosition = newPos;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class ResizeHandle : MonoBehaviour, IDragHandler, IPointerEnterHandler, IPointerExitHandler
|
|
|
|
|
{
|
|
|
|
|
private RectTransform panelRect;
|
|
|
|
|
private Vector2 minSize;
|
|
|
|
|
private Vector2 maxSize;
|
|
|
|
|
private bool isHovered;
|
|
|
|
|
|
|
|
|
|
public void Initialize(RectTransform panel, Vector2 min, Vector2 max)
|
|
|
|
|
{
|
|
|
|
|
panelRect = panel;
|
|
|
|
|
minSize = min;
|
|
|
|
|
maxSize = max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawMainWindow(int windowID)
|
|
|
|
|
public void OnDrag(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
UnityEngine.GUI.DragWindow(new Rect(0, 0, windowWidth - 20, 25));
|
|
|
|
|
if (panelRect == null) return;
|
|
|
|
|
|
|
|
|
|
scrollPosition = GUILayout.BeginScrollView(scrollPosition);
|
|
|
|
|
Vector2 delta = eventData.delta;
|
|
|
|
|
Vector2 newSize = panelRect.sizeDelta + delta;
|
|
|
|
|
|
|
|
|
|
GUILayout.Space(margin);
|
|
|
|
|
newSize.x = Mathf.Clamp(newSize.x, minSize.x, maxSize.x);
|
|
|
|
|
newSize.y = Mathf.Clamp(newSize.y, minSize.y, maxSize.y);
|
|
|
|
|
|
|
|
|
|
DrawHeader();
|
|
|
|
|
GUILayout.Space(margin);
|
|
|
|
|
|
|
|
|
|
DrawConfigSliders();
|
|
|
|
|
GUILayout.Space(10);
|
|
|
|
|
|
|
|
|
|
DrawInstructions();
|
|
|
|
|
GUILayout.Space(10);
|
|
|
|
|
|
|
|
|
|
DrawDebugButtons();
|
|
|
|
|
GUILayout.Space(margin);
|
|
|
|
|
|
|
|
|
|
GUILayout.EndScrollView();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label($"v1.0.0 | F1: Toggle | F2: Close", GUILayout.Height(20));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
panelRect.sizeDelta = newSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawHeader()
|
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
GUILayout.BeginVertical("box");
|
|
|
|
|
GUILayout.Label("=== HOMURAHIME AUDIO MIXER ===", GUILayout.Height(25));
|
|
|
|
|
GUILayout.Label("Configure audio parameters below", GUILayout.Height(20));
|
|
|
|
|
GUILayout.EndVertical();
|
|
|
|
|
isHovered = true;
|
|
|
|
|
Cursor.lockState = CursorLockMode.None;
|
|
|
|
|
Cursor.visible = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawConfigSliders()
|
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
|
|
|
{
|
|
|
|
|
GUILayout.BeginVertical("box");
|
|
|
|
|
GUILayout.Label("CONFIGURATION", GUILayout.Height(20));
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label("Max Voices:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
ModConfig.MaxVoiceCount.Value = (int)GUILayout.HorizontalSlider(
|
|
|
|
|
ModConfig.MaxVoiceCount.Value, 32, 256,
|
|
|
|
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
GUILayout.Label($"{ModConfig.MaxVoiceCount.Value}", GUILayout.Width(40));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label("Duck Fade Time:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
ModConfig.DuckFadeTime.Value = GUILayout.HorizontalSlider(
|
|
|
|
|
ModConfig.DuckFadeTime.Value, 0.01f, 0.3f,
|
|
|
|
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
GUILayout.Label($"{ModConfig.DuckFadeTime.Value:F3}s", GUILayout.Width(50));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label("Duck Volume:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
ModConfig.DuckVolume.Value = GUILayout.HorizontalSlider(
|
|
|
|
|
ModConfig.DuckVolume.Value, 0.1f, 0.8f,
|
|
|
|
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
GUILayout.Label($"{ModConfig.DuckVolume.Value:F2}", GUILayout.Width(50));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label("Indicator Boost:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
ModConfig.EnemyIndicatorBoost.Value = GUILayout.HorizontalSlider(
|
|
|
|
|
ModConfig.EnemyIndicatorBoost.Value, 0.5f, 2.0f,
|
|
|
|
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
GUILayout.Label($"{ModConfig.EnemyIndicatorBoost.Value:F2}x", GUILayout.Width(50));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label("Alert Boost:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
ModConfig.AlertSoundBoost.Value = GUILayout.HorizontalSlider(
|
|
|
|
|
ModConfig.AlertSoundBoost.Value, 0.5f, 2.0f,
|
|
|
|
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
GUILayout.Label($"{ModConfig.AlertSoundBoost.Value:F2}x", GUILayout.Width(50));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label("Attack Boost:", GUILayout.Width(labelWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
ModConfig.AttackSoundBoost.Value = GUILayout.HorizontalSlider(
|
|
|
|
|
ModConfig.AttackSoundBoost.Value, 0.5f, 2.0f,
|
|
|
|
|
GUILayout.Width(sliderWidth), GUILayout.Height(lineHeight));
|
|
|
|
|
GUILayout.Label($"{ModConfig.AttackSoundBoost.Value:F2}x", GUILayout.Width(50));
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.EndVertical();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawInstructions()
|
|
|
|
|
{
|
|
|
|
|
GUILayout.BeginVertical("box");
|
|
|
|
|
GUILayout.Label("SETUP INSTRUCTIONS", GUILayout.Height(20));
|
|
|
|
|
|
|
|
|
|
GUILayout.Label("1. Press F5 to open UnityExplorer", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label("2. Go to Object Search tab", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label("3. Search for audio manager types:", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label(" - FmodVoiceManager", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label(" - CFVoiceEventUtility", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label(" - SnapshotManager", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label("4. Use Hook Manager for runtime patches", GUILayout.Height(18));
|
|
|
|
|
GUILayout.Label("5. Current patches: NOT LOADED", GUILayout.Height(18));
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label($"VoiceLimitFix: ", GUILayout.Width(100), GUILayout.Height(18));
|
|
|
|
|
ModConfig.EnableVoiceLimitFix.Value = GUILayout.Toggle(
|
|
|
|
|
ModConfig.EnableVoiceLimitFix.Value, "Enabled");
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label($"DuckingFix: ", GUILayout.Width(100), GUILayout.Height(18));
|
|
|
|
|
ModConfig.EnableDuckingFix.Value = GUILayout.Toggle(
|
|
|
|
|
ModConfig.EnableDuckingFix.Value, "Enabled");
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.BeginHorizontal();
|
|
|
|
|
GUILayout.Label($"EnemyAudio: ", GUILayout.Width(100), GUILayout.Height(18));
|
|
|
|
|
ModConfig.EnableEnemyAudioBoost.Value = GUILayout.Toggle(
|
|
|
|
|
ModConfig.EnableEnemyAudioBoost.Value, "Enabled");
|
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
|
|
|
|
|
GUILayout.EndVertical();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawDebugButtons()
|
|
|
|
|
{
|
|
|
|
|
GUILayout.BeginVertical("box");
|
|
|
|
|
GUILayout.Label("DEBUG", GUILayout.Height(20));
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Log Current Config", GUILayout.Height(buttonHeight)))
|
|
|
|
|
{
|
|
|
|
|
LogCurrentConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Reset to Defaults", GUILayout.Height(buttonHeight)))
|
|
|
|
|
{
|
|
|
|
|
ResetToDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GUILayout.EndVertical();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void LogCurrentConfig()
|
|
|
|
|
{
|
|
|
|
|
Plugin.Log.LogInfo("=== CURRENT AUDIO MOD CONFIG ===");
|
|
|
|
|
Plugin.Log.LogInfo($"MaxVoiceCount: {ModConfig.MaxVoiceCount.Value}");
|
|
|
|
|
Plugin.Log.LogInfo($"DuckFadeTime: {ModConfig.DuckFadeTime.Value}");
|
|
|
|
|
Plugin.Log.LogInfo($"DuckVolume: {ModConfig.DuckVolume.Value}");
|
|
|
|
|
Plugin.Log.LogInfo($"EnemyIndicatorBoost: {ModConfig.EnemyIndicatorBoost.Value}");
|
|
|
|
|
Plugin.Log.LogInfo($"AlertSoundBoost: {ModConfig.AlertSoundBoost.Value}");
|
|
|
|
|
Plugin.Log.LogInfo($"AttackSoundBoost: {ModConfig.AttackSoundBoost.Value}");
|
|
|
|
|
Plugin.Log.LogInfo("===============================");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ResetToDefaults()
|
|
|
|
|
{
|
|
|
|
|
ModConfig.MaxVoiceCount.Value = 128;
|
|
|
|
|
ModConfig.DuckFadeTime.Value = 0.05f;
|
|
|
|
|
ModConfig.DuckVolume.Value = 0.3f;
|
|
|
|
|
ModConfig.EnemyIndicatorBoost.Value = 1.2f;
|
|
|
|
|
ModConfig.AlertSoundBoost.Value = 1.3f;
|
|
|
|
|
ModConfig.AttackSoundBoost.Value = 1.15f;
|
|
|
|
|
Plugin.Log.LogInfo("[GUI] Config reset to defaults");
|
|
|
|
|
isHovered = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|