Hone jump and dash delays tied to attacking and to each other

This commit is contained in:
Nico 2025-07-06 23:32:18 -07:00
parent 7781d68924
commit a148b98016
3 changed files with 199 additions and 37 deletions

View File

@ -1,12 +1,18 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
[System.Serializable]
public class ClassBase {
[HideInInspector] public float TimeElapsed;
[HideInInspector] public int MaxHealth;
[HideInInspector] public int MaxMana;
[HideInInspector] public float AttackPower;
@ -20,6 +26,8 @@ public class ClassBase {
protected FloatingTextSpawner TextPopUp;
/// <summary>Always in the order of Up, Down, Left, Right</summary>
public string AnimationToPlay = "";
public Dictionary<int, ClassSkill> Skills = new Dictionary<int, ClassSkill>();
[SerializeField] private List<ClassSkill> AvailableSkills = new List<ClassSkill>();
public ClassBase(Player player) {
Player = player;
@ -28,7 +36,59 @@ public class ClassBase {
TextPopUp = new FloatingTextSpawner(player.transform);
}
virtual public void Tick() { }
public void GenerateAvailableSkillsList() {
AvailableSkills.AddRange(Skills.Values);
}
virtual public void Tick() {
TimeElapsed = Time.time;
ClassSkill.TimeElapsed = TimeElapsed;
AvailableSkills.ForEach((x) => x.UpdateCooldown());
foreach (var skill in Skills.Values) { skill.UpdateCooldown(); }
}
virtual public void HandlePrimaryAttack() { }
virtual public void HandleSecondaryAttack() { }
[Serializable]
public class ClassSkill {
public static float TimeElapsed;
public string Name { get; private set; }
public float CooldownTime { get; private set; }
public float CooldownTimeElapsed { get; private set; }
public float CooldownRef { get; private set; }
public int SkillCountMax { get; private set; }
public int SkillCount { get; private set; } = 0;
public bool IsPaused { get; set; }
public bool IsNotReady { get { return SkillCount == 0; } }
protected bool SkillCountMaxed { get { return SkillCount == SkillCountMax; } }
protected float CooldownLeftInRatio { get { return SkillCountMaxed ? 1 : (CooldownTimeElapsed / CooldownTime); } }
public ClassSkill(string skillName, float cooldownTime, int skillCount) {
Name = skillName;
CooldownTime = cooldownTime;
SkillCountMax = skillCount;
}
public bool IsReady(bool useSkill = true) {
if (SkillCount == 0) return false;
if (useSkill) {
if (SkillCountMaxed) CooldownRef = Time.time;
SkillCount--;
Debug.Log($"[{Name}] Using skill [{SkillCount}/{SkillCountMax}]");
}
return true;
}
public void UpdateCooldown() {
if (SkillCount == SkillCountMax) return;
CooldownTimeElapsed = TimeElapsed - CooldownRef;
if (CooldownTimeElapsed < CooldownTime) return;
SkillCount++;
CooldownRef = Time.time;
Debug.Log($"[{Name}] Updating skill count [{SkillCount}/{SkillCountMax}]");
}
}
}

View File

@ -1,4 +1,7 @@
using UnityEngine;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.VisualScripting;
using UnityEngine;
[System.Serializable]
public class MeleeFighterClass : ClassBase {
@ -10,16 +13,19 @@ public class MeleeFighterClass : ClassBase {
public float ChargeValue;
public bool AllowBladeVortex;
public int ChargeTick;
public float TimeElapsed;
public float ComboTimeElapsed;
public float Cooldown;
public bool TimesUp;
private bool HandlingOnStateEnter;
public VfxHandlerBase VfxKineticSurgeHandler { get { return Player.VfxKineticSurgeHandler; } }
public MeleeFighterClass(Player player) : base(player) {
Skills.Add((int)AttackState.PhaseCleave, new ClassSkill("PhaseCleave", 2f, 3));
Skills.Add((int)AttackState.BladeVortex, new ClassSkill("BladeVortex", 2f, 3));
Skills.Add((int)AttackState.Shockwave, new ClassSkill("Shockwave", 2f, 3));
GenerateAvailableSkillsList();
}
@ -43,8 +49,10 @@ public class MeleeFighterClass : ClassBase {
override public void Tick() {
TimeElapsed = Time.time - LastComboTime;
TimesUp = TimeElapsed > ComboResetTime;
base.Tick();
ComboTimeElapsed = Time.time - LastComboTime;
TimesUp = ComboTimeElapsed > ComboResetTime;
switch (CurrentState) {
case AttackState.None:
@ -52,7 +60,7 @@ public class MeleeFighterClass : ClassBase {
return;
case AttackState.BasicAttack1:
AllowBladeVortex = TimeElapsed <= 0.1f;
AllowBladeVortex = ComboTimeElapsed <= 0.1f;
break;
@ -70,7 +78,7 @@ public class MeleeFighterClass : ClassBase {
// break;
}
if (CurrentState == AttackState.BasicAttack3 && TimeElapsed > 0.1) {
if (CurrentState == AttackState.BasicAttack3 && ComboTimeElapsed > 0.1) {
ChangeState(AttackState.KineticSurgeRelease);
AttackAnimator.MeleeResetKineticCharge();
AttackAnimator.MeleeKineticSurge();
@ -80,7 +88,7 @@ public class MeleeFighterClass : ClassBase {
//Player.MoveSpeed = PlayerOriginalSpeed;
}
if (!ChargingAnAttack && TimesUp) {
if (!ChargingAnAttack && TimesUp || Player.IsJumping) {
Player.MoveSpeedDampener = 1;
ChangeState(AttackState.None);
AttackAnimator.MeleeResetKineticCharge();
@ -118,9 +126,10 @@ public class MeleeFighterClass : ClassBase {
if ((Time.time - Player.DashTime) <= 0.1f)
ChangeState(AttackState.PhaseCleave, 1.5f);
else if (Player.IsJumping)
else if (Player.IsJumping) {
if (Player.ActionAfterJumpReady)
ChangeState(AttackState.Shockwave, 0);
else
} else
ChangeState(AttackState.BasicAttack1, 0.35f);
break;
@ -158,6 +167,10 @@ public class MeleeFighterClass : ClassBase {
case AttackState.BasicAttack1:
if (!AllowBladeVortex) return;
if (!Skills[(int)AttackState.BladeVortex].IsReady()) {
ChangeState(AttackState.None);
return;
}
Cooldown = 0;
ChangeState(AttackState.BladeVortex, 0.4f, 1.5f);
break;
@ -182,7 +195,7 @@ public class MeleeFighterClass : ClassBase {
float resetTime = 0.3f,
float cooldown = 0.05f) {
if (TimeElapsed < Cooldown) return;
if (ComboTimeElapsed < Cooldown) return;
CurrentState = state;
Player.MoveSpeedDampener = (state == AttackState.None) ? 1 : 1 / decreasedSpeed;
if (state == AttackState.None) return;
@ -232,6 +245,7 @@ public class MeleeFighterClass : ClassBase {
}
}
public void RotateTowardsMouse() {
return;
Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

View File

@ -2,6 +2,7 @@ using System.Collections;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[SelectionBase]
@ -10,7 +11,7 @@ public class Player : MonoBehaviour {
[SerializeField] public BuilderManager Builder;
[Header("Movement")]
[SerializeField] private Rigidbody2D RigidBody;
[SerializeField] private Rigidbody2D Rigidbody;
[SerializeField] public Animator Animator;
[SerializeField] private SpriteRenderer Renderer;
@ -24,9 +25,14 @@ public class Player : MonoBehaviour {
[Header("Movement Attributes")]
[SerializeField] public float MoveSpeed = 8;
[SerializeField] public float MoveSpeedDampener = 1;
[SerializeField] private float DashMultiplier = 60;
[SerializeField] private float DriftSpeed = 60;
[SerializeField] private float DriftFactorial = 0.85f;
[SerializeField] private float DashSpeedInitial = 200;
[SerializeField] private float DashSpeed = 0;
[SerializeField] private float DashDecayRate = 30;
[SerializeField] private float DashDelay1 = 0.05f;
[SerializeField] private float DashDelay2 = 0.05f;
[SerializeField] private float DashCooldown = 0.1f;
//[SerializeField] private float DriftSpeed = 60;
//[SerializeField] private float DriftFactorial = 0.85f;
[SerializeField] private float JumpDelay = 0.3f;
[Header("VFX")]
@ -42,11 +48,21 @@ public class Player : MonoBehaviour {
public Vector2 PrevDirection = Vector2.zero;
private Vector2 MoveDirection = Vector2.zero;
private Vector2 DashDirection = Vector2.zero;
private Directions FaceDir = Directions.Down;
public bool IsJumping { get; set; }
public float LastJumpTime { get; private set; }
public Coroutine CoroutineJumpReset { get; private set; }
public bool ActionAfterJumpReady {
get {
return (!IsJumping || (Time.time - LastJumpTime > 0.07f));
}
}
public bool IsDashing { get; private set; }
public float DashTime { get; private set; }
public bool CanDash { get; private set; } = true;
public Vector2 DriftDirection { get; private set; } = Vector2.zero;
private float Drift = 0;
@ -65,8 +81,8 @@ public class Player : MonoBehaviour {
}
private void Update() {
GatherInput();
KeyPressActions();
GatherInput();
ActiveClass.Tick();
}
@ -77,7 +93,7 @@ public class Player : MonoBehaviour {
private void KeyPressActions() {
if (Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.RightShift)) {
Dash(MoveDirection);
DoDash();
} else if (!IsJumping && Input.GetKeyDown(KeyCode.Space)) {
Jump();
} else if (Input.GetKeyDown(KeyCode.F1)) {
@ -95,25 +111,77 @@ public class Player : MonoBehaviour {
else if (Input.GetKeyDown(KeyCode.C)) ActiveClass.HandleSecondaryAttack();
}
private void DoDash() {
if (!CanDash) return;
if (!ActionAfterJumpReady) return;
CanDash = false;
IsDashing = true;
DashDirection = MoveDirection.normalized;
DashSpeed = DashSpeedInitial;
//StartCoroutine(DoDash(MoveDirection));
}
private void Dash(Vector2 direction) {
if (Drift > 0.5f) return;
if (direction == Vector2.zero) return;
//if (Drift > 0.5f) return;
if (!ActionAfterJumpReady) return;
IsDashing = true;
DashTime = Time.time;
RigidBody.linearVelocity = (direction.normalized * MoveSpeed * DashMultiplier) / MoveSpeedDampener;
//Rigidbody.linearVelocity = direction.normalized * speed;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg + 180;
if (direction.normalized != Vector2.zero)
VfxDashHandler.PlayAll(this.transform.position, Quaternion.Euler(0f, 0f, angle));
DriftDirection = direction.normalized;
Drift = DriftSpeed;
//Drift = speed;
//Rigidbody.AddForce(direction * speed, ForceMode2D.Impulse);
//Rigidbody.AddForce(direction.normalized * speed, ForceMode.Acceleration);
IsDashing = false;
}
IEnumerator DoDash(Vector2 direction) {
var startTime = Time.time;
var speed = MoveSpeed * DashSpeedInitial / MoveSpeedDampener;
//if (IsJumping) speed /= 2;
Rigidbody.linearVelocity = Vector2.zero;
//Rigidbody.AddForce(direction * speed, ForceMode2D.Impulse);
var mag = (direction.normalized * speed).magnitude;
Rigidbody.linearVelocity = direction.normalized * speed;
var isJumping = IsJumping;
if (isJumping) Jump();
while ((Time.time - startTime) < DashDelay1)
yield return null;
//yield return new WaitForSeconds(DashDelay1);
Rigidbody.linearVelocity = Vector2.zero;
var endTime = Time.time;
Debug.Log($"[{Mathf.Abs(mag):0.00}] Time elapsed {(endTime - startTime):0.000}");
yield return new WaitForSeconds(DashDelay2);
IsDashing = false;
yield return new WaitForSeconds(DashCooldown);
while (IsJumping)
yield return null;
CanDash = true;
}
private void Jump() {
if (SkillInUse) return;
IsJumping = true;
LastJumpTime = Time.time;
foreach (var col in BoxColliders)
col.enabled = false;
StartCoroutine(ResetJumpAfterDelay());
if (CoroutineJumpReset != null)
StopCoroutine(CoroutineJumpReset);
CoroutineJumpReset = StartCoroutine(ResetJumpAfterDelay());
//Rigidbody.AddForce(MoveDirection.normalized * MoveSpeed / 2, ForceMode2D.Force);
MoveSpeedDampener = 2;
}
private IEnumerator ResetJumpAfterDelay() {
@ -121,6 +189,7 @@ public class Player : MonoBehaviour {
foreach (var col in BoxColliders)
col.enabled = true;
IsJumping = false;
MoveSpeedDampener = 1;
}
private void SetClass(int classIdx) {
@ -143,6 +212,13 @@ public class Player : MonoBehaviour {
private void FixedUpdate() {
MovementUpdate();
CalculateFacingDirection();
@ -150,16 +226,28 @@ public class Player : MonoBehaviour {
}
private void MovementUpdate() {
if (IsDashing) return;
RigidBody.linearVelocity = (MoveDirection.normalized * MoveSpeed) / MoveSpeedDampener;
if (Drift > 0.2f) {
RigidBody.linearVelocity += DriftDirection * Drift;
Drift *= DriftFactorial;
//if (IsJumping && !IsDashing) {
// Rigidbody.AddForce(MoveDirection.normalized * MoveSpeed / 5, ForceMode2D.Force);
// return;
//}
var movement = (MoveDirection.normalized * MoveSpeed) / MoveSpeedDampener;
//var movement = MoveDirection.normalized * MoveSpeed;
if (IsDashing) {
if (DashSpeed < 0.2f) {
DashSpeed = 0;
CanDash = true;
IsDashing = false;
} else if (DashSpeed > (movement.magnitude * 2)) {
if (IsJumping) Jump();
movement = DashDirection * DashSpeed;
DashSpeed *= Mathf.Exp(-DashDecayRate * Time.deltaTime);
} else {
Drift = 0f;
movement = ((DashDirection * DashSpeed) + movement) / 2;
DashSpeed *= Mathf.Exp(-DashDecayRate * Time.deltaTime);
}
}
Rigidbody.linearVelocity = movement;
}
private void CalculateFacingDirection() {
@ -201,13 +289,13 @@ public class Player : MonoBehaviour {
}
private void DrawPlayerDirection() {
if (RigidBody == null) RigidBody = GetComponent<Rigidbody2D>();
if (RigidBody == null) return;
if (Rigidbody == null) Rigidbody = GetComponent<Rigidbody2D>();
if (Rigidbody == null) return;
Gizmos.color = Color.cyan;
Vector3 start = RigidBody.transform.position;
Vector3 end = start + (Vector3)(RigidBody.linearVelocity * 1);
Vector3 start = Rigidbody.transform.position;
Vector3 end = start + (Vector3)(Rigidbody.linearVelocity * 1);
Gizmos.DrawLine(start, end);
DrawArrowHead(end, (end - start).normalized);