Implement basics of enemy's attack states

This commit is contained in:
Nico 2025-07-25 01:05:46 -07:00
parent ba13eb9e51
commit d0349c8d99
5 changed files with 198 additions and 39 deletions

View File

@ -354,7 +354,7 @@ NavMeshAgent:
m_Enabled: 1 m_Enabled: 1
m_AgentTypeID: 0 m_AgentTypeID: 0
m_Radius: 0.5 m_Radius: 0.5
m_Speed: 3.5 m_Speed: 2.5
m_Acceleration: 30 m_Acceleration: 30
avoidancePriority: 50 avoidancePriority: 50
m_AngularSpeed: 120 m_AngularSpeed: 120

View File

@ -195493,6 +195493,11 @@ Tilemap:
e31: 0 e31: 0
e32: 0 e32: 0
e33: 1 e33: 1
--- !u!4 &931976748 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 7536677720423648120, guid: d00d92ab204198c489965b31a298b234, type: 3}
m_PrefabInstance: {fileID: 2316236105731553357}
m_PrefabAsset: {fileID: 0}
--- !u!1 &972432121 --- !u!1 &972432121
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -200846,6 +200851,75 @@ Transform:
m_Children: [] m_Children: []
m_Father: {fileID: 267352325} m_Father: {fileID: 267352325}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1314549305
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1314549306}
- component: {fileID: 1314549307}
m_Layer: 0
m_Name: HurtBox
m_TagString: SuperSpecialGem
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &1314549306
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1314549305}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 1341160148}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!70 &1314549307
CapsuleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1314549305}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 1
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0.003704071, y: 0.8854513}
m_Size: {x: 0.9819565, y: 1.7847328}
m_Direction: 0
--- !u!1 &1320165402 --- !u!1 &1320165402
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -200970,7 +201044,7 @@ GameObject:
- component: {fileID: 1341160151} - component: {fileID: 1341160151}
m_Layer: 0 m_Layer: 0
m_Name: SuperSpecialGem m_Name: SuperSpecialGem
m_TagString: Untagged m_TagString: SuperSpecialGem
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
@ -200991,6 +201065,7 @@ Transform:
- {fileID: 972432122} - {fileID: 972432122}
- {fileID: 1273554248} - {fileID: 1273554248}
- {fileID: 399472911} - {fileID: 399472911}
- {fileID: 1314549306}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!50 &1341160149 --- !u!50 &1341160149
@ -201027,7 +201102,7 @@ CapsuleCollider2D:
m_PrefabInstance: {fileID: 0} m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1341160147} m_GameObject: {fileID: 1341160147}
m_Enabled: 1 m_Enabled: 0
serializedVersion: 3 serializedVersion: 3
m_Density: 1 m_Density: 1
m_Material: {fileID: 0} m_Material: {fileID: 0}
@ -202257,6 +202332,75 @@ CanvasRenderer:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2031312102} m_GameObject: {fileID: 2031312102}
m_CullTransparentMesh: 1 m_CullTransparentMesh: 1
--- !u!1 &2059963722
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2059963723}
- component: {fileID: 2059963724}
m_Layer: 9
m_Name: Hurtbox
m_TagString: PlayerHurtBox
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2059963723
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2059963722}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 931976748}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!70 &2059963724
CapsuleCollider2D:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2059963722}
m_Enabled: 1
serializedVersion: 3
m_Density: 1
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_ForceSendLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ForceReceiveLayers:
serializedVersion: 2
m_Bits: 4294967295
m_ContactCaptureLayers:
serializedVersion: 2
m_Bits: 4294967295
m_CallbackLayers:
serializedVersion: 2
m_Bits: 4294967295
m_IsTrigger: 1
m_UsedByEffector: 0
m_CompositeOperation: 0
m_CompositeOrder: 0
m_Offset: {x: 0, y: -0.07961166}
m_Size: {x: 1.0406871, y: 2.3430235}
m_Direction: 0
--- !u!1 &2076322255 --- !u!1 &2076322255
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@ -202410,7 +202554,10 @@ PrefabInstance:
objectReference: {fileID: 0} objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: [] m_AddedGameObjects:
- targetCorrespondingSourceObject: {fileID: 7536677720423648120, guid: d00d92ab204198c489965b31a298b234, type: 3}
insertIndex: -1
addedObject: {fileID: 2059963723}
m_AddedComponents: [] m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: d00d92ab204198c489965b31a298b234, type: 3} m_SourcePrefab: {fileID: 100100000, guid: d00d92ab204198c489965b31a298b234, type: 3}
--- !u!1001 &3495966144891276242 --- !u!1001 &3495966144891276242

View File

