Files
chameleon/Assets/Scripts/Helper/GameSettings.cs
T
adminandClaude Fable 5 0e7ce0c410 Add player names: settings persistence, replication, screen-space nameplates
- GameSettings: playerName field persisted in Settings.json
- NetworkPlayerSetup: owner-written DisplayName NetworkVariable
  (seeded from settings on spawn, sanitized/truncated, live rename push)
- PlayerNameField: binds the session panel name input to settings
- PlayerNameplates: screen-space overlay labels above players with
  distance-based font scaling (clamped min/max), pooling, FP self-hide

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 14:58:15 +02:00

94 lines
2.7 KiB
C#

using System;
using System.IO;
using UnityEngine;
/// Shared JSON-backed store for player-facing game settings (<persistentDataPath>/Settings.json).
/// Loaded lazily and cached in memory, so per-frame reads never touch the disk; each change is
/// written immediately (settings edits are rare), so a hard-killed build keeps them. The typed
/// facades (MouseSensitivity, MasterVolume) own the ranges/clamping; this class only persists 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;
public string playerName = "";
}
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();
}
}
/// <summary>Display name shown above the avatar. Empty = per-spawn fallback ("Player &lt;clientId&gt;").</summary>
public static string PlayerName
{
get => Store.playerName ?? "";
set
{
string v = value == null ? "" : value.Trim();
if (Store.playerName == v) return;
Store.playerName = v;
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}");
}
}
}