๐Ÿ“˜TIL - ์—ํ”ฝ ๋ชฌ์Šคํ„ฐ ๊ตฌํ˜„ ๋ฐ ๋“œ๋ž˜๊ณค ์ „ํˆฌ ๊ฐœ์„ 

HappyCircleยท2026๋…„ 6์›” 16์ผ

Unreal ๊ฐœ๋ฐœ

๋ชฉ๋ก ๋ณด๊ธฐ
146/163

1. ์—ํ”ฝ ๋ชฌ์Šคํ„ฐ ๊ทธ๋กœ๊ธฐ ์‹œ์Šคํ…œ ๊ตฌํ˜„

๋ฐฐ๊ฒฝ

์—ํ”ฝ ๋ชฌ์Šคํ„ฐ๋Š” ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ๋ณด๋‹ค ์ „ํˆฌ ํŒจํ„ด์ด ๊ธธ๊ณ , ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ํŠน์ • ์กฐ๊ฑด์„ ๋งŒ์กฑํ–ˆ์„ ๋•Œ ๊ทธ๋กœ๊ธฐ ์ƒํƒœ๋กœ ์ง„์ž…ํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค.

๊ธฐ์กด NormalMonsterHealthBarComponent๋Š” HP๋งŒ ํ‘œ์‹œํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ทธ๋กœ๊ธฐ ๋ˆ„์  ์ƒํƒœ๋Š” ๋ณ„๋„ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฌํ–ˆ๋‹ค.

๊ตฌํ˜„

EpicMonsterGroggyComponent๋ฅผ ์ถ”๊ฐ€ํ•ด ๊ฐ•๊ณต๊ฒฉ ํ”ผ๊ฒฉ ํšŸ์ˆ˜๋ฅผ ๋ˆ„์ ํ•˜๊ณ , ์ผ์ • ํšŸ์ˆ˜ ์ด์ƒ ๋ˆ„์ ๋˜๋ฉด GameplayEvent.GroggyTrigger๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋„๋ก ํ–ˆ๋‹ค.

GAS์˜ OnGameplayEffectAppliedDelegateToSelf๋ฅผ ๊ตฌ๋…ํ•˜๊ณ , ์ ์šฉ๋œ GE์˜ DynamicAssetTags์— Attack.Type.Heavy๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฐ•๊ณต๊ฒฉ์„ ํŒ์ •ํ–ˆ๋‹ค.

if (Spec.DynamicAssetTags.HasTag(RetrieveGameplayTags::Attack_Type_Heavy))
{
    OnHeavyAttackReceived();
}

๊ทธ๋กœ๊ธฐ ์ข…๋ฃŒ๋Š” State.Enemy.Groggy ํƒœ๊ทธ ๋ณ€ํ™” ์ฝœ๋ฐฑ์œผ๋กœ ๊ฐ์ง€ํ–ˆ๋‹ค.

๋ฐฐ์šด ์ 

GAS์—์„œ ํŠน์ • ๊ณต๊ฒฉ ํƒ€์ž…์„ ๊ตฌ๋ถ„ํ•  ๋•Œ GE ํด๋ž˜์Šค๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ๋ณด๋‹ค DynamicAssetTags ๊ธฐ๋ฐ˜์œผ๋กœ ๋ถ„๊ธฐํ•˜๋Š” ๋ฐฉ์‹์ด ๋” ์œ ์—ฐํ•˜๋‹ค.


2. ์—ํ”ฝ ๋ชฌ์Šคํ„ฐ ์ฒด๋ ฅ๋ฐ”์— ๊ทธ๋กœ๊ธฐ ๊ฒŒ์ด์ง€ ์—ฐ๋™

๋ฐฐ๊ฒฝ

์—ํ”ฝ ๋ชฌ์Šคํ„ฐ๋Š” HP๋ฟ ์•„๋‹ˆ๋ผ ๊ทธ๋กœ๊ธฐ ๋ˆ„์  ์ƒํƒœ๋„ UI์— ํ‘œ์‹œํ•ด์•ผ ํ–ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ชจ๋“  ๋ชฌ์Šคํ„ฐ๊ฐ€ ๊ทธ๋กœ๊ธฐ ๊ฒŒ์ด์ง€๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ, ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ UI ๊ตฌ์กฐ๋ฅผ ํฌ๊ฒŒ ๋ฐ”๊พธ์ง€ ์•Š๊ณ  ํ™•์žฅํ•  ํ•„์š”๊ฐ€ ์žˆ์—ˆ๋‹ค.

