Files
adminandClaude Fable 5 270c42d85b Add host-configurable match settings persisted in settings
- GameSettings: 7 match fields (mode, hunter count, hide/seek/resolve
  durations, radar ping interval/lifetime) with authored defaults
- MatchSettingSlider (new): enum-driven panel binder, seeds from
  settings, saves on change; lifetime label shows one decimal
  (invariant culture)
- MatchManager: ApplyHostMatchSettings() on StartMatch (clamped);
  phase message now carries ping interval so clients tick correctly

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 22:04:54 +02:00

101 lines
3.7 KiB
C#

using System.Globalization;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
/// Binds a UI Slider (and optional value label) to one host-side match rule persisted via
/// GameSettings (Settings.json). The slider's range / whole-numbers are authored in the inspector;
/// this only reads/writes the value. The machine that starts the match applies the stored values
/// over the MatchManager's inspector defaults (MatchManager.ApplyHostMatchSettings).
public class MatchSettingSlider : MonoBehaviour
{
public enum Setting
{
Mode,
HunterCount,
HideDuration,
SeekDuration,
ResolveDuration,
RadarPingInterval,
RadarPingLifetime,
}
[Tooltip("Which persisted match setting this slider edits.")]
[SerializeField] private Setting setting;
[SerializeField] private Slider slider;
[Tooltip("Optional TMP label showing the current value (mode name / count / seconds).")]
[SerializeField] private TMP_Text valueLabel;
void OnEnable()
{
if (!slider) return;
float value = ReadSetting();
slider.SetValueWithoutNotify(value);
UpdateLabel(value);
slider.onValueChanged.AddListener(OnSliderChanged);
}
void OnDisable()
{
if (slider) slider.onValueChanged.RemoveListener(OnSliderChanged);
}
void OnSliderChanged(float value)
{
WriteSetting(value);
UpdateLabel(value);
}
private float ReadSetting()
{
switch (setting)
{
case Setting.Mode: return GameSettings.MatchModeIndex;
case Setting.HunterCount: return GameSettings.MatchHunterCount;
case Setting.HideDuration: return GameSettings.MatchHideDuration;
case Setting.SeekDuration: return GameSettings.MatchSeekDuration;
case Setting.ResolveDuration: return GameSettings.MatchResolveDuration;
case Setting.RadarPingInterval: return GameSettings.MatchRadarPingInterval;
case Setting.RadarPingLifetime: return GameSettings.MatchRadarPingLifetime;
default: return 0f;
}
}
private void WriteSetting(float value)
{
switch (setting)
{
case Setting.Mode: GameSettings.MatchModeIndex = Mathf.RoundToInt(value); break;
case Setting.HunterCount: GameSettings.MatchHunterCount = Mathf.RoundToInt(value); break;
case Setting.HideDuration: GameSettings.MatchHideDuration = value; break;
case Setting.SeekDuration: GameSettings.MatchSeekDuration = value; break;
case Setting.ResolveDuration: GameSettings.MatchResolveDuration = value; break;
case Setting.RadarPingInterval: GameSettings.MatchRadarPingInterval = value; break;
case Setting.RadarPingLifetime: GameSettings.MatchRadarPingLifetime = value; break;
}
}
private void UpdateLabel(float value)
{
if (!valueLabel) return;
switch (setting)
{
case Setting.Mode:
valueLabel.text = ((MatchManager.MatchMode)Mathf.RoundToInt(value)).ToString();
break;
case Setting.HunterCount:
valueLabel.text = Mathf.RoundToInt(value).ToString();
break;
case Setting.RadarPingInterval when value <= 0f:
valueLabel.text = "Off";
break;
case Setting.RadarPingLifetime:
valueLabel.text = $"{value.ToString("0.0", CultureInfo.InvariantCulture)} s";
break;
default:
valueLabel.text = $"{Mathf.RoundToInt(value)} s";
break;
}
}
}