Move settings to Settings.json and add master volume
Replace the former per-value PlayerPrefs storage with a shared human-readable Settings.json store (GameSettings). MouseSensitivity keeps its public .Multiplier API and only swaps its backing to the JSON store, so the camera controllers stay untouched. Add a MasterVolume facade that drives the AudioMixer's exposed "MasterVolume" parameter (loaded from Resources, linear<->dB mapping), applied at startup and on change, plus a MasterVolumeSlider binder. The default is the level currently authored on the mixer instead of an arbitrary constant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
f586ef7a15
commit
ba7f3c2e89
9 files changed
+290
-27
No files matched your search
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
/// Shared JSON-backed store for the player-facing game settings, written human-readable
|
||||
/// to <persistentDataPath>/Settings.json. Replaces the former per-value PlayerPrefs storage.
|
||||
/// Loaded lazily on first access and cached in memory (reads are plain field access, so the
|
||||
/// per-frame Multiplier reads from the camera controllers never touch the disk). Each change is
|
||||
/// written immediately (settings edits are rare user actions), so a hard-killed build keeps them.
|
||||
///
|
||||
/// The typed domain facades (MouseSensitivity, MasterVolume) own the ranges/clamping and read/write
|
||||
/// through here; this class stays domain-agnostic and only persists the raw values.
|
||||
public static class GameSettings
|
||||
{
|
||||
private const string FileName = "Settings.json";
|
||||
private const int FileVersion = 1;
|
||||
|
||||
[Serializable]
|
||||
private class Data
|
||||
{
|
||||
public int version = FileVersion;
|
||||
public float mouseSensitivity = global::MouseSensitivity.Default;
|
||||
public float masterVolume = global::MasterVolume.Default;
|
||||
}
|
||||
|
||||
private static Data _data;
|
||||
private static Data Store => _data ??= Load();
|
||||
|
||||
private static string SavePath() => Path.Combine(Application.persistentDataPath, FileName);
|
||||
|
||||
public static float MouseSensitivity
|
||||
{
|
||||
get => Store.mouseSensitivity;
|
||||
set
|
||||
{
|
||||
if (Mathf.Approximately(Store.mouseSensitivity, value)) return;
|
||||
Store.mouseSensitivity = value;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
public static float MasterVolume
|
||||
{
|
||||
get => Store.masterVolume;
|
||||
set
|
||||
{
|
||||
if (Mathf.Approximately(Store.masterVolume, value)) return;
|
||||
Store.masterVolume = value;
|
||||
Save();
|
||||
}
|
||||
}
|
||||
|
||||
private static Data Load()
|
||||
{
|
||||
string path = SavePath();
|
||||
if (File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = JsonUtility.FromJson<Data>(File.ReadAllText(path));
|
||||
if (data != null) return data;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning($"[GameSettings] Loading {FileName} failed, using defaults: {e.Message}");
|
||||
}
|
||||
}
|
||||
return new Data();
|
||||
}
|
||||
|
||||
private static void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Application.persistentDataPath);
|
||||
File.WriteAllText(SavePath(), JsonUtility.ToJson(Store, true));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogWarning($"[GameSettings] Saving {FileName} failed: {e.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user