Settings are now loaded from and saved to the config.json file. Reworked the UI structure a bit (the script that manage the settings have to be active before the UI is opened to actually take effect at game startup). Fixed several UI bugs (slider deselection, UI labels blocking the sliders, etc).

This commit is contained in:
2026-02-03 21:47:16 +02:00
parent 415484c1f0
commit ba1f0c855d
8 changed files with 439 additions and 297 deletions

View File

@@ -0,0 +1,112 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
abstract public class AbstractSlider : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public RectTransform sliderBackground; // Assign in Inspector
public float minValue = 0f;
public float maxValue = 1f;
public float slideareaOffsetMultiplier = 0.9f;
public float CurrentValue { get; private set; }
public float CurrentNormalizedValue { get; private set; }
private RectTransform handleRect;
private Vector2 backgroundStart;
private float backgroundWidth;
public System.Action<float, bool> OnValueChanged;
private void OnEnable()
{
if (null == handleRect)
{
handleRect = GetComponent<RectTransform>();
}
if (sliderBackground != null)
{
backgroundStart = sliderBackground.position;
backgroundWidth = sliderBackground.rect.width;
}
UpdateHandlePosition();
}
virtual public void OnBeginDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
virtual public void OnDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
virtual public void OnEndDrag(PointerEventData eventData)
{
UpdateSlider(eventData, true);
EventSystem.current.SetSelectedGameObject(null);
}
virtual public void SetHandleValue(float unnormalizedValue)
{
SetValuesFromValue(unnormalizedValue);
UpdateHandlePosition();
}
virtual public void SetHandleNormalizedValue(float normalizedValue)
{
SetValuesFromNormalizedValue(normalizedValue);
UpdateHandlePosition();
}
virtual protected void UpdateHandlePosition()
{
if (null == handleRect) return; // The options menu might not be opened yet
float halfWidth = sliderBackground.rect.width * 0.5f;
float limit = halfWidth * slideareaOffsetMultiplier;
float x = Mathf.Lerp(-limit, limit, CurrentNormalizedValue);
handleRect.localPosition = new Vector3(x, handleRect.localPosition.y, 0);
}
virtual protected void UpdateSlider(PointerEventData eventData, bool draggingEnded = false)
{
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(sliderBackground, eventData.position, eventData.pressEventCamera, out localPoint);
float halfWidth = sliderBackground.rect.width * 0.5f;
// Only allow dragging within 90% of the slider width, centered
float limit = halfWidth * slideareaOffsetMultiplier;
float clampedX = Mathf.Clamp(localPoint.x, -limit, limit);
Vector3 newPosition = new Vector3(clampedX, handleRect.localPosition.y, handleRect.localPosition.z);
handleRect.localPosition = newPosition;
// Normalize within the limited 90% range
float normalized = (clampedX + limit) / (limit * 2f);
SetValuesFromValue(Mathf.Lerp(minValue, maxValue, normalized));
OnValueChanged?.Invoke(CurrentValue, draggingEnded);
}
protected void SetValuesFromNormalizedValue(float normalizedValue)
{
CurrentNormalizedValue = normalizedValue;
CurrentValue = CurrentNormalizedValue * (maxValue - minValue) + minValue;
}
protected void SetValuesFromValue(float unnormalizedValue)
{
CurrentValue = unnormalizedValue;
CurrentNormalizedValue = (CurrentValue - minValue) / (maxValue - minValue);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8fe704cafb6cf2441a62a6497d58f229
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -4,87 +4,8 @@ using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
public class AudioSliderDragHandler : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
public class AudioSliderDragHandler : AbstractSlider, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public RectTransform sliderBackground; // Assign in Inspector
public float minValue = 0f;
public float maxValue = 1f;
public float slideareaOffsetMultiplier = 0.9f;
public float CurrentValue { get; private set; }
private RectTransform handleRect;
private Vector2 backgroundStart;
private float backgroundWidth;
public System.Action<float> OnValueChanged;
void Awake()
{
handleRect = GetComponent<RectTransform>();
if (sliderBackground != null)
{
backgroundStart = sliderBackground.position;
backgroundWidth = sliderBackground.rect.width;
}
}
public void OnBeginDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void SetHandlePosition(float normalizedValue)
{
float halfWidth = sliderBackground.rect.width * 0.5f;
float limit = halfWidth * slideareaOffsetMultiplier;
float x = Mathf.Lerp(-limit, limit, normalizedValue);
handleRect.localPosition = new Vector3(x, handleRect.localPosition.y, 0);
CurrentValue = normalizedValue;
}
public void OnDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
//notify FMOD
}
private void UpdateSlider(PointerEventData eventData)
{
//Debug.Log("UpDating Slider");
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(sliderBackground, eventData.position, eventData.pressEventCamera, out localPoint);
float halfWidth = sliderBackground.rect.width * 0.5f;
// Only allow dragging within 90% of the slider width, centered
float limit = halfWidth * slideareaOffsetMultiplier;
float clampedX = Mathf.Clamp(localPoint.x, -limit, limit);
Vector3 newPosition = new Vector3(clampedX, handleRect.localPosition.y, handleRect.localPosition.z);
handleRect.localPosition = newPosition;
// Normalize within the limited 90% range
float normalized = (clampedX + limit) / (limit * 2f);
//Debug.Log(normalized);
CurrentValue = Mathf.Lerp(minValue, maxValue, normalized);
//Debug.Log(warningThreshholdValue);
OnValueChanged?.Invoke(CurrentValue);
}
}

