MiniGames/Assets/Scripts/SkyWalker/Skywalker_GameManager.cs
2025-09-06 23:30:06 +05:00

269 lines
9.0 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");
// AllIn1SpriteShader keywords
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"; // we'll keep this OFF unless you want multiply overlay
// 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 = "_GlowIntensity"; // change to your exact prop name if different
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;
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 --------
void BeginHeavenSequence(bool laserStyle)
{
if (deathSeq != null && deathSeq.IsActive()) deathSeq.Kill();
if (playerMaterial) DOTween.Kill(playerMaterial);
// Enable FADE keyword for both styles
if (playerMaterial)
{
playerMaterial.EnableKeyword(KW_FADE);
// Style-specific keywords
if (laserStyle)
{
// Laser: Overlay + Ghost, NO Greyscale
playerMaterial.DisableKeyword(KW_GREYSCALE);
playerMaterial.EnableKeyword(KW_OVERLAY);
playerMaterial.DisableKeyword(KW_OVERLAYMULT); // keep overlay in normal blend; enable if you prefer multiply
playerMaterial.EnableKeyword(KW_GHOST);
}
else
{
// Spikes: Greyscale + Ghost, NO Overlay
playerMaterial.EnableKeyword(KW_GREYSCALE);
playerMaterial.DisableKeyword(KW_OVERLAY);
playerMaterial.DisableKeyword(KW_OVERLAYMULT);
playerMaterial.EnableKeyword(KW_GHOST);
}
// Make sure we start visible before fade
playerMaterial.SetFloat(ID_FadeAmount, -0.1f);
if (!laserStyle) playerMaterial.SetFloat(ID_FadeBurnWidth, 0f);
}
Vector3 endPos = player.transform.position + Vector3.up * heavenHeight;
deathSeq = DOTween.Sequence();
if (laserStyle && playerMaterial)
{
// Laser: widen burn first
deathSeq.Append(playerMaterial.DOFloat(1f, ID_FadeBurnWidth, 0.5f));
}
// 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)
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);
if (playerMaterial)
{
// revert fade values
playerMaterial.SetFloat(ID_FadeAmount, 0f);
playerMaterial.SetFloat(ID_FadeBurnWidth, 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);
}
}