๐Ÿ“˜ TIL - ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ StateTree ์ „ํˆฌ ํ๋ฆ„ ๊ฐœ์„  ๋ฐ ์ถฉ๋Œ ๊ตฌ์กฐ ์ •๋ฆฌ

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

Unreal ๊ฐœ๋ฐœ

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

๐Ÿ“˜ TIL - ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ StateTree ์ „ํˆฌ ํ๋ฆ„ ๊ฐœ์„  ๋ฐ ์ถฉ๋Œ ๊ตฌ์กฐ ์ •๋ฆฌ

๋ฐฐ๊ฒฝ

์˜ค๋Š˜์€ ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ AI ์ „ํˆฌ ํ๋ฆ„์„ ์ค‘์‹ฌ์œผ๋กœ ๊ณต๊ฒฉ ์ง„์ž… ์กฐ๊ฑด, ๊ณต๊ฒฉ๊ถŒ ๊ด€๋ฆฌ ๊ตฌ์กฐ, ์ถฉ๋Œ ์ฑ„๋„ ๊ตฌ์„ฑ, ๋ฝ์˜จ ๋Œ€์ƒ ํŒ์ • ๋“ฑ์„ ์ ๊ฒ€ํ–ˆ๋‹ค.

๊ธฐ์กด์—๋Š” ์†Œ์ˆ˜์˜ ๋ชฌ์Šคํ„ฐ๋งŒ ์žˆ์„ ๋•Œ๋Š” ํฐ ๋ฌธ์ œ๊ฐ€ ๋ณด์ด์ง€ ์•Š์•˜์ง€๋งŒ, ์—ฌ๋Ÿฌ ๋งˆ๋ฆฌ๊ฐ€ ๋™์‹œ์— ํ”Œ๋ ˆ์ด์–ด๋ฅผ ์ถ”์ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๊ณต๊ฒฉ ์ƒํƒœ ์ง„์ž…์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํŒจํ•˜๊ฑฐ๋‚˜ ๋ชฌ์Šคํ„ฐ๋ผ๋ฆฌ ์„œ๋กœ ๊ฐ„์„ญํ•˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค. ๋˜ํ•œ ๋ฃจ๋ฉ˜ NPC๊ฐ€ ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ๋Œ€์ƒ์ด๋‚˜ ๋ฝ์˜จ ๋Œ€์ƒ์— ํฌํ•จ๋˜๋Š” ๋ฌธ์ œ๋„ ํ™•์ธ๋˜์—ˆ๋‹ค.

์ฒ˜์Œ์—๋Š” ๊ฐœ๋ณ„ StateTree Task๋‚˜ ๊ณต๊ฒฉ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฌธ์ œ๋ฅผ ์˜์‹ฌํ–ˆ์ง€๋งŒ, ์‹ค์ œ ์›์ธ์€ ๊ณต๊ฒฉ๊ถŒ ๊ด€๋ฆฌ ๋ฐฉ์‹๊ณผ ์ถฉ๋Œ ์ฑ„๋„ ๊ตฌ์„ฑ, ํƒ€๊ฒŸ ํŒ์ • ๋กœ์ง์ด ์„œ๋กœ ๋งž๋ฌผ๋ ค ๋ฐœ์ƒํ•˜๋Š” ๊ตฌ์กฐ์ ์ธ ๋ฌธ์ œ์— ๊ฐ€๊นŒ์› ๋‹ค. ์ด๋ฒˆ ์ž‘์—…์—์„œ๋Š” ์ „ํˆฌ ํ๋ฆ„ ์ž์ฒด๋ฅผ ๋‹ค์‹œ ์ ๊ฒ€ํ•˜๋ฉด์„œ ๊ณต๊ฒฉ ์ง„์ž… ์กฐ๊ฑด๊ณผ ์ถฉ๋Œ ๊ตฌ์กฐ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ ‘๊ทผํ–ˆ๋‹ค.


1. ๊ณต๊ฒฉ๊ถŒ(Token) ๊ด€๋ฆฌ ๊ตฌ์กฐ ๊ฐœ์„ 

์›์ธ ๋ถ„์„

๊ธฐ์กด EncirclementSubsystem์€ ๊ณต๊ฒฉ ๊ฐ€๋Šฅํ•œ ๋ชฌ์Šคํ„ฐ ์ˆ˜๋ฅผ ๋‹จ์ˆœ ์นด์šดํŠธ ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

