์ค๋์ ์ํฝ ๋ชฌ์คํฐ(๋๋๊ณคยท๋๋ฌด ๋ชฌ์คํฐยท๋ฐ์ ๋ชฌ์คํฐ) ์ ๋ฐ์ ๊ฑธ์ณ ์ธ ๊ฐ์ง ํฐ ์ฃผ์ ๋ฅผ ๋ค๋ค๋ค.
์ฒ์์๋ ๊ฐ๊ฐ ๋ ๋ฆฝ๋ ๋ฌธ์ ์ฒ๋ผ ๋ณด์์ง๋ง, ํฌ์ฌ์ฒด ์ถฉ๋ ์ฒ๋ฆฌ โ GAS GameplayEffect ์ ์ฉ โ ํจ๋ฆฌ ์ํ ํ๊ทธ โ ํจํด ์นด์ดํฐยท๊ทธ๋ก๊ธฐ ์ด๋ฒคํธ โ ๊ณต์ค/์ง์ ์ํ ์ ํ โ AnimBP ์๋ ๋ณ์ยท์ฌ๋กฏ ๋ชฝํ์ฃผ โ ์ปค๋งจ๋๋ ์ ํตํ Blueprint/Asset CDO ์ค์ ๊น์ง ์ฌ๋ฌ ์์คํ ์ด ์ด์ด์ ธ ์์๋ค.
๋๋๊ณค์ด ๋ฐ์ฌํ ๋ผ๋ฐ ํฌ์ฌ์ฒด๊ฐ ํ๋ ์ด์ด์๊ฒ ๋ฟ์๋ ๋ฐ๋ฏธ์ง๊ฐ ์ ์ฉ๋์ง ์์๋ค. ํฌ์ฌ์ฒด ์์ฒด๋ ์คํฐ๋๊ณ ์ถฉ๋๋ ๋ฐ์ํ์ง๋ง, GAS ๋ฐ๋ฏธ์ง ์ ์ฉ๊น์ง ์ด์ด์ง์ง ์์๋ค.
AEnemyProjectile::OnProjectileOverlap์ ์ถฉ๋ ์ฒ๋ฆฌ ์์ ๋ฌธ์ ๋ค. ํฌ์ฌ์ฒด BP CDO์ DamageEffectClass๊ฐ ์๊ฑฐ๋, ๋ฐ์ฌ ํ์ ๊ณผ ๋ฐ๋ฏธ์ง ํ์ ์ ์์๊ฐ ์ถฉ๋ํ๋ฉด ๋ฐ๋ฏธ์ง๊ฐ ๋ฌปํ๋ค.
์ฌ๋ฐ๋ฅธ ์ฒ๋ฆฌ ์์:
1. ๋ฌด์ํด์ผ ํ๋ ์กํฐ์ธ์ง ํ์ธ
2. ์ด๋ฏธ ๋ฐ์ฌ๋ ํฌ์ฌ์ฒด์ธ์ง ํ์ธ (HandleReflectedOverlap)
3. ๋์ ASC ํ๋
4. ํจ๋ฆฌ ์ค์ด๋ฉด ๋ฐ์ฌ ์ฒ๋ฆฌ (TryReflectOnHit)
5. ์ผ๋ฐ ํผ๊ฒฉ์ด๋ฉด DamageEffect ์ ์ฉ
6. ๋๋ฐฑ, Impact VFX, Destroy ์ฒ๋ฆฌ
Source/Retrieve/AbilitySystem/Enemy/EnemyProjectile.cpp์์ ์ถฉ๋ ํ๋ฆ์ ์ ๋ฆฌํ๋ค.
if (HandleReflectedOverlap(OtherActor, SweepResult))
{
return;
}
UAbilitySystemComponent* TargetASC = ...;
if (!TargetASC)
{
return;
}
if (HasAuthority() && TryReflectOnHit(OtherActor, TargetASC))
{
return;
}
if (HasAuthority() && DamageEffectClass)
{
SourceASC->ApplyGameplayEffectSpecToTarget(*Spec.Data.Get(), TargetASC);
}
RetrieveConfigureEpicMonstersCommandlet.cpp์์ ๋ผ๋ฐ/๋ฌผ ํฌ์ฌ์ฒด BP CDO์ ๋ค์ ๊ฐ์ ์ง์ ํ๋ค.
DamageEffectClass โ /Game/Retrieve/AbilitySystem/Player/GE_BasicHitDamage.GE_BasicHitDamage_CFlightVFX, ImpactVFXํ๋ ์ด์ด๊ฐ R ํค๋ก ํจ๋ฆฌ์ ์ฑ๊ณตํด๋ ๋๋๊ณค ํฌ์ฌ์ฒด๊ฐ ๋๋์๊ฐ์ง ์์๋ค.
๋ฐ์ฌ ๊ฐ๋ฅํ ํฌ์ฌ์ฒด๋ ๋ฐ๋ฏธ์ง ํ์ ๋ณด๋ค ๋จผ์ ํ๋ ์ด์ด์ ํจ๋ฆฌ ์ํ(State.Player.Parrying ํ๊ทธ)๋ฅผ ํ์ธํด์ผ ํ๋ค. ํด๋น ํ๊ทธ๊ฐ ์์ผ๋ฉด ๋ฐ๋ฏธ์ง๋ฅผ ์ฃผ์ง ์๊ณ ๋๋๊ณค์ ์นด์ดํฐ ํ๊ฒ์ผ๋ก ์ผ์ ๋ฐฉํฅ์ ๋ฐ๊ฟ์ผ ํ๋ค.
Source/Retrieve/AbilitySystem/Enemy/EpicEnemyProjectile.cpp์ ์ํฝ ํฌ์ฌ์ฒด ์ ์ฉ ๋ฐ์ฌ ํ๋ฆ์ ๊ตฌํํ๋ค.
TryReflectOnHit ์กฐ๊ฑด:
bReflectable = truebReflected = false (์์ง ๋ฐ์ฌ ์ )State_Player_Parrying ํ๊ทธ ์์ํจ๋ฆฌ ์ฑ๊ณต ์ ์ฒ๋ฆฌ:
GameplayEvent_Parry_Success ์ ์กOptionalObject์ ๋๋๊ณค(๋ฐ์ฌ ์นด์ดํฐ ํ๊ฒ) ์ธํ
ReflectTowardCounterTarget(OtherActor) ํธ์ถReflectTowardCounterTarget์์ ๋ณ๊ฒฝํ๋ ๊ฐ:
ReflectedInstigator = ParryingActorbReflected = trueReflectedSpeedMultiplier ์ ์ฉ ํ ๋๋๊ณค ๋ฐฉํฅ์ผ๋ก ์ฌ๋ฐ์ฌconst FVector Direction = (TargetLocation - GetActorLocation()).GetSafeNormal();
const float CurrentSpeed = FMath::Max(ProjectileMovement->Velocity.Size(), ProjectileMovement->MaxSpeed);
const float ReflectedSpeed = FMath::Max(CurrentSpeed * ReflectedSpeedMultiplier, 300.f);
Launch(Direction, ReflectedSpeed);
SetActorRotation(Direction.Rotation());
๋ฐ์ฌ๋ ํฌ์ฌ์ฒด๊ฐ ๋๋๊ณค์๊ฒ ๋์๊ฐ์ง๋ง, ๊ณต์ค ์ํ์์ ๊ทธ๋ก๊ธฐ๊ฐ ๊ฑธ๋ ค ํ๋ ์ด์ด๊ฐ ์ง์ ๊ณต๊ฒฉ์ผ๋ก ๋๋ฆฌ๊ธฐ ์ด๋ ค์ ๋ค. ํจํด ํํผ ๋ณด์์ผ๋ก ๊ธฐ๋ฅํ์ง ๋ชปํ๋ ์ํ.
๋๋๊ณค์ ๊ณต์ค ํจํด ์ค ํฌ์ฌ์ฒด๋ฅผ ๋ฐ์ฌํ๋ฏ๋ก, ์นด์ดํฐ ํ๊ฒ ์ ์ค ์์ ์๋ AerialMode, MOVE_Flying, ๊ณต์ค ์ฌ๋กฏ ์ ๋๋ฉ์ด์
์ด ๋จ์ ์๋ค. ๊ทธ๋ก๊ธฐ๋ ํ๋ ์ด์ด๊ฐ ์ค์ ๋ก ๊ณต๊ฒฉํ ์ ์๋ ์ ํฌ ๋ณด์ ์ํ์ฌ์ผ ํ๋ฏ๋ก, ์ ์ฉ ์ ์ ์์น์ MovementMode๋ฅผ ์ง์ ๊ธฐ์ค์ผ๋ก ์ ๋ฆฌํด์ผ ํ๋ค.
AEpicEnemyProjectile::HandleReflectedOverlap์์ bReflected ์ํ์ธ ํฌ์ฌ์ฒด๋ ๋ฒ ์ด์ค ๋ฐ๋ฏธ์ง ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๋๋ก ๋ถ๋ฆฌํ๋ค.
if (!bReflected)
{
return false;
}
if (TryApplyReflectedCounter(OtherActor))
{
PlayImpactVFX(...);
Destroy();
}
return true;
TryApplyReflectedCounter์์ ์นด์ดํฐ ์ ์ฉ ์ ์ง์ ๋ณด์ :
ForceEnemyToGroundForGroggy(CounterTarget)
โโ SetAerialMode(false)
โโ ์๋ ๋ฐฉํฅ ๋ผ์ธํธ๋ ์ด์ค โ ์บก์ half height ๋ณด์ ์ผ๋ก ์ง๋ฉด ๋ฐฐ์น
โโ CharacterMovement โ MOVE_Walking
โโ StopMovementImmediately
โโ DefaultSlot ์ฌ๋กฏ ์ ๋๋ฉ์ด์
์ ์ง
์ดํ ์นด์ดํฐ ์ฒ๋ฆฌ:
PatternCounterComponent->OpenCounterWindow(0.1f)
PatternCounterComponent->TryCounter(Ability_Player_Parry, Element_None, ReflectedInstigator)
PatternCounterComponent.cpp์์ ๊ทธ๋ก๊ธฐ ์ด๋ฒคํธ EventMagnitude์ GroggyDuration์ด ๋ค์ด๊ฐ๋๋ก ์์ ํด ๋ฐ์ดํฐ ๊ธฐ๋ฐ ๊ทธ๋ก๊ธฐ ์ง์ ์๊ฐ ์ ์ฉ.
๋๋๊ณค์ด ์ง์์์ ์ถ์ ์ด๋ ์ค์ธ๋ฐ ๊ฑท๊ธฐ ์ ๋๋ฉ์ด์ ์์ด idle ํฌ์ฆ๋ก ๋ฏธ๋๋ฌ์ง๋ ํ์์ด ๋ฐ๋ณต๋๋ค.
| ์์ธ | ์ค๋ช |
|---|---|
| Velocity ๊ธฐ๋ฐ Speed ๊ณ์ฐ | AI ์ด๋ยท์บก์ ๋ณด์ ยทStateTree ์ด๋์ด ์์ด๋ฉด Actor ์์น๋ ๋ณํด๋ Velocity๊ฐ ์๊ฐ ๋ฎ๊ฒ ์กํ๋ ํ๋ ์ ๋ฐ์ |
| DefaultSlot ์ฌ๋กฏ ๋ชฝํ์ฃผ ์ถฉ๋ | ๊ณต๊ฒฉยท๊ณต์คยท์ฐฉ์งยทํ์ ๋ชฝํ์ฃผ๊ฐ DefaultSlot์ ์ฌ์ฉํ๋ฉด์ ์ง์ ์ด๋ ํฌ์ฆ๋ฅผ ๋ฎ๋ ์๊ฐ ๋ฐ์ |
| Chase ํ๊ทธ ๋ถ์ผ์น | ๊ณต์คโ์ง์ ์ ํ ์ค State.Enemy.Chase ํ๊ทธ์ ์ค์ ์ด๋ ์ํ๊ฐ ์๊ฐ์ ์ผ๋ก ๋ถ์ผ์น |
| AnimBP Direction ๊ณ์ฐ | Direction์ด ํ๊ฒ facing์ด ์๋ ์ด๋ ๋ฐฉํฅ ๊ธฐ์ค์ผ๋ก ๊ณ์ฐ โ ์ ๋ฐฉํฅ์ด ๋ค๋ฅด๋ฉด strafe ๋ธ๋ ๋์คํ์ด์ค ์
๋ ฅ |
Source/Retrieve/Animation/RetrieveEnemyAnimInstance.cpp์์ Velocity๋ง ์ฐ์ง ์๊ณ Actor ์์น ๋ณํ๋๋ ํจ๊ป ์ํ๋งํ๋ค.
์ถ๊ฐ ์ํ: CachedPawnForMovementSample, LastMovementSampleLocation, bHasMovementSampleLocation
const FVector Velocity2D(Pawn->GetVelocity().X, Pawn->GetVelocity().Y, 0.f);
FVector Movement2D = Velocity2D;
const FVector DeltaLocation2D = ActorLocation - LastMovementSampleLocation;
const FVector LocationDeltaVelocity2D = DeltaLocation2D / DeltaSeconds;
if (LocationDeltaVelocity2D.SizeSquared() > Movement2D.SizeSquared())
{
Movement2D = LocationDeltaVelocity2D;
}
Speed = Movement2D.Size();
Source/Retrieve/Character/RetrieveEpicMonsterCharacter.cpp์ Tick์์ ์ง์ ์ด๋ ์ฌ๋ถ๋ฅผ ๋ณ๋๋ก ํ๋จํด AnimInstance์ Reflection์ผ๋ก ์ง์ ์ธํ
ํ๋ค.
์ด๋ ํ๋จ ์ ์ธ ์กฐ๊ฑด: Falling/Flying, ๊ณต๊ฒฉ/ํน์๊ณต๊ฒฉ/ํผ๊ฒฉ/์คํ๊ฑฐ/๊ทธ๋ก๊ธฐ/์ฌ๋ง ์ํ
์ธํ
ํ๋ ๋ณ์ (ํ๋กํผํฐ๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ์๋ง):
Speed, GroundSpeed, Direction, IsMoving, bIsMoving, ShouldMove, bShouldMove, IsChasing, bIsChasing
์ค์ ์ด๋ ์ค์ธ๋ฐ State.Enemy.Chase ํ๊ทธ๊ฐ ์๋ ๊ฒฝ์ฐ๋ฅผ ์ํด C++์์ ์์๋ก loose tag๋ฅผ ๋ถ์ธ๋ค.
// ์ด๋ ๊ฐ์ง ์
ASC->AddLooseGameplayTag(State_Enemy_Chase);
bMovementDrivenChaseTagAdded = true;
// ์ด๋ ์ข
๋ฃ ์ (๋ด๊ฐ ๋ถ์ธ ํ๊ทธ๋ง ์ ๊ฑฐ)
if (bMovementDrivenChaseTagAdded)
{
ASC->RemoveLooseGameplayTag(State_Enemy_Chase);
bMovementDrivenChaseTagAdded = false;
}
bMovementDrivenChaseTagAdded๋ฅผ ๋ ์ด์ : ๋ค๋ฅธ ์์คํ
์ด ๋ถ์ธ Chase ํ๊ทธ๋ฅผ ์ค์๋ก ์ ๊ฑฐํ์ง ์๊ธฐ ์ํจ.
RetrieveEpicMonsterCharacter.h์ Dragon BP์์ ์ค์ ๊ฐ๋ฅํ fallback ํ๋๋ฅผ ์ถ๊ฐํ๋ค.
ForcedGroundMoveAnimationForcedGroundMovePlayRateGroundMoveMontage์ง์ ์ด๋์ด ๊ฐ์ง๋๊ณ ์์ ์ํ(๊ณต๊ฒฉ/ํผ๊ฒฉ/๊ทธ๋ก๊ธฐ ๋ฑ)๊ฐ ์๋๋ฉด ForcedGroundMoveAnimation์ DefaultSlot ๋์ ๋ชฝํ์ฃผ๋ก ๋ฐ๋ณต ์ฌ์ํ๋ค.
GroundMoveMontage = AnimInstance->PlaySlotAnimationAsDynamicMontage(
MoveSequence,
TurnAnimationSlot,
0.12f, // BlendIn
0.12f, // BlendOut
ForcedGroundMovePlayRate,
999); // Priority
StopLocomotionMontages์์ ํ์ ๋ชฝํ์ฃผ์ ์ด๋ ๋ชฝํ์ฃผ๋ฅผ ํจ๊ป ์ ๋ฆฌํ๋๋ก ์์ :
GroundTurnMontageGroundMoveMontageGroundTurnDirectionC++์์ Speed๋ฅผ ์ ๋ฃ์ด๋ AnimBP ๊ทธ๋ํ๊ฐ ํด๋น ๊ฐ์ ์ ๋๋ก ์ฐ์ง ์๊ฑฐ๋, Slot ๋
ธ๋๊ฐ Root ์์ ์์ผ๋ฉด ๋ชฝํ์ฃผ fallback์ด ์ต์ข
ํฌ์ฆ์ ๋ฐ์๋์ง ์๋๋ค.
RetrieveConfigureEpicMonstersCommandlet.cpp์์ ๋๋๊ณค AnimBPยทBlendSpace๋ฅผ ๊ตฌ์ฑํ๋ค.
์ฌ์ฉ ์์ :
Polygonal_Dragon_AnimationIdlePolygonal_Dragon_AnimationWalk_Forward_WO_Root/Game/Retrieve/AI/Animations/Dragon/BS_DragonChase/Game/Retrieve/AI/Animations/ABP_DragonEnemyAnimBP AnimGraph ๊ตฌ์กฐ:
Speed ๋ณ์
โ BlendSpacePlayer(BS_DragonChase)
โ Slot(DefaultSlot) โ ๋ฐ๋์ Root ์์
โ Root
DefaultSlot์ Root ์์ ๋๋ ์ด์ : C++์์ ์ฌ์ํ๋ ์ง์ ์ด๋ fallback ๋ชฝํ์ฃผยทํ์ ๋ชฝํ์ฃผยท๊ณต๊ฒฉ/๊ณต์ค ๊ณ์ด ๋ชฝํ์ฃผ๊ฐ ์ต์ข
AnimGraph์ ๋ฐ์๋๋๋ก ํ๊ธฐ ์ํจ.
์ปค๋งจ๋๋ ์์ BP_Dragon CDO์ ์ ์ฅํ ๊ฐ:
ForcedGroundMoveAnimationABP_DragonEnemy ParentClass: /Script/Retrieve.RetrieveEnemyAnimInstance
AnimGraph Nodes: 4
Root ์
๋ ฅ: AnimGraphNode_Slot
BlendSpacePlayer: BS_DragonChase
Slot: DefaultSlot
๋ผ๋ฐ ํฌ์ฌ์ฒด ๋นํ VFX๊ฐ ๋ถ๊ฝ ํธ๋ ์ผ์ด ์๋๋ผ ํ๋ฉด์์ ๊ฒฉ์ ํํ์ ํํฐํด ๋ฉ์ด๋ฆฌ๊ฐ ์ฐํ๋ ๊ฒ์ฒ๋ผ ๋ณด์๋ค.
๊ธฐ์กด NS_LavaProjectile_Flight์ Niagara ์ค์ ์ด ํฌ์ฌ์ฒด ๋นํ์ฉ ํธ๋ ์ผ๋ณด๋ค sprite/grid ํํ๊ฐ ๋๋๋ฌ์ง๋ ๊ตฌ์ฑ์ด์๋ค. ํฌ์ฌ์ฒด๊ฐ ๋น ๋ฅด๊ฒ ์์ง์ด๋ฉด ๊ฒฉ์๊ฐ์ด ๋ ๊ฐํ๊ฒ ๋ณด์๋ค.
๋ฐ์ด๋๋ฆฌ .uasset์ ์ง์ ์์ ํ์ง ์๊ณ , ์ปค๋งจ๋๋ ์์ ์์ ์ ์ธ ์ธ๋ถ Niagara ํธ๋ ์ผ ์์
์ ํฌ์ฌ์ฒด BP CDO์ ํ ๋นํ๋ค.
| ์ฉ๋ | ์์ |
|---|---|
| Flight VFX | /Game/External/PolygonParticleFX/Particles/NS_Trail_Fireball_01 |
| Impact VFX | /Game/External/PolygonFantasyVillage/PolygonGeneric/FX/NS_Fire_01 |
ConfigureProjectileBlueprintVFX์์ ์ค์ ํ ๋ด์ฉ:
FlightVFXComponent->SetAsset(FlightVFX)FlightVFXImpactVFXDamageEffectClassDragon/Treant/Magma ์ ์ฉ ๋ก์ง์ด ๊ณตํต ํ์ผ์ ์ง์ ์ฃผ์ ๋ ๊ฒ์ด ํต์ฌ์ด๋ค.
| ๊ณตํต ํ์ผ | ๋ฌธ์ |
|---|---|
RetrieveEnemyCharacter | Dragon ์ ์ฉ ํ์ /์ด๋ ์ค์ , ๊ณต์ค ํ์ด์ฆ ๋ก์ง์ด ์์ |
EnemyCombatComponent | ํจํด Sequence/Hitbox ํ๋๊ฐ Dragon ๊ตฌ์กฐ ๊ฐ์ |
GA_ShootProjectiles | AerialFireball/Rain/Spread ํ๋ณ์ด row ์ด๋ฆ ๋ฌธ์์ด ํ๋์ฝ๋ฉ |
StateTreeTask_EnemyAttack | 8๋ facing ๊ฒ์ดํธ + Dragon ์ ์ฉ ํ์ ๋ฐฉ์ ์ถฉ๋ |
๊ณต๊ฒฉ ๋ฐ๋ ์คํจ: FaceTargetForAttack() (์ง์ ํ์ )๊ณผ ApplyDragonGroundMovementSettings() (bOrientRotationToMovement)๊ฐ ๋์์ ํ์ฑํ โ 8๋ facing ๊ฒ์ดํธ๋ฅผ ์ ๋ ํต๊ณผ ๋ชป ํจ
ํน์ ํจํด ๋ฏธ๋ฐ๋: IsDragonAerialFireballPattern()์ด row ์ด๋ฆ ๋ฌธ์์ด ๋น๊ต๋ก ํ๋ณ โ ์ ํจํด ์ถ๊ฐ/๋ฆฌ๋ค์ ์ ์ฝ๋ ์์ ๋ถ๊ฐํผ
์ถ์ ์ด๋ ์์: ShiftOrbitSlot์ bOrientRotationToMovement ์ ํ์ด EnemyAttack์ ์ง์ ํ์ ๊ณผ ๊ณ์ ์ถฉ๋
strafe ์ ๋๋ฉ์ด์
: Direction์ด ํ๊ฒ facing์ด ์๋ ์ด๋ ๋ฐฉํฅ ๊ธฐ์ค โ ๊ณต๊ฒฉ ์ค ์ด๋ ๋ฐฉํฅ๊ณผ ํ๊ฒ ๋ฐฉํฅ์ด ๋ฌ๋ผ strafe ๋ธ๋ ๋์คํ์ด์ค ์
๋ ฅ
| ๋ถ๋ฆฌ ๋์ | ๋ฐฉ๋ฒ |
|---|---|
| ์ํฝ ๋ชฌ์คํฐ ๊ณตํต ๊ธฐ๋ฐ | ARetrieveEpicMonsterCharacter : ARetrieveEnemyCharacter ์ ๊ท ํด๋์ค |
| StateTree ํ์คํฌ | Monster_Type_Epic ํ๊ทธ๋ก Epic ํด๋์ค ๊ฒ์ฆ ํ ๋ถ๊ธฐ |
| ์ด๋น๋ฆฌํฐ ์์คํ | GA_EpicShootProjectiles ๋ณ๋ ๊ตฌํ + enum ๊ธฐ๋ฐ ํจํด ๋ถ๊ธฐ |
| ํฌ์ฌ์ฒด | AEpicEnemyProjectile ๋ณ๋ ๊ตฌํ (virtual hook ๋ถ๋ฆฌ) |
| DataTable | MonsterPattern row + SpawnPattern enum + VFX ์ค์ ์ผ๋ก ์ ํจํด ์ถ๊ฐ ๊ฐ๋ฅ |
Source/Retrieve/Character/RetrieveEpicMonsterCharacter.h/.cpp (์ ๊ท)Source/Retrieve/Character/RetrieveEnemyCharacter.cpp/.hSource/Retrieve/Enemy/StateTree/StateTreeTask_EnemyAttack.cppSource/Retrieve/Enemy/StateTree/StateTreeTask_EnemyPatternAttack.cppSource/Retrieve/Enemy/StateTree/StateTreeTask_ShiftOrbitSlot.cppSource/Retrieve/Components/Enemy/EnemyCombatComponent.cppSource/Retrieve/AbilitySystem/Enemy/GAS/GA_ShootProjectiles.cppSource/Retrieve/AbilitySystem/Enemy/GAS/GA_EpicShootProjectiles.cpp (์ ๊ท)Source/Retrieve/AbilitySystem/Enemy/EnemyProjectile.cppSource/Retrieve/AbilitySystem/Enemy/EpicEnemyProjectile.cpp (์ ๊ท)Source/Retrieve/Data/RetrieveDataTableTypes.hConfig/DefaultEngine.ini (CoreRedirects)์ฌ์ฉ ๋๊ตฌ: Monolith MCP + Niagara
๊ตฌ์กฐ: Flight VFX + Impact VFX ๋ถ๋ฆฌ
Phase 1 โ NS_DragonMeteor_Flight
NS_LavaRocks๋ฅผ duplicate_system์ผ๋ก ๋ณต์ NS_Smoke_Black_01 ๊ธฐ๋ฐ ๊ฒ์ ๊ถค์ ์ฐ๊ธฐPhase 2 โ NS_DragonMeteor_Impact
| ์์ | ์ญํ |
|---|---|
NS_LavaRocks | ๋ฉํ ์ค ๊ธฐ๋ณธ ๊ตฌ์กฐ (Flight ๋ฒ ์ด์ค) |
NS_Smoke_Black_01 | ๋ํ ๊ถค์ ์ฐ๊ธฐ |
M_Burst | ์ถฉ๊ฒฉ ํญ๋ฐ ํจ๊ณผ |
M_explosion_subUV | ํญ๋ฐ subUV ์ ๋๋ฉ์ด์ |
| ๋ฌธ์ | ํด๊ฒฐ |
|---|---|
add_emitter์ NiagaraSystem ํ์
์ ๋ฌ | NiagaraEmitter ๊ฒฝ๋ก๋ก ๋ด๋ถ emitter ์ง์ ์ฐธ์กฐ |
| Smoke Emitter ๊ฒฝ๋ก ๋ถํ์ค | NS_Smoke_Black_01.NS_Smoke_Black_01:Smoke_0 ํํ๋ก ์ง์ |
1. niagara_query: list_systems โ ๊ธฐ์กด ์์
ํ์
2. niagara_query: duplicate_system โ NS_LavaRocks โ NS_DragonMeteor_Flight
3. niagara_query: add_emitter โ Smoke emitter ์ถ๊ฐ
4. niagara_query: set_module_input_value โ ํ๋ผ๋ฏธํฐ ์กฐ์
5. niagara_query: save_system โ ์ ์ฅ
์ฐธ๊ณ ๋ฌธ์: C:\Users\lhw45\Downloads\TeamProject\CH5_Project\Docs\VFX_Niagara_Guide.md
๊ตฌ์กฐ: Flight / Impact๋ฅผ ๋ณ๋ ์์คํ
์ผ๋ก ๋ถ๋ฆฌ (Dragon์ ๋จ์ผ ๋ณตํฉ ๊ตฌ์กฐ์ ์ฐจ์ด)
BP_WaterProjectile์ FlightVFX/ImpactVFX ํ๋๊ฐ ๋น์ด ์์๊ณ stub ํ์ผ์ด ๋จ์ ์์๋ค.
STEP 1 โ NS_WaterProjectile_Flight
NS_Waterfall_Drops_01 (Realistic Starter VFX Pack Vol2) ๋ณต์ STEP 2 โ NS_WaterProjectile_Impact
NS_Waterfall_Splashes_01 ๋ณต์ STEP 3 โ BP_WaterProjectile ์ฐ๊ฒฐ
NS_WaterProjectile_FlightNS_WaterProjectile_Impact| ์์ | ์ญํ |
|---|---|
NS_Waterfall_Drops_01 | Flight VFX ๋ฒ ์ด์ค |
NS_Waterfall_Splashes_01 | Impact VFX ๋ฒ ์ด์ค |
M_WaterDrop_A | ํ๋์ ๋ฌผ ๋จธํฐ๋ฆฌ์ผ (Vol2 pack) |
| ํญ๋ชฉ | ์ํ |
|---|---|
| NS_WaterProjectile_Flight ์์ฑ | โ |
| NS_WaterProjectile_Impact ์์ฑ | โ |
| BP_WaterProjectile FlightVFX ์ฐ๊ฒฐ | โ |
| BP_WaterProjectile ImpactVFX ์ฐ๊ฒฐ | โ |
| ์ปดํ์ผ ์๋ฌ | โ 0๊ฐ |
| VFX ๊ฐ์ด๋ ๋ฌธ์ ์ ๋ฐ์ดํธ | โ Dragon + Water ๊ตฌํ ์ ์ฐจ ์ถ๊ฐ |
& 'C:\Program Files\Epic Games\UE_5.7\Engine\Build\BatchFiles\Build.bat' RetrieveEditor Win64 Development -Project='...\Retrieve.uproject' -WaitMutex -NoHotReload
๊ฒฐ๊ณผ: ์ฑ๊ณต.
& 'C:\Program Files\Epic Games\UE_5.7\Engine\Binaries\Win64\UnrealEditor-Cmd.exe' '...\Retrieve.uproject' -run=RetrieveConfigureEpicMonsters -unattended -nop4
๊ฒฐ๊ณผ: ์ฑ๊ณต.
& '...\UnrealEditor-Cmd.exe' '...\Retrieve.uproject' -run=RetrieveConfigureEpicMonsters DumpAnim -unattended -nop4
ํ์ธ:
ABP_DragonEnemy ParentClass: /Script/Retrieve.RetrieveEnemyAnimInstance| ํ์ผ | ์์ |
|---|---|
AbilitySystem/Enemy/EnemyProjectile.cpp | ์ถฉ๋ ์ฒ๋ฆฌ ์์ ์ ๋ฆฌ |
AbilitySystem/Enemy/EpicEnemyProjectile.cpp | ํจ๋ฆฌ ๋ฐ์ฌ + ๊ทธ๋ก๊ธฐ ๋ณด์ |
Components/Enemy/PatternCounterComponent.cpp | ๊ทธ๋ก๊ธฐ EventMagnitude ๋ฐ์ดํฐ ์ฐ๋ |
Animation/RetrieveEnemyAnimInstance.cpp/.h | ์์น ๋ณํ๋ ๊ธฐ๋ฐ Speed ๋ณด๊ฐ |
Character/RetrieveEpicMonsterCharacter.cpp/.h | Tick ์ด๋ ๋ณด์ + fallback ๋ชฝํ์ฃผ |
Commandlets/RetrieveConfigureEpicMonstersCommandlet.cpp | BP CDO ์ค์ , AnimBP ๊ตฌ์กฐ |
Content/.../BP_Dragon.uasset | CDO ์ ์ฅ |
Content/.../ABP_DragonEnemy.uasset | AnimGraph ๊ตฌ์กฐ |
Content/.../BS_DragonChase.uasset | BlendSpace |
ํฌ์ฌ์ฒด์ฒ๋ผ ์ถฉ๋ ์๊ฐ์ ์ฌ๋ฌ ๊ธฐ๋ฅ์ด ์ด์ด์ง๋ ์กํฐ๋ ์ฒ๋ฆฌ ์์๊ฐ ๋งค์ฐ ์ค์ํ๋ค. ๋ฐ์ฌ ํ์ ์ ๋ฐ๋ฏธ์ง๋ณด๋ค ๋จผ์ ๋๊ณ , ๋ฐ์ฌ๋ ํฌ์ฌ์ฒด๋ ๋ฒ ์ด์ค ๋ฐ๋ฏธ์ง ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๋๋ก ๋ถ๋ฆฌํ ๊ฒ์ด ํต์ฌ์ด์๋ค. HandleReflectedOverlap โ TryReflectOnHit โ ApplyDamage ์์๋ฅผ ์งํค๋ฉด ๊ธฐ๋ฅ์ด ๋ฌปํ์ง ์๋๋ค.
๊ทธ๋ก๊ธฐ๋ ๋จ์ํ ํ๊ทธ๋ง ๋ถ์ด๋ฉด ์ ๋๋ค. ์ ํฌ ๋ณด์ ์ํ๋ก ๊ธฐ๋ฅํ๋ ค๋ฉด ์ ์ฉ ์ ์ SetAerialMode(false), ์ง๋ฉด ๋ผ์ธํธ๋ ์ด์ค ์ค๋
, MOVE_Walking, ์ฌ๋กฏ ์ ๋๋ฉ์ด์
์ ์ง๊ฐ ํจ๊ป ํ์ํ๋ค.
Velocity๊ฐ ๋ฎ๊ฒ ์กํ๋ ํ๋ ์์ด ์๊ธธ ์ ์์ด์ Actor ์์น ๋ณํ๋์ ํจ๊ป ์ํ๋งํด์ผ "์ค์ ๋ก ์์ง์ด๋๋ฐ idle"์ธ ์ํฉ์ ์ก์ ์ ์๋ค. ๊ทธ๋๋ AnimBP ์ ์ด๋ ์ฌ๋กฏ ๋ชฝํ์ฃผ๊ฐ ์ฝํ๋ฉด C++ fallback์ด ํ์ํ๋ค.
ํน์ ๋ชฌ์คํฐ ์ ์ฉ ๋ก์ง์ ๊ณตํต ํ์ผ์ ๋ฃ์ผ๋ฉด ํ์ ๋ฐฉ์์ด ์ถฉ๋ํ๊ณ , facing ๊ฒ์ดํธ๋ฅผ ํต๊ณผํ์ง ๋ชปํด ๊ณต๊ฒฉ ์์ฒด๊ฐ ๋ฐ๋ํ์ง ์๋๋ค. Epic ์ ์ฉ ๊ธฐ๋ฐ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ virtual/override๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ ๋ต์ด๋ค.
row ์ด๋ฆ ๋ฌธ์์ด ๋น๊ต๋ก ํจํด์ ๋ถ๊ธฐํ๋ฉด ๋์ค์ ์ถ๊ฐ/๋ฆฌ๋ค์ํ ๋ ๋ฐ๋์ ์ฝ๋๋ฅผ ๊ฑด๋๋ ค์ผ ํ๋ค. ์ฒ์๋ถํฐ enum ๋๋ GameplayTag๋ก ํ๋ณํด์ผ DataTable ๋ณ๊ฒฝ์๋ ์ฝ๋ ์์ ์ด ์๋ค.
AnimBP ๊ทธ๋ํ ๊ตฌ์กฐ๋ ํฌ์ฌ์ฒด BP CDO ๊ฐ์ฒ๋ผ ์์
๊ธฐ๋ณธ๊ฐ์ด ํ์ํ ์์ ์ C++๋ง ๋ฐ๊ฟ์๋ ๋๋์ง ์๋๋ค. ์ปค๋งจ๋๋ ์ผ๋ก CDO๋ฅผ ์ ์ฅํ๊ณ DumpAnim์ผ๋ก ์ค์ ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ํ์ธํ๋ ๊ฒ์ฆ ๋ฃจํด์ด ์ค์ํ๋ค.
duplicate_system โ add_emitter โ set_module_input_value โ save_systemadd_emitter์๋ NiagaraSystem์ด ์๋ NiagaraEmitter ๊ฒฝ๋ก๋ฅผ ๋๊ฒจ์ผ ํ๋คNS_SystemName.NS_SystemName:EmitterName_0