๊ตฌํ˜„

NormalMonsterHealthBarComponent์—์„œ EpicMonsterGroggyComponent๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๊ทธ๋กœ๊ธฐ ๊ฒŒ์ด์ง€ ์—…๋ฐ์ดํŠธ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ๋ฐ”์ธ๋”ฉํ–ˆ๋‹ค.

UEpicMonsterGroggyComponent* GroggyComp =
    GetOwner()->FindComponentByClass<UEpicMonsterGroggyComponent>();

if (GroggyComp)
{
    GroggyComp->OnGroggyGaugeUpdated.AddDynamic(
        this, &UNormalMonsterHealthBarComponent::HandleGroggyGaugeUpdated);
}

๋ฐฐ์šด ์ 

์ปดํฌ๋„ŒํŠธ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™” ์กฐ๊ฑด์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ์™€ ์—ํ”ฝ ๋ชฌ์Šคํ„ฐ๋ฅผ ๋ณ„๋„ ํด๋ž˜์Šค๋กœ ๊ณผํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค.


3. ๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ” ๊ตฌ์กฐ์™€ ๋“œ๋ž˜๊ณค ํŒจํ„ด ์ฒ˜๋ฆฌ ๋ฐฉํ–ฅ ์ •๋ฆฌ

๋ฐฐ๊ฒฝ

๋“œ๋ž˜๊ณค์€ ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ์™€ ๋™์ผํ•˜๊ฒŒ DT_MonsterData, DT_MonsterPattern, StateTree ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•ด์•ผ ํ–ˆ๋‹ค.

์ดˆ๊ธฐ์—๋Š” ๋“œ๋ž˜๊ณค ์ „์šฉ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œํ€€์Šค, ํžˆํŠธ๋ฐ•์Šค ํƒ€์ด๋ฐ, ๊ณต์ค‘ ํŽ˜์ด์ฆˆ ์—ฌ๋ถ€ ๋“ฑ์„ ๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ” ํ•„๋“œ๋กœ ํ™•์žฅํ•˜๋Š” ๋ฐฉํ–ฅ๋„ ๊ฒ€ํ† ํ–ˆ๋‹ค.

์ตœ์ข… ๋ฐฉํ–ฅ

ํ”„๋กœ์ ํŠธ ๊ธฐ์ค€์ƒ ๊ธฐ์กด DT_MonsterData, DT_MonsterPattern ๊ตฌ์กฐ๋ฅผ ๊ณ ์ •ํ•˜๊ธฐ๋กœ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ตœ์ข… ๊ตฌํ˜„์—์„œ๋Š” ๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ” ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•˜๋‹ค.

๋Œ€์‹  ๋“œ๋ž˜๊ณค ์ „์šฉ ์˜ˆ์™ธ๋Š” RowName ๊ธฐ๋ฐ˜ ๋Ÿฐํƒ€์ž„ ๋ณด์ •์œผ๋กœ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด Dragon_Bite๋Š” AttackMontage๊ฐ€ ์—†์–ด๋„ ์ฝ”๋“œ์—์„œ ๋“œ๋ž˜๊ณค ๋ฐ”์ดํŠธ ์‹œํ€€์Šค๋ฅผ ๋™์  ๋ชฝํƒ€์ฃผ๋กœ ์žฌ์ƒํ•˜๋„๋ก ํ–ˆ๋‹ค.

Polygonal_Dragon_AnimationBite_Attack
HitboxStartTime = 0.38f
HitboxDuration = 0.28f

๋ฐฐ์šด ์ 

