Files
AppleHillsProduction/docs/settings_readme.md
2025-10-21 12:37:57 +02:00

8.0 KiB
Raw Blame History

Apple Hills Settings System

Centralized, designer-friendly configuration using ScriptableObject assets, with runtime access via SettingsProvider (Addressables-backed) and editor/live-preview access via SettingsAccess. This page follows the style of other updated docs (TOC, inline code, code-first usage, case studies).

Table of Contents

What This Solves

  • Consistent, centralized configuration across gameplay systems.
  • Safe, designer-editable ScriptableObject assets with validation (OnValidate).
  • Simple, Addressables-based runtime loading and caching via SettingsProvider.
  • Editor-time overrides and scene gizmo feedback via SettingsAccess helpers.

Architecture at a Glance

  • Base: BaseSettings (ScriptableObject) — common parent for all settings. Implements optional OnValidate().
  • Access (runtime): SettingsProvider (singleton MonoBehaviour) — loads assets synchronously via Addressables at keys Settings/<TypeName> and caches them.
  • Access (editor/dev): SettingsAccess (static) — editor-friendly shim for reading selected values even when not in Play Mode, falling back to GameManager at runtime.
  • Contracts: SettingsInterfaces (IPlayerFollowerSettings, IInteractionSettings, IDivingMinigameSettings) used by systems to remain decoupled from concrete assets.
  • Editor tooling: AppleHills/Settings Editor — finds/creates assets under Assets/Settings and provides a tabbed UI.

Quick Start (Code-First)

Get Settings at Runtime

using AppleHills.Core.Settings;

var playerFollower = SettingsProvider.Instance.GetSettings<PlayerFollowerSettings>();
float speed = playerFollower.MoveSpeed;

Or fetch interaction settings once and reuse:

using AppleHills.Core.Settings;

private IInteractionSettings _interaction;

void Awake()
{
    _interaction = SettingsProvider.Instance.GetSettings<InteractionSettings>();
}

void UseIt()
{
    float stopDist = _interaction.PlayerStopDistance;
}

Use Editor-Time Values via SettingsAccess

For scene tools, gizmos, or editors that should reflect current settings outside Play Mode:

// Returns editor-sourced values in Edit Mode; GameManager-backed in Play Mode
float stopDist = AppleHills.SettingsAccess.GetPlayerStopDistance();
float directStop = AppleHills.SettingsAccess.GetPlayerStopDistanceDirectInteraction();
float puzzleRange = AppleHills.SettingsAccess.GetPuzzlePromptRange();

Access Example Fields

using AppleHills.Core.Settings;

var pf = SettingsProvider.Instance.GetSettings<PlayerFollowerSettings>();
// Player
float moveSpeed = pf.MoveSpeed;
float accel = pf.MaxAcceleration;
bool useRb = pf.UseRigidbody;
// Follower
float followDist = pf.FollowDistance;
float near = pf.ThresholdNear;

var inter = SettingsProvider.Instance.GetSettings<InteractionSettings>();
LayerMask interactMask = inter.InteractableLayerMask;
GameObject pickupPrefab = inter.BasePickupPrefab;
float promptRange = inter.DefaultPuzzlePromptRange;

Authoring in the Editor

Creating/Editing Settings Assets

  • Open via menu: AppleHills/Settings Editor.
  • The window discovers all assets of type BaseSettings and provides tabbed editing for:
    • PlayerFollowerSettings
    • InteractionSettings
    • DivingMinigameSettings
  • If an asset is missing, the tool auto-creates it under Assets/Settings/:
    • Assets/Settings/PlayerFollowerSettings.asset
    • Assets/Settings/InteractionSettings.asset
    • Assets/Settings/DivingMinigameSettings.asset
  • Click “Save All” to persist and refresh editor providers/gizmos.

Addressables Keys & Loading