View File

@@ -9,6 +9,7 @@ public class ContinuoslocomotionConfigurator : MonoBehaviour
{
public Button turnOffButton;
public Button turnOnButton;
public MoveSliderDragHandler moveSpeedSlider;
public ContinuousMoveProviderBase locomotion;
// Events for listeners
@@ -19,13 +20,21 @@ public class ContinuoslocomotionConfigurator : MonoBehaviour
{
turnOnButton.onClick.AddListener(enableLocomotion);
turnOffButton.onClick.AddListener(disableLocomotion);
turnOffButton.gameObject.SetActive(false);
bool isContinuousLocomotion = ConfigManager.instance.GetIsContinuousLocomotion();
turnOffButton.gameObject.SetActive(isContinuousLocomotion);
locomotion.enabled = isContinuousLocomotion;
float continuousLocomotionSpeed = ConfigManager.instance.GetContinuousLocomotionSpeed();
moveSpeedSlider.SetHandleValue(continuousLocomotionSpeed);
locomotion.moveSpeed = continuousLocomotionSpeed;
}
public void UpdateSpeed(float speed)
{
locomotion.moveSpeed = speed;
OnSpeedChanged?.Invoke(speed);
WriteToConfig();
}
private void enableLocomotion()
@@ -35,6 +44,7 @@ public class ContinuoslocomotionConfigurator : MonoBehaviour
turnOnButton.gameObject.SetActive(false);
turnOffButton.gameObject.SetActive(true);
OnLocomotionToggled?.Invoke(true);
WriteToConfig();
}
private void disableLocomotion()
@@ -44,5 +54,12 @@ public class ContinuoslocomotionConfigurator : MonoBehaviour
turnOnButton.gameObject.SetActive(true);
turnOffButton.gameObject.SetActive(false);
OnLocomotionToggled?.Invoke(false);
WriteToConfig();
}
protected void WriteToConfig()
{
ConfigManager.instance.SetIsContinuousLocomotion(locomotion.enabled);
ConfigManager.instance.SetContinuousLocomotionSpeed(locomotion.moveSpeed);
}
}

View File

@@ -3,82 +3,35 @@ using UnityEngine.UI;
using UnityEngine.EventSystems;
using TMPro;
public class MoveSliderDragHandler : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
public class MoveSliderDragHandler : AbstractSlider, IDragHandler, IBeginDragHandler, IEndDragHandler
{
public RectTransform sliderBackground; // Assign in Inspector
public float minValue = 2f;
public float maxValue = 5f;
public float slideareaOffsetMultiplier = 0.9f;
public TMP_Text warningText;
public float warningThreshholdValue = 0.65f;
public float CurrentValue { get; private set; }
public ContinuoslocomotionConfigurator configurator;
private RectTransform handleRect;
private Vector2 backgroundStart;
private float backgroundWidth;
void Awake()
override public void OnEndDrag(PointerEventData eventData)
{
handleRect = GetComponent<RectTransform>();
if (sliderBackground != null)
{
backgroundStart = sliderBackground.position;
backgroundWidth = sliderBackground.rect.width;
}
}
public void OnBeginDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
base.OnEndDrag(eventData);
configurator.UpdateSpeed(CurrentValue);
EventSystem.current.SetSelectedGameObject(null);
}
private void UpdateSlider(PointerEventData eventData)
override protected void UpdateSlider(PointerEventData eventData, bool draggingEnded = false)
{
Debug.Log("UpDating Slider");
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(sliderBackground, eventData.position, eventData.pressEventCamera, out localPoint);
base.UpdateSlider(eventData, draggingEnded);
DisplayWarningTextIfNecessary();
}
float halfWidth = sliderBackground.rect.width * 0.5f;
override protected void UpdateHandlePosition()
{
base.UpdateHandlePosition();
DisplayWarningTextIfNecessary();
}
// Only allow dragging within 90% of the slider width, centered
float limit = halfWidth * slideareaOffsetMultiplier;
float clampedX = Mathf.Clamp(localPoint.x, -limit, limit);
Vector3 newPosition = new Vector3(clampedX, handleRect.localPosition.y, handleRect.localPosition.z);
handleRect.localPosition = newPosition;
// Normalize within the limited 90% range
float normalized = (clampedX + limit) / (limit * 2f);
//Debug.Log(normalized);
CurrentValue = Mathf.Lerp(minValue, maxValue, normalized);
// Displaying the warning.
if (CurrentValue > (warningThreshholdValue*(maxValue - minValue) + minValue)) warningText.gameObject.SetActive(true);
protected void DisplayWarningTextIfNecessary()
{
if (CurrentValue > (warningThreshholdValue * (maxValue - minValue) + minValue)) warningText.gameObject.SetActive(true);
else warningText.gameObject.SetActive(false);
//Debug.Log(warningThreshholdValue);
}
}