๊ณต์šฉ ๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ”์€ ์—ฌ๋Ÿฌ ๋ชฌ์Šคํ„ฐ๊ฐ€ ์˜์กดํ•˜๋ฏ€๋กœ, ํŠน์ • ๋ชฌ์Šคํ„ฐ ์š”๊ตฌ์‚ฌํ•ญ๋งŒ ๋ณด๊ณ  ๊ตฌ์กฐ๋ฅผ ํ™•์žฅํ•˜๋ฉด ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ์ด ์ปค์งˆ ์ˆ˜ ์žˆ๋‹ค.


4. CSV ๋ฆฌ์ž„ํฌํŠธ ๊ณผ์ •์—์„œ ์ปฌ๋Ÿผ ๊ฐœ์ˆ˜ ์˜ค๋ฅ˜ ์ˆ˜์ •

๋ฌธ์ œ

DT_MonsterPattern.csv ๋ฆฌ์ž„ํฌํŠธ ์ค‘ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

Row has more cells than properties, is there a malformed string?

์›์ธ์€ bCanTriggerGroggy์™€ HitboxBoneName ์‚ฌ์ด์˜ ๋นˆ ์ปฌ๋Ÿผ ๊ฐœ์ˆ˜๊ฐ€ ๋งž์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

Header:
..., bCanBeParried, bCanTriggerGroggy, CounterEventTag, RequiredElementTag, RequiredActionTag, HitboxBoneName, ...

CounterEventTag, RequiredElementTag, RequiredActionTag 3๊ฐœ ๋นˆ ๊ฐ’์„ ํ‘œํ˜„ํ•ด์•ผ ํ•˜๋Š”๋ฐ ์‰ผํ‘œ ๊ฐœ์ˆ˜๊ฐ€ ์ž˜๋ชป๋˜์–ด ํ–‰ ์ „์ฒด๊ฐ€ ๋ฐ€๋ ธ๋‹ค.

๋ฐฐ์šด ์ 

UE DataTable CSV ์˜ค๋ฅ˜์—์„œ more cells than properties๊ฐ€ ๋‚˜์˜ค๋ฉด ์‹ค์ œ ๊ฐ’๋ณด๋‹ค ๋นˆ ์…€ ๊ฐœ์ˆ˜๋ฅผ ๋จผ์ € ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.


5. BP_Dragon / BP_Treant / BP_Magma ๊ตฌ์„ฑ

์ž‘์—… ๋‚ด์šฉ

์—ํ”ฝ ๋ชฌ์Šคํ„ฐ์šฉ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ์— ๊ทธ๋กœ๊ธฐ ์ปดํฌ๋„ŒํŠธ์™€ ๋ฐ์ดํ„ฐ Row ์„ค์ •์„ ์ ์šฉํ–ˆ๋‹ค.

BP์ž‘์—…
BP_DragonGroggyComponent ์ถ”๊ฐ€, ๋“œ๋ž˜๊ณค ๋ฐ์ดํ„ฐ ์—ฐ๊ฒฐ
BP_TreantRetrieveEnemyCharacter ๊ธฐ๋ฐ˜ ์‹ ๊ทœ ๊ตฌ์„ฑ, Treant_Water Row ์—ฐ๊ฒฐ
BP_MagmaRetrieveEnemyCharacter ๊ธฐ๋ฐ˜ ์‹ ๊ทœ ๊ตฌ์„ฑ, Magma_Fire Row ์—ฐ๊ฒฐ

๋ฌธ์ œ

๋ธ”๋ฃจํ”„๋ฆฐํŠธ CDO ์„ค์ • ์ค‘ DataRowName ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค.

์‹ค์ œ ํ”„๋กœํผํ‹ฐ๋ช…์€ MonsterDataRowName์ด์—ˆ๋‹ค.

๋ฐฐ์šด ์ 

๋ธ”๋ฃจํ”„๋ฆฐํŠธ CDO๋ฅผ ์ž๋™ํ™”๋กœ ์ˆ˜์ •ํ•  ๋•Œ๋Š” ์ถ”์ธกํ•œ ์ด๋ฆ„์„ ์“ฐ๊ธฐ๋ณด๋‹ค ์‹ค์ œ CDO ํ”„๋กœํผํ‹ฐ ๋ชฉ๋ก์„ ๋จผ์ € ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.


