diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index 6aed512e..3c93646e 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -128,6 +128,7 @@ net.AllowPIESeamlessTravel=1 +ClassRedirects=(OldName="/Script/ProjectMJ.MJGA_BaseProjectile",NewName="/Script/ProjectMJ.MJGA_SpawnProjectile") +ClassRedirects=(OldName="/Script/ProjectMJ.MJGA_ActionAbility",NewName="/Script/ProjectMJ.MJGA_AIActionInstantAbility") +ClassRedirects=(OldName="/Script/ProjectMJ.MJGA_ActionInstantAbility",NewName="/Script/ProjectMJ.MJGA_AIActionInstantAbility") ++ClassRedirects=(OldName="/Script/ProjectMJ.MJCollisionProjectile",NewName="/Script/ProjectMJ.MJNiagaraProjectile") [/Script/Engine.CollisionProfile] -Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision",bCanModify=False) diff --git a/Config/Tags/GameplayCue.ini b/Config/Tags/GameplayCue.ini index 2ab84360..24edc74d 100644 --- a/Config/Tags/GameplayCue.ini +++ b/Config/Tags/GameplayCue.ini @@ -10,4 +10,5 @@ GameplayTagList=(Tag="GameplayCue.Skill.NormalMeleeAttack.Attack",DevComment="") GameplayTagList=(Tag="GameplayCue.Skill.NormalMeleeAttack.Hit",DevComment="") GameplayTagList=(Tag="GameplayCue.Skill.PoisonSlash.Hit",DevComment="") GameplayTagList=(Tag="GameplayCue.Skill.PoisonSlash.Status",DevComment="") +GameplayTagList=(Tag="GameplayCue.Skill.WaterElementalIdentity",DevComment="") diff --git a/Config/Tags/Skill.ini b/Config/Tags/Skill.ini index bead7469..2867e420 100644 --- a/Config/Tags/Skill.ini +++ b/Config/Tags/Skill.ini @@ -17,9 +17,11 @@ GameplayTagList=(Tag="Event.Character.Action.Normal.ForestCreature",DevComment=" GameplayTagList=(Tag="Event.Character.Action.Normal.IceGolem",DevComment="") GameplayTagList=(Tag="Event.Character.Action.Normal.Spider",DevComment="") GameplayTagList=(Tag="Event.Character.Action.Normal.Stone",DevComment="") +GameplayTagList=(Tag="Event.Character.Action.Normal.WaterElemental",DevComment="") GameplayTagList=(Tag="Event.Character.Action.NormalMeleeAttack",DevComment="") GameplayTagList=(Tag="Event.Character.Action.PoisonSlash",DevComment="") GameplayTagList=(Tag="Event.Character.Action.StoneElementMeleeAttack",DevComment="") +GameplayTagList=(Tag="Event.Character.Action.WaterElementalIdentity",DevComment="") GameplayTagList=(Tag="Event.Character.Appear",DevComment="") GameplayTagList=(Tag="Event.Character.Dead",DevComment="") GameplayTagList=(Tag="Event.Character.Hurt",DevComment="") @@ -40,6 +42,7 @@ GameplayTagList=(Tag="Skill.Instant.IceGolemIdentity",DevComment="") GameplayTagList=(Tag="Skill.Instant.MysticShot",DevComment="") GameplayTagList=(Tag="Skill.Instant.PoisonSlash",DevComment="") GameplayTagList=(Tag="Skill.Instant.StoneElementalMeleeAttack",DevComment="") +GameplayTagList=(Tag="Skill.Instant.WaterElementalIdentity",DevComment="") GameplayTagList=(Tag="Skill.Normal.Cooldown",DevComment="") GameplayTagList=(Tag="Skill.Normal.EarthGolem",DevComment="") GameplayTagList=(Tag="Skill.Normal.Fire",DevComment="") @@ -49,6 +52,7 @@ GameplayTagList=(Tag="Skill.Normal.IceGolem",DevComment="") GameplayTagList=(Tag="Skill.Normal.MeleeAttack",DevComment="") GameplayTagList=(Tag="Skill.Normal.Spider",DevComment="") GameplayTagList=(Tag="Skill.Normal.Stone",DevComment="") +GameplayTagList=(Tag="Skill.Normal.WaterElemental",DevComment="") GameplayTagList=(Tag="Skill.Passive",DevComment="") GameplayTagList=(Tag="Skill.Passive.DamageUp",DevComment="") GameplayTagList=(Tag="Skill.Passive.Test",DevComment="") diff --git a/Content/AI/Elemental/AM_ElementalDead.uasset b/Content/AI/Elemental/AM_ElementalDead.uasset index 72bf7fcb..7edc46a5 100644 Binary files a/Content/AI/Elemental/AM_ElementalDead.uasset and b/Content/AI/Elemental/AM_ElementalDead.uasset differ diff --git a/Content/AI/Elemental/AM_ElementalInActivated.uasset b/Content/AI/Elemental/AM_ElementalInActivated.uasset index 4932c995..540a101d 100644 Binary files a/Content/AI/Elemental/AM_ElementalInActivated.uasset and b/Content/AI/Elemental/AM_ElementalInActivated.uasset differ diff --git a/Content/AI/Elemental/Anim_ElementalInActivated.uasset b/Content/AI/Elemental/Anim_ElementalInActivated.uasset index 4698c392..4c42a8e1 100644 Binary files a/Content/AI/Elemental/Anim_ElementalInActivated.uasset and b/Content/AI/Elemental/Anim_ElementalInActivated.uasset differ diff --git a/Content/AI/Elemental/Anim_WaterElementalDeath.uasset b/Content/AI/Elemental/Anim_WaterElementalDeath.uasset new file mode 100644 index 00000000..f71651f0 Binary files /dev/null and b/Content/AI/Elemental/Anim_WaterElementalDeath.uasset differ diff --git a/Content/AI/Elemental/GA_ElementalStateAbility.uasset b/Content/AI/Elemental/GA_ElementalStateAbility.uasset index c252d49c..b351a69d 100644 Binary files a/Content/AI/Elemental/GA_ElementalStateAbility.uasset and b/Content/AI/Elemental/GA_ElementalStateAbility.uasset differ diff --git a/Content/AI/Elemental/MJGA_ActionDamageElemental.uasset b/Content/AI/Elemental/MJGA_ActionDamageElemental.uasset index 88b02086..5456cb54 100644 Binary files a/Content/AI/Elemental/MJGA_ActionDamageElemental.uasset and b/Content/AI/Elemental/MJGA_ActionDamageElemental.uasset differ diff --git a/Content/AI/Elemental/MJGA_ActionDeadElemental.uasset b/Content/AI/Elemental/MJGA_ActionDeadElemental.uasset index 32709acd..1eb68282 100644 Binary files a/Content/AI/Elemental/MJGA_ActionDeadElemental.uasset and b/Content/AI/Elemental/MJGA_ActionDeadElemental.uasset differ diff --git a/Content/AI/Elemental/NS_ElementalInActivated.uasset b/Content/AI/Elemental/NS_ElementalInActivated.uasset index 50a06501..604c8cf0 100644 Binary files a/Content/AI/Elemental/NS_ElementalInActivated.uasset and b/Content/AI/Elemental/NS_ElementalInActivated.uasset differ diff --git a/Content/AI/Elemental/NS_ElementalStep.uasset b/Content/AI/Elemental/NS_ElementalStep.uasset new file mode 100644 index 00000000..0fe84098 Binary files /dev/null and b/Content/AI/Elemental/NS_ElementalStep.uasset differ diff --git a/Content/AI/Elemental/NS_Water_Magic_Waterstep.uasset b/Content/AI/Elemental/NS_Water_Magic_Waterstep.uasset deleted file mode 100644 index e44f9bbc..00000000 Binary files a/Content/AI/Elemental/NS_Water_Magic_Waterstep.uasset and /dev/null differ diff --git a/Content/AI/Elemental/WaterElemental/BP_WaterElemental.uasset b/Content/AI/Elemental/WaterElemental/BP_WaterElemental.uasset new file mode 100644 index 00000000..a6d19861 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/BP_WaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Curve_WaterElemental_Table.uasset b/Content/AI/Elemental/WaterElemental/Curve_WaterElemental_Table.uasset new file mode 100644 index 00000000..537b16ef Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Curve_WaterElemental_Table.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/DA_WaterElementalDropItems.uasset b/Content/AI/Elemental/WaterElemental/DA_WaterElementalDropItems.uasset new file mode 100644 index 00000000..099e69de Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/DA_WaterElementalDropItems.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/NS_Water_Magic_Wave1.uasset b/Content/AI/Elemental/WaterElemental/NS_Water_Magic_Wave1.uasset deleted file mode 100644 index 689d7b0b..00000000 Binary files a/Content/AI/Elemental/WaterElemental/NS_Water_Magic_Wave1.uasset and /dev/null differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/AM_WaterElementalIdentity.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/AM_WaterElementalIdentity.uasset new file mode 100644 index 00000000..750ae272 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/AM_WaterElementalIdentity.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_ImpactWaterElementalIdentity.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_ImpactWaterElementalIdentity.uasset new file mode 100644 index 00000000..a1b4122e Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_ImpactWaterElementalIdentity.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_MJActionIdentityWaterElemental.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_MJActionIdentityWaterElemental.uasset new file mode 100644 index 00000000..1df0cfe9 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_MJActionIdentityWaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_MJIdentityWaterElemental.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_MJIdentityWaterElemental.uasset new file mode 100644 index 00000000..b8de139b Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGA_MJIdentityWaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGE_DamageIdentityWaterElemental.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGE_DamageIdentityWaterElemental.uasset new file mode 100644 index 00000000..facefc9b Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/BPGE_DamageIdentityWaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/BP_MovementWaterElementalIdentity.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/BP_MovementWaterElementalIdentity.uasset new file mode 100644 index 00000000..882539ca Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/BP_MovementWaterElementalIdentity.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/BP_WaterElementalIdentityProjectile.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/BP_WaterElementalIdentityProjectile.uasset new file mode 100644 index 00000000..be7ee48a Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/BP_WaterElementalIdentityProjectile.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/Curve_IdentityWaterElemental_Table.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/Curve_IdentityWaterElemental_Table.uasset new file mode 100644 index 00000000..38add31b Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/Curve_IdentityWaterElemental_Table.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/DT_IdentityWaterElementalAbility.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/DT_IdentityWaterElementalAbility.uasset new file mode 100644 index 00000000..179f6826 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/DT_IdentityWaterElementalAbility.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Identity/NS_WaterElementalIdentityWave.uasset b/Content/AI/Elemental/WaterElemental/Skill/Identity/NS_WaterElementalIdentityWave.uasset new file mode 100644 index 00000000..34e386e0 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Identity/NS_WaterElementalIdentityWave.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Normal/AM_WaterElementalNormal.uasset b/Content/AI/Elemental/WaterElemental/Skill/Normal/AM_WaterElementalNormal.uasset new file mode 100644 index 00000000..9a283856 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Normal/AM_WaterElementalNormal.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGA_MJActionNormalWaterElemental.uasset b/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGA_MJActionNormalWaterElemental.uasset new file mode 100644 index 00000000..afa3ad9d Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGA_MJActionNormalWaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGA_MJNormalWaterElemental.uasset b/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGA_MJNormalWaterElemental.uasset new file mode 100644 index 00000000..7ec012f3 Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGA_MJNormalWaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGE_DamageNormalWaterElemental.uasset b/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGE_DamageNormalWaterElemental.uasset new file mode 100644 index 00000000..55f33edb Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Normal/BPGE_DamageNormalWaterElemental.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Normal/Curve_NormalWaterElemental_Table.uasset b/Content/AI/Elemental/WaterElemental/Skill/Normal/Curve_NormalWaterElemental_Table.uasset new file mode 100644 index 00000000..4dfd905d Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Normal/Curve_NormalWaterElemental_Table.uasset differ diff --git a/Content/AI/Elemental/WaterElemental/Skill/Normal/DT_NormalWaterElementalAbility.uasset b/Content/AI/Elemental/WaterElemental/Skill/Normal/DT_NormalWaterElementalAbility.uasset new file mode 100644 index 00000000..ed7db90b Binary files /dev/null and b/Content/AI/Elemental/WaterElemental/Skill/Normal/DT_NormalWaterElementalAbility.uasset differ diff --git a/Content/AI/ForestCreture/BPGA_ActionDamage_Forest.uasset b/Content/AI/ForestCreture/BPGA_ActionDamage_Forest.uasset index 92c02b8e..2b18cb50 100644 Binary files a/Content/AI/ForestCreture/BPGA_ActionDamage_Forest.uasset and b/Content/AI/ForestCreture/BPGA_ActionDamage_Forest.uasset differ diff --git a/Content/AI/ForestCreture/DT_ForestCreatureStateAbility.uasset b/Content/AI/ForestCreture/DT_ForestCreatureStateAbility.uasset index 0fde598d..b2af2e77 100644 Binary files a/Content/AI/ForestCreture/DT_ForestCreatureStateAbility.uasset and b/Content/AI/ForestCreture/DT_ForestCreatureStateAbility.uasset differ diff --git a/Content/AI/Golem/FireGolem/Skill/Normal/BPGA_MJNormalFireGolem.uasset b/Content/AI/Golem/FireGolem/Skill/Normal/BPGA_MJNormalFireGolem.uasset index 5b5ff270..fe9c8578 100644 Binary files a/Content/AI/Golem/FireGolem/Skill/Normal/BPGA_MJNormalFireGolem.uasset and b/Content/AI/Golem/FireGolem/Skill/Normal/BPGA_MJNormalFireGolem.uasset differ diff --git a/Content/AI/Golem/FireGolem/Skill/Normal/DT_NormalFireGolemAbility.uasset b/Content/AI/Golem/FireGolem/Skill/Normal/DT_NormalFireGolemAbility.uasset index 7af425dd..2bc7065d 100644 Binary files a/Content/AI/Golem/FireGolem/Skill/Normal/DT_NormalFireGolemAbility.uasset and b/Content/AI/Golem/FireGolem/Skill/Normal/DT_NormalFireGolemAbility.uasset differ diff --git a/Content/AI/Golem/GA_GolemStateAbility.uasset b/Content/AI/Golem/GA_GolemStateAbility.uasset index fb7c0fa7..fd27d472 100644 Binary files a/Content/AI/Golem/GA_GolemStateAbility.uasset and b/Content/AI/Golem/GA_GolemStateAbility.uasset differ diff --git a/Content/AI/Golem/MJGA_ActionDamageGolem.uasset b/Content/AI/Golem/MJGA_ActionDamageGolem.uasset index fdff6a10..ef18e5db 100644 Binary files a/Content/AI/Golem/MJGA_ActionDamageGolem.uasset and b/Content/AI/Golem/MJGA_ActionDamageGolem.uasset differ diff --git a/Content/AI/SpiderMinion/BPGA_ActionDamage_SpiderMinion.uasset b/Content/AI/SpiderMinion/BPGA_ActionDamage_SpiderMinion.uasset index 1ab8dfbf..85d42e2c 100644 Binary files a/Content/AI/SpiderMinion/BPGA_ActionDamage_SpiderMinion.uasset and b/Content/AI/SpiderMinion/BPGA_ActionDamage_SpiderMinion.uasset differ diff --git a/Content/AI/SpiderMinion/DT_SpiderMinionStateAbility.uasset b/Content/AI/SpiderMinion/DT_SpiderMinionStateAbility.uasset index 1f56f36b..d8fedf8c 100644 Binary files a/Content/AI/SpiderMinion/DT_SpiderMinionStateAbility.uasset and b/Content/AI/SpiderMinion/DT_SpiderMinionStateAbility.uasset differ diff --git a/Content/AI/StoneElemental/GA_StoneStateAbility.uasset b/Content/AI/StoneElemental/GA_StoneStateAbility.uasset index 9bb00b35..fa1e3199 100644 Binary files a/Content/AI/StoneElemental/GA_StoneStateAbility.uasset and b/Content/AI/StoneElemental/GA_StoneStateAbility.uasset differ diff --git a/Content/AI/StoneElemental/MJGA_ActionDamageStone.uasset b/Content/AI/StoneElemental/MJGA_ActionDamageStone.uasset index b4842508..c2d549e7 100644 Binary files a/Content/AI/StoneElemental/MJGA_ActionDamageStone.uasset and b/Content/AI/StoneElemental/MJGA_ActionDamageStone.uasset differ diff --git a/Content/DataTable/Enemy/DT_EnemyDataTable.uasset b/Content/DataTable/Enemy/DT_EnemyDataTable.uasset index 98e2cc69..fcf5e5d0 100644 Binary files a/Content/DataTable/Enemy/DT_EnemyDataTable.uasset and b/Content/DataTable/Enemy/DT_EnemyDataTable.uasset differ diff --git a/Content/DataTable/Skill/DT_EnemySkillDataTable.uasset b/Content/DataTable/Skill/DT_EnemySkillDataTable.uasset index bafdee95..20d2ce60 100644 Binary files a/Content/DataTable/Skill/DT_EnemySkillDataTable.uasset and b/Content/DataTable/Skill/DT_EnemySkillDataTable.uasset differ diff --git a/Content/MJ/AIC/BPAIC_Elemental.uasset b/Content/MJ/AIC/BPAIC_Elemental.uasset index 19d958ae..48fd4c6c 100644 Binary files a/Content/MJ/AIC/BPAIC_Elemental.uasset and b/Content/MJ/AIC/BPAIC_Elemental.uasset differ diff --git a/Content/MJ/BT/BT_MJElemental.uasset b/Content/MJ/BT/BT_MJElemental.uasset new file mode 100644 index 00000000..1018f9ee Binary files /dev/null and b/Content/MJ/BT/BT_MJElemental.uasset differ diff --git a/Content/MJ/BT/BT_MJGolem.uasset b/Content/MJ/BT/BT_MJGolem.uasset index c6809b4d..8da6cd30 100644 Binary files a/Content/MJ/BT/BT_MJGolem.uasset and b/Content/MJ/BT/BT_MJGolem.uasset differ diff --git a/Content/MJ/DropSkill/NS_GiveSkillHit.uasset b/Content/MJ/DropSkill/NS_GiveSkillHit.uasset index 40ba4277..5b1e0e4d 100644 Binary files a/Content/MJ/DropSkill/NS_GiveSkillHit.uasset and b/Content/MJ/DropSkill/NS_GiveSkillHit.uasset differ diff --git a/Content/MJ/DropSkill/NS_GiveSkillProjectile.uasset b/Content/MJ/DropSkill/NS_GiveSkillProjectile.uasset index f1787517..7cb9a880 100644 Binary files a/Content/MJ/DropSkill/NS_GiveSkillProjectile.uasset and b/Content/MJ/DropSkill/NS_GiveSkillProjectile.uasset differ diff --git a/Content/Maps/MJ_AITest.umap b/Content/Maps/MJ_AITest.umap index 71f876c3..0d600b80 100644 Binary files a/Content/Maps/MJ_AITest.umap and b/Content/Maps/MJ_AITest.umap differ diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionAppearAbility.cpp b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionAppearAbility.cpp index a63512f9..70fee294 100644 --- a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionAppearAbility.cpp +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionAppearAbility.cpp @@ -33,18 +33,19 @@ void UMJGA_AIActionAppearAbility::ActivateAbility(const FGameplayAbilitySpecHand AMJCharacter->GetCharacterMovement()->SetMovementMode(MOVE_None); - // IsInactivated 태그 제거 - 활성화 + // Minjin: IsInactivated 태그 제거 - 활성화 const FGameplayTag InActivatedTag = FGameplayTag::RequestGameplayTag(TEXT("Character.State.IsInactivated")); AMJCharacter->ASC->RemoveLooseGameplayTag(InActivatedTag); - UAbilityTask_PlayMontageAndWait* PlayDeathMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, TEXT("PlayAppear"), AppearanceActionAnimMontage, 1.0f); + UAbilityTask_PlayMontageAndWait* PlayAppearMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy + (this, TEXT("PlayAppear"), AppearanceActionAnimMontage, 1.0f); - PlayDeathMontage->OnCompleted.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnCompleteCallback); - PlayDeathMontage->OnInterrupted.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnInterruptedCallback); - PlayDeathMontage->OnCancelled.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnInterruptedCallback); - PlayDeathMontage->OnBlendOut.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnBlendOutCallback); + PlayAppearMontage->OnCompleted.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnCompleteCallback); + PlayAppearMontage->OnInterrupted.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnInterruptedCallback); + PlayAppearMontage->OnCancelled.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnInterruptedCallback); + PlayAppearMontage->OnBlendOut.AddDynamic(this, &UMJGA_AIActionAppearAbility::OnBlendOutCallback); - PlayDeathMontage->ReadyForActivation(); + PlayAppearMontage->ReadyForActivation(); } void UMJGA_AIActionAppearAbility::CancelAbility(const FGameplayAbilitySpecHandle Handle, diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionDamageAbility.cpp b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionDamageAbility.cpp new file mode 100644 index 00000000..a594bcb4 --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionDamageAbility.cpp @@ -0,0 +1,86 @@ +// ThenOneDayStudio + + +#include "AbilitySystem/Abilities/MJGA_AIActionDamageAbility.h" + +#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h" +#include "Character/MJCharacterBase.h" +#include "GameFramework/CharacterMovementComponent.h" + +UMJGA_AIActionDamageAbility::UMJGA_AIActionDamageAbility() +{ +} + +void UMJGA_AIActionDamageAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle, + const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, + const FGameplayEventData* TriggerEventData) +{ + Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData); + + if (HurtActionAnimMontage == nullptr) + { + EndAbility(Handle, ActorInfo, ActivationInfo, true, false); + return; + } + + AMJCharacterBase* AMJCharacter = Cast(ActorInfo->AvatarActor.Get()); + if (!AMJCharacter) + { + EndAbility(Handle, ActorInfo, ActivationInfo, true, false); + return; + } + + AMJCharacter->GetCharacterMovement()->SetMovementMode(MOVE_None); + + UAbilityTask_PlayMontageAndWait* PlayHurtMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, TEXT("PlayHurt"), HurtActionAnimMontage, 1.0f); + + PlayHurtMontage->OnCompleted.AddDynamic(this, &UMJGA_AIActionDamageAbility::OnCompleteCallback); + PlayHurtMontage->OnInterrupted.AddDynamic(this, &UMJGA_AIActionDamageAbility::OnInterruptedCallback); + PlayHurtMontage->OnCancelled.AddDynamic(this, &UMJGA_AIActionDamageAbility::OnInterruptedCallback); + + PlayHurtMontage->ReadyForActivation(); +} + +void UMJGA_AIActionDamageAbility::CancelAbility(const FGameplayAbilitySpecHandle Handle, + const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, + bool bReplicateCancelAbility) +{ + Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility); +} + +void UMJGA_AIActionDamageAbility::EndAbility(const FGameplayAbilitySpecHandle Handle, + const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, + bool bReplicateEndAbility, bool bWasCancelled) +{ + AMJCharacterBase* AMJCharacter = Cast(ActorInfo->AvatarActor.Get()); + if (!AMJCharacter) + { + return; + } + + // Minjin: Nav_Walking 이란 것이 있음 + AMJCharacter->GetCharacterMovement()->SetMovementMode(MOVE_Walking); + + Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled); +} + +void UMJGA_AIActionDamageAbility::OnCompleteCallback() +{ + bool bReplicatedEndAbility = true; + bool bWasCancelled = false; + EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); +} + +void UMJGA_AIActionDamageAbility::OnInterruptedCallback() +{ + bool bReplicatedEndAbility = true; + bool bWasCancelled = true; + EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); +} + +void UMJGA_AIActionDamageAbility::OnBlendOutCallback() +{ + bool bReplicatedEndAbility = true; + bool bWasCancelled = true; + EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); +} diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionDamageAbility.h b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionDamageAbility.h new file mode 100644 index 00000000..96eeb8b6 --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_AIActionDamageAbility.h @@ -0,0 +1,39 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "AbilitySystem/Abilities/MJGA_ActionDamageAbility.h" +#include "MJGA_AIActionDamageAbility.generated.h" + +/** + * Class Description: 적 데미지 입음 + * Author: Kim Minjin + * Created Date: 2025.08.28. + * Description of Change: + * Modified By: + * Modified Date: + */ +UCLASS() +class PROJECTMJ_API UMJGA_AIActionDamageAbility : public UMJGA_ActionDamageAbility +{ + GENERATED_BODY() + +public: + UMJGA_AIActionDamageAbility(); + + virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override; + virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility) override; + virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override; + +protected: + + UFUNCTION() + void OnCompleteCallback(); + + UFUNCTION() + void OnInterruptedCallback(); + + UFUNCTION() + void OnBlendOutCallback(); +}; diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.cpp b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.cpp index 8364dece..927dbfd7 100644 --- a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.cpp +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.cpp @@ -25,37 +25,6 @@ void UMJGA_ActionDamageAbility::ActivateAbility(const FGameplayAbilitySpecHandle constexpr bool bWasCancelled = true; EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled); } - ///// - - if (HurtActionAnimMontage == nullptr) - { - EndAbility(Handle, ActorInfo, ActivationInfo, true, false); - return; - } - - AMJCharacterBase* AMJCharacter = Cast(ActorInfo->AvatarActor.Get()); - if (!AMJCharacter) - { - EndAbility(Handle, ActorInfo, ActivationInfo, true, false); - return; - } - - AMJCharacter->GetCharacterMovement()->SetMovementMode(MOVE_None); - - UAbilityTask_PlayMontageAndWait* PlayHurtMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, TEXT("PlayHurt"), HurtActionAnimMontage, 1.0f); - - PlayHurtMontage->OnCompleted.AddDynamic(this, &UMJGA_ActionDamageAbility::OnCompleteCallback); - PlayHurtMontage->OnInterrupted.AddDynamic(this, &UMJGA_ActionDamageAbility::OnInterruptedCallback); - PlayHurtMontage->OnCancelled.AddDynamic(this, &UMJGA_ActionDamageAbility::OnInterruptedCallback); - - PlayHurtMontage->ReadyForActivation(); -} - -void UMJGA_ActionDamageAbility::CancelAbility(const FGameplayAbilitySpecHandle Handle, - const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, - bool bReplicateCancelAbility) -{ - Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility); } void UMJGA_ActionDamageAbility::EndAbility(const FGameplayAbilitySpecHandle Handle, @@ -63,27 +32,4 @@ void UMJGA_ActionDamageAbility::EndAbility(const FGameplayAbilitySpecHandle Hand bool bReplicateEndAbility, bool bWasCancelled) { Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled); - - AMJCharacterBase* AMJCharacter = Cast(ActorInfo->AvatarActor.Get()); - if (!AMJCharacter) - { - return; - } - - // Minjin: Nav_Walking 이란 것이 있음 - AMJCharacter->GetCharacterMovement()->SetMovementMode(MOVE_Walking); -} - -void UMJGA_ActionDamageAbility::OnCompleteCallback() -{ - bool bReplicatedEndAbility = true; - bool bWasCancelled = false; - EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); -} - -void UMJGA_ActionDamageAbility::OnInterruptedCallback() -{ - bool bReplicatedEndAbility = true; - bool bWasCancelled = true; - EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); -} +} \ No newline at end of file diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.h b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.h index 119c4f78..81532e0d 100644 --- a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.h +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_ActionDamageAbility.h @@ -10,9 +10,9 @@ * Class Description: 데미지를 입었을 때. 몽타주 재생동안 IsHurt 태그 부여 * Author: Kim Minjin * Created Date: 2025.08.08. - * Description of Change: - * Modified By: - * Modified Date: + * Description of Change: 플레이어와 적 구분 + * Modified By: Kim Minjin + * Modified Date: 2025.08.28. */ UCLASS() class PROJECTMJ_API UMJGA_ActionDamageAbility : public UMJGA_GameplayAbility @@ -23,16 +23,9 @@ class PROJECTMJ_API UMJGA_ActionDamageAbility : public UMJGA_GameplayAbility UMJGA_ActionDamageAbility(); virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override; - virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility) override; virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override; protected: - UFUNCTION() - void OnCompleteCallback(); - - UFUNCTION() - void OnInterruptedCallback(); - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Animation") TObjectPtr HurtActionAnimMontage; }; diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.cpp b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.cpp new file mode 100644 index 00000000..6cbe36e2 --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.cpp @@ -0,0 +1,75 @@ +// ThenOneDayStudio + + +#include "AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.h" + +#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h" +#include "Character/MJCharacterBase.h" +#include "GameFramework/CharacterMovementComponent.h" + +UMJGA_PlayerActionDamageAbility::UMJGA_PlayerActionDamageAbility() +{ +} + +void UMJGA_PlayerActionDamageAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle, + const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, + const FGameplayEventData* TriggerEventData) +{ + Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData); + + if (HurtActionAnimMontage == nullptr) + { + EndAbility(Handle, ActorInfo, ActivationInfo, true, false); + return; + } + + AMJCharacterBase* AMJCharacter = Cast(ActorInfo->AvatarActor.Get()); + if (!AMJCharacter) + { + EndAbility(Handle, ActorInfo, ActivationInfo, true, false); + return; + } + + UAbilityTask_PlayMontageAndWait* PlayHurtMontage = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, TEXT("PlayHurt"), HurtActionAnimMontage, 1.0f); + + PlayHurtMontage->OnCompleted.AddDynamic(this, &UMJGA_PlayerActionDamageAbility::OnCompleteCallback); + PlayHurtMontage->OnInterrupted.AddDynamic(this, &UMJGA_PlayerActionDamageAbility::OnInterruptedCallback); + PlayHurtMontage->OnCancelled.AddDynamic(this, &UMJGA_PlayerActionDamageAbility::OnInterruptedCallback); + + PlayHurtMontage->ReadyForActivation(); +} + +void UMJGA_PlayerActionDamageAbility::CancelAbility(const FGameplayAbilitySpecHandle Handle, + const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, + bool bReplicateCancelAbility) +{ + Super::CancelAbility(Handle, ActorInfo, ActivationInfo, bReplicateCancelAbility); +} + +void UMJGA_PlayerActionDamageAbility::EndAbility(const FGameplayAbilitySpecHandle Handle, + const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, + bool bReplicateEndAbility, bool bWasCancelled) +{ + Super::EndAbility(Handle, ActorInfo, ActivationInfo, bReplicateEndAbility, bWasCancelled); +} + +void UMJGA_PlayerActionDamageAbility::OnCompleteCallback() +{ + bool bReplicatedEndAbility = true; + bool bWasCancelled = false; + EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); +} + +void UMJGA_PlayerActionDamageAbility::OnInterruptedCallback() +{ + bool bReplicatedEndAbility = true; + bool bWasCancelled = true; + EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); +} + +void UMJGA_PlayerActionDamageAbility::OnBlendOutCallback() +{ + bool bReplicatedEndAbility = true; + bool bWasCancelled = true; + EndAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, bReplicatedEndAbility, bWasCancelled); +} diff --git a/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.h b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.h new file mode 100644 index 00000000..a49e82dd --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/Abilities/MJGA_PlayerActionDamageAbility.h @@ -0,0 +1,39 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "AbilitySystem/Abilities/MJGA_ActionDamageAbility.h" +#include "MJGA_PlayerActionDamageAbility.generated.h" + +/** + * Class Description: 플레이어 데미지 입음 + * Author: Kim Minjin + * Created Date: 2025.08.28. + * Description of Change: + * Modified By: + * Modified Date: + */ +UCLASS() +class PROJECTMJ_API UMJGA_PlayerActionDamageAbility : public UMJGA_ActionDamageAbility +{ + GENERATED_BODY() + +public: + UMJGA_PlayerActionDamageAbility(); + + virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override; + virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility) override; + virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override; + +protected: + + UFUNCTION() + void OnCompleteCallback(); + + UFUNCTION() + void OnInterruptedCallback(); + + UFUNCTION() + void OnBlendOutCallback(); +}; diff --git a/Source/ProjectMJ/AbilitySystem/Actor/MJNiagaraProjectile.cpp b/Source/ProjectMJ/AbilitySystem/Actor/MJNiagaraProjectile.cpp new file mode 100644 index 00000000..931eca47 --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/Actor/MJNiagaraProjectile.cpp @@ -0,0 +1,77 @@ +// ThenOneDayStudio + + +#include "AbilitySystem/Actor/MJNiagaraProjectile.h" + +#include "AbilitySystemComponent.h" +#include "NiagaraComponent.h" +#include "NiagaraFunctionLibrary.h" +#include "ProjectMJ.h" +#include "Character/MJCharacterBase.h" +#include "Components/SphereComponent.h" +#include "Physics/MJCollision.h" +#include "Behavior/MJProjectileReactionBehaviorBase.h" +#include "Behavior/MJProjectileMovementBehaviorBase.h" +#include "Behavior/MJProjectileMovementLinear.h" + +AMJNiagaraProjectile::AMJNiagaraProjectile() +{ +} + +void AMJNiagaraProjectile::BeginPlay() +{ + Super::BeginPlay(); + + NiagaraComponent->OnSystemFinished.AddDynamic(this, &AMJNiagaraProjectile::OnNiagaraEnded); +} + +void AMJNiagaraProjectile::OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, + UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) +{ + //Super::OnSphereOverlap(OverlappedComponent, OtherActor, OtherComp, OtherBodyIndex, bFromSweep, SweepResult); + + AMJCharacterBase* OwnerActor = Cast(ProjectileParams.SourceASC->GetAvatarActor()); + if (!OwnerActor) + { + MJ_LOG(LogMJ, Warning, TEXT("Not Exist OwnerActor")); + return; + } + + if (OtherActor == this || (OwnerActor && OtherActor == OwnerActor)) + { + MJ_LOG(LogMJ, Warning, TEXT("Target is User")); + return; + } + + USceneComponent* RootComp = OtherActor->GetRootComponent(); + if (!RootComp) + { + MJ_LOG(LogMJ, Warning, TEXT("RootComp is nullptr.")); + return; + } + + ECollisionChannel CollisionChannel = RootComp->GetCollisionObjectType(); + if (CollisionChannel == CCHANNEL_MJGROUND) + { + MJ_LOG(LogMJ, Warning, TEXT("This Actor is Ground.")); + return; + } + + NiagaraComponent->SetBoolParameter(TEXT("HasCollided"), true); + Sphere->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + for (const TObjectPtr ReactionBehavior : ReactionBehaviors) + { + if (ReactionBehavior) + { + ReactionBehavior->OnProjectileReact(this, OtherActor, SweepResult); + } + } + + MJ_LOG(LogMJ, Warning, TEXT("Sphere Overlap")); +} + +void AMJNiagaraProjectile::OnNiagaraEnded(UNiagaraComponent* PSystem) +{ + Destroy(); +} diff --git a/Source/ProjectMJ/AbilitySystem/Actor/MJNiagaraProjectile.h b/Source/ProjectMJ/AbilitySystem/Actor/MJNiagaraProjectile.h new file mode 100644 index 00000000..b34341e3 --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/Actor/MJNiagaraProjectile.h @@ -0,0 +1,30 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "AbilitySystem/Actor/MJProjectileBase.h" +#include "MJNiagaraProjectile.generated.h" + +/** + * Class Description: 나이아가라 자연스럽게 사라지는 발사체 + * Author: Kim Minjin + * Created Date: 2025.08.24. + * Last Modified By: + * Last Modified Date: + */ +UCLASS() +class PROJECTMJ_API AMJNiagaraProjectile : public AMJProjectileBase +{ + GENERATED_BODY() + +public: + AMJNiagaraProjectile(); + +protected: + virtual void BeginPlay() override; + virtual void OnSphereOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) override; + + UFUNCTION() + virtual void OnNiagaraEnded(UNiagaraComponent* PSystem); +}; diff --git a/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.cpp b/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.cpp index 957f9820..dc644ab4 100644 --- a/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.cpp +++ b/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.cpp @@ -71,12 +71,11 @@ void AMJProjectileBase::InitProjectile(const FMJSkillProjectileParams& InParams, if (ProjectileParams.SkillRadius > 0.0f) { Sphere->SetSphereRadius(ProjectileParams.SkillRadius); - } if (NiagaraComponent) { - const float NiagaraScale = ProjectileParams.SkillRadius / VFXRatio; + const float NiagaraScale = /*ProjectileParams.SkillRadius /*/ VFXRatio; NiagaraComponent->SetFloatParameter(TEXT("Scale_All"), NiagaraScale); } } @@ -157,5 +156,5 @@ void AMJProjectileBase::OnSphereHit(UPrimitiveComponent* HitComponent, AActor* O ReactionBehavior->OnProjectileReact(this, OtherActor, Hit); } } - Destroy(); + //Destroy(); } diff --git a/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.h b/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.h index c2f5ccb4..a8a63f37 100644 --- a/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.h +++ b/Source/ProjectMJ/AbilitySystem/Actor/MJProjectileBase.h @@ -12,8 +12,9 @@ * Class Description: Projectile Actor * Author: 신동민 * Created Date: 2025.07.03 - * Last Modified By: - * Last Modified Date: + * Last Modified By: 김민진 + * Last Modified Date: (25.08.24.)상속받아서 쓸 수 있게 private 영역을 protected로 변경, + * 나이아가라 스케일 계산 변경, OnSphereHit Detroy 주석 처리 */ class UMJProjectileReactionBehaviorBase; @@ -58,7 +59,7 @@ class PROJECTMJ_API AMJProjectileBase : public AActor UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Behavior") TArray> ReactionBehaviors; -private: +/*private:*/ UPROPERTY(EditDefaultsOnly, Category = "Projectile") TObjectPtr Sphere; diff --git a/Source/ProjectMJ/AbilitySystem/Attributes/MJCharacterAttributeSet.cpp b/Source/ProjectMJ/AbilitySystem/Attributes/MJCharacterAttributeSet.cpp index 6e60eebc..f28fea63 100644 --- a/Source/ProjectMJ/AbilitySystem/Attributes/MJCharacterAttributeSet.cpp +++ b/Source/ProjectMJ/AbilitySystem/Attributes/MJCharacterAttributeSet.cpp @@ -181,7 +181,6 @@ void UMJCharacterAttributeSet::PostGameplayEffectExecute(const struct FGameplayE if (!StatComp->GetbIsDead()) { // Minjin: 데미지를 입힌 상대 전달 - //StatComp->OnDeath.Broadcast(Data.EffectSpec.GetEffectContext().GetEffectCauser()); StatComp->OnDead(Data.EffectSpec.GetEffectContext().GetEffectCauser()); } } @@ -201,12 +200,12 @@ void UMJCharacterAttributeSet::PostGameplayEffectExecute(const struct FGameplayE StatComp->OnDamaged(Data.EvaluatedData.Magnitude, bIsCritical); // Minjin: Damage Perception - Data 사용함. TODO.위치 수정하기 - // EventLocation으로 들어가는 값이 Stimulus Location이다.- HitResult값이 nullptr이라서 Target의 Location 넣어놓음 + // EventLocation으로 들어가는 값이 Stimulus Location이다.- HitResult값이 nullptr이라서 Instigator의 Location 넣어놓음 AActor* Target = Data.Target.GetAvatarActor(); - FVector TargetLocation = Target->GetActorLocation(); + AActor* Instigator = Data.EffectSpec.GetEffectContext().GetEffectCauser(); UAISense_Damage::ReportDamageEvent(Target->GetWorld(), Target, - Data.EffectSpec.GetEffectContext().GetEffectCauser(), Data.EvaluatedData.Magnitude, - Target->GetActorLocation(), FVector::Zero()/*Data.EffectSpec.GetEffectContext().GetHitResult()->Location*/ + Instigator, Data.EvaluatedData.Magnitude, + Instigator->GetActorLocation(), FVector::Zero()/*Data.EffectSpec.GetEffectContext().GetHitResult()->Location*/ ); // Minjin: Damage Ability diff --git a/Source/ProjectMJ/AbilitySystem/TargetActor/MJTA_CustomTrace.cpp b/Source/ProjectMJ/AbilitySystem/TargetActor/MJTA_CustomTrace.cpp new file mode 100644 index 00000000..81f788a2 --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/TargetActor/MJTA_CustomTrace.cpp @@ -0,0 +1,102 @@ +// ThenOneDayStudio + + +#include "AbilitySystem/TargetActor/MJTA_CustomTrace.h" + +#include "AbilitySystemBlueprintLibrary.h" +#include "AbilitySystemComponent.h" +#include "ProjectMJ.h" +#include "AbilitySystem/Attributes/MJCharacterSkillAttributeSet.h" +#include "Components/CapsuleComponent.h" +#include "Engine/OverlapResult.h" +#include "GameFramework/Character.h" +#include "Physics/MJCollision.h" + +class UMJCharacterSkillAttributeSet; + +AMJTA_CustomTrace::AMJTA_CustomTrace() +{ + TraceLocation = FVector::ZeroVector; + TraceShape = ETraceShape::Sphere; +} + +FGameplayAbilityTargetDataHandle AMJTA_CustomTrace::MakeTargetData() const +{ + ACharacter* Character = CastChecked(SourceActor); + + UAbilitySystemComponent* ASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(SourceActor); + if (!ASC) + { + MJ_LOG(LogMJ, Error, TEXT("ASC not found!")); + return FGameplayAbilityTargetDataHandle(); + } + + const UMJCharacterSkillAttributeSet* SkillAttributeSet = ASC->GetSet(); + if (!SkillAttributeSet) + { + MJ_LOG(LogMJ, Error, TEXT("SkillAttributeSet not found!")); + return FGameplayAbilityTargetDataHandle(); + } + + const float AttackRadius = SkillAttributeSet->GetSkillRadius(); + const float AttackRange = FMath::Max(SkillAttributeSet->GetSkillRange(), AttackRadius * 2.0f); + + const FVector OriginLocation = (TraceLocation==FVector::ZeroVector?Character->GetActorLocation():TraceLocation); + const FVector Forward = Character->GetActorForwardVector(); + const float Offset = SkillAttributeSet->GetSkillAttackLocationOffset(); + + FCollisionQueryParams Params(SCENE_QUERY_STAT(UMJTA_Trace), false, Character); + + TArray OutOverlapResults; + + switch (TraceShape) + { + case ETraceShape::Sphere: + { + // Sphere + + FVector Center = OriginLocation + Forward * ((Offset!=0)?Offset:1); + GetWorld()->OverlapMultiByChannel(OutOverlapResults, Center, FQuat::Identity, CCHANNEL_MJAbilityTargetTrace, FCollisionShape::MakeSphere(AttackRadius), Params); + } + case ETraceShape::Capsule: + { + // Capsule + const FVector Start = OriginLocation + Forward * Character->GetCapsuleComponent()->GetScaledCapsuleRadius() * ((Offset != 0) ? Offset : 1); + const FVector End = Start + Forward * AttackRange; + const FVector CapsuleOrigin = Start + (End - Start) * 0.5f; + float CapsuleHalfHeight = AttackRange * 0.5f; + + GetWorld()->OverlapMultiByChannel(OutOverlapResults, CapsuleOrigin, FRotationMatrix::MakeFromZ(Forward).ToQuat(), CCHANNEL_MJAbilityTargetTrace, FCollisionShape::MakeCapsule(AttackRadius, CapsuleHalfHeight), Params); + + } + } + + /* + * Minjin + * HowTo: 적끼리 공격하지 않는다. + * FGameplayTargetDataFilter 생성, RequiredActorClass로 SourceActor의 C++ 클래스를 설정한다. + * -> 이러면 FilterPassesForActor 중 !ActorToBeFiltered(HitActor를 뜻함)->IsA(RequiredActorClass)에 걸려 false를 리턴: Target 대상에서 제외됨 + * => bReverseFilter를 true로 한다... + */ + + TSubclassOf ActorClass = GetParentNativeClass(SourceActor.GetClass()); + + FGameplayTargetDataFilter FilteringData; + FilteringData.RequiredActorClass = ActorClass; + FilteringData.bReverseFilter = true; + FilteringData.InitializeFilterContext(SourceActor); + + TArray> HitActors; + for (const FOverlapResult& Overlap : OutOverlapResults) + { + AActor* HitActor = Overlap.OverlapObjectHandle.FetchActor(); + if (HitActor && !HitActors.Contains(HitActor)&& (FilteringData.FilterPassesForActor(HitActor))) + { + HitActors.Add(HitActor); + } + } + FGameplayAbilityTargetData_ActorArray* ActorData = new FGameplayAbilityTargetData_ActorArray(); + ActorData->SetActors(HitActors); + + return FGameplayAbilityTargetDataHandle(ActorData); +} diff --git a/Source/ProjectMJ/AbilitySystem/TargetActor/MJTA_CustomTrace.h b/Source/ProjectMJ/AbilitySystem/TargetActor/MJTA_CustomTrace.h new file mode 100644 index 00000000..46fd023c --- /dev/null +++ b/Source/ProjectMJ/AbilitySystem/TargetActor/MJTA_CustomTrace.h @@ -0,0 +1,41 @@ +// ThenOneDayStudio + +#pragma once + +#include "CoreMinimal.h" +#include "AbilitySystem/TargetActor/MJTA_Trace.h" +#include "MJTA_CustomTrace.generated.h" + +/** + * Class Description: 모양 및 위치를 선택할 수 있는 Trace + * Author: Kim Minjin + * Created Date: 2025.08.20. + * Description of Change: + * Modified By: + * Modified Date: + */ + +UENUM(BlueprintType) +enum class ETraceShape: uint8 +{ + Sphere = 0, + Capsule = 1, +}; + +UCLASS() +class PROJECTMJ_API AMJTA_CustomTrace : public AMJTA_Trace +{ + GENERATED_BODY() + +public: + AMJTA_CustomTrace(); + void SetLocation(FVector InLocation){TraceLocation = InLocation;}; + +protected: + virtual FGameplayAbilityTargetDataHandle MakeTargetData() const override; + + FVector TraceLocation; + + UPROPERTY(BlueprintReadWrite, EditAnywhere) + ETraceShape TraceShape; +}; diff --git a/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.cpp b/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.cpp index 077d42d5..3437f09c 100644 --- a/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.cpp +++ b/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.cpp @@ -92,7 +92,7 @@ void UMJEnemySkillComponent::ActivateIdentitySkill() ActivateSkill(IdentitySkillTag); } -FGameplayTag UMJEnemySkillComponent::TryGiveMemory() +FGameplayTag UMJEnemySkillComponent::TryGiveMemory() const { if(!IdentitySkillTag.IsValid()) { diff --git a/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.h b/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.h index b23cba93..3515f1b5 100644 --- a/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.h +++ b/Source/ProjectMJ/Character/Component/MJEnemySkillComponent.h @@ -41,5 +41,5 @@ class PROJECTMJ_API UMJEnemySkillComponent : public UMJSkillComponentBase void ActivateIdentitySkill(); // Minjin TODO: 확률에 따른 기억(스킬) 전달 - FGameplayTag TryGiveMemory(); + FGameplayTag TryGiveMemory() const; }; diff --git a/Source/ProjectMJ/Character/MJCharacterBase.cpp b/Source/ProjectMJ/Character/MJCharacterBase.cpp index fd321886..60fed9dc 100644 --- a/Source/ProjectMJ/Character/MJCharacterBase.cpp +++ b/Source/ProjectMJ/Character/MJCharacterBase.cpp @@ -62,14 +62,11 @@ void AMJCharacterBase::BeginPlay() if(StateAbilityDataAsset) { // Minjin: State Ability 부여 - FGameplayAbilitySpec AppearAbilitySpec(StateAbilityDataAsset->ActionAppearanceAbilityClass); - ASC->GiveAbility(AppearAbilitySpec); - - FGameplayAbilitySpec DamageAbilitySpec(StateAbilityDataAsset->ActionDamageAbilityClass); - ASC->GiveAbility(DamageAbilitySpec); - - FGameplayAbilitySpec DeathAbilitySpec(StateAbilityDataAsset->ActionDeathAbilityClass); - ASC->GiveAbility(DeathAbilitySpec); + for (auto StateAbilityClass: StateAbilityDataAsset->StateAbilityClasses) + { + FGameplayAbilitySpec StateAbilitySpec(StateAbilityClass); + ASC->GiveAbility(StateAbilitySpec); + } } // TODO: 함수로 만들기 - 동민 - diff --git a/Source/ProjectMJ/DataAsset/MJStateAbilityDataAsset.h b/Source/ProjectMJ/DataAsset/MJStateAbilityDataAsset.h index f038c375..fc435df9 100644 --- a/Source/ProjectMJ/DataAsset/MJStateAbilityDataAsset.h +++ b/Source/ProjectMJ/DataAsset/MJStateAbilityDataAsset.h @@ -22,13 +22,7 @@ class PROJECTMJ_API UMJStateAbilityDataAsset : public UDataAsset public: UMJStateAbilityDataAsset(){}; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TSubclassOf ActionAppearanceAbilityClass; - - UPROPERTY(EditAnywhere, BlueprintReadWrite) - TSubclassOf ActionDamageAbilityClass; UPROPERTY(EditAnywhere, BlueprintReadWrite) - TSubclassOf ActionDeathAbilityClass; + TArray> StateAbilityClasses; }; diff --git a/Source/ProjectMJ/MJ/AI/AIPerceptionInfo.h b/Source/ProjectMJ/MJ/AI/AIPerceptionInfo.h index 4ccbeb0a..49f886a7 100644 --- a/Source/ProjectMJ/MJ/AI/AIPerceptionInfo.h +++ b/Source/ProjectMJ/MJ/AI/AIPerceptionInfo.h @@ -6,9 +6,13 @@ UENUM(BlueprintType) enum class ETeam_ID: uint8 { - PLAYER = 0 UMETA(DisplayName = "PLAYER")/*플레이어*/, - NPC UMETA(DisplayName = "NPC")/*NPC*/, - MONSTER UMETA(DisplayName = "MONSTER")/*몬스터*/, - NONE = 255 UMETA(DisplayName = "NONE") /*기본값. Neutral로 처리됩니다*/ + // 몬스터는 플레이어를 적으로 인식합니다. + PLAYER = 0 UMETA(DisplayName = "PLAYER"), + // 몬스터는 NPC를 적으로 인식하지 않습니다(Neutral로 인식). + NPC UMETA(DisplayName = "NPC"), + // 몬스터의 기본 설정입니다. + MONSTER UMETA(DisplayName = "MONSTER"), + // 기본값. Neutral로 처리됩니다. + NONE = 255 UMETA(DisplayName = "NONE") }; diff --git a/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.cpp b/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.cpp index 297545c1..3f7eefa4 100644 --- a/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.cpp +++ b/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.cpp @@ -21,7 +21,11 @@ UBTService_MJCheckAttackRange::UBTService_MJCheckAttackRange() { NodeName = "CheckAttackRange"; - Interval = 0.1f; + + INIT_SERVICE_NODE_NOTIFY_FLAGS(); + + // Force the service to tick every frame + Interval = 0.0f; PreTargetLocation = FVector::ZeroVector; CurrTargetLocation = FVector::ZeroVector; } @@ -31,9 +35,8 @@ void UBTService_MJCheckAttackRange::TickNode(UBehaviorTreeComponent& OwnerComp, /* * How to: 타겟이 몬스터의 공격 범위에 들어갔을 때 Maximum 혹은 Minimum 범위에 들어오면 블랙보드 키를 설정 */ - CachedOwnerComp = &OwnerComp; Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds); - + OwnerComp.GetBlackboardComponent()->ClearValue("IsInAttackRange"); APawn* ControlledPawn = OwnerComp.GetAIOwner()->GetPawn(); @@ -65,13 +68,6 @@ void UBTService_MJCheckAttackRange::TickNode(UBehaviorTreeComponent& OwnerComp, * HowTo: 설정한 태그를 가지고 있는 태그와 비교해서 구체적인 태그를 가져온다. * 가져온 태그로 Skill Set 가져온다. */ - - /*if (!Enemy->HasAnyMatchingGameplayTags(SkillTags)) - { - MJ_LOG(LogMJ, Log, TEXT("Has not AnyMatchingGameplayTags")); - return; - }*/ - UMJSkillComponentBase* SkillComp = Enemy->GetSkillComponent(); FGameplayTag SkillTag = FGameplayTag::EmptyTag; @@ -127,9 +123,6 @@ void UBTService_MJCheckAttackRange::TickNode(UBehaviorTreeComponent& OwnerComp, const float MinimumAttackRange = Character->GetCapsuleComponent()->GetScaledCapsuleRadius() * ((Offset!=0)?Offset:1); const float MaximumAttackRange = MinimumAttackRange + AttackRange; - //DrawDebugCircle(GetWorld(), ControlledPawn->GetActorLocation(), MaximumAttackRange, 16, FColor::Emerald, false, 0.2f, 0, 0, FVector::RightVector,FVector::ForwardVector, false); - //DrawDebugCircle(GetWorld(), ControlledPawn->GetActorLocation(), MinimumAttackRange, 16, FColor::Magenta, false, 0.2f, 0, 0, FVector::RightVector,FVector::ForwardVector, false); - bool IsInAttackRange = DistanceToTarget <= MaximumAttackRange && DistanceToTarget >= MinimumAttackRange; @@ -185,12 +178,9 @@ void UBTService_MJCheckAttackRange::TickNode(UBehaviorTreeComponent& OwnerComp, OwnerComp.GetBlackboardComponent()->SetValueAsVector("KeepDistancePos", MoveToLocation); } -void UBTService_MJCheckAttackRange::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) -{ - Super::PostEditChangeProperty(PropertyChangedEvent); -} - void UBTService_MJCheckAttackRange::InitializeFromAsset(UBehaviorTree& Asset) { Super::InitializeFromAsset(Asset); + + bCallTickOnSearchStart = true; } diff --git a/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.h b/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.h index 0543a435..9da86332 100644 --- a/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.h +++ b/Source/ProjectMJ/MJ/AI/BTService_MJCheckAttackRange.h @@ -13,6 +13,7 @@ * Last Modified By: Kim Minjin * Last Modified Date: (2025.08.10.) 하드코딩 수정. 스킬 태그를 받아와 스킬의 공격범위를 체크. KeepDistancePos 설정 */ + UCLASS() class PROJECTMJ_API UBTService_MJCheckAttackRange : public UBTService { @@ -23,7 +24,6 @@ class PROJECTMJ_API UBTService_MJCheckAttackRange : public UBTService protected: virtual void TickNode(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, float DeltaSeconds) override; - virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override; virtual void InitializeFromAsset(UBehaviorTree& Asset) override; UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tag", meta=(Categories = "Skill")) @@ -31,6 +31,4 @@ class PROJECTMJ_API UBTService_MJCheckAttackRange : public UBTService FVector PreTargetLocation; FVector CurrTargetLocation; - - UBehaviorTreeComponent* CachedOwnerComp; }; diff --git a/Source/ProjectMJ/MJ/AI/BTTask_MJAppear.cpp b/Source/ProjectMJ/MJ/AI/BTTask_MJAppear.cpp index 1061d637..576edda3 100644 --- a/Source/ProjectMJ/MJ/AI/BTTask_MJAppear.cpp +++ b/Source/ProjectMJ/MJ/AI/BTTask_MJAppear.cpp @@ -21,9 +21,6 @@ EBTNodeResult::Type UBTTask_MJAppear::ExecuteTask(UBehaviorTreeComponent& OwnerC return EBTNodeResult::Failed; } - // ControlledPawn->SetActorHiddenInGame(false); - // ControlledPawn->SetActorEnableCollision(true); - OwnerComp.GetBlackboardComponent()->SetValueAsBool("IsAppear", true); AMJCharacterBase* Character = Cast(ControlledPawn); diff --git a/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.cpp b/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.cpp index ce535f40..8ee52cd8 100644 --- a/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.cpp +++ b/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.cpp @@ -14,6 +14,8 @@ UBTTask_MJNormalAttack::UBTTask_MJNormalAttack() { NodeName = TEXT("Normal Attack"); + + INIT_TASK_NODE_NOTIFY_FLAGS(); } EBTNodeResult::Type UBTTask_MJNormalAttack::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) @@ -35,7 +37,35 @@ EBTNodeResult::Type UBTTask_MJNormalAttack::ExecuteTask(UBehaviorTreeComponent& SkillComponent->ActivateNormalSkill(); + Handle = ASC->OnAbilityEnded.AddLambda( + [&](const FAbilityEndedData& EndedData) + { + MJ_LOG(LogMJ, Error,TEXT("A")); + FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded); + }); + MJ_LOG(LogMJ, Warning, TEXT("Normal Attack")); - return EBTNodeResult::Succeeded; + return EBTNodeResult::InProgress; +} + +void UBTTask_MJNormalAttack::OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, + EBTNodeResult::Type TaskResult) +{ + APawn* ControlledPawn = OwnerComp.GetAIOwner()->GetPawn(); + if (ControlledPawn == nullptr) + { + return; + } + + AMJMonsterCharacter* Monster = Cast(ControlledPawn); + if (Monster == nullptr) + { + return; + } + UAbilitySystemComponent* ASC = Monster->GetAbilitySystemComponent(); + ASC->OnAbilityEnded.Remove(Handle); + MJ_LOG(LogMJ, Error,TEXT("Remove Handle.")); + + Super::OnTaskFinished(OwnerComp, NodeMemory, TaskResult); } diff --git a/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.h b/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.h index 3ffd1633..696c64fd 100644 --- a/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.h +++ b/Source/ProjectMJ/MJ/AI/BTTask_MJNormalAttack.h @@ -22,5 +22,9 @@ class PROJECTMJ_API UBTTask_MJNormalAttack : public UBTTaskNode UBTTask_MJNormalAttack(); protected: + FDelegateHandle Handle; + virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override; + + virtual void OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult) override; }; diff --git a/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.cpp b/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.cpp index 923fc4f4..9baaef6f 100644 --- a/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.cpp +++ b/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.cpp @@ -5,12 +5,14 @@ #include "AIController.h" #include "ProjectMJ.h" +#include "BehaviorTree/BlackboardComponent.h" #include "Character/Component/MJEnemySkillComponent.h" #include "MJ/Character/MJMonsterCharacter.h" UBTTask_MJSkillAttack::UBTTask_MJSkillAttack() { NodeName = TEXT("SkillAttack"); + INIT_TASK_NODE_NOTIFY_FLAGS(); } EBTNodeResult::Type UBTTask_MJSkillAttack::ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) @@ -31,8 +33,34 @@ EBTNodeResult::Type UBTTask_MJSkillAttack::ExecuteTask(UBehaviorTreeComponent& O UMJEnemySkillComponent* SkillComponent = Monster->GetSkillComponent(); SkillComponent->ActivateIdentitySkill(); + Handle = ASC->OnAbilityEnded.AddLambda( + [&](const FAbilityEndedData& EndedData) + { + MJ_LOG(LogMJ, Error,TEXT("A")); + FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded); + }); MJ_LOG(LogMJ, Warning, TEXT("Skill Attack")); - return EBTNodeResult::Succeeded; + return EBTNodeResult::InProgress; +} + +void UBTTask_MJSkillAttack::OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, + EBTNodeResult::Type TaskResult) +{ + APawn* ControlledPawn = OwnerComp.GetAIOwner()->GetPawn(); + if (ControlledPawn == nullptr) + { + return; + } + + AMJMonsterCharacter* Monster = Cast(ControlledPawn); + if (Monster == nullptr) + { + return; + } + UAbilitySystemComponent* ASC = Monster->GetAbilitySystemComponent(); + ASC->OnAbilityEnded.Remove(Handle); + MJ_LOG(LogMJ, Error,TEXT("Remove Handle.")); + Super::OnTaskFinished(OwnerComp, NodeMemory, TaskResult); } diff --git a/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.h b/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.h index 3befa54e..b88416e8 100644 --- a/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.h +++ b/Source/ProjectMJ/MJ/AI/BTTask_MJSkillAttack.h @@ -22,6 +22,9 @@ class PROJECTMJ_API UBTTask_MJSkillAttack : public UBTTaskNode UBTTask_MJSkillAttack(); protected: - virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override; + FDelegateHandle Handle; + virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override; + + virtual void OnTaskFinished(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory, EBTNodeResult::Type TaskResult) override; }; diff --git a/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp b/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp index cc5f6a0a..98e6467f 100644 --- a/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp +++ b/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.cpp @@ -104,15 +104,15 @@ void AMJMonsterAIControllerBase::TargetPerceptionUpdated(AActor* Actor, FAIStimu // Minjin: 감지한 첫 순간 if(Stimulus.Type == UAISense::GetSenseID()) { - HandleSight_Detected(Actor, Stimulus); + HandleSightDetected(Actor, Stimulus); } else if (Stimulus.Type == UAISense::GetSenseID()) { - HandleDamage_Detected(Actor, Stimulus); + HandleDamageDetected(Actor, Stimulus); } else if(Stimulus.Type == UAISense::GetSenseID()) { - HandleHearing_Detected(Actor, Stimulus); + HandleHearingDetected(Actor, Stimulus); } } else @@ -120,15 +120,15 @@ void AMJMonsterAIControllerBase::TargetPerceptionUpdated(AActor* Actor, FAIStimu // Minjin: 감지 실패한 첫 순간 if(Stimulus.Type == UAISense::GetSenseID()) { - HandleSight_Lost(Actor, Stimulus); + HandleSightLost(Actor, Stimulus); } else if (Stimulus.Type == UAISense::GetSenseID()) { - HandleDamage_Lost(Actor, Stimulus); + HandleDamageLost(Actor, Stimulus); } else if(Stimulus.Type == UAISense::GetSenseID()) { - HandleHearing_Lost(Actor, Stimulus); + HandleHearingLost(Actor, Stimulus); } } } @@ -190,42 +190,42 @@ ETeamAttitude::Type AMJMonsterAIControllerBase::GetTeamAttitudeTowards(const AAc } } -void AMJMonsterAIControllerBase::HandleSight_Detected(AActor* Actor, FAIStimulus Stimulus) +void AMJMonsterAIControllerBase::HandleSightDetected(AActor* Actor, FAIStimulus Stimulus) { Blackboard->SetValueAsObject("Target", Actor); UE_LOG(LogMJ, Log, TEXT("시야로 감지")); Blackboard->SetValueAsBool("IsTargetVisible", true); } -void AMJMonsterAIControllerBase::HandleDamage_Detected(AActor* Actor, FAIStimulus Stimulus) +void AMJMonsterAIControllerBase::HandleDamageDetected(AActor* Actor, FAIStimulus Stimulus) { UE_LOG(LogMJ, Log, TEXT("데미지로 감지")); Blackboard->SetValueAsVector("DamagePos", Stimulus.StimulusLocation); } -void AMJMonsterAIControllerBase::HandleHearing_Detected(AActor* Actor, FAIStimulus Stimulus) +void AMJMonsterAIControllerBase::HandleHearingDetected(AActor* Actor, FAIStimulus Stimulus) { UE_LOG(LogMJ, Log, TEXT("소리로 감지")); Blackboard->SetValueAsVector("HearingPos", Stimulus.StimulusLocation); } -void AMJMonsterAIControllerBase::HandleHearing_Lost(AActor* Actor, FAIStimulus Stimulus) +void AMJMonsterAIControllerBase::HandleHearingLost(AActor* Actor, FAIStimulus Stimulus) { UE_LOG(LogMJ, Log, TEXT("소리감지 해제")); Blackboard->ClearValue("HearingPos"); } -void AMJMonsterAIControllerBase::HandleSight_Lost(AActor* Actor, FAIStimulus Stimulus) +void AMJMonsterAIControllerBase::HandleSightLost(AActor* Actor, FAIStimulus Stimulus) { UE_LOG(LogTemp, Log, TEXT("시야 감지 해제")); Blackboard->SetValueAsVector("LastKnownPos", Stimulus.StimulusLocation); Blackboard->ClearValue("IsTargetVisible"); } -void AMJMonsterAIControllerBase::HandleDamage_Lost(AActor* Actor, FAIStimulus Stimulus) +void AMJMonsterAIControllerBase::HandleDamageLost(AActor* Actor, FAIStimulus Stimulus) { UE_LOG(LogMJ, Log, TEXT("데미지 감지 해제")); diff --git a/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.h b/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.h index 2ba88c11..b25acc55 100644 --- a/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.h +++ b/Source/ProjectMJ/MJ/AI/MJMonsterAIControllerBase.h @@ -55,20 +55,20 @@ class PROJECTMJ_API AMJMonsterAIControllerBase : public AAIController // Minjin: Handle AI Sense // 자식 클래스에서 오버라이드해서 각 감각별로 다른 처리 진행 UFUNCTION() - virtual void HandleSight_Detected(AActor* Actor, FAIStimulus Stimulus); + virtual void HandleSightDetected(AActor* Actor, FAIStimulus Stimulus); UFUNCTION() - virtual void HandleDamage_Detected(AActor* Actor, FAIStimulus Stimulus); + virtual void HandleDamageDetected(AActor* Actor, FAIStimulus Stimulus); UFUNCTION() - virtual void HandleHearing_Detected(AActor* Actor, FAIStimulus Stimulus); + virtual void HandleHearingDetected(AActor* Actor, FAIStimulus Stimulus); UFUNCTION() - virtual void HandleSight_Lost(AActor* Actor, FAIStimulus Stimulus); + virtual void HandleSightLost(AActor* Actor, FAIStimulus Stimulus); UFUNCTION() - virtual void HandleDamage_Lost(AActor* Actor, FAIStimulus Stimulus); + virtual void HandleDamageLost(AActor* Actor, FAIStimulus Stimulus); UFUNCTION() - virtual void HandleHearing_Lost(AActor* Actor, FAIStimulus Stimulus); + virtual void HandleHearingLost(AActor* Actor, FAIStimulus Stimulus); }; diff --git a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp index c5dd57d3..58e24549 100644 --- a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp +++ b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.cpp @@ -20,6 +20,7 @@ #include "UI/MJUIManagerSubsystem.h" #include "TG/MJGameInstance.h" #include "Character/Component/MJPlayerStatComponent.h" +#include "Components/CapsuleComponent.h" #include "DataAsset/MJStateAbilityDataAsset.h" #include "Item/MJItemBase.h" #include "Kismet/GameplayStatics.h" @@ -202,7 +203,9 @@ void AMJMonsterCharacter::GiveDeathRewardTo() if (ItemClass) { FVector SpawnLocation = GetActorLocation(); - //SpawnLocation.Z = 0.0f; + float CapsuleHalfHeight = GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); + SpawnLocation.Z -= CapsuleHalfHeight; + FTransform SpawnTransform(SpawnLocation); if (GetWorld()) { diff --git a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h index dc31b7a9..be333c27 100644 --- a/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h +++ b/Source/ProjectMJ/MJ/Character/MJMonsterCharacter.h @@ -8,6 +8,7 @@ #include "Character/MJCharacterBase.h" #include "AbilitySystem/MJAbilitySystemComponent.h" #include "AbilitySystemComponent.h" +#include "ProjectMJ.h" #include "MJMonsterCharacter.generated.h" class UMJEnemySkillComponent; @@ -74,7 +75,7 @@ class PROJECTMJ_API AMJMonsterCharacter : public AMJCharacterBase, public IGamep bool HasAnyMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override { - return ASC->HasAllMatchingGameplayTags(TagContainer); + return ASC->HasAnyMatchingGameplayTags(TagContainer); } protected: diff --git a/Source/ProjectMJ/MJ/DataAssetMJ/MJDropItemsDataAsset.cpp b/Source/ProjectMJ/MJ/DataAssetMJ/MJDropItemsDataAsset.cpp index f929a8a5..0871067c 100644 --- a/Source/ProjectMJ/MJ/DataAssetMJ/MJDropItemsDataAsset.cpp +++ b/Source/ProjectMJ/MJ/DataAssetMJ/MJDropItemsDataAsset.cpp @@ -21,9 +21,9 @@ FGameplayTag UMJDropItemsDataAsset::TryDropItem() const return FGameplayTag::EmptyTag; } - int32 IndexRamge = DropItems.Num()-1; + int32 IndexRange = DropItems.Num()-1; - int32 RandIndex = UKismetMathLibrary::RandomIntegerInRange(0, IndexRamge); + int32 RandIndex = UKismetMathLibrary::RandomIntegerInRange(0, IndexRange); FGameplayTag ItemTag = DropItems[RandIndex].ItemTag; diff --git a/Source/ProjectMJ/MJ/Drop/MJTargetingProjectileBase.cpp b/Source/ProjectMJ/MJ/Drop/MJTargetingProjectileBase.cpp index a00744b2..7d152190 100644 --- a/Source/ProjectMJ/MJ/Drop/MJTargetingProjectileBase.cpp +++ b/Source/ProjectMJ/MJ/Drop/MJTargetingProjectileBase.cpp @@ -62,7 +62,7 @@ void AMJTargetingProjectileBase::BeginPlay() ProjectileMovement->Velocity = NewVelocity; ProjectileMovement->InitialSpeed = 300.0f; - ProjectileMovement->MaxSpeed = 600.0f; + ProjectileMovement->MaxSpeed = 1000.0f; ProjectileMovement->bIsHomingProjectile = true; ProjectileMovement->HomingAccelerationMagnitude = 300.0f; @@ -91,7 +91,7 @@ void AMJTargetingProjectileBase::Tick(float DeltaSeconds) } float Distance = GetDistanceTo(Target); - ProjectileMovement->MaxSpeed = FMath::GetMappedRangeValueClamped(FVector2D(0.0f, 600.0f), FVector2D(1.0f, 600.0f), Distance); + ProjectileMovement->MaxSpeed = FMath::GetMappedRangeValueClamped(FVector2D(0.0f, 600.0f), FVector2D(600.0f, 1000.0f), Distance); } // MJ_LOG(LogMJ, Warning, TEXT("MaxSpeed: %f"), ProjectileMovement->MaxSpeed); diff --git a/Source/ProjectMJ/MJ/Drop/Notify_MJSpawnTargetProjectile.cpp b/Source/ProjectMJ/MJ/Drop/Notify_MJSpawnTargetProjectile.cpp index de4702c2..4193961d 100644 --- a/Source/ProjectMJ/MJ/Drop/Notify_MJSpawnTargetProjectile.cpp +++ b/Source/ProjectMJ/MJ/Drop/Notify_MJSpawnTargetProjectile.cpp @@ -6,6 +6,7 @@ #include "MJTargetingProjectileBase.h" #include "ProjectMJ.h" #include "Character/MJPlayerCharacter.h" +#include "Components/CapsuleComponent.h" #include "MJ/Character/MJMonsterCharacter.h" UNotify_MJSpawnTargetProjectile::UNotify_MJSpawnTargetProjectile() @@ -36,8 +37,10 @@ void UNotify_MJSpawnTargetProjectile::Notify(USkeletalMeshComponent* MeshComp, U if (TargetingProjectile) { FVector SpawnLocation = Player->GetActorLocation(); - SpawnLocation.Z = 0.0f; + float CapsuleHalfHeight = Player->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); + SpawnLocation.Z -= CapsuleHalfHeight; FTransform SpawnTransform(SpawnLocation); + AMJTargetingProjectileBase* Projectile = Player->GetWorld()->SpawnActorDeferred(TargetingProjectile, SpawnTransform/*, this, this, ESpawnActorCollisionHandlingMethod::AlwaysSpawn*/); MJ_LOG(LogMJ, Warning, TEXT("Create TargetProjectile")); @@ -56,14 +59,22 @@ void UNotify_MJSpawnTargetProjectile::Notify(USkeletalMeshComponent* MeshComp, U MJ_LOG(LogMJ, Warning, TEXT("Target is nullptr")); return; } + AMJPlayerCharacter* TargetPlayer = Cast(Enemy->GetEnemyBequest().Target); + if (TargetPlayer == nullptr) + { + MJ_LOG(LogMJ, Warning, TEXT("Target is not Player.")); + return; + } if (!Enemy->GetEnemyBequest().IdentitySkillTag.IsValid()) { MJ_LOG(LogMJ, Warning, TEXT("SkillTage is not valid")); return; } FVector SpawnLocation = Enemy->GetActorLocation(); - SpawnLocation.Z = 0.0f; + float CapsuleHalfHeight = Enemy->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); + SpawnLocation.Z -= CapsuleHalfHeight; FTransform SpawnTransform(SpawnLocation); + AMJTargetingProjectileBase* Projectile = Enemy->GetWorld()->SpawnActorDeferred(TargetingProjectile, SpawnTransform/*, this, this, ESpawnActorCollisionHandlingMethod::AlwaysSpawn*/); MJ_LOG(LogMJ, Warning, TEXT("Create TargetProjectile"));