MaxAttackTokens = 3

์ด ๋ฐฉ์‹์€ ๋ชฌ์Šคํ„ฐ ์ข…๋ฅ˜์™€ ๊ด€๊ณ„์—†์ด ๋ชจ๋‘ ๋™์ผํ•œ ๋น„์šฉ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ฒด๊ธ‰์ด ๋‹ค๋ฅธ ๋ชฌ์Šคํ„ฐ๋ฅผ ํ•จ๊ป˜ ์šด์šฉํ•  ๊ฒฝ์šฐ ์ „ํˆฌ ๋ฐ€๋„๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์กฐ์ ˆํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค.

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

๊ณต๊ฒฉ ์ƒํƒœ ์ง„์ž…
โ†’ ์ด๋™ ๊ฒฝ๋กœ ๊ฐ„์„ญ
โ†’ ๋ฐฉํ–ฅ ์ „ํ™˜ ๋ฐ˜๋ณต
โ†’ ๊ณต๊ฒฉ ์‹œ์ž‘ ์‹คํŒจ
โ†’ ๊ณต๊ฒฉ ์ƒํƒœ ์žฌ์ง„์ž… ๋ฐ˜๋ณต

๊ฒฐ๊ณผ์ ์œผ๋กœ ์ „ํˆฌ ํ๋ฆ„์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด์–ด์ง€์ง€ ๋ชปํ•˜๊ณ  ๊ณต๊ฒฉ ์ƒํƒœ์™€ ์ด๋™ ์ƒํƒœ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๊ณต๊ฒฉ๊ถŒ ๊ตฌ์กฐ๋ฅผ ๋‹จ์ˆœ ์นด์šดํŠธ ๋ฐฉ์‹์—์„œ ์˜ˆ์‚ฐ(Budget) ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค.

AttackTokenCost
AttackTokenBudget

๊ฐ ๋ชฌ์Šคํ„ฐ๋Š” DataTable์— ์ •์˜๋œ ๋น„์šฉ์„ ์‚ฌ์šฉํ•˜๊ณ , ๊ณต๊ฒฉ ๊ฐ€๋Šฅํ•œ ์ด ์˜ˆ์‚ฐ ๋ฒ”์œ„ ์•ˆ์—์„œ๋งŒ ๊ณต๊ฒฉ ์ƒํƒœ์— ์ง„์ž…ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑํ–ˆ๋‹ค.

const int32 CurrentCost = GetCurrentAttackTokenCost(Ring);
const int32 RequestCost = GetAttackTokenCost(Requester);
const int32 Budget      = GetAttackTokenBudget(Ring, Requester);

if (CurrentCost + RequestCost > Budget)
{
    return false;
}

์ด๋ฅผ ํ†ตํ•ด ๋ชฌ์Šคํ„ฐ ์ข…๋ฅ˜์— ๋”ฐ๋ผ ๊ณต๊ฒฉ ๋ฐ€๋„๋ฅผ ๋ฐ์ดํ„ฐ๋งŒ์œผ๋กœ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์„ ๋งˆ๋ จํ–ˆ๋‹ค.

์ „ํˆฌ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •๋ฆฌ๋œ๋‹ค.

๋ชฌ์Šคํ„ฐ ์ถ”์ 
    โ†“
ํ”Œ๋ ˆ์ด์–ด ์ฃผ๋ณ€ ๋ฐฐํšŒ
    โ†“
๊ณต๊ฒฉ๊ถŒ ํš๋“
    โ†“
๊ณต๊ฒฉ ์ƒํƒœ ์ง„์ž…
    โ†“
๊ณต๊ฒฉ ์ข…๋ฃŒ
    โ†“
๋ฐฐํšŒ ๋ณต๊ท€

2. StateTree ๊ณต๊ฒฉ ์ง„์ž… ์กฐ๊ฑด ๊ฐœ์„ 

์›์ธ ๋ถ„์„

๊ธฐ์กด ๊ณต๊ฒฉ ๋กœ์ง์€ ๊ณต๊ฒฉ ๋ฒ”์œ„์— ์ง„์ž…ํ•˜๋Š” ์ˆœ๊ฐ„ ์ฆ‰์‹œ ๊ณต๊ฒฉ์„ ์‹œ๋„ํ•˜๋Š” ๊ตฌ์กฐ์˜€๋‹ค.