6. ๋“œ๋ž˜๊ณค ๊ณต์ค‘ ๋ชจ๋“œ ์ „ํ™˜ ์ฒ˜๋ฆฌ

๋ฌธ์ œ

StateTreeTask_EnemyAerialPhase์—์„œ ๋“œ๋ž˜๊ณค ๊ณต์ค‘ ํŽ˜์ด์ฆˆ ์ง„์ž…/๋ณต๊ท€ ์‹œ SetAerialMode()๋ฅผ ํ˜ธ์ถœํ•˜์ง€๋งŒ, ๋จธ์ง€ ๊ณผ์ •์—์„œ ํ•ด๋‹น ํ•จ์ˆ˜๊ฐ€ ๋ˆ„๋ฝ๋˜์–ด ๋นŒ๋“œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

ํ•ด๊ฒฐ

ARetrieveEnemyCharacter์— SetAerialMode(bool bAerial)์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

if (bAerial)
{
    MoveComp->SetMovementMode(MOVE_Flying);
    MoveComp->GravityScale = 0.f;
}
else
{
    MoveComp->GravityScale = DefaultGravityScale;
    MoveComp->SetMovementMode(MOVE_Falling);
}

์ฐฉ์ง€ ์‹œ์—๋Š” MOVE_Falling์—์„œ ์ง€๋ฉด ๊ฐ์ง€ ํ›„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ MOVE_Walking์œผ๋กœ ๋Œ์•„๊ฐ€๋„๋ก ํ–ˆ๋‹ค.

๋ฐฐ์šด ์ 

๊ณต์ค‘ ํŽ˜์ด์ฆˆ ์ข…๋ฃŒ ์‹œ ๋ฐ”๋กœ MOVE_Walking์œผ๋กœ ๋Œ๋ฆฌ๋Š” ๊ฒƒ๋ณด๋‹ค MOVE_Falling์„ ๊ฑฐ์ณ CharacterMovement์˜ ์ง€๋ฉด ๊ฐ์ง€๋ฅผ ํ™œ์šฉํ•˜๋Š” ํŽธ์ด ์ž์—ฐ์Šค๋Ÿฝ๋‹ค.


7. ๋“œ๋ž˜๊ณค ์ผ๋ฐ˜ ๊ณต๊ฒฉ ํŒ์ • ์ˆ˜์ •

๋ฌธ์ œ

๋“œ๋ž˜๊ณค์ด ํ”Œ๋ ˆ์ด์–ด๋ฅผ ์ธ์‹ํ•˜๊ณ  ๊ณต๊ฒฉ ๋ชจ์…˜์€ ์ˆ˜ํ–‰ํ•˜์ง€๋งŒ ์‹ค์ œ ๋ฐ๋ฏธ์ง€๊ฐ€ ๋“ค์–ด๊ฐ€์ง€ ์•Š์•˜๋‹ค.

์›์ธ์€ Dragon_Bite ํžˆํŠธ๋ฐ•์Šค๊ฐ€ Head ๋ณธ์— ๋ถ™๋„๋ก ๋˜์–ด ์žˆ์—ˆ์ง€๋งŒ, ์‹ค์ œ ๋“œ๋ž˜๊ณค ์Šค์ผˆ๋ ˆํ†ค์˜ ๋จธ๋ฆฌ ๋ณธ์€ RigHead์˜€๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํ•ด๊ฒฐ

Dragon_Bite์— ํ•œํ•ด ๋Ÿฐํƒ€์ž„ ๋ณด์ •์œผ๋กœ ํžˆํŠธ๋ฐ•์Šค ๋ณธ๊ณผ ํŒ์ • ํฌ๊ธฐ๋ฅผ ์กฐ์ •ํ–ˆ๋‹ค.

HitboxBoneName = RigHead
HitboxRadius = 200
HitboxOffset = (130, 0, 0)
MaxActivationRange = 520

๋˜ํ•œ ๋“œ๋ž˜๊ณค ๋ฉ”์‹œ ํฌ๊ธฐ์— ๋งž๊ฒŒ ์บก์А ํฌ๊ธฐ์™€ ๋ฉ”์‹œ ์ƒ๋Œ€ ์œ„์น˜๋„ ๋ณด์ •ํ–ˆ๋‹ค.