View File

@@ -13,76 +13,81 @@ public class SliderToVCA : MonoBehaviour
}
public VCATarget target;
private AudioSliderDragHandler slider;
public AudioSliderDragHandler slider;
private void Awake()
{
slider = GetComponent<AudioSliderDragHandler>();
slider.OnValueChanged += ApplyVolume;
}
private void Start()
{
float initialValue = GetInitialValueFromAudioManager();
slider.SetHandlePosition(initialValue); // we will add this function
}
private float GetInitialValueFromAudioManager()
{
switch (target)
{
case VCATarget.Master:
return AudioManager.Instance.MasterVolume;
case VCATarget.Ambiences:
return AudioManager.Instance.AmbienceVolume;
case VCATarget.Music:
return AudioManager.Instance.MusicVolume;
case VCATarget.SFX:
return AudioManager.Instance.SFXVolume;
case VCATarget.UI:
return AudioManager.Instance.UIVolume;
case VCATarget.Voiceovers:
return AudioManager.Instance.VoiceoverVolume;
default:
return 0.5f;
}
}
private void Update()
{
// Constantly push slider value to the VCA
ApplyVolume(slider.CurrentValue);
//Debug.Log("CurrentValue: " + slider.CurrentValue);
float initialValue = GetInitialValue();
slider.SetHandleValue(initialValue);
}
private void ApplyVolume(float value)
private float GetInitialValue()
{
switch (target)
{
case VCATarget.Master:
return ConfigManager.instance.getVolumeMaster();
case VCATarget.Ambiences:
return ConfigManager.instance.getVolumeAmbient();
case VCATarget.Music:
return ConfigManager.instance.getVolumeMusic();
case VCATarget.SFX:
return ConfigManager.instance.getVolumeSFX();
case VCATarget.UI:
return ConfigManager.instance.getVolumeUI();
case VCATarget.Voiceovers:
return ConfigManager.instance.getVolumeVO();
default:
return 0.5f;
}
}
private void Update()
{
// Constantly push slider value to the VCA
ApplyVolume(slider.CurrentValue, false);
//Debug.Log("CurrentValue: " + slider.CurrentValue);
}
private void ApplyVolume(float value, bool isLastChange)
{
switch (target)
{
case VCATarget.Master:
AudioManager.Instance.SetMasterVCA(value);
//Debug.LogError(value);
break;
if (isLastChange) ConfigManager.instance.SetVolumeMaster(value);
break;
case VCATarget.Ambiences:
AudioManager.Instance.SetAmbientVCA(value);
if (isLastChange) ConfigManager.instance.SetVolumeAmbient(value);
break;
case VCATarget.Music:
AudioManager.Instance.SetMusicVCA(value);
if (isLastChange) ConfigManager.instance.SetVolumeMusic(value);
break;
case VCATarget.SFX:
AudioManager.Instance.SetSFXVCA(value);
if (isLastChange) ConfigManager.instance.SetVolumeSFX(value);
break;
case VCATarget.UI:
AudioManager.Instance.SetUIVCA(value);
if (isLastChange) ConfigManager.instance.SetVolumeUI(value);
break;
case VCATarget.Voiceovers:
AudioManager.Instance.SetVoiceoverVCA(value);
if (isLastChange) ConfigManager.instance.SetVolumeVO(value);
break;
}
}
}