using System; using System.Collections; using System.Data; using System.Linq; using Unity.VisualScripting; using UnityEditor; using UnityEngine; [Serializable] public class PlayerJumpHandler { private Player Player; public Transform Transform; private Vector2 Position => Transform.position; [Header("FakeZ and Jump Attributes")] public float GroundFakeZ = 0; public float CurrentFakeZ = 0; public float Height = 2.5f; public float AirTime = 0.7f; public float FreeFallSpeedPerSec = 13.5f; public bool Active { get; set; } public bool Paused { get; set; } public bool IsFalling => TimeElapsedNormalized > 0.5; public bool IsFreeFalling => TimeElapsedNormalized > 1; public float LastJump { get; private set; } public float PauseTimeStamp { get; private set; } public float PauseTime { get; private set; } = 0; public float TimeElapsedNormalized => (Time.time - LastJump) / AirTime; public float TimeLeftNormalized => 1 - TimeElapsedNormalized; public bool IsNonBlocking => !Active || (Time.time - LastJump > 0.03f); private int JumpCount = 0; private float Yref = 0; [Header("Jump Curve Parameters")] public float a = 1.2f; public float b = 1.4f; public float c = 1; public PlayerJumpHandler(Player player) { Player = player; Transform = player.transform.Find("Visuals").Find("CharacterPos"); player.DoUpdate += SetHeight; } private void SetHeight() { if (!Active || Paused) return; if (!IsFreeFalling) { var shift = (TimeElapsedNormalized < 0.5) ? 0 : AirTime; var elapsed = Math.Abs(TimeElapsedNormalized * AirTime - shift) / (AirTime / 2); var min = Math.Min(elapsed, 1); var t = Math.Max(min, 0); var u = 1 - t; var h1 = 4 * u * u * u * t * a; var h2 = 4 * u * u * t * t * b; var h3 = 4 * u * t * t * t * c; var h4 = t * t * t * t; var h = (Height * (h1 + h2 + h3 + h4)) / JumpCount + GroundFakeZ + Yref; CurrentFakeZ = h; } else { Yref -= (TimeElapsedNormalized - 1) * FreeFallSpeedPerSec; if (Yref < 0) Yref = 0; CurrentFakeZ = Yref; } if (TimeLeftNormalized <= 0 && Yref == 0) Stop(); else SetTransformYPos(CurrentFakeZ); } public void Pause() { if (!Active) return; PauseTimeStamp = Time.time; Paused = true; } public void Unpause() { if (!Active) return; PauseTime = Time.time - PauseTimeStamp; LastJump = Time.time - (AirTime * TimeLeftNormalized); Paused = false; } public void Start() { if (JumpCount++ > 2) return; if (Player.SkillInUse) return; if (JumpCount > 1) { var pos = Player.transform.position; pos.y += Transform.localPosition.y - 0.7f; Player.VfxAirJumpPool.Get(pos); } Yref = Transform.localPosition.y; Active = true; LastJump = Time.time; PauseTime = 0; } public void Stop() { Active = false; JumpCount = 0; SetTransformYPos(0); } public void SetTransformYPos(float yPos) { var pos = Transform.localPosition; pos.y = Math.Max(yPos, 0); Transform.localPosition = pos; Yref = Math.Min(Yref, pos.y); } }