CapsuleRadius = 170
CapsuleHalfHeight = 255
MeshRelativeLocation = (0, 0, -255)

๋ฐฐ์šด ์ 

๊ณต๊ฒฉ์ด ๋งž์ง€ ์•Š๋Š” ๋ฌธ์ œ๋Š” ๋ฐ๋ฏธ์ง€ ๋กœ์ง๋ณด๋‹ค ๋จผ์ € ํžˆํŠธ๋ฐ•์Šค๊ฐ€ ์‹ค์ œ ์Šค์ผˆ๋ ˆํ†ค์˜ ์˜ฌ๋ฐ”๋ฅธ ๋ณธ์— ๋ถ™๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.


8. ๋“œ๋ž˜๊ณค ํšŒ์ „ ๋ฐ ์ด๋™ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ฐœ์„ 

๋ฌธ์ œ

๋“œ๋ž˜๊ณค์ด ๊ณต๊ฒฉ ์ „ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ๋ฐ”๋ผ๋ณผ ๋•Œ ๋ฐœ์€ ์›€์ง์ด์ง€ ์•Š๊ณ  ๋ชธ๋งŒ ํšŒ์ „ํ•ด ๋ถ€์ž์—ฐ์Šค๋Ÿฌ์› ๋‹ค.

๋˜ํ•œ ์Šฌ๋กฏ ์ด๋™ ์ค‘ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ๋ฐ”๋ผ๋ณธ ์ฑ„ ์˜†์œผ๋กœ ์ด๋™ํ•ด, ํฐ ๋ชธ์ง‘์˜ ๋“œ๋ž˜๊ณค์ด ๋ฏธ๋„๋Ÿฌ์ง€๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€๋‹ค.

ํ•ด๊ฒฐ

๊ณต๊ฒฉ ์ง์ „ ๋ฐฉํ–ฅ ์ •๋ ฌ ์ค‘์—๋Š” ๋“œ๋ž˜๊ณค์˜ ์ขŒ/์šฐ ์ŠคํŠธ๋ ˆ์ดํ”„ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์งง์€ ๋™์  ๋ชฝํƒ€์ฃผ๋กœ ์žฌ์ƒํ–ˆ๋‹ค.

์ „์šฉ Turn-in-place ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด Strafe_Left_WO_Root, Strafe_Right_WO_Root๋ฅผ ๋ณด์กฐ ํ„ด ์• ๋‹ˆ๋ฉ”์ด์…˜์œผ๋กœ ํ™œ์šฉํ–ˆ๋‹ค.

์Šฌ๋กฏ ์ด๋™๊ณผ ์ถ”์  ์ด๋™์—์„œ๋Š” ๋“œ๋ž˜๊ณค์— ํ•œํ•ด ์ŠคํŠธ๋ ˆ์ดํ”„๋ฅผ ๋„๊ณ  ์ด๋™ ๋ฐฉํ–ฅ์œผ๋กœ ํšŒ์ „ํ•˜๋„๋ก ํ–ˆ๋‹ค.

bOrientRotationToMovement = true
bUseControllerDesiredRotation = false
ClearFocus()
MoveToLocation(..., bCanStrafe = false)

๋ฐฐ์šด ์ 

์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ์—๊ฒŒ ์ž์—ฐ์Šค๋Ÿฌ์šด ์ŠคํŠธ๋ ˆ์ดํ”„ ์ด๋™๋„ ๋Œ€ํ˜• ๋ชฌ์Šคํ„ฐ์—๊ฒŒ๋Š” ์–ด์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ชฌ์Šคํ„ฐ ์ฒดํ˜•์— ๋”ฐ๋ผ ํšŒ์ „ ์ •์ฑ…๊ณผ ์ด๋™ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‚ฌ์šฉ ๋ฐฉ์‹์„ ๋‹ค๋ฅด๊ฒŒ ๊ฐ€์ ธ๊ฐ€์•ผ ํ•œ๋‹ค.