@ -13,7 +13,7 @@ public class Gobler : Alive {
[Header("Mechanics Attributes")] [Header("Mechanics Attributes")]
[SerializeField] public float ChaseDistance = 10f; [SerializeField] public float ChaseDistance = 10f;
[SerializeField] public float ChaseDistanceBuffer = 1f; [SerializeField] public float ChaseDistanceBuffer = 1f;
[SerializeField] public float AttackDistance = 1f; [SerializeField] public float AttackDistance = 1.5f;
[SerializeField] public float AttackMaskDiameter = 1f; [SerializeField] public float AttackMaskDiameter = 1f;
@ -107,7 +107,8 @@ public class Gobler : Alive {
protected void SetPriorityState() { protected void SetPriorityState() {
if (CurrentState == State.AttackPlayer) return; if (CurrentState == State.PrepareAttack) return;
if (CurrentState == State.FinalizeAttack) return;
if (CurrentState == State.ChasePlayer) return; if (CurrentState == State.ChasePlayer) return;
if (CurrentState == State.TakeDamage) return; if (CurrentState == State.TakeDamage) return;
if (CurrentState == State.Die) return; if (CurrentState == State.Die) return;
@ -133,8 +134,8 @@ public class Gobler : Alive {
case State.GoToCrystal: case State.GoToCrystal:
PathAgent.SetDestination(CrystalPos); if (DistFromCrystal <= AttackDistance)
SetState(State.PrepareAttack);
break; break;
@ -143,9 +144,9 @@ public class Gobler : Alive {
case State.ChasePlayer: case State.ChasePlayer:
if (DistFromPlayer > ChaseDistance + ChaseDistanceBuffer) if (DistFromPlayer <= AttackDistance)
SetState(State.GoToCrystal); SetState(State.PrepareAttack);
if (DistFromPlayer > ChaseDistance + ChaseDistanceBuffer) else if (DistFromPlayer > ChaseDistance + ChaseDistanceBuffer)
SetState(State.GoToCrystal); SetState(State.GoToCrystal);
else else
PathAgent.SetDestination(PlayerPos); PathAgent.SetDestination(PlayerPos);
@ -158,28 +159,20 @@ public class Gobler : Alive {
case State.TakeDamage: case State.TakeDamage:
if (IsInvincible) {
Rigidbody.linearVelocity = DirectionOfDamage * Knockback * 10 * InvincibilityLeft; Rigidbody.linearVelocity = DirectionOfDamage * Knockback * 10 * InvincibilityLeft;
MaterialColorOverlay.SetFloat("_FlashAmount", InvincibilityLeft); MaterialColorOverlay.SetFloat("_FlashAmount", InvincibilityLeft);
if (!IsInvincible) SetState(State.None); }
if (!IsFrameFrozen) SetState(State.None);
break; break;
case State.PrepareAttack: case State.PrepareAttack:
MaterialColorOverlay.SetFloat("_FlashColor", 1 - InvincibilityLeft); MaterialColorOverlay.SetFloat("_FlashAmount", 1 - FrameFreezeLeft);
if (!IsInvincible) SetState(State.FinalizeAttack); if (!IsFrameFrozen) SetState(State.FinalizeAttack);
break; break;
case State.FinalizeAttack:
Collider2D[] hits = Physics2D.OverlapCircleAll(MyPos + Vector2.down, 4);
foreach (var hit in hits) {
if (!hit.CompareTag("PlayerHurtBox")) continue;
//GameObject parent = hit.transform.parent?.gameObject;
//Vector2 knockbakDirection = ActiveClass.HitBoxDraw.Directional ? PrevDirection : parent.transform.position - transform.position;
//EnemySpawnerData.EnemyMap[parent].Damage(ActiveClass.HitBoxDraw.Damage, knockbakDirection, ActiveClass.HitBoxDraw.Knockback);
}
break;
} }
@ -198,6 +191,7 @@ public class Gobler : Alive {
case State.GoToCrystal: case State.GoToCrystal:
PathAgent.SetDestination(CrystalPos);
break; break;
@ -222,10 +216,24 @@ public class Gobler : Alive {
case State.PrepareAttack: case State.PrepareAttack:
PathAgent.isStopped = true; PathAgent.isStopped = true;
FrameFrozenUntil = Time.time + 1;
MaterialColorOverlay.SetColor("_FlashColor", Color.purple); MaterialColorOverlay.SetColor("_FlashColor", Color.purple);
break; break;
case State.FinalizeAttack:
Collider2D[] hits = Physics2D.OverlapCircleAll(MyPos + Vector2.down, 4);
foreach (var hit in hits) {
if (!hit.CompareTag("PlayerHurtBox") || !hit.CompareTag("SuperSpecialGem")) continue;
Debug.Log("Player hit");
//GameObject parent = hit.transform.parent?.gameObject;
//Vector2 knockbakDirection = ActiveClass.HitBoxDraw.Directional ? PrevDirection : parent.transform.position - transform.position;
//EnemySpawnerData.EnemyMap[parent].Damage(ActiveClass.HitBoxDraw.Damage, knockbakDirection, ActiveClass.HitBoxDraw.Knockback);
}
SetState(State.None);
break;
case State.Die: case State.Die:
UnsubscribeToEvent(); UnsubscribeToEvent();
SpawnableEnemyInfo.DestroyEnemy(Owner, Enemies.Gobler); SpawnableEnemyInfo.DestroyEnemy(Owner, Enemies.Gobler);
@ -281,6 +289,11 @@ public class Alive {
protected float InvincibilityLeft => Math.Max(0, InvincibleUntil - Time.time); protected float InvincibilityLeft => Math.Max(0, InvincibleUntil - Time.time);
protected float InvincibilityDuration = 0.1f; protected float InvincibilityDuration = 0.1f;
public bool IsFrameFrozen => Time.time < FrameFrozenUntil;
protected float FrameFrozenUntil = 0f;
protected float FrameFreezeLeft => Math.Max(0, FrameFrozenUntil - Time.time);
protected float FrameFreezeDuration = 0.3f;
public event Action<int, Vector2> OnTakeDamage; public event Action<int, Vector2> OnTakeDamage;
public event Action OnDeath; public event Action OnDeath;
public event Action<int> OnHeal; public event Action<int> OnHeal;
@ -295,6 +308,7 @@ public class Alive {
CurrentHealth -= amount; CurrentHealth -= amount;
CurrentHealth = Mathf.Max(CurrentHealth, 0); CurrentHealth = Mathf.Max(CurrentHealth, 0);
InvincibleUntil = Time.time + InvincibilityDuration; InvincibleUntil = Time.time + InvincibilityDuration;
FrameFrozenUntil = Time.time + FrameFreezeDuration;
DamageTaken = amount; DamageTaken = amount;
Knockback = knockback; Knockback = knockback;

View File

@ -81,13 +81,7 @@ public class MeleeFighterClass : ClassBase {
case AttackState.BasicAttack3: case AttackState.BasicAttack3:
if (ComboTimeElapsed <= 0.1) break; if (ComboTimeElapsed <= 0.1) break;
ChangeState(AttackState.KineticSurgeRelease); ChangeState(AttackState.KineticSurgeRelease, -1, -1, -1);
AttackAnimator?.MeleeResetKineticCharge();
AttackAnimator?.MeleeKineticSurge();
AnimationToPlay = "Attack1";
//TextPopUp.SpawnFloatingText("KineticSurge", Color.red, 3);
AllowBladeVortex = ComboTimeElapsed <= 0.1f;
CreateHitBoxOffset(0, 5, 0.1f, 0.1f, (10 * DamageMultiplier) + DamageOffset, 20);
break; break;
@ -215,11 +209,10 @@ public class MeleeFighterClass : ClassBase {
if (ComboTimeElapsed < Cooldown) return; if (ComboTimeElapsed < Cooldown) return;
CurrentState = state; CurrentState = state;
Player.MoveSpeedDampener = (state == AttackState.None) ? 1 : 1 / decreasedSpeed; if (decreasedSpeed != -1) Player.MoveSpeedDampener = (state == AttackState.None) ? 1 : 1 / decreasedSpeed;
if (state == AttackState.None) return; if (state == AttackState.None) return;
Cooldown = cooldown; if (resetTime != -1) ComboResetTime = resetTime;
//TextPopUp.SpawnFloatingText(state.ToString(), Color.red, 3); if (cooldown != -1) Cooldown = cooldown;
ComboResetTime = resetTime;
LastComboTime = Time.time; LastComboTime = Time.time;
RotateTowardsMouse(); RotateTowardsMouse();
@ -246,12 +239,12 @@ public class MeleeFighterClass : ClassBase {
case AttackState.BasicAttack1: case AttackState.BasicAttack1:
AnimationToPlay = "Attack1"; AnimationToPlay = "Attack1";
CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (2 * DamageMultiplier) + DamageOffset, 10); CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (2 * DamageMultiplier) + DamageOffset, 20);
break; break;
case AttackState.BasicAttack2: case AttackState.BasicAttack2:
AnimationToPlay = "Attack2"; AnimationToPlay = "Attack2";
CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (4 * DamageMultiplier) + DamageOffset, 15); CreateHitBoxOffset(4, 4, 0.1f, 0.1f, (4 * DamageMultiplier) + DamageOffset, 20);
break; break;
case AttackState.BasicAttack3: case AttackState.BasicAttack3:
@ -260,7 +253,10 @@ public class MeleeFighterClass : ClassBase {
break; break;
case AttackState.KineticSurgeRelease: case AttackState.KineticSurgeRelease:
AttackAnimator?.MeleeResetKineticCharge();
AttackAnimator?.MeleeKineticSurge();
VfxKineticSurgeHandler.PlayAll(Player.transform.position); VfxKineticSurgeHandler.PlayAll(Player.transform.position);
CreateHitBoxOffset(0, 5, 0.1f, 0.1f, (10 * DamageMultiplier) + DamageOffset, 20);
break; break;
} }
} }

View File

@ -9,6 +9,8 @@ TagManager:
- HitBox - HitBox
- EnemyHitBox - EnemyHitBox
- EnemyHurtBox - EnemyHurtBox
- SuperSpecialGem
- PlayerHurtBox
layers: layers:
- Default - Default
- TransparentFX - TransparentFX