MiniGames/Assets/Scripts/SkyWalker/Skywalker_GameManager.cs
2025-09-07 02:00:26 +05:00

298 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using DG.Tweening;
public enum DeathType { Normal, Laser, Spikes }
public class Skywalker_GameManager : MonoBehaviour
{
public static Skywalker_GameManager Instance;
[Header("UI References")]
public GameObject gameOverPanel;
[Header("Player Reference")]
public Skywalker_PlayerController player; // assign in inspector
[Header("Heaven Tween")]
public float heavenHeight = 4f; // ascent height
public float ascendDuration = 2.5f; // ascent time
public float fadeDelay = 2.0f; // wait before fade (23s)
public float fadeDuration = 0.5f; // fade to 1
[Header("Material (AllIn1SpriteShader)")]
public Material playerMaterial;
private bool isGameOver = false;
// AllIn1SpriteShader property IDs
static readonly int ID_FadeAmount = Shader.PropertyToID("_FadeAmount");
static readonly int ID_FadeBurnWidth = Shader.PropertyToID("_FadeBurnWidth");
static readonly int ID_GreyscaleBlend = Shader.PropertyToID("_GreyscaleBlend"); // <-- added
static readonly int ID_GhostBlend = Shader.PropertyToID("_GhostBlend"); // <-- added
// AllIn1SpriteShader keywords (kept; safe even if features are enabled on the asset)
const string KW_FADE = "FADE_ON";
const string KW_GREYSCALE = "GREYSCALE_ON";
const string KW_GHOST = "GHOST_ON";
const string KW_OVERLAY = "OVERLAY_ON";
const string KW_OVERLAYMULT = "OVERLAYMULT_ON";
// store original keyword states so we can restore on disable
bool origFade, origGrey, origGhost, origOverlay, origOverlayMult;
Sequence deathSeq;
// --- Blueberry Glow Pulse (AllIn1SpriteShader) ---
[Header("Blueberry Glow Pulse")]
public Material glowMaterial; // optional: defaults to playerMaterial if null
[Tooltip("Shader float property for glow intensity (AllIn1SpriteShader).")]
public string glowIntensityProp = "_Glow"; // <-- default corrected to _Glow
public float glowBase = 1.75f;
public float glowPeak = 7.75f;
public float glowPulseDuration = 0.6f; // total time (up + down)
private Sequence glowSeq;
private int _ID_GlowIntensity;
private string _lastGlowPropName;
static readonly int ID_OverlayBlend = Shader.PropertyToID("_OverlayBlend");
void Awake()
{
if (Instance == null) Instance = this;
else { Destroy(gameObject); return; }
if (gameOverPanel) gameOverPanel.SetActive(false);
if (!glowMaterial) glowMaterial = playerMaterial;
_ID_GlowIntensity = Shader.PropertyToID(glowIntensityProp);
_lastGlowPropName = glowIntensityProp;
CacheOriginalKeywordStates();
}
void CacheOriginalKeywordStates()
{
if (!playerMaterial) return;
origFade = playerMaterial.IsKeywordEnabled(KW_FADE);
origGrey = playerMaterial.IsKeywordEnabled(KW_GREYSCALE);
origGhost = playerMaterial.IsKeywordEnabled(KW_GHOST);
origOverlay = playerMaterial.IsKeywordEnabled(KW_OVERLAY);
origOverlayMult = playerMaterial.IsKeywordEnabled(KW_OVERLAYMULT);
}
// --- Public helpers to call from hazards / tests ---
public void KillBySpikes() => TriggerGameOver(DeathType.Spikes);
public void KillByLaser() => TriggerGameOver(DeathType.Laser);
public void KillNormal() => TriggerGameOver(DeathType.Normal);
[ContextMenu("TEST: Kill By Spikes")] void _TestKillSpikes() => KillBySpikes();
[ContextMenu("TEST: Kill By Laser")] void _TestKillLaser() => KillByLaser();
public void TriggerGameOver(DeathType type)
{
if (isGameOver || player == null) return;
isGameOver = true;
var col = player.GetComponent<Collider>();
var rb = player.GetComponent<Rigidbody>();
if (col) col.enabled = false;
switch (type)
{
case DeathType.Spikes:
PrepKinematic(rb);
DeathBySpikes();
break;
case DeathType.Laser:
PrepKinematic(rb);
DeathByLaser();
break;
default: // Normal
player.ForceJumpForGameOver();
if (rb) { rb.useGravity = true; rb.isKinematic = false; }
break;
}
GameoverInvoker(); // now 5 seconds
Debug.Log("GAME OVER!");
}
void PrepKinematic(Rigidbody rb)
{
if (!rb) return;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.useGravity = false;
rb.isKinematic = true;
}
public void PulseBlueberryGlow()
{
if (!glowMaterial) return;
// Refresh property ID if you change the prop name in the Inspector
if (_lastGlowPropName != glowIntensityProp || _ID_GlowIntensity == 0)
{
_ID_GlowIntensity = Shader.PropertyToID(glowIntensityProp);
_lastGlowPropName = glowIntensityProp;
}
// Kill previous pulse only (dont touch other tweens like fade)
if (glowSeq != null && glowSeq.IsActive()) glowSeq.Kill();
// Ensure starting at base
glowMaterial.SetFloat(_ID_GlowIntensity, glowBase);
float half = Mathf.Max(0.01f, glowPulseDuration * 0.5f);
glowSeq = DOTween.Sequence().SetId("BlueberryGlow")
.Append(glowMaterial.DOFloat(glowPeak, _ID_GlowIntensity, half).SetEase(Ease.OutQuad).SetId("BlueberryGlow"))
.Append(glowMaterial.DOFloat(glowBase, _ID_GlowIntensity, half).SetEase(Ease.InQuad).SetId("BlueberryGlow"));
glowSeq.Play();
}
// -------- Death styles --------
void DeathBySpikes()
{
player.animator.Play("Angel");
BeginHeavenSequence(laserStyle: false);
}
void DeathByLaser()
{
player.animator.Play("Angel");
BeginHeavenSequence(laserStyle: true);
}
public void GameoverInvoker(int duration = 5)
{
CancelInvoke(nameof(GameoverPanelEnabler));
Invoke(nameof(GameoverPanelEnabler), duration);
}
public void GameoverPanelEnabler()
{
if (gameOverPanel) gameOverPanel.SetActive(true);
}
// -------- Tweens + Shader toggles / values --------
void BeginHeavenSequence(bool laserStyle)
{
if (deathSeq != null && deathSeq.IsActive()) deathSeq.Kill();
if (playerMaterial) DOTween.Kill(playerMaterial);
if (playerMaterial)
{
playerMaterial.EnableKeyword(KW_FADE);
if (laserStyle)
{
// Laser: Overlay + Ghost, NO Greyscale
playerMaterial.DisableKeyword(KW_GREYSCALE);
playerMaterial.EnableKeyword(KW_OVERLAY);
playerMaterial.DisableKeyword(KW_OVERLAYMULT);
playerMaterial.EnableKeyword(KW_GHOST);
}
else
{
// Spikes: Greyscale + Ghost, NO Overlay (+ make sure OVERLAYMULT is OFF)
playerMaterial.EnableKeyword(KW_GREYSCALE);
playerMaterial.DisableKeyword(KW_OVERLAY);
playerMaterial.DisableKeyword(KW_OVERLAYMULT);
playerMaterial.EnableKeyword(KW_GHOST);
}
// Ensure visible before fade
playerMaterial.SetFloat(ID_FadeAmount, -0.1f);
if (!laserStyle) playerMaterial.SetFloat(ID_FadeBurnWidth, 0f);
// Start blends from zero so tweens are visible
playerMaterial.SetFloat(ID_GreyscaleBlend, 0f);
playerMaterial.SetFloat(ID_GhostBlend, 0f);
playerMaterial.SetFloat(ID_OverlayBlend, 0f);
}
Vector3 endPos = player.transform.position + Vector3.up * heavenHeight;
deathSeq = DOTween.Sequence();
if (laserStyle && playerMaterial)
{
// Start ALL laser visuals together:
// - BurnWidth widens (0.5s)
// - Ghost 0 -> 0.65 (0.35s)
// - Overlay 0 -> 1.0 (0.35s)
deathSeq.Append(playerMaterial.DOFloat(1f, ID_FadeBurnWidth, 0.5f)); // append first
deathSeq.Join(playerMaterial.DOFloat(0.65f, ID_GhostBlend, 0.35f).SetEase(Ease.OutQuad));
deathSeq.Join(playerMaterial.DOFloat(1.0f, ID_OverlayBlend, 0.35f).SetEase(Ease.OutQuad));
}
else if (playerMaterial)
{
// Spikes: Greyscale 0 -> 0.7, Ghost 0 -> 0.65 together
deathSeq.Join(playerMaterial.DOFloat(0.7f, ID_GreyscaleBlend, 0.35f).SetEase(Ease.OutQuad));
deathSeq.Join(playerMaterial.DOFloat(0.65f, ID_GhostBlend, 0.35f).SetEase(Ease.OutQuad));
}
// Float up like an angel
deathSeq.Append(player.transform.DOMoveY(endPos.y, ascendDuration).SetEase(Ease.OutSine));
// Wait before final fade
deathSeq.AppendInterval(fadeDelay);
// Final fade to 1
if (playerMaterial)
{
if (laserStyle)
{
// Laser: fade out AND shrink burn width back to 0 at the same time
deathSeq.Append(playerMaterial.DOFloat(1f, ID_FadeAmount, fadeDuration));
deathSeq.Join(playerMaterial.DOFloat(0f, ID_FadeBurnWidth, fadeDuration)); // <- new
}
else
{
// Spikes: just fade out
deathSeq.Append(playerMaterial.DOFloat(1f, ID_FadeAmount, fadeDuration));
}
}
deathSeq.Play();
}
// -------- Revert shader changes on disable --------
void OnDisable()
{
if (deathSeq != null && deathSeq.IsActive()) deathSeq.Kill();
DOTween.Kill(playerMaterial);
playerMaterial.SetFloat(ID_OverlayBlend, 0f);
if (playerMaterial)
{
// revert fade values
playerMaterial.SetFloat(ID_FadeAmount, 0f);
playerMaterial.SetFloat(ID_FadeBurnWidth, 0f);
// revert blends
playerMaterial.SetFloat(ID_GreyscaleBlend, 0f);
playerMaterial.SetFloat(ID_GhostBlend, 0f);
// restore original keywords
SetKeyword(playerMaterial, KW_FADE, origFade);
SetKeyword(playerMaterial, KW_GREYSCALE, origGrey);
SetKeyword(playerMaterial, KW_GHOST, origGhost);
SetKeyword(playerMaterial, KW_OVERLAY, origOverlay);
SetKeyword(playerMaterial, KW_OVERLAYMULT, origOverlayMult);
}
if (glowSeq != null && glowSeq.IsActive()) glowSeq.Kill();
DOTween.Kill("BlueberryGlow");
if (glowMaterial) glowMaterial.SetFloat(_ID_GlowIntensity, glowBase);
}
static void SetKeyword(Material m, string keyword, bool enabled)
{
if (!m) return;
if (enabled) m.EnableKeyword(keyword);
else m.DisableKeyword(keyword);
}
}