9. ๋“œ๋ž˜๊ณค ํŠน์ˆ˜๊ณต๊ฒฉ ํˆฌ์‚ฌ์ฒด ๋ฐ˜์‚ฌ ๋ฐ ๊ทธ๋กœ๊ธฐ ์—ฐ๋™

๋ฌธ์ œ

๋“œ๋ž˜๊ณค ํŠน์ˆ˜๊ณต๊ฒฉ ํˆฌ์‚ฌ์ฒด๋Š” ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ํŒจ๋งํ•˜๋ฉด GameplayEvent.Parry.Success๊นŒ์ง€๋Š” ๋ฐœ์ƒํ–ˆ์ง€๋งŒ, ํˆฌ์‚ฌ์ฒด๊ฐ€ ๋“œ๋ž˜๊ณค์—๊ฒŒ ๋˜๋Œ์•„๊ฐ€ ๊ทธ๋กœ๊ธฐ๋ฅผ ์œ ๋ฐœํ•˜๋Š” ํ๋ฆ„์€ ์—†์—ˆ๋‹ค.

๋˜ํ•œ ๊ฐ€๋””์–ธ๋„ ๊ฐ™์€ EnemyProjectile์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด, ๊ณตํ†ต ํˆฌ์‚ฌ์ฒด์— ๋ฐ˜์‚ฌ ๊ธฐ๋Šฅ์„ ๋ฌด์กฐ๊ฑด ๋„ฃ์œผ๋ฉด ๋‹ค๋ฅธ ๋ชฌ์Šคํ„ฐ ๋™์ž‘์ด ๊นจ์งˆ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

ํ•ด๊ฒฐ

EnemyProjectile์—๋Š” ๊ณตํ†ต ๋ฐ˜์‚ฌ ๊ธฐ๋Šฅ๋งŒ ์ถ”๊ฐ€ํ•˜๊ณ , ๊ธฐ๋ณธ๊ฐ’์€ ๋น„ํ™œ์„ฑํ™”ํ–ˆ๋‹ค.

GA_ShootProjectiles์—์„œ ํ˜„์žฌ ํŒจํ„ด์ด Dragon_AerialFireball์ผ ๋•Œ๋งŒ ๋ฐ˜์‚ฌ ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ–ˆ๋‹ค.

if (IsDragonAerialFireballPattern())
{
    Projectile->ConfigureReflection(AvatarActor);
}

ํŒจ๋ง ์„ฑ๊ณต ์‹œ ํˆฌ์‚ฌ์ฒด๋Š” ํŒŒ๊ดด๋˜์ง€ ์•Š๊ณ  ๋“œ๋ž˜๊ณค ๋ฐฉํ–ฅ์œผ๋กœ ๋˜๋Œ์•„๊ฐ„๋‹ค.

๋ฐ˜์‚ฌ๋œ ํˆฌ์‚ฌ์ฒด๊ฐ€ ๋“œ๋ž˜๊ณค์—๊ฒŒ ์ ์ค‘ํ•˜๋ฉด PatternCounterComponent๋ฅผ ํ†ตํ•ด ์นด์šดํ„ฐ/๊ทธ๋กœ๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๋ฐฐ์šด ์ 

๊ณต์šฉ ํด๋ž˜์Šค์— ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ๊ธฐ๋Šฅ ์ž์ฒด์™€ ํ™œ์„ฑํ™” ์กฐ๊ฑด์„ ๋ถ„๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.
์ด๋ฒˆ ๊ฒฝ์šฐ EnemyProjectile์€ ๋ฐ˜์‚ฌ ๊ธฐ๋Šฅ์„ ์ œ๊ณต๋งŒ ํ•˜๊ณ , ๋“œ๋ž˜๊ณค ํŒจํ„ด์—์„œ๋งŒ opt-in ๋ฐฉ์‹์œผ๋กœ ์ผœ๋Š” ๊ตฌ์กฐ๊ฐ€ ๊ฐ€์žฅ ์•ˆ์ „ํ–ˆ๋‹ค.


์˜ค๋Š˜์˜ ์ •๋ฆฌ

1. ๊ณต์šฉ ๊ตฌ์กฐ๋Š” ์œ ์ง€ํ•˜๊ณ , ํŠน์ˆ˜ ์ผ€์ด์Šค๋Š” ์ข๊ฒŒ ๋ณด์ •ํ•œ๋‹ค

