[๊ฒ์๊ฐ๋ฐ] Daydream
๐น ํ์ดํ : Daydream - Tower of The Loar -
๐น ์ฅ๋ฅด : 2D ์ก์
๐น ํ๋ซํผ : PC
๐น ๊ฐ๋ฐ๊ธฐ๊ฐ : 2020.06 ~ 2021.05
๐น ๊ฐ๋ฐ์ธ์ : 2๋ช
( ํ๋ก๊ทธ๋๋จธ, ๋์์ด๋)
๐น ํ๋ ์ดํ์ : 20-30๋ถ
๐น ์ฌ์ฉ ํด : Unity
๐ธ ํ๋ ์ด ์์
- ์คํ ์ด์ง 1 ํ๋ ์ด ์์ ( ๊ธฐ์ฌ / ์ฌ๋ฅ๊พผ)
- ์คํ ์ด์ง 2 ํ๋ ์ด ์์ ( ๋ง๋ฒ์ฌ / ๊ด์ ์ฌ)
๐ธ ์คํฌ๋ฆฐ ์ท
๐ธ ๊ฒ์ ์ค๋ช
์น๊ตฌ์ ์์ผ์ ๋ฌผ ๋ง๋ค์ด์ฃผ๊ธฐ ํ๋ก์ ํธ๋ก ๋ง๋ค์ด์ง PROJECT-Aํ์ ์ธ๋ฒ์งธ ๊ฒ์์
๋๋ค.
์ฅ๋ฅด๋ ํก์คํฌ๋กค ์ก์
์ด๊ณ , ์์์ ์ด๋ฃจ๊ธฐ ์ํด ํ์ ์ฌ๋ผ ๊ฐ์ ๋ค์ ์ฐ๋ ค๋จ๋ ค์ผ ํ๋ ๋ชจํ๊ฐ๋ค์ ์ด์ผ๊ธฐ์
๋๋ค. ๊ท์ฝ์ง๋ง ๋ค์ ์ํนํ? ๋ถ์๊ธฐ์ ๊ฒ์์ผ๋ก 2๋ช
์ ์บ๋ฆญํฐ๋ฅผ ์ ํํด ํ์ ์ฌ๋ผ์ผ ํ๋ฉฐ, ํ์ ํ์ธต ํ์ธต์๋ ๊ฐ๋ ฅํ ๋ณด์ค๊ฐ ์กด์ฌํฉ๋๋ค. ๋ค๋ฅธ ์์ ์์ด ์ค๋ก์ง ๋ณด์ค์์ ์ ํฌ์๋ง ์ง์คํ๋ ๋ณด์ค๋ฌ์ ํ์์ ๊ฒ์์
๋๋ค. ํ์ฌ๊น์ง๋ 2์ข
๋ฅ์ ๋ณด์ค๊ฐ ๊ตฌํ๋์ด ์์ต๋๋ค.
์์ฑ๋๋ ์กฐ๊ธ ๋ถ์กฑํ์ง๋ง, ๋ง์ ๊ณต๋ถ๊ฐ ๋์๋ ํ๋ก์ ํธ ์ ๋๋ค.
โผ ์บ๋ฆญํฐ์ ๋ณด์ค ๋ชฌ์คํฐ
[ ์บ๋ฆญํฐ ]
4๋ช ์ ์บ๋ฆญํฐ๊ฐ ์กด์ฌํ๋ฉฐ ๊ฐ ์บ๋ฆญํฐ๋ ๋์ฌ์ 3๊ฐ์ง ์คํฌ์ ๊ฐ์ง๊ณ ์์ต๋๋ค. ๊ฐํ๊ณ ๋๋ฆฐ ์คํฌ๊ณผ ์กฐ๊ธ ์ฝํ์ง๋ง ๋น ๋ฅธ ์คํฌ ๋ ๊ฐ์ง๊ฐ ์๊ณ , ํน๋ณํ ๋ฅ๋ ฅ์ ์ฌ์ฉ ํ ์ ์๋ ๊ณ ์ ์คํฌ์ด ์์ต๋๋ค. ๊ณ ์ ์คํฌ์ ์บ๋ฆญํฐ์ ํ๋ ์ด ์คํ์ผ์ ๋๋ฌ๋ผ ์ ์๋ ํน์ง์ ์ธ ์คํฌ์ ๋๋ค.
< "๊ธฐ์ฌ" ์บ๋ฆญํฐ ๋งํฌ์ ์คํ
์ดํฐ์ค ๋ฐ >
๊ฐ ์คํฌ์ SP(ํ๋ ฅ)์ด๋ผ๋ ์์์ ์๋ชจํ๋๋ฐ SP๋ ํญ์ ์กฐ๊ธ์ฉ ํ๋ณต๋ฉ๋๋ค. ํน๋ณํ ํ ๋๋ฆฌ๊ฐ ์ณ์ ธ์๋ ์บ๋ฆญํฐ ๊ณ ์ ์คํฌ์ SP๋ฅผ ์๋ชจํ๋ ๋์ ์ต๋ SP์ ๊ฐ์ ์๋ชจํ์ฌ ํน์ํ ํจ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค. ์ต๋ SP์ ํ๊ณ๊ฐ๋ ์๊ฐ์ ๋ฐ๋ผ ํ๋ณตํ์ง๋ง ํ๋ณต์๋๊ฐ SP์ ๋นํด์๋ ๋๋ฆฝ๋๋ค.
๊ฐ ์บ๋ฆญํฐ์ ๊ณ ์ ์คํฌ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์บ๋ฆญํฐ | ๊ณ ์ ์คํฌ | ์ค๋ช |
---|---|---|
๊ธฐ์ฌ | ๋ฐฉ์ด | ์ฌ์ฉ ์ค ๋ฐ๋ ํผํด๋ฅผ ๋ฌด์ |
์ฌ๋ฅ๊พผ | ๋ซ ์ค์น | ๋ซ์ ์ค์นํ์ฌ ๋ซ์ ๊ฑธ๋ฆฐ ์ ์๊ฒ ์ผ์ ์๊ฐ ์ถ๊ฐ ํผํด |
๊ด์ ์ฌ | ๊ด๋ถ | ์ฆ์ ์ต๋ SP์ 100%๋ฅผ ํ๋ณต |
๋ง๋ฒ์ฌ | ๋ง๋ ฅ ์์ถ | SP์๋ชจ ์์ด ๋ค๋ฅธ ์คํฌ์ ์ฌ์ฉํ ์ ์๋ ๋ง๋ ฅ๊ตฌ์ฌ ์ํ |
๋๋ช ์ ์บ๋ฆญํฐ์ค ์์ ์ด ์กฐ์ํ๊ณ ์์ง ์๋ ์บ๋ฆญํฐ๋ ํญ์ ์กฐ์์ค์ธ ์บ๋ฆญํฐ๋ฅผ ์ผ์ ๊ฑฐ๋ฆฌ ๋ด์์ ๋ฐ๋ผ๋ค๋๋ฉฐ, ์ฒด๋ ฅ์ด ๋คํด ์ฐ๋ฌ์ง์ง ์์ ํ ์ธ์ ๋ ์ง ์ค์์นญํด๊ฐ๋ฉฐ ์ ํฌ๋ฅผ ์งํํ ์ ์์ต๋๋ค.
์บ๋ฆญํฐ๋ ํ๋์ Base ์คํฌ๋ฆฝํธ์ Animator๋ฅผ ์์
๋ฐ์ ์ด๋, ์ ํ, ๊ธฐ๋ณธ๊ณต๊ฒฉ ๋ฑ ๊ณตํต๋ ํ๋์ ์ํํฉ๋๋ค. ์บ๋ฆญํฐ๋ง๋ค์ ๋ค๋ฅธ ์คํฌ์ Base ์คํฌ๋ฆฝํธ์์ ๊ฐ์ํจ์
์ ์ค๋ฒ๋ผ์ด๋ฉ
์ ์ฌ์ฉํ์ฌ ๊ตฌํํ์๊ณ , ์ ๋๋ฉ์ด์
์ Animator Override Controller
๋ฅผ ์ฌ์ฉํด ๊ฐ์ Base Animator๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํ์ฌ ์ฌ์ฉํ์์ต๋๋ค.
[ ๋ณด์ค๋ชฌ์คํฐ ]
๋ณด์ค๋ชฌ์คํฐ๋ ํ์ฌ๊น์ง 2์ข
๋ฅ์ ๋ณด์ค๊ฐ ์์ต๋๋ค.
๊ฐ๋ฐ ์ค ์ฒซ๋ฒ์งธ ๋ณด์ค๋ฅผ ๋ง๋ ๋ฐฉ๋ฒ์ด ๋นํจ์จ์ ์ด๋ผ๊ณ ์๊ฐ๋์ด, ๋๋ฒ์งธ ๋ณด์ค๋ถํฐ๋ ๊ฐ๋ฐ ๊ธฐ๊ฐ์ ๋จ์ถ์ํค๊ธฐ ์ํ ๊ณ ๋ฏผ์ ํ๊ณ ํจํด ์ ์ ๋๊ตฌ๋ฅผ ๋ง๋ค์ด ๊ฐ๋ฐ์ ์ด์ด๋๊ฐ์ต๋๋ค.
์ฒซ๋ฒ์งธ ๋ณด์ค์ธ ์ง์์ ๊ณจ๋ ์ ๊ฐ ๋ถ์๋ณ๋ก ์ค๋ธ์ ํธ๋ฅผ ๋ง๋ ํ ์๊ฐ์ ๋ฐ๋ฅธ ๋ถ์๋ณ ์์น๋ฅผ ์ ๋๋ฉ์ด์
์ผ๋ก ์ง์ ์ ์ํ์ฌ Animator
๋ฅผ ํตํด ์์ง์ด๋๋ก ๋ง๋ค์์ต๋๋ค. ๊ณจ๋ ์ Ai๋ ์คํฌ๋ฆฝํธ ๋ด์์ FSM๊ณผ ๊ฐ์ข
์กฐ๊ฑด๋ฌธ์ ๋ฐ๋ผ์ ํ๋์ ์ํํ๋๋ก ํ์ต๋๋ค. ํ๊ฒ๊ณผ์ ๊ฑฐ๋ฆฌ์ ๋ฐ๋ผ์ ์๊ฑฐ๋ฆฌ ๋๋ ๊ทผ๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ ํจํด์ ์ฌ์ฉํ ํ, ์งง์ ์๊ฐ ํ๊ฒ์๊ฒ๋ก ์ด๋ํด ๋ค์ ๊ณต๊ฒฉ์ ์๋ํฉ๋๋ค.
์ด ๋ณด์ค๋ ์ ๋ถ์๋ฅผ ํ๊ฒฉํ๋ฉด ๋์ ๋ ๋ฐ๋ฏธ์ง์ ๋ฐ๋ผ ์ ๋ถ๋ถ์ด ํ๊ดด๋๋๋ก ์ค๊ณํ์์ต๋๋ค. ํ์ชฝ ์์ด ํ๊ดด๋๋ฉด ๊ทธ๋๋ถํฐ ํด๋นํ๋ ์ด๊นจ์์ ๋ถ / ์ผ์์์ฑ ๋ง๋ฒ์ ์ฌ์ฉํ์ฌ ๋์ด๋๊ฐ ์ฆ๊ฐํ๊ฒ ๋๋ฉฐ ์ฒด๋ ฅ์ด ๋ฎ์์ง๋ฉด ์ผ๊ตด์์ ๋ ์ด์ ๋ฅผ ๋ฟ๋ ๊ณต๊ฒฉ์ ์ฌ์ฉํฉ๋๋ค.
๊ทธ๋ฌ๋ ์ ์ํ๋ฉด์ ๋ช๊ฐ์ง ๋ฌธ์ ๊ฐ ์กด์ฌํ์ต๋๋ค.
- ๊ณจ๋ ์ ์์ชฝ ์ด๊บ ์ ์ฑ ์ฅ ์์ด ๋ฐฉํฅ์ ๊ด๊ฒ์์ด ํญ์ ๊ณ ์ ์ด์์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ข/์ฐ ๋ฐฉํฅ ๋๊ฐ์ง ๋์ผํ ์ ๋๋ฉ์ด์ ์ ๋ง๋ค์๋๋ฐ, ์ด ๋ฐฉ์์ ๋์์ ์์ ํ ๋๋ง๋ค ๋ฐฉํฅ๋ณ๋ก ์ ๋ถ ์์ ์ ํด์ฃผ์ด์ผ ํด์ ๋ฒ๊ฑฐ๋กญ๊ณ ์๊ฐ์ด ๋ง์ด ์๋ชจ๋์์ต๋๋ค. Animator๊ฐ ๋ณต์กํด์ง๋ ๊ฒ๋ ๋ง์์ ๋ค์ง ์์์ต๋๋ค. ๋์ค์์์ผ ์คํ๋ ค Bone์ ์ ์ฉํ์ฌ ๋ง๋ค์๋ค๋ฉด ๋ ์ข์์ํ ๋ฐ ํ๋ ์์ฌ์์ด ์์ต๋๋ค.
- ํ๋ฒ์ ํ๋์ ํ๋๋ง ํ๊ธฐ ๋๋ฌธ์ ํจํด์ด ๋จ์กฐ๋กญ๊ณ ๋ฐ๋ณต๋๋ ์์์ด ์์์ต๋๋ค. ํจํด์ ์๊ฐ ๊ทธ๋ฆฌ ๋ง์ง ์๊ณ ๋ฐ๋ณต๋๊ธฐ ๋๋ฌธ์ ํ๋ ์ด๊ฐ ์ง๋ฃจํ๋ค๋ ํผ๋๋ฐฑ์ ๋ฐ์์์ต๋๋ค.
- ์ค๋ก์ง ์คํฌ๋ฆฝํธ๋ด๋ถ์์๋ง ๊ณจ๋ ์ ํ๋์ ์ ์ดํ ์ ์์๊ณ ์กฐ๊ฑด๋ฌธ์ด ์ค์ฒฉ๋๋ฉฐ ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ๋จ์ด์ง๋ ๋ฌธ์ ์, ์์ง ์์์๋ ๊ณต๊ฒฉํจํด์ ์ถ๊ฐ๋ ์์ ์ด ๋ถ๊ฐ๋ฅํ ๋ฌธ์ ๋ก ์๋นํ ๋ถํธํ์์ต๋๋ค.
- ๋ํ ๊ณต๊ฒฉ๊ฑฐ๋ฆฌ๋ฅผ ํ๋จํ๋ AttackDistCheck ํจ์์์ ๊ณต๊ฒฉํจํด์ ๊ฒฐ์ ํ๊ณ ์์ด ์ด๋ฆ๊ณผ ๊ธฐ๋ฅ์ด ๋ง์ง ์๊ณ ํจํด์ ์ ํ ํ๋ฅ ๋ ํ๋์ฝ๋ฉ๋์ด ์ข์ง ์์ ์ฝ๋๊ฐ ๋์์ต๋๋ค.
๊ณจ๋ ์ ๊ณต๊ฒฉํจํด ์ ํ ์ฝ๋
public override void Attack()
{
if (isAttack == false)
{
animator.SetBool("isAttack", true);
animator.SetInteger("attack", atkNum);
}
}
bool HPTrigger = false;
//๊ณต๊ฒฉ๊ฑฐ๋ฆฌ๋ฅผ ํ๋จํ๋ ์ด๋ฆ์ ํจ์์์ ๊ณต๊ฒฉ์ ๊ฒฐ์ ํ๊ณ ์์ด ์ข์ง ๋ชปํ ๊ฒฝ์ฐ..
public override void AttackDistCheck()
{
if (!animator.GetCurrentAnimatorStateInfo(0).IsName("Neutral_Move"))
{
//์ฒด๋ ฅํธ๋ฆฌ๊ฑฐ๋ก 30ํ๋ก๊ฐ ๋ ๋ ํ์ ์ผ๋ก ํ๋ฒ ์ฌ์ฉ, ์ดํ ํ๋ฅ ์ ์ผ๋ก ๋ ์ด์ ๊ณต๊ฒฉ
if (Stat.CurrentHP <= Stat.TotalHp * 0.3f)
{
if (HPTrigger == false)
{
HPTrigger = true;
atkNum = GetDirection() * 20; //์ ๋๋ฉ์ดํฐ์์ ์ง์ ๋ ํ๋๋ฒํธ๋ฅผ ์ ํ
state = eFSM.attack; //ํ์ฌ ์ํ๋ฅผ ๊ณต๊ฒฉ์ผ๋ก ์ ํ
return;
}
else
{
bool random = Random.value <= 0.2f ? true : false;
if (random == true)
{
atkNum = GetDirection() * 20; //์ ๋๋ฉ์ดํฐ์์ ์ง์ ๋ ํ๋๋ฒํธ๋ฅผ ์ ํ
state = eFSM.attack;
return;
}
}
}
//๊ทผ๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ๋ฒ์์ ์๋ค๋ฉด
if (Vector3.Distance(target.position, transform.position) < meleeArea)
{
//๋ํ ๋ค ํ๊ดด์
if (leftH.activeSelf == false && rightH.activeSelf == false)
{
atkNum = GetDirection() * (10 + 1); //์ ๋๋ฉ์ดํฐ์์ ์ง์ ๋ ํ๋๋ฒํธ๋ฅผ ์ ํ
state = eFSM.attack;
}
//์ค๋ฅธ์ ํ๊ดด์
else if (rightH.activeSelf == false)
{
if (GetDirection() == 1)
{
atkNum = GetDirection() * 1;
state = eFSM.attack;
}
else if (GetDirection() == -1)
{
if (Mathf.Abs(target.position.x - transform.position.x) < 2f)
{
int rand = Random.value <= 0.8f ? 3 : 11;
atkNum = GetDirection() * rand;
state = eFSM.attack;
}
}
}
// ์ค๋ฅธ์ชฝ ๊ทผ์ : ๋ฐ์น๊ธฐ ์๊ฑฐ๋ฆฌ: ์ ํ, ๋จธ๋ฆฌ์ฐ๊ธฐ
// ์ผ์ชฝ ๊ทผ์ : ํ์์ฐ๊ธฐ ์๊ฑฐ๋ฆฌ: ์ ํ
//์ผ์ ํ๊ดด์
else if (leftH.activeSelf == false)
{
if (GetDirection() == -1)
{
atkNum = GetDirection() * 1;
state = eFSM.attack;
}
else if (GetDirection() == 1)
{
if (Mathf.Abs(target.position.x - transform.position.x) < 2f)
{
int rand = Random.value <= 0.8f ? 3 : 11;
atkNum = GetDirection() * rand;
state = eFSM.attack;
}
}
}
//์ค๋ฅธ์ ๊ทผ์ : ํ์์ฐ๊ธฐ ์๊ฑฐ๋ฆฌ ์ ํ
//์ผ์ ๊ทผ์ :๋ฐ์น๊ธฐ ์๊ฑฐ๋ฆฌ ์ ํ ๋จธ๋ฆฌ์ฐ๊ธฐ
//๋ฉ์ฉกํ ๋
else
{
//๊ทผ์ ๋ด๋ ค์ฐ๊ธฐ
if (Mathf.Abs(target.position.x - transform.position.x) >= 2f)
{
atkNum = GetDirection() * 1;
}
else
{
atkNum = GetDirection() * Random.Range(2, 4);
}
state = eFSM.attack;
}
}
//์๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ๋ฒ์์ ์๋ค๋ฉด
else if (Vector3.Distance(target.position, transform.position) < rangeArea)
{
if (rightH.activeSelf == false && leftH.activeSelf == false)
{
atkNum = GetDirection() * (10 + 1);
state = eFSM.attack;
}
else if (leftH.activeSelf == false)
{
if (GetDirection() == -1)
{
atkNum = GetDirection() * (10 + Random.Range(1, 3));
state = eFSM.attack;
}
else if (GetDirection() == 1)
{
atkNum = GetDirection() * (10 + 1);
state = eFSM.attack;
}
}
else if (rightH.activeSelf == false)
{
if (GetDirection() == 1)
{
atkNum = GetDirection() * (10 + Random.Range(1, 3));
state = eFSM.attack;
}
else if (GetDirection() == -1)
{
atkNum = GetDirection() * (10 + 1);
state = eFSM.attack;
}
}
//๋ฉ์ฉกํ ๋
else
{
atkNum = GetDirection() * (10 + Random.Range(1, 3));
state = eFSM.attack;
}
}
//์ผ์ ์๊ฐ ๋ค ๋ค์ ๊ณต๊ฒฉํ ์ง ๋ง์ง ํ๋จ์ Boss_CancleAttack์์
}
}
< ๊ณจ๋ ์ ๊ณต๊ฒฉํจํด ์ ๋๋ฉ์ด์
ํ
์คํธ>
< ๊ณจ๋ ์ Animator. ์๋ง์ transition์ผ๋ก ์ฐ๊ฒฐ๋์ด์๋ค. >
๊ทธ๋์
๋๋ฒ์งธ ๋ณด์ค์ธ ์๊ฐ์ ๊ด๋ฆฌ์ ๋ ์ค๋ธ์ ํธ๋ฅผ ๋ถ์๋ณ๋ก ์กฐํฉํ์ฌ ์ฌ์ฉํ๋ ์ฒซ ๋ณด์ค์ ๋ฌ๋ฆฌ, ๋ณด์ค์ ๋ชธ์ฒด๋ฅผ ์ต์ํ์ ์ค๋ธ์ ํธ๋ง์ผ๋ก ๊ตฌ์ฑํ๊ณ ๋จ์ผ ์คํ๋ผ์ดํธ๊ฐ ํ๋ ์์ ๋ฐ๋ผ ๋ณํ๋ ์ ๋๋ฉ์ด์ ๋ฐฉ์์ผ๋ก ์ ์๋ฐฉ์์ ๋ณ๊ฒฝํ์์ต๋๋ค. ๊ทธ์ ๋์์ ํจํด ์ ์ ๋๊ตฌ์ ๋์ ์ผ๋ก ์์ ๋ฌธ์ ๋ค์ ๋๋ถ๋ถ ํด๊ฒฐํ ์ ์์์ต๋๋ค. ๋์์ด๋๊ฐ ๊ฐ์ข ํ๋์ ํ๋ ์์ ๋ง๋ค์ด๋ด๋๋ผ ์กฐ๊ธ ๊ณ ์ํ๊ธฐ๋ ํ์ง๋ง..
- ํจํด ์์ฑ๊ธฐ๋ฅผ ์ด์ฉํด ๋ฏธ๋ฆฌ ์ ์๋์ด์๋ ์ ์ฒด ๋์๋ค ์ค์ ์ํํ ์ ๋๋ฉ์ด์ ์ ์ง์ ์ ํํ๊ณ ์ํํ๊ธฐ ๋๋ฌธ์ Animator๊ฐ transition์ผ๋ก ๋ณต์กํด์ง๋ ๋ฌธ์ ๊ฐ ํด์๋์๊ณ ๋์์ ์ถ๊ฐ ๋ฐ ์์ ๋ ์ฉ์ดํด์ก์ต๋๋ค.
- ๋ํ ํจํด ์์ฑ๊ธฐ์์ ํ๋์ ํจํด์ ์ฌ๋ฌ ํ๋์ ์ฝค๋ณด์ฒ๋ผ ์ฐ๋ฌ์ ์ํํ ์ ์๊ฒ ํ์ฌ ํ๋ฒ์ ํ๋์ ํ๋๋ง ์ํํด ๋จ์กฐ๋กญ๋ ํจํด์ ๋ค์ํํ์์ต๋๋ค. ์ด์ ๋ํด์๋ ํ๋จ ๋ชฌ์คํฐ ํจํด ์์ฑ ๋๊ตฌ ํญ๋ชฉ์์ ์ถ๊ฐ๋ก ์ค๋ช ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
- ํจํด ์์ฑ๊ธฐ๊ฐ ํจํด์ ์ ํํ๋ ๋ถ๋ถ์ ๋์ ํจ์ผ๋ก์ ์ฒซ๋ฒ์งธ ๋ณด์ค์ ์ค์ฒฉ์กฐ๊ฑด๋ฌธ ๋ฑ ๋ณต์กํ๋ ํจํด์ ํํจ์์ ์ฝ๋๊ฐ ๊ต์ฅํ ๊ฐ๊ฒฐํด์ก์ต๋๋ค. ํจํด ์์ฑ๊ธฐ๋ ์คํฌ๋ฆฝํธ๊ฐ ์๋ ์์ง์์์ ์์ ํ๊ธฐ ๋๋ฌธ์ ์คํฌ๋ฆฝํธ๋ก๋ง ์ ์ด ๊ฐ๋ฅํ๋ ๋ฌธ์ ๋ ํด๊ฒฐ๋์์ต๋๋ค.
- ํจ์์ ์ด๋ฆ๊ณผ ๊ธฐ๋ฅ์ด ๋ง์ง ์๋ ๋ถ๋ถ๋ ๋ช ํํ๊ฒ ๋ถ๋ฆฌ๋์ด AttackDistCheck๋ ์ค๋ก์ง ๊ณต๊ฒฉํ์ ์ ํ๋จํ๋ ๊ธฐ๋ฅ๋ง ํ๊ฒ ๋์์ต๋๋ค.
์๊ฐ๋ณด์ค์ ๊ณต๊ฒฉํจํด ์ ํ ์ฝ๋
//FSM์์ ์ํ๊ฐ move์ผ ๋ ๋ค์ ๊ณต๊ฒฉ์ ํ์
์ ํ๋จํ๋ค.
public virtual void AttackDistCheck()
{
//์บ๋ฆญํฐ์์ ๊ฑฐ๋ฆฌ๋ฅผ ์ฒดํฌํ์ฌ ๋ค์ ๊ณต๊ฒฉ์ range/melee ํ๋จ
if (Vector3.Distance(target.position, transform.position) < meleeArea)
{
typeOfAttack = eEnemy_TypeOfAttack.MELEE;
}
else
{
typeOfAttack = eEnemy_TypeOfAttack.RANGE;
}
//FSM ์ํ๋ฅผ ๊ณต๊ฒฉ์ผ๋ก ์ ํ
SetState(eFSM.attack);
}
//FSM์์ ์ํ๊ฐ attack์ด ๋๋ฉด ์ํ๋๋ค.
public virtual void Attack()
{
//์ ๋๋ฉ์ดํฐ๋ฅผ ๊ณต๊ฒฉ์ํ๋ก ์ ํ
if (isAttack == false)
{
animator.SetBool("isAttack", true);
}
//์ด๋ ์ค์ด๋ผ๋ฉด ์ฝ๋ฃจํด์ ๋๊ณ ๊ฐ์ ๋ก ๊ณต๊ฒฉ ์ํ
if (coroutine != null)
StopCoroutine(coroutine);
//ํจํด ์์ฑ๊ธฐ ๋ด์ ๊ณต๊ฒฉํจํด์ ์ ํํ์ฌ ์ํํ ํ๋๋ค์ ํ์ ๋ด๋๋ค.
actionQueue = enemyPatternManager.SelectPattern(typeOfAttack, this);
// ํ์ ๋ด๊ธด ํ๋์ ์์ฐจ์ ์ผ๋ก ์ํํ๋ค. ๋น ํจํด์ผ ๊ฒฝ์ฐ ์์ธ์ฒ๋ฆฌ
if(actionQueue != null)
{
ChangeAnimation(actionQueue.Dequeue().action);
}
}
< ์๊ฐ๋ณด์ค์ ๊ณต๊ฒฉํจํด ์ ๋๋ฉ์ด์
ํ
์คํธ>
< ์๋ก ๊ตฌ์ฑํ Animator. ๋จ์ํ ์ ๋๋ฉ์ด์
๋ง ์ ์๋์ด ์๋ค. >
์๊ฐ์ ๊ด๋ฆฌ์๋ ์๊ณ์นจ์ ์ฌ์ฉํ๋ ๊ฐ์ข ๊ณต๊ฒฉ์ ์ฌ์ฉํ๋ฉฐ ์ฒด๋ ฅ์ด ๋ฎ์์ง๋ฉด ๊ณต์ค์ ์ฌ๋ผ๊ฐ ์ง์์ ๋ชจ๋์๊ณ๋ฅผ 3๊ฐ ์ํํ๋ฉฐ 2ํ์ด์ฆ๋ฅผ ์์ํฉ๋๋ค. ๋ชจ๋์๊ณ๊ทผ์ฒ ์์ญ์ ๋ค์ด๊ฐ๋ฉด SP๊ฐ ํ๋ณต๋์ง ์๋ ๋๋ฒํ๊ฐ ๊ฑธ๋ฆฝ๋๋ค. ๋ชจ๋์๊ณ๋ฅผ ๊ณต๊ฒฉํ์ฌ ๋ถ์ ์ ์์ง๋ง ๋ถ์์ง ๋ชจ๋์๊ณ๋ ์ผ์ ์๊ฐ ํ ์๊ฐ์ ๋๋๋ ค ์๊ฐ ๋ณต๊ตฌํฉ๋๋ค. ๋์ ๋๋ฒํ ์์ญ์ด ์ด๊ธฐํ๋์ด ์์ฃผ ์์ ๋ฒ์๋ก ์์ํด ์กฐ๊ธ์ฉ ๋์ด์ง๋๋ค.
โผ ๋ชฌ์คํฐ ํจํด ์์ฑ ๋๊ตฌ
์ฒซ๋ฒ์งธ ๋ณด์ค์ธ โ์ง์์ ๊ณจ๋ โ์ ์ฝ๋๋ก๋ง ํจํด์ ๋ง๋ค์๋๋ฐ ์๊ฐ์ด ๊ต์ฅํ ์ค๋๊ฑธ๋ ธ๊ณ ํจํด ์์ ์ด๋ ์ถ๊ฐ๋ ์๋นํ ๋ถํธํ์ต๋๋ค. ๋๋ฒ์งธ ๋ณด์ค๋ถํฐ๋ ๋์์ด๋๋ ์ฝ๊ฒ ํจํด์ ์์ฑํ ์ ์๋๋ก ํ๊ณ , ์ดํ ์ ์ํ ๋ณด์ค๋ค์ ๊ฐ๋ฐ์๋๋ฅผ ๋์ด๊ธฐ ์ํ์ฌ custom inspector
๋ฅผ ์ด์ฉํ์ฌ ํจํด ์ ์ ๋๊ตฌ๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ์์ต๋๋ค.
๋ชฌ์คํฐ ํจํด ์์ฑ๊ธฐ๋ ๋ชฌ์คํฐ๊ฐ ์ฌ์ฉํ๋ ์ ์ฒด ํจํด๋ค์ ๋ง๋๋ ๋๊ตฌ์
๋๋ค. ๋ฐ๋ ํ์
์ด๋ ์กฐ๊ฑด ๋ฑ์ ์ค์ ํ ์ ์๊ณ ๊ฐ์ค์น ํ๋ฅ ์ ์ ์ฉํ ๋ฐ๋ ํ๋ฅ ์ ์ฝ๊ฒ ํ์ธํ ์ ์์ต๋๋ค.
๋น์ทํ๋ฉด์๋ ๋ค๋ฅธ ๊ณต๊ฒฉ์ ํ๋ ํจํด๋ค์ ๋ง๋ค๊ฑฐ๋, ๊ฐ์ ํจํด์์๋ ๋จ์ ์ฒด๋ ฅ ์์ค์ ๋ฐ๋ผ ๊ฐํ๋ ๊ณต๊ฒฉ์ ์ํํ๋๋ก ํ ์ ๋ ์์ต๋๋ค.
< ๋๋ฒ์งธ ๋ณด์ค์ ์ค์ ํจํด ๋ฐ์ดํฐ >
๊ฐ ํญ๋ชฉ์ ๋ํ ์ค๋ช ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ํญ๋ชฉ | ์ค๋ช |
---|---|
ํ์ | ๊ทผ์ (MELEE), ์๊ฑฐ๋ฆฌ(RANGE), ํน์(SPECIAL) ํ์ ์ ํ |
์ด๋ฆ | ํจํด์ ์ด๋ฆ ์ค์ |
๊ฐ์ค์น | ํจํด์ ๋ฐ๋ ๋น์จ์ ๊ฐ์ค์น๋ก ์์นํ |
ํ๋ฅ | ๊ฐ์ค์น๊ฐ ์ ์ฉ๋ ๋ฐ๋ ํ๋ฅ , ๊ทผ์ (M), ์๊ฑฐ๋ฆฌ(R) ๊ฐ๋ณ ์ ์ฉ |
์ฟจํ์ | ํจํด ์ฌ์ฉ ํ ์ฌ์ฌ์ฉ ๋๊ธฐ์๊ฐ (๋จ์:์ด) |
์ฒด๋ ฅํธ๋ฆฌ๊ฑฐ | ํจํด์ ์ฌ์ฉ์กฐ๊ฑด. ๊ธฐ์ ๋ ์ฒด๋ ฅ ์ดํ์ผ ๊ฒฝ์ฐ์๋ง ํ๋ฅ ๊ณ์ฐ์ ํฌํจ |
์ฒด๋ ฅ๋น์จ ์๋ฎฌ๋ ์ดํฐ | ์ ์ ์ฒด๋ ฅ์ด ์ผ์ ์์น์ผ๋ ๋ฐ๋ ํ๋ฅ ์ ํ์ธ ๊ฐ๋ฅ |
์ธ๋ถํจํด ์ด๋ฆ์ค์ | ๋ชฌ์คํฐ์๊ฒ ํ ๋น๋ ํ๋๋ค์ ์ด๋ฆ์ ๋ถ์ฌ |
๋ชฌ์คํฐ ์ ์ฅ์์ ํ๋ ์ด์ด๊ฐ ์์ ์ ๊ทผ๊ฑฐ๋ฆฌ ๊ณต๊ฒฉ ๋ฒ์ ๋ด์ ์๋ค๋ฉด MELEEํ์ ํจํด์, ๋ฒ์ ๋ฐ์ ์๋ค๋ฉด RANGEํ์ ํจํด์ ๊ฐ์ค์นํ๋ฅ ์ ๋ฐ๋ผ ์ ํํ์ฌ ์ํํฉ๋๋ค. ๋ง์ผ ์ผ์ ์ฒด๋ ฅ ์ดํ๋ก ๋ด๋ ค๊ฐ์ ๊ฒฝ์ฐ, SPECIALํ์ ํจํด์ ์ฌ์ฉํ๊ธฐ๋ ํฉ๋๋ค. ํ๋์ ํจํด์ ์ํํ๋ฉด ๊ทธ ํจํด์ ์ฌ์ฌ์ฉ ๋๊ธฐ์๊ฐ์ ๊ฐ์ง๋ฉฐ, ์ฒด๋ ฅํธ๋ฆฌ๊ฑฐ๊ฐ ์ค์ ๋ ๊ฒฝ์ฐ์๋ ํน์ ์ฒด๋ ฅ ์ดํ์ผ ๋๋ง ๊ฐ์ค์น๋ฅผ ๊ณ์ฐํ๊ณ ๊ทธ๋ ์ง ์์ผ๋ฉด ํ๋ฅ ์ด 0์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
๊ฐ์ค์น ํ๋ฅ ์ ์ ์ฉํ ํจํด ์ ํ ์ฝ๋
public Queue<EnemyAttack> SelectPattern(eEnemy_TypeOfAttack attackType, EnemyActor actor)
{
//์ฒด๋ ฅ์ ๋ฐ๋ผ ํ๋ฅ ๊ฐฑ์
CalculatePatternProb(actor);
//์ ํ๋ ํจํด
EnemyPattern selected = null;
if (patternList.Count == 0)
patternList = patterns;
//ํ๋ฅ ๊ฐ์ ๋ฐ๋ผ์ ํจํด ๋ฆฌ์คํธ๋ฅผ ์ ๋ ฌ
patternList.Sort((x, y) => float.Parse(x.probability).CompareTo(float.Parse(y.probability)));
//์คํ์
ํจํด ์ฐ์ ์ฒดํฌ
for (int i = 0; i < patternList.Count; ++i)
{
if (patternList[i].typeOfAttack == eEnemy_TypeOfAttack.SPECIAL)
{
float HPratio = ((float)actor.Stat.CurrentHP / (float)actor.Stat.TotalHp) * 100f;
bool triggerCheck = patternList[i].triggerRatio >= HPratio;
//์ฒด๋ ฅ์กฐ๊ฑด์ด ์๋ง์ผ๋ฉด ํจ์ค
if (!triggerCheck) continue;
//์กฐ๊ฑด์ ๋ง๋ ํจํด์ผ ๊ฒฝ์ฐ
selected = patternList[i];
patternList.Remove(patternList[i]);
return SelctActions(selected, actor);
}
}
float randomValue = UnityEngine.Random.value * 100f;
float accrueValue = 0; //๋์ ๊ฐ์ค์น๊ฐ
for (int i = 0; i < patternList.Count; ++i)
{
//ํ์
์ด ๋ค๋ฅธ ํจํด์ ์ ํ์์ ์ ์ธ
if (patternList[i].typeOfAttack != attackType) continue;
// ๊ฐ์ค์น ํ๋ฅ ์ ๋ฐ๋ผ์ ์กฐ๊ฑด์ด ๋ง๋์ง ํ์ธ
float prob = float.Parse(patternList[i].probability);
//ํ๋ฅ ์ด 0์ด๋ฉด ๊ทธ ์ก์
์ ์ฆ์ ํจ์ค
if (prob == 0) continue;
if ((prob + accrueValue) > randomValue)
{
//* ํธ๋ฆฌ๊ฑฐ ์ก์
์ฒดํฌ
if (patternList[i].isTriggerAction == true)
{
float HPratio = ((float)actor.Stat.CurrentHP / (float)actor.Stat.TotalHp) * 100f;
bool triggerCheck = patternList[i].triggerRatio >= HPratio;
//ํธ๋ฆฌ๊ฑฐ์กฐ๊ฑด์ธ๋ฐ ๋ง์ฝ ์ฒด๋ ฅ์กฐ๊ฑด์ด ์๋ง์ผ๋ฉด ๊ทธ ์ก์
์ ํจ์ค
if (!triggerCheck) continue;
}
//*์ฟจํ์ ์ฒดํฌ
if (patternList[i].isCoolDown == true) //์ฟจํ์์ค์ด๋ฉด
{
if (selected == patternList[i])
{
accrueValue += prob;
continue;
}
float tmpProb = 100f - float.Parse(patternList[i].probability);
randomValue = UnityEngine.Random.Range(0, tmpProb);
accrueValue = 0;
selected = patternList[i];
i = -1;
continue;
}
selected = patternList[i];
break;
}
else
{
accrueValue += prob;
}
}
//null์ด ๋ฆฌํด๋๋ฉด ๋ฌด์ธ๊ฐ ์๋ชป๋ ๊ฒ์ด๋ฏ๋ก ์์ธ์ฒ๋ฆฌ
if (selected == null)
{
Debug.LogError("ํจํด ์ ํ ์๋ฌ! ์ฌ์ ํ์ ์๋ํฉ๋๋ค");
try
{
return SelectPattern(attackType, actor); ;
}
catch
{
Debug.LogError("์ฌ์ ํ ์คํจ!");
return null;
}
}
//์ ํ๋ ํจํด์ ์ฟจํ์ ํ์ฑํ
if (selected.coolTime > 0)
SetCoolDown(selected);
//์ ํ๋ ํจํด ์์ ํ๋ ์ํ
return SelctActions(selected, actor);
}
ํ๋์ ํจํด์ ๋ชฌ์คํฐ๋ค์๊ฒ ํ ๋น๋ ํ๋ํ์ ๋ค์ ๋ฌถ์์ผ๋ก, ํ๋์ ํจํด์์ ํ๋๋ค์ ์ฐ์ด์ด ์ฌ์ฉํ๋๋ก ์ค์ ํ๋ฉด ๋ณด์ค์ ์ฐ์๋์์ ์ ์ํ ์ ์๋๋ก ๊ตฌํํ์์ต๋๋ค. ํจํด์ ์ ํํ๋ฉด ํ๋จ ์ธ๋ถ ํจํด ์ ๋ณด ๊ตฌ์ญ์ ์ด๋ค ํ๋๋ค์ ์ํํ ๊ฒ์ธ์ง ์ค์ ํ ์ ์์ต๋๋ค.
๊ฐ ํ๋์ ํ๋์ ํ๋์ด ๋๋๋ฉด ์์๋๋ก, ๋ ์ฐ์์ ์ผ๋ก ์ํ๋๋ฏ๋ก ๋ชฌ์คํฐ๋ ์์ฐ์ค๋ฝ๊ฒ ํ๋์ ์ด์ด๊ฐ๋๋ค.
ํจํด ์์ฑ๊ธฐ๋ Reorderable List
๋ฅผ ์ฌ์ฉํ์ฌ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์๊ณ , ๋ด๋ถ๋ queue
์ list
๋ก ๊ตฌํํ์์ต๋๋ค.
์) ํ์ฌ ์ ํ๋ โ๋๋์ง๋โ์ด๋ผ๋ ํจํด์ ๋ค์๊ณผ ๊ฐ์ ํ๋๋ค์ ์งํฉ์ ๋๋ค.
- ๋ ์์ค๋ฅด๊ธฐ -> 2. 360๋ ์๊ณ์นจ ๋ฐ์ฌ -> 3. ์ ์ง ๋์ฌ -> 4. 360๋ ์๊ณ์นจ ๋ฐ์ฌ -> 5. ๋ด๋ ค์ค๊ธฐ
์ธ๋ถ ํจํด ์ ํ ์ฝ๋
Queue<EnemyAttack> SelctActions(EnemyPattern pattern, EnemyActor actor)
{
Queue<EnemyAttack> action = new Queue<EnemyAttack>();
List<EnemyAttack> attackList = pattern.attacks;
//ํจํด์์ฑ๊ธฐ์์ ๋น์ด์๋ ํจํด์ด ๋จ์์์ ๋ ์์ธ์ฒ๋ฆฌ
if (attackList.Count == 0)
Debug.LogError("ํ๋์ด ์ค์ ๋์ง ์์ ๋น์ด์๋ ํจํด์ด ์กด์ฌํฉ๋๋ค!");
for (int depth = 0; depth < attackList.Count; depth++)
{
//* ํธ๋ฆฌ๊ฑฐ ์ก์
์ฒดํฌ
if (attackList[depth].isTriggerAction)
{
float ratio = ((float)actor.Stat.CurrentHP / (float)actor.Stat.TotalHp) * 100f;
bool triggerCheck = attackList[depth].triggerRatio >= ratio;
//ํธ๋ฆฌ๊ฑฐ์ก์
์ธ๋ฐ ๋ง์ฝ ์ฒด๋ ฅ์กฐ๊ฑด์ด ์๋ง์ผ๋ฉด ๊ทธ ์ก์
์ ํจ์ค
if (!triggerCheck) continue;
}
//ํจํด ๋ฆฌ์คํธ ๋ด๋ถ์ ํ๋์ action ํ์ ์ฝ์
action.Enqueue(attackList[depth]);
}
//์ํํด์ผ ํ ํ๋๋ค์ด ๋ด๊ธด queue๋ฅผ ๋ฆฌํด
return action;
}
โผ ์์ด๋
์์ด๋ ๊ณต๋ถ๋ฅผ ์ํด HLSL๋ก ํ์ํ ํจ๊ณผ๋ค์ ๊ตฌํํ๋ ค๊ณ ๋
ธ๋ ฅํ์์ต๋๋ค.
๊ฐ๋จํ ํจ๊ณผ๋ค์ด์ง๋ง ์์ด๋ํจ์๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง๋ฅผ ์ ์ ์์์ต๋๋ค.
-
๋ ๋๋ง ์์ ์กฐ์ ์ ์ํ ์์ด๋
2D์ 3D๋ฅผ ๋์์ ์ฌ์ฉํ๋ค๋ณด๋ ๊ธฐ๋ณธ material๋ก๋ ๋ ๋๋ง ์์์์ ์๋ํ์ง ์์ ๋ฌธ์ ๋ค์ด ๋ฐ์ํ์์ต๋๋ค. 3D ํํฐํด๋ค์ด 2D ์คํ๋ผ์ดํธ์ ๊ฐ๋ ค์ง๋ค๊ฑฐ๋ 2D๊ฐ 3D ๋ฐฐ๊ฒฝ ๋ค์์ ๋ ๋๋ง ๋๋ค๊ฑฐ๋ ํ๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค. ๋ํ ๊ฐ์ 2D์ค๋ธ์ ํธ ์ฌ์ด์์๋ ์บ๋ฆญํฐ์ ๋ณด์ค ์ค๋ธ์ ํธ์ z-fight๋ฌธ์ ๋ฑ ๋ ๋๋ง์ ๊ดํ ์ด์๊ฐ ๋ง์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํํฐํด / 3D๋ฐฐ๊ฒฝ์ค๋ธ์ ํธ / ์บ๋ฆญํฐ / ๋ณด์ค ๋ฑ ์ข ๋ฅ๋ณ๋ก
Render Queue
๋ฅผ ์กฐ์ ํ ์์ด๋์ material์ ๋ง๋ค์ด ๋ ๋๋ง ์์๋ฅผ ์๋ํ ๋๋ก ์ง์ ํด์ฃผ์์ต๋๋ค. -
Outline ์์ด๋
์บ๋ฆญํฐ ์ ํํ๋ฉด๊ณผ ์ ํฌ ์ค ๋ฌด์ ํจ๊ณผ๋ฅผ ๋ํ๋ด๋ ์ฉ๋๋ก Outline์ ์ฌ์ฉํ์์ต๋๋ค. -
Dissolve ์์ด๋
๊ณจ๋ ๋ณด์ค์ ์ผ์๋ง๋ฒ์ด ๋ฑ์ฅํ ๋ Dissolveํจ๊ณผ๋ฅผ ์ฌ์ฉํ์์ต๋๋ค. -
Stencil ์์ด๋
์ธ๋ฒ์งธ ๋ณด์ค์ ํฌํ ํจ๊ณผ๋ฅผ ์ํด ๊ฐ๋จํ Stencil ์์ด๋๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
๐ธ ๊ฐ๋ฐ ์๋
๊ณ ๋ฑํ๊ต๋ ์น๊ตฌ๋ค๊ณผ ํจ๊ป ์ ์ํด ๋์๋ ๋ณด๋๊ฒ์์ด ์์ต๋๋ค. ์ด๋ฒ ๊ฒ์์์๋ ๋น์ ๋ง๋ค์ด๋์๋ ์ธ๊ณ๊ด๊ณผ ์บ๋ฆญํฐ๋ฅผ ๋ถํ์์ผ๋ณด๊ณ ์ ํ์๊ณ ๊ทธ ๊ณผ์ ์ ์ถ์ต ์์ ์ฅ๋๊ฐ์ ๋ค์ ์ ํ ๊ฒ ์ฒ๋ผ ์ฆ๊ฑฐ์ ์ต๋๋ค. ์ก์ ๊ฒ์์ ์ข์ํ๊ธฐ ๋๋ฌธ์ ์ก์ ์ด ์๋ ๊ฒ์์ ๋ง๋ค์ด๋ณด๋ ค๊ณ ํ์ผ๋, ๊ตฌํ ๋ฐฉ์ ๋ฑ์ ๊ณ ๋ฏผ์ด ๋ง์ ์๊ฐ๋ณด๋ค ์ด๋ ค์ด ์์ ์ด์๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๋ฒ ํ๋ก์ ํธ๋ ๊ธฐํ๋จ๊ณ์์๋ถํฐ ๋์์ด๋ ์น๊ตฌ์ ํจ๊ป ์ ํ ๊ฒ์ด ์์ต๋๋ค.
์ด ๊ฒ์์ ์์ฌ์ ๊ฐ๋ ๋ด์์ ๋ง๋ค์ด๋ณด์!
๋ง ๊ทธ๋๋ก ์๋ก ํ๊ณ ์ถ์๋ ์์๋ค์ ์ง์ด๋ฃ์ด ๊ฒ์์ ๋ง๋ค๊ธฐ๋ก ์ ํ๋๋ฐ, ์ ๋ ๊ธฐ์ ์ ์ธ ์๋๋ฅผ ๋ง์ด ํ๊ณ ์ถ์๊ณ ๋์์ด๋๋ 3D์ ๋ํ ์๋๋ฅผ ํด๋ณด๊ณ ์ถ์ดํ์ต๋๋ค. ๊ทธ๋ ๊ฒ ์ํธ์์ ๊ฒ์์ ๋งต๊ณผ ๋ณด์ค์ ์ผ๋ฌ์คํธ๊ฐ 3D๋ก ์์
๋์๊ณ , ํ๋ก๊ทธ๋๋ฐ ์ชฝ์์๋ ์ก์
๊ฒ์์ ๊ตฌํ
๊ณผ ์์ด๋
, ๊ฐ๋ฐํด ์ ์
์ ์ค์ ์ ์ฉ ๋ฑ ๊ทธ๊ฐ ๋ฐฐ์ ๊ฑฐ๋ ๊ถ๊ธํ๋ ๊ธฐ์ ๋ค์ ์ ์ฉํด๋ณด๊ณ ์ ํ์์ต๋๋ค.
๐ธ ๊ธ์ ์ ์ธ ๋ถ๋ถ
์ค์ ๋ก ๊ฒ์์ ์ํ๋ ๊ฒ๋ค์ ๊ตฌํ์ ํ๊ธฐ ์ํด ๊ณต๋ถ๋ ๋ง์ด ํ๊ฒ ๋์์ต๋๋ค. ํนํ ๋ชฌ์คํฐ ํจํด ์ ์ ๋๊ตฌ๋ฅผ ๋ง๋ค์ด ๋ณธ ๊ฒ์ด ํฐ ๊ฒฝํ์ด์์ต๋๋ค. ์ด์ ์์ธ The Fins์์ ๊ฐ๋จํ๊ฒ ๋ง๋ค์๋ ๋ ๋ฒจ ์ ์๋๊ตฌ๋ณด๋ค ๋ ์ฒด๊ณ์ ์ผ๋ก ๊ตฌํํ๊ณ , ๊ทธ ๊ณผ์ ์์ ๊ฐ์ค์นํ๋ฅ ๊ณ์ฐ ๋ฑ ์ํ์ ์ธ ์์๋ ๊ฒ์์ ์ ์ฉํด ๋ณผ ์ ์์์ต๋๋ค. ์ฒซ๋ฒ์งธ ๋ณด์ค๋ฅผ ๋ง๋ค๋ฉฐ ๋ต๋ตํ๋ ๋ถ๋ถ์ ์๋น๋ถ๋ถ ๊ฐ์ ํ๊ณ ํด๊ฒฐ๋ฐฉ๋ฒ์ ์ฐพ์๋๋ค๋ ๊ฒ์ ์กฐ๊ธ์ ๋ฟ๋ฏํจ๊ณผ ์์ ๊ฐ์ ์ป์์ต๋๋ค.
๋, ์ก์ ๊ฒ์์ ๋ง๋๋ ค๋ ์๋์์ ์ก์ ์ ๋ง๋ค์ด๋ด๋๊ฒ ์๋นํ ์ด๋ ต๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ์ฌ๋ฌ ๋ ํผ๋ฐ์ค๋ฅผ ์ฐธ์กฐํ๋ฉด์ ๋ช๋ฒ์ด๋ ์บ๋ฆญํฐ์ ์กฐ์๊ฐ์ ๊ฐ์ ํ๊ณ , ํ ์คํธ๋ฅผ ๊ฑฐ์น๋ฉฐ ์คํฌ ๋๋ ์ด๋ ์๋๋ฅผ ๋ฏธ์ธํ๊ฒ ์กฐ์ ํ๊ณ , ํ๊ฒฉ๊ฐ์ ์ด๋ฆฌ๋ ค๋ฉด ์ด๋ค ๋ฐฉ๋ฒ์ ์จ์ผํ ์ง ๊ณ ๋ฏผํ๋ ๋ฑ ์ก์ ์ด ์๋ ๊ฒ์์ ๋ํ ๊ณ ๋ฏผ์ ๋ง์ด ํ๊ฒ ๋์๋ ํ๋ก์ ํธ ์ ๋๋ค.
์ ๋ํฐ์์๋ ์์ด๋๊ทธ๋ํ๋ก ๋ ธ๋๋ฐฉ์์ ์์ฝ๊ฒ ์์ด๋๋ฅผ ๊ฑด๋๋ฆด ์ ์์ง๋ง, ๊ณต๋ถ๋ฅผ ์ํด ์์ด๋๊ทธ๋ํ๋ฅผ ์ด์ฉํ์ง ์๊ณ HLSL๋ฅผ ์ด์ฉํ์ฌ ์ง์ ์์ด๋๋ฅผ ๋ง๋ค์์ต๋๋ค. ์์ด๋๋ฅผ ๊ฑด๋๋ฆฌ๋๊ฑด ์ฝ์ง ์์๊ณ ์ฌ์ ํ ์ด๋ ต์ง๋ง, ํ๋ํ๋ ์์๊ฐ๊ณ ์๋ก์ด ๊ฒ์ ๋์ ํ๋ ์ผ์ด๋ผ ์ฌ๋ฏธ์๊ฒ ์์ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๐ธ ์์ฌ์ ๋ ๋ถ๋ถ
๊ธฐ์ ์ ์ผ๋ก ๋ง์ ์๋๋ฅผ ํ ํ๋ก์ ํธ์๋ ๊ฒ์ ์ฅ์ ์ด๊ธฐ๋ ํ์ง๋ง ํํธ์ผ๋ก๋ ๋จ์ ์ผ๋ก ์์ฉํ๊ธฐ๋ ํ์ต๋๋ค. ํ๋์ ์๋๋ฅผ ์ํ ๊ณต๋ถ์ ์ํ์ฐฉ์ค๋ฅผ ๋ฐ๋ณตํ๋ฉด์ ์งํํด์ผ ํ๊ธฐ์ ๊ฐ๋ฐ์ ์๋๊ฐ ๋ถ์ง๋ฅผ ์์์ต๋๋ค.
๊ฐ๋ฐ๊ธฐ๊ฐ์ ๊ฑฐ์ 1๋ ์ด์์ผ๋ ์ค๊ฐ์ ๋ช ๊ฐ์๊ฐ ํด์์ ํ๊ธฐ๋ ํ๊ณ , ์บ๋ฆญํฐ์ ์คํฌ๊ณผ ๋ณด์ค์ ํจํด์ ๋ช์ฐจ๋ก ๊ฐ์์๋ ๋ฑ ์ปจํ ์ธ ์ ์ถ๊ฐ ์๋ ์ญ์ ์๋นํ ๋๋ฆฐ ํธ์ด์์ต๋๋ค. ๊ธฐํ์ ํฌ๊ธฐ๋ ์์ฌ ๊ฐ๋ ๋ด์ ๋ฃ์ ์ค์ผ์ผ์ ๊ฐ๋นํ๊ธฐ ์ด๋ ค์ ๊ณ์ ์ค์ฌ๋๊ฐ์ต๋๋ค.
์์ผ์ ๋ฌผ๋ก 1์ฐจ ๋น๋๋ฅผ ๋ฌ์ฑํ ์ดํ์๋ ์ ํด์ง ๊ฐ๋ฐ์ผ์ ์์ด ๊พธ์คํ ์ถ๊ฐ ๊ฐ๋ฐ๊ณผ ๊ฐ์ ์ ํด๋๊ฐ๋๋ฐ ์ผ์ ์ด ์ ํด์ ธ์์ง ์๋ค๋ณด๋ ๊ฒฐ๊ณผ๋ฌผ์ ๋ด๊ธฐ๋ณด๋ค๋ ๊ธฐ์ ์ ์ธ ์๋๋ฅผ ํ๋๋ฐ ์๊ฐ์ ๋ ๋ง์ด ํฌ์ํ์์ต๋๋ค. ๋ํ ๊ฐ ์ฌ์ด ํํธํ ๋์ด ๋ง๋ค์ด์ง๋ค ๋ณด๋ ๊ฒ์์ผ๋ก์์ ์ ์ฒด์ ์ธ ์์ฑ๋๊ฐ ์กฐ๊ธ ์์ฝ์ต๋๋ค.
(post-code: daydream)