At runtime, SettingsProvider synchronously loads settings via Addressables with keys:

  • Settings/PlayerFollowerSettings
  • Settings/InteractionSettings
  • Settings/DivingMinigameSettings

Ensure these assets are marked as Addressables with the exact keys above. The provider caches objects, so subsequent GetSettings<T>() calls are fast.

Available Settings Types

  • PlayerFollowerSettings (IPlayerFollowerSettings)
    • Player: MoveSpeed, MaxAcceleration, StopDistance, UseRigidbody, DefaultHoldMovementMode.
    • Follower: FollowDistance, ManualMoveSmooth, ThresholdFar, ThresholdNear, StopThreshold.
    • Backend: FollowUpdateInterval, FollowerSpeedMultiplier, HeldIconDisplayHeight.
  • InteractionSettings (IInteractionSettings)
    • Interactions: PlayerStopDistance, PlayerStopDistanceDirectInteraction, FollowerPickupDelay.
    • Input/Layering: InteractableLayerMask.
    • Prefabs: BasePickupPrefab, LevelSwitchMenuPrefab, DefaultPuzzleIndicatorPrefab.
    • Puzzle/UI: DefaultPuzzlePromptRange.
    • Items: CombinationRules, SlotItemConfigs plus helpers GetCombinationRule(...), GetSlotItemConfig(...).
  • DivingMinigameSettings (IDivingMinigameSettings)
    • Movement, spawning, scoring, surfacing, normalized movement, tile generation, obstacles, camera viewfinder settings, photo input mode (PhotoInputModes).

Case Studies

Tune Interaction Distances

using AppleHills.Core.Settings;

public class InteractDistanceExample
{
    private readonly IInteractionSettings _s = SettingsProvider.Instance.GetSettings<InteractionSettings>();
    public bool IsInRange(float dist) => dist <= _s.PlayerStopDistance;
}

Follower Handling & Movement

using AppleHills.Core.Settings;

public class FollowerMover
{
    private readonly IPlayerFollowerSettings _pf = SettingsProvider.Instance.GetSettings<PlayerFollowerSettings>();
    public float TargetSpeed(float error) => Mathf.Clamp(error * _pf.FollowerSpeedMultiplier, 0f, _pf.MoveSpeed);
}

Diving Minigame Tuning

using AppleHills.Core.Settings;

public class SpawnController
{
    private readonly IDivingMinigameSettings _m = SettingsProvider.Instance.GetSettings<DivingMinigameSettings>();
    public float NextCooldown(float baseCooldown) => Mathf.Clamp(baseCooldown + Random.Range(-_m.ObstacleSpawnIntervalVariation, _m.ObstacleSpawnIntervalVariation), 0.1f, 99);
}

Troubleshooting / FAQ

  • Settings return null at runtime:
    • Ensure assets are Addressable with keys Settings/<TypeName> and Addressables are initialized before first access.
  • Editor changes dont reflect in scene gizmos:
    • Click “Save All” in AppleHills/Settings Editor; the editor provider refresh call updates views.
  • Which API to use: SettingsProvider vs SettingsAccess?
    • Use SettingsProvider in runtime code. Use SettingsAccess in editor tools/gizmos or shared code that runs both in Edit and Play Modes.

Paths & Namespaces

  • Scripts: Assets/Scripts/Core/Settings/
    • BaseSettings.cs
    • SettingsInterfaces.cs
    • SettingsProvider.cs
    • PlayerFollowerSettings.cs
    • InteractionSettings.cs
    • DivingMinigameSettings.cs
  • Editor tooling: Assets/Editor/SettingsEditorWindow.cs
  • Editor-time facade: Assets/Scripts/Core/SettingsAccess.cs
  • Namespaces:
    • Runtime: AppleHills.Core.Settings
    • Editor window: AppleHills.Core.Settings.Editor
    • Facade: AppleHills

Change Log

  • v1.1: New page with TOC, code-first usage, authoring workflow, Addressables keys, case studies, troubleshooting, and paths.