Implement click combo system for melee class attacks

This commit is contained in:
Nico 2025-07-01 00:53:51 -07:00
parent ea1527f3b3
commit 0bc7bfcf99
3 changed files with 176 additions and 16 deletions

View File

@ -36,11 +36,14 @@ public class Player : MonoBehaviour {
private VfxHandlerBase VfxDashHandler; private VfxHandlerBase VfxDashHandler;
private Vector2 MoveDirection = Vector2.zero; private Vector2 MoveDirection = Vector2.zero;
private Directions FaceDir = Directions.Down; private Directions FaceDir = Directions.Down;
private bool isDashing; public bool IsJumping { get; private set; }
private Vector2 DriftDirection = Vector2.zero; public bool IsDashing { get; private set; }
public float DashTime { get; private set; }
public Vector2 DriftDirection { get; private set; } = Vector2.zero;
private float Drift = 0; private float Drift = 0;
private readonly int AnimMoveRight = Animator.StringToHash("Anim_Player_MoveRight"); private readonly int AnimMoveRight = Animator.StringToHash("Anim_Player_MoveRight");
@ -55,6 +58,7 @@ public class Player : MonoBehaviour {
void Awake() { void Awake() {
Builder = GetComponent<BuilderManager>(); Builder = GetComponent<BuilderManager>();
VfxDashHandler = new VfxHandlerBase(VfxDash, 5, 5); VfxDashHandler = new VfxHandlerBase(VfxDash, 5, 5);
FighterClass = new MeleeFighterClass(this); FighterClass = new MeleeFighterClass(this);
SetClass(1); SetClass(1);
@ -63,6 +67,7 @@ public class Player : MonoBehaviour {
private void Update() { private void Update() {
GatherInput(); GatherInput();
KeyPressActions(); KeyPressActions();
ActiveClass.Tick();
} }
private void GatherInput() { private void GatherInput() {
MoveDirection.x = Input.GetAxisRaw("Horizontal"); MoveDirection.x = Input.GetAxisRaw("Horizontal");
@ -82,13 +87,15 @@ public class Player : MonoBehaviour {
SetClass(3); SetClass(3);
} }
if (Input.GetMouseButtonDown(0)) ActiveClass.UseSkill1(); if (Input.GetMouseButtonDown(0)) ActiveClass.HandleLMB();
else if (Input.GetMouseButtonDown(1)) ActiveClass.HandleRMB();
} }
private void Dash(Vector2 direction) { private void Dash(Vector2 direction) {
if (SkillInUse) return; if (SkillInUse) return;
if (Drift > 0.5f) return; if (Drift > 0.5f) return;
isDashing = true; IsDashing = true;
DashTime = Time.time;
RigidBody.linearVelocity = direction.normalized * MoveSpeed * DashMultiplier; RigidBody.linearVelocity = direction.normalized * MoveSpeed * DashMultiplier;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg + 180; float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg + 180;
@ -96,7 +103,7 @@ public class Player : MonoBehaviour {
VfxDashHandler.PlayAll(this.transform.position, Quaternion.Euler(0f, 0f, angle)); VfxDashHandler.PlayAll(this.transform.position, Quaternion.Euler(0f, 0f, angle));
DriftDirection = direction.normalized; DriftDirection = direction.normalized;
Drift = DriftSpeed; Drift = DriftSpeed;
isDashing = false; IsDashing = false;
} }
private void SetClass(int classIdx) { private void SetClass(int classIdx) {
@ -126,7 +133,7 @@ public class Player : MonoBehaviour {
} }
private void MovementUpdate() { private void MovementUpdate() {
if (isDashing) return; if (IsDashing) return;
RigidBody.linearVelocity = MoveDirection.normalized * MoveSpeed; RigidBody.linearVelocity = MoveDirection.normalized * MoveSpeed;
if (Drift > 0.2f) { if (Drift > 0.2f) {

View File

@ -15,6 +15,7 @@ public class ClassBase {
protected Animator Animator; protected Animator Animator;
protected Player Player; protected Player Player;
protected float PlayerOriginalSpeed;
public ClassBase(Player player) { public ClassBase(Player player) {
Player = player; Player = player;
@ -26,5 +27,7 @@ public class ClassBase {
Animator = Player.Animator; Animator = Player.Animator;
} }
virtual public void UseSkill1() { } virtual public void Tick() { }
virtual public void HandleLMB() { }
virtual public void HandleRMB() { }
} }

View File

@ -10,17 +10,167 @@ public class MeleeFighterClass : ClassBase {
public MeleeFighterClass(Player player) : base(player) { } public MeleeFighterClass(Player player) : base(player) { }
private readonly int BladeVortex = Animator.StringToHash("BladeVortex"); private readonly int BladeVortex = Animator.StringToHash("BladeVortex");
private float BladeVortexSpeed = 0.4f; private float BladeVortexSpeed = 0.4f;
private float ComboResetTime;
private float LastComboTime;
private bool ChargingAnAttack;
private float ChargeValue;
private bool AllowBladeVortex;
override public void UseSkill1() {
Player.SkillInUse = true; private AttackState CurrentState;
Player.MoveSpeed *= BladeVortexSpeed; private enum AttackState {
Animator.CrossFade(BladeVortex, 0); None,
Player.StartCoroutine(StopVortexAfterDelay(1.5f)); PhaseCleave,
DrainEdge,
Shockwave,
BladeVortex,
BasicAttack1,
BasicAttack2,
BasicAttack3,
ChargeSurgeA,
ChargeSurgeB,
KineticSurgeA,
KineticSurgeB,
} }
private IEnumerator StopVortexAfterDelay(float delay) {
yield return new WaitForSeconds(delay); override public void Tick() {
Player.SkillInUse = false; float timeElapsed = Time.time - LastComboTime;
Player.MoveSpeed /= BladeVortexSpeed;
switch (CurrentState) {
case AttackState.None:
return;
case AttackState.BasicAttack1:
AllowBladeVortex = timeElapsed <= 0.1f;
break;
case AttackState.ChargeSurgeA:
ChargingAnAttack = Input.GetMouseButton(0);
ChargeValue = timeElapsed;
if (!ChargingAnAttack) ChangeState(AttackState.KineticSurgeA);
break;
case AttackState.ChargeSurgeB:
ChargingAnAttack = Input.GetMouseButton(1);
ChargeValue = timeElapsed;
if (!ChargingAnAttack) ChangeState(AttackState.KineticSurgeB);
break;
}
if (!ChargingAnAttack && timeElapsed > ComboResetTime) {
Player.MoveSpeed = PlayerOriginalSpeed;
ChangeState(AttackState.None);
Player.SkillInUse = false;
}
}
override public void HandleLMB() {
Player.SkillInUse = true;
switch (CurrentState) {
case AttackState.None:
PlayerOriginalSpeed = Player.MoveSpeed;
if ((Time.time - Player.DashTime) <= 0.1f)
ChangeState(AttackState.PhaseCleave, 1.5f);
else if (Player.IsJumping)
ChangeState(AttackState.Shockwave, 0, 1.5f);
else
ChangeState(AttackState.BasicAttack1);
break;
case AttackState.BasicAttack1:
ChangeState(AttackState.BasicAttack2);
break;
case AttackState.BasicAttack2:
ChangeState(AttackState.BasicAttack3);
break;
case AttackState.BasicAttack3:
ChangeState(AttackState.ChargeSurgeA);
break;
}
}
override public void HandleRMB() {
Player.SkillInUse = true;
switch (CurrentState) {
case AttackState.None:
PlayerOriginalSpeed = Player.MoveSpeed;
if (Player.IsDashing)
ChangeState(AttackState.None);
else if (Player.IsJumping)
ChangeState(AttackState.None);
else
ChangeState(AttackState.DrainEdge);
break;
case AttackState.BasicAttack1:
if (!AllowBladeVortex) return;
ChangeState(AttackState.BladeVortex, 0.4f, 1.5f);
break;
case AttackState.BasicAttack3:
ChangeState(AttackState.ChargeSurgeB);
break;
}
}
private void ChangeState(AttackState state, float decreasedSpeed = 0.2f, float resetTime = 0.3f) {
CurrentState = state;
ComboResetTime = resetTime;
LastComboTime = Time.time;
Player.MoveSpeed = (state == AttackState.None) ? PlayerOriginalSpeed : PlayerOriginalSpeed * decreasedSpeed;
Debug.Log(CurrentState.ToString());
switch (CurrentState) {
case AttackState.None:
if (Player.IsDashing) {
} else if (Player.IsJumping) {
} else {
}
break;
case AttackState.Shockwave:
break;
case AttackState.BladeVortex:
Animator.CrossFade(BladeVortex, 0);
break;
case AttackState.BasicAttack1:
break;
case AttackState.BasicAttack2:
break;
case AttackState.BasicAttack3:
break;
case AttackState.KineticSurgeA:
Debug.Log($"Charged Value: {ChargeValue}");
break;
case AttackState.KineticSurgeB:
Debug.Log($"Charged Value: {ChargeValue}");
break;
}
} }
} }