Hallucination system setup & implementation with the infinite staircase + Fake volumetric lights test
This commit is contained in:
@@ -1,42 +1,86 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unheimlich.Features.Dialogue.UI;
|
||||
|
||||
namespace Unheimlich.Features.Hallucination
|
||||
{
|
||||
// ─── Per-label override data ───────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Describes how a specific FloatingLabel should behave when a HallucinationEvent fires.
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class FloatingLabelOverride
|
||||
{
|
||||
[Tooltip("The FloatingLabel to override when this event fires.")]
|
||||
public FloatingLabel Target;
|
||||
|
||||
[Header("Shake Override")]
|
||||
[Tooltip("Absolute shake radius applied during the override (world units). 0 = no shake.")]
|
||||
[Min(0f)] public float ShakeRadius = 0.15f;
|
||||
[Tooltip("Shake speed during the override.")]
|
||||
[Min(0f)] public float ShakeSpeed = 3f;
|
||||
[Tooltip("Shake smoothness during the override.")]
|
||||
[Min(0f)] public float ShakeSmoothness = 4f;
|
||||
|
||||
[Header("Ghost Trail Override")]
|
||||
public bool GhostEnabled = true;
|
||||
[Range(0f, 1f)] public float GhostAlpha = 0.5f;
|
||||
|
||||
[Header("Duration")]
|
||||
[Tooltip("How long the override lasts (seconds) before reverting to the sanity baseline.")]
|
||||
[Min(0f)] public float Duration = 2f;
|
||||
}
|
||||
|
||||
// ─── ScriptableObject ──────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// ScriptableObject describing a discrete hallucination event.
|
||||
/// Configure in the inspector and pass to HallucinationManager.TriggerHallucinationEvent().
|
||||
///
|
||||
/// Ghost word spawn removed. Words live on FloatingLabel components in the scene.
|
||||
/// LabelOverrides targets specific labels with timed shake/ghost overrides.
|
||||
/// </summary>
|
||||
[CreateAssetMenu(fileName = "HallucinationEvent", menuName = "Unheimlich/Hallucination/Hallucination Event")]
|
||||
[CreateAssetMenu(
|
||||
fileName = "HallucinationEvent",
|
||||
menuName = "Unheimlich/Hallucination/Hallucination Event")]
|
||||
public class HallucinationEvent : ScriptableObject
|
||||
{
|
||||
[Header("Identity")]
|
||||
[Tooltip("Human-readable label for this event (used in logs and the inspector)")]
|
||||
[SerializeField] private string _label;
|
||||
|
||||
[Header("Ghost Word")]
|
||||
[Tooltip("Spawn a ghost word that moves toward the player")]
|
||||
[SerializeField] private bool _spawnGhostWord;
|
||||
|
||||
[Tooltip("Text displayed by the ghost word")]
|
||||
[SerializeField] private string _ghostWordText;
|
||||
|
||||
[Tooltip("World-space spawn position offset from the anchor point")]
|
||||
[SerializeField] private Vector3 _ghostWordSpawnOffset = new Vector3(0f, 1.5f, 2f);
|
||||
|
||||
[Tooltip("Duration before the ghost word disappears (seconds)")]
|
||||
[SerializeField] private float _ghostWordLifetime = 3f;
|
||||
|
||||
[Header("Sanity Cost")]
|
||||
[Tooltip("Sanity added to the player when this event fires (0 = no change)")]
|
||||
[SerializeField, Range(0f, 1f)] private float _sanityCost = 0f;
|
||||
|
||||
// ─── Public Accessors ──────────────────────────────────────────────────────
|
||||
[Header("Floating Label Overrides")]
|
||||
[Tooltip("One entry per FloatingLabel to affect when this event fires.")]
|
||||
[SerializeField] private List<FloatingLabelOverride> _labelOverrides = new();
|
||||
|
||||
public string Label => _label;
|
||||
public bool SpawnGhostWord => _spawnGhostWord;
|
||||
public string GhostWordText => _ghostWordText;
|
||||
public Vector3 GhostWordSpawnOffset => _ghostWordSpawnOffset;
|
||||
public float GhostWordLifetime => _ghostWordLifetime;
|
||||
public float SanityCost => _sanityCost;
|
||||
// ─── Public Accessors ──────────────────────────────────────────────────
|
||||
|
||||
public string Label => _label;
|
||||
public float SanityCost => _sanityCost;
|
||||
public IReadOnlyList<FloatingLabelOverride> LabelOverrides => _labelOverrides;
|
||||
|
||||
// ─── Internal ─────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Pushes all label overrides onto their target FloatingLabels.
|
||||
/// Called by HallucinationManager.TriggerHallucinationEvent().
|
||||
/// </summary>
|
||||
internal void ApplyLabelOverrides()
|
||||
{
|
||||
foreach (FloatingLabelOverride entry in _labelOverrides)
|
||||
{
|
||||
if (entry.Target == null) continue;
|
||||
|
||||
entry.Target.ApplyOverride(
|
||||
entry.ShakeRadius,
|
||||
entry.ShakeSpeed,
|
||||
entry.ShakeSmoothness,
|
||||
entry.GhostEnabled,
|
||||
entry.GhostAlpha,
|
||||
entry.Duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user