DistanceToTarget <= AttackRange

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

๊ณต๊ฒฉ ๋ฒ”์œ„ ์ง„์ž…
โ†’ ๊ณต๊ฒฉ ์‹œ์ž‘ ์‹œ๋„
โ†’ ๊ฑฐ๋ฆฌ ์กฐ๊ฑด ํ•ด์ œ
โ†’ ๊ณต๊ฒฉ ์‹คํŒจ
โ†’ ์žฌ์ง„์ž… ๋ฐ˜๋ณต

ํŠนํžˆ ์—ฌ๋Ÿฌ ๋ชฌ์Šคํ„ฐ๊ฐ€ ๋™์‹œ์— ์ด๋™ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ํ˜„์ƒ์ด ๋”์šฑ ์ž์ฃผ ๋ฐœ์ƒํ–ˆ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

StateTreeTask_EnemyAttack์— ์†Œํ”„ํŠธ ์ง„์ž… ๊ตฌ๊ฐ„์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

์‹ ๊ทœ ๋ณ€์ˆ˜:

AttackStartRangeTolerance
AttackStartDelay

๋™์ž‘ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

Distance > AttackRange + Tolerance
โ†’ ๊ณต๊ฒฉ ๋ถˆ๊ฐ€

AttackRange < Distance โ‰ค AttackRange + Tolerance
โ†’ ์†Œํ”„ํŠธ ์ง„์ž… ๊ตฌ๊ฐ„

AttackRange ์ดํ•˜
โ†’ ์ฆ‰์‹œ ๊ณต๊ฒฉ ๊ฐ€๋Šฅ

์†Œํ”„ํŠธ ์ง„์ž… ๊ตฌ๊ฐ„์—์„œ๋Š” ์ผ์ • ์‹œ๊ฐ„ ๋™์•ˆ ๋ฒ”์œ„๋ฅผ ์œ ์ง€ํ•ด์•ผ๋งŒ ๊ณต๊ฒฉ์ด ์‹œ์ž‘๋œ๋‹ค.

๊ณต๊ฒฉ ๊ฐ€๋Šฅ ๊ฑฐ๋ฆฌ ์ง„์ž…
โ†’ AttackStartDelay ์ฒด๋ฅ˜
โ†’ ๊ณต๊ฒฉ ์‹œ์ž‘

๋˜ํ•œ EnterState์™€ ExitState์—์„œ ์ฒด๋ฅ˜ ์‹œ๊ฐ„์„ ์ดˆ๊ธฐํ™”ํ•˜๋„๋ก ์ˆ˜์ •ํ•ด ์ƒํƒœ ์ „ํ™˜ ์‹œ ์ด์ „ ๊ฐ’์ด ๋‚จ์ง€ ์•Š๋„๋ก ์ •๋ฆฌํ–ˆ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ๊ณต๊ฒฉ ๋ฒ”์œ„ ๊ฒฝ๊ณ„์—์„œ ๋ฐœ์ƒํ•˜๋˜ ์‹คํŒจ-์žฌ์‹œ๋„ ๋ฃจํ”„๋ฅผ ์ค„์ด๊ณ  ๋ณด๋‹ค ์•ˆ์ •์ ์œผ๋กœ ๊ณต๊ฒฉ์ด ์‹œ์ž‘๋  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ ํ–ˆ๋‹ค.


3. EnemyPawn ์ฑ„๋„ ๋ถ„๋ฆฌ ๋ฐ ์ถฉ๋Œ ๊ตฌ์กฐ ์ •๋ฆฌ

์›์ธ ๋ถ„์„

์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ์™€ ๋ณด์Šค๊ฐ€ ๋ชจ๋‘ ๊ธฐ๋ณธ Pawn ์ฑ„๋„์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๋‹ค.

ECC_Pawn

์ด ๊ตฌ์กฐ์—์„œ๋Š” ๋ชฌ์Šคํ„ฐ๋ผ๋ฆฌ ์„œ๋กœ Block ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๊ณ , ๋ฝ์˜จ ํƒ์ง€๋‚˜ ์ „ํˆฌ ํŒ์ •์—์„œ๋„ ํ”Œ๋ ˆ์ด์–ด์™€ ๋ชฌ์Šคํ„ฐ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค.

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ ์ „์šฉ ์ฑ„๋„์ธ EnemyPawn์„ ์ ์šฉํ–ˆ๋‹ค.