๋“œ๋ž˜๊ณค์€ ๊ธฐ์กด ๋ชฌ์Šคํ„ฐ ์‹œ์Šคํ…œ์„ ์žฌ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์ง€๋งŒ, ํฌ๊ธฐ์™€ ํŒจํ„ด ํŠน์„ฑ ๋•Œ๋ฌธ์— ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ–ˆ๋‹ค.

๋ฐ์ดํ„ฐ ํ…Œ์ด๋ธ” ๊ตฌ์กฐ๋ฅผ ํ™•์žฅํ•˜๊ธฐ๋ณด๋‹ค Dragon_Bite, Dragon_AerialFireball ๊ฐ™์€ ํŠน์ • RowName ๊ธฐ์ค€์œผ๋กœ ๋Ÿฐํƒ€์ž„ ๋ณด์ •์„ ์ œํ•œํ–ˆ๋‹ค.

2. GAS ์ด๋ฒคํŠธ๋Š” ํƒœ๊ทธ ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฐ๊ฒฐํ•˜๋ฉด ํ™•์žฅ์„ฑ์ด ์ข‹๋‹ค

๊ฐ•๊ณต๊ฒฉ ๊ฐ์ง€, ํŒจ๋ง ์„ฑ๊ณต, ๊ทธ๋กœ๊ธฐ ํŠธ๋ฆฌ๊ฑฐ ๋ชจ๋‘ GameplayTag๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์—ฐ๊ฒฐํ–ˆ๋‹ค.

GE ์ข…๋ฅ˜๋ฅผ ๋Š˜๋ฆฌ๋Š” ๊ฒƒ๋ณด๋‹ค ํƒœ๊ทธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ๋ฆ„์„ ๋ถ„๊ธฐํ•˜๋Š” ์ชฝ์ด ๋ฐ์ดํ„ฐ ๋“œ๋ฆฌ๋ธ ๊ตฌ์กฐ์™€ ๋” ์ž˜ ๋งž์•˜๋‹ค.

3. ๋Œ€ํ˜• ๋ชฌ์Šคํ„ฐ๋Š” ์ด๋™/ํšŒ์ „ ์ •์ฑ…์ด ์ค‘์š”ํ•˜๋‹ค

๋“œ๋ž˜๊ณค์€ ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ์ฒ˜๋Ÿผ ์ŠคํŠธ๋ ˆ์ดํ”„ํ•˜๋ฉด ์˜คํžˆ๋ ค ๋ถ€์ž์—ฐ์Šค๋Ÿฝ๋‹ค.

๋Œ€ํ˜• ๋ชฌ์Šคํ„ฐ๋Š” ์ด๋™ ๋ฐฉํ–ฅ์œผ๋กœ ๋ชธ์„ ๋Œ๋ฆฌ๊ณ  ์ „์ง„ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ์ชฝ์ด ๋” ์•ˆ์ •์ ์ด๋‹ค.

4. ๊ณต์šฉ ํˆฌ์‚ฌ์ฒด ๊ธฐ๋Šฅ์€ opt-in์œผ๋กœ ์„ค๊ณ„ํ•ด์•ผ ํ•œ๋‹ค

๋“œ๋ž˜๊ณค๊ณผ ๊ฐ€๋””์–ธ์ด ๊ฐ™์€ ํˆฌ์‚ฌ์ฒด ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜์‚ฌ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ ๋™์ž‘์œผ๋กœ ๋„ฃ์ง€ ์•Š์•˜๋‹ค.

๊ณตํ†ต ๊ธฐ๋Šฅ์€ EnemyProjectile์— ๋‘๋˜, Dragon_AerialFireball์—์„œ๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ์ผœ๋Š” ๊ตฌ์กฐ๋กœ ๋‹ค๋ฅธ ๋ชฌ์Šคํ„ฐ์— ๋Œ€ํ•œ ๋ถ€์ž‘์šฉ์„ ์ค„์˜€๋‹ค.

profile
๊ฐœ๋ฐœํ•ฉ์‹œ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€