ECC_GameTraceChannel1

์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ๋Š” ์ƒ์„ฑ ์‹œ EnemyPawn ์ฑ„๋„์„ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ๋‹ค.

GetCapsuleComponent()->SetCollisionObjectType(ECC_GameTraceChannel1);
GetCapsuleComponent()->SetCollisionResponseToChannel(
    ECC_GameTraceChannel1,
    ECR_Overlap);

๋˜ํ•œ LockOnComponent์˜ SphereTrace์—์„œ๋„ ํ•ด๋‹น ์ฑ„๋„์„ ํƒ์ง€ํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

SearchObjectTypes.AddUnique(
    UEngineTypes::ConvertToObjectType(
        ECC_GameTraceChannel1));

์ด๋ฅผ ํ†ตํ•ด ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ๋ผ๋ฆฌ๋Š” Overlap์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด์„œ ํ”Œ๋ ˆ์ด์–ด ๋Œ€์ƒ ์ „ํˆฌ ํŒ์ •์€ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋ฅผ ๋งˆ๋ จํ–ˆ๋‹ค.


4. ๋ฃจ๋ฉ˜ NPC ๊ณต๊ฒฉ ๋Œ€์ƒ ์˜ค์‹๋ณ„ ๋ฌธ์ œ ์ˆ˜์ •

์›์ธ ๋ถ„์„

๋ฃจ๋ฉ˜ NPC๊ฐ€ ๋ชฌ์Šคํ„ฐ ๊ณต๊ฒฉ ๋Œ€์ƒ์ด๋‚˜ ๋ฝ์˜จ ๋Œ€์ƒ์œผ๋กœ ์ž˜๋ชป ์ธ์‹๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

์›์ธ์€ ํฌ๊ฒŒ ์„ธ ๊ฐ€์ง€์˜€๋‹ค.

1. Pawn ์ฑ„๋„ ์ถฉ๋Œ ์œ ์ง€
2. LockOn ASC ํ•„ํ„ฐ ๋ถ€์žฌ
3. NoTeam ํŒ์ • ์ฒ˜๋ฆฌ ๋ฏธํก

๊ทธ ๊ฒฐ๊ณผ ๋ฃจ๋ฉ˜์ด ์‹ค์ œ ์ „ํˆฌ ๋Œ€์ƒ์ด ์•„๋‹˜์—๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ–ˆ๋‹ค.

๋ชฌ์Šคํ„ฐ ํžˆํŠธ๋ฐ•์Šค ์˜ค๋ฒ„๋žฉ
โ†’ ๋ฃจ๋ฉ˜ ๊ฐ์ง€

๋ฝ์˜จ SphereTrace
โ†’ ๋ฃจ๋ฉ˜ ํฌํ•จ

AI ํŒ€ ํŒ์ •
โ†’ Hostile ์ฒ˜๋ฆฌ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๋จผ์ € ๋ฃจ๋ฉ˜์˜ Pawn ์ฑ„๋„ ์ถฉ๋Œ์„ ๋ฌด์‹œํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

Capsule->SetCollisionResponseToChannel(
    ECC_Pawn,
    ECR_Ignore);

๋˜ํ•œ LockOnComponent์—์„œ๋Š” ASC๊ฐ€ ์—†๋Š” ์•กํ„ฐ๋ฅผ ์ œ์™ธํ•˜๋„๋ก ํ•„ํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

if (!ASCIface ||
    !ASCIface->GetAbilitySystemComponent())
{
    continue;
}

๋งˆ์ง€๋ง‰์œผ๋กœ ํŒ€ ํŒ์ • ๋กœ์ง์—์„œ NoTeam์„ Neutral๋กœ ์ฒ˜๋ฆฌํ•˜๋„๋ก ์ˆ˜์ •ํ–ˆ๋‹ค.

if (OtherTeamId == FGenericTeamId::NoTeam)
{
    return ETeamAttitude::Neutral;
}

์ด๋ฅผ ํ†ตํ•ด ๋น„์ „ํˆฌ NPC๊ฐ€ ์ „ํˆฌ ์‹œ์Šคํ…œ์— ํฌํ•จ๋˜์ง€ ์•Š๋„๋ก ์ •๋ฆฌํ–ˆ๋‹ค.


5. ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ ์ฒด๋ ฅ๋ฐ” ๊ตฌํ˜„

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

์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ ๋จธ๋ฆฌ ์œ„์— ํ‘œ์‹œ๋˜๋Š” ์ฒด๋ ฅ๋ฐ” UI๋ฅผ ์ƒˆ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.

์‹ ๊ทœ ์ƒ์„ฑ ํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

NormalMonsterHealthBarComponent
RetrieveNormalMonsterHealthBarWidget
RetrieveElementUILibrary

RetrieveEnemyCharacter ์ƒ์„ฑ์ž์—์„œ WidgetComponent๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์บ๋ฆญํ„ฐ์— ๋ถ€์ฐฉํ–ˆ๋‹ค.

NormalHealthBarComponent =
    CreateDefaultSubobject<
        UNormalMonsterHealthBarComponent>(...);

NormalHealthBarComponent
    ->SetupAttachment(GetRootComponent());

NormalHealthBarComponent
    ->SetRelativeLocation(
        FVector(0.f, 0.f, 120.f));

๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋А๋‚€ ์ 

์›”๋“œ ๊ณต๊ฐ„ UI๋Š” WidgetComponent๋ฅผ ์ง์ ‘ ๋ถ€์ฐฉํ•˜๋Š” ๋ฐฉ์‹์ด ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์‰ฝ๋‹ค.

๋˜ํ•œ Component๋Š” ๋ฐ์ดํ„ฐ ๊ฐฑ์‹ ๊ณผ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๊ณ , Widget์€ ํ‘œํ˜„๋งŒ ๋‹ด๋‹นํ•˜๋„๋ก ์—ญํ• ์„ ๋ถ„๋ฆฌํ•ด๋‘๋ฉด ์ดํ›„ ์›์†Œ ์ƒํƒœ, ๋ฒ„ํ”„ ํ‘œ์‹œ, ๋””๋ฒ„ํ”„ ์•„์ด์ฝ˜ ๋“ฑ์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜๊ธฐ๋„ ์ˆ˜์›”ํ•˜๋‹ค.


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

  • ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ ์ „ํˆฌ ํ๋ฆ„์„ ์ ๊ฒ€ํ•˜๋ฉด์„œ ๊ณต๊ฒฉ ์ƒํƒœ ์ง„์ž… ์‹คํŒจ์˜ ์›์ธ์ด ๋‹จ์ˆœ StateTree ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ณต๊ฒฉ๊ถŒ ๊ด€๋ฆฌ ๊ตฌ์กฐ์™€ ๊ฑฐ๋ฆฌ ์กฐ๊ฑด ๊ฒฝ๊ณ„์— ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.
  • ๊ณต๊ฒฉ๊ถŒ์„ Cost/Budget ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ๋กœ ๋ณ€๊ฒฝํ•ด ๋ชฌ์Šคํ„ฐ ์ข…๋ฅ˜๋ณ„ ์ „ํˆฌ ๋ฐ€๋„๋ฅผ ๋ฐ์ดํ„ฐ๋งŒ์œผ๋กœ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์„ ๋งˆ๋ จํ–ˆ๋‹ค.
  • EnemyPawn ์ฑ„๋„ ๋ถ„๋ฆฌ์™€ ๋ฃจ๋ฉ˜ NPC ํ•„ํ„ฐ๋ง์„ ํ†ตํ•ด ์ „ํˆฌ ๋Œ€์ƒ ํŒ์ • ๋ฐ ์ถฉ๋Œ ๊ตฌ์กฐ๋ฅผ ๋ณด๋‹ค ๋ช…ํ™•ํ•˜๊ฒŒ ์ •๋ฆฌํ–ˆ๋‹ค.
  • ์ผ๋ฐ˜ ๋ชฌ์Šคํ„ฐ ์ฒด๋ ฅ๋ฐ”๋ฅผ WidgetComponent ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ์ „ํˆฌ UI ํ™•์žฅ์— ํ•„์š”ํ•œ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋„ ํ•จ๊ป˜ ๊ตฌ์ถ•ํ–ˆ๋‹ค.
profile
๊ฐœ๋ฐœํ•ฉ์‹œ๋‹ค!

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