๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Unity/AR

[์œ ๋‹ˆํ‹ฐ AR FPS ๊ฒŒ์ž„ ๊ฐœ๋ฐœ] - 1. AR ํ™˜๊ฒฝ์—์„œ ์ด์„ ๋ฐœ์‚ฌํ•˜๊ธฐ / Physics.Raycast

728x90
๋ฐ˜์‘ํ˜•

โ˜ž  ๋ณธ ๊ธ€์€ ์ž‘์„ฑ์ž๊ฐ€ ๊ฐœ๋ฐœํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ๊ธ€๋กœ ์ž˜๋ชป๋œ ์ ์ด ์žˆ์„ ์ˆ˜ ์žˆ์–ด,  ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.
โ˜ž  ํ•ด๋‹น ๋‚ด์šฉ์„ ๊ณต์œ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด, ๋ฐ˜๋“œ์‹œ ์ถœ์ฒ˜๋ฅผ ๊ผญ ๋ช…์‹œํ•ด์ฃผ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

 

https://vrworld.tistory.com/2

 

Unity AR Foundation AR ๊ฐœ๋ฐœ ์ดˆ๊ธฐ ์„ค์ • & ํ‰๋ฉด ์ธ์‹

โ˜ž ๋ธ”๋กœ๊ทธ๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ณ„๊ธฐ ์ง„ํ–‰ํ•ด ์™”๋˜ AR ๊ฐœ๋ฐœ์„ ์‹œํ—˜๊ธฐ๊ฐ„๊ณผ ๊ณ„์ ˆํ•™๊ธฐ๋กœ ์ธํ•ด ๊ณต๋ฐฑ๊ธฐ๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋˜์ž ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ–ˆ๋Š”์ง€ ๊ธฐ์–ต์ด ์‚ฌ๋ผ์ง€๊ฒŒ ๋˜์—ˆ๋‹ค... ๊ทธ๋ ‡๊ฒŒ ์ง€๊ธˆ๊นŒ์ง€์˜ ๊ณผ์ •์„ ์ •๋ฆฌ๋„ ํ•  ๊ฒธ, ํ˜น

vrworld.tistory.com

์ €๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” AR ๊ฐœ๋ฐœ์— ๋Œ€ํ•œ ์ดˆ๊ธฐ ์„ค์ • ๊ณผ์ •์„ ๊ฑฐ์ณค๋‹ค. ์ด ์„ค์ •์„ ๋ฐ”ํƒ•์œผ๋กœ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ•ด์„œ ๋‚˜๊ฐ€๋ฉด ๋œ๋‹ค.

 

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ ๊ธฐํš์„œ

์ง„ํ–‰ํ•˜๊ณ ์ž ํ–ˆ๋˜ AR FPS ๊ฒŒ์ž„ ๊ฐœ๋ฐœ ํ”„๋กœ์ ํŠธ๋Š” ์œ„์˜ ์‚ฌ์ง„๊ณผ ๊ฐ™๋‹ค. ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ๋งํ•˜์ž๋ฉด ๋ณธ๋ž˜ ๋จธ๋ฆฟ์†์œผ๋กœ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ–ˆ๋˜ ๋ฐฉํ–ฅ๊ณผ๋Š” ๋‹ฌ๋ฆฌ ํฌ๊ธฐํ•œ ์ ์ด ๋ช‡ ๊ฐ€์ง€ ์žˆ์–ด ๋„ˆ๋ฌด ์•„์‰ฌ์šด ํ”„๋กœ์ ํŠธ์˜€๋‹ค.

 

์ด์ œ ์ €์˜ ๊ฐœ์ธ์  ์ด์•ผ๊ธฐ๋Š” ๋ง์„ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉด์„œ, AR FPS ๊ฒŒ์ž„ ๊ตฌํ˜„์€ ์–ด๋–ป๊ฒŒ ์‹œ์ž‘ํ•˜์˜€๋Š”์ง€ ํฌ์ŠคํŒ…์„ ์ด์–ด ๋‚˜๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

 


 

 

 ๊ตฌํ˜„ ์š”์•ฝ

  1. ์‚ฌ์šฉ์ž๊ฐ€ Fire ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ์‹œ ์ฆ‰, ์ด์„ ์ˆ์„ ๋•Œ ์ ์˜ ํ”ผ๊ฐ€ ๋ชจ๋‘ ์†Œ์ง„ ์‹œ ์ ์€ ์‚ฌ๋ผ์ ธ์•ผ ํ•œ๋‹ค.
  2. ์ด์„ ์ˆ์„ ๋•Œ ์ด๊ตฌ์— ์ดํŽ™ํŠธ๊ฐ€ ๋‚˜์™€์•ผ ํ•˜๊ณ , ์ด์„ ๋งž์€ ์ ์€ ์ด์„ ๋งž์•˜๋‹ค๋Š” ํ”ผ๊ฒฉ ํŒŒํ‹ฐํด์„ ๋งŒ๋“ค์–ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  3. ์ ์€ ์‚ฌ์šฉ์ž์˜ ์•ž๊ณผ ๋’ค์— ๋žœ๋ค์˜ ์œ„์น˜์— ๋ฐฐ์น˜๋œ๋‹ค.
  4. ์ ์„ ์ฒ˜์น˜ ์‹œ์—๋Š” ์‚ฌ์šฉ์ž์˜ Score(์ ์ˆ˜)๊ฐ€ 1์”ฉ ์ฆ๊ฐ€ํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ UI์— ํ‘œ์‹œ๋œ๋‹ค.

 

์—ฌ๊ธฐ์„œ Enemy(์ )์€ ๊ฐœ๋ฐœ์ด ์ž˜ ์ง„ํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด 3D Object์ธ Cube๋ฅผ ๋งŒ๋“ค์–ด Enemy๋กœ ์ง€์ •ํ•ด์ฃผ์—ˆ๋‹ค.

์œ„ 4๊ฐ€์ง€ ๊ตฌํ˜„์„ ์œ„ํ•ด์„œ ์ด 4๊ฐœ์˜ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

PlayerInform.cs  → ํ”Œ๋ ˆ์ด์–ด์˜ ์ •๋ณด๋ฅผ ๋‹ด๋‹นํ•œ๋‹ค.
HandGunFire.cs  → Fire ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ์‹œ์— ์ด์„ ์˜๊ณ , ์ ์„ ํ”ผ๊ฒฉํ–ˆ๋Š”์ง€ ์œ ๋ฌด๋ฅผ ๋‹ด๋‹นํ•œ๋‹ค.
CubeSpawn.cs & CubeBackSpawn.cs  → ์‚ฌ์šฉ์ž ์•ž ๊ณผ ๋’ค์— ๋žœ๋ค ์œ„์น˜์— Enemy(์ )์ด ์ƒ์„ฑ๋œ๋‹ค.
EnemyCube.cs  → Cube์˜ ์ƒํƒœ ์ฆ‰, ์ ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ๋‹ด๋‹นํ•œ๋‹ค.

 


 

 

 

 AR ํ™˜๊ฒฝ์—์„œ ์ด์„ ๋ฐœ์‚ฌ

 

public class HandGunFire : MonoBehaviour
{
    public Camera fpsCamera;         // ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์กฐ์ค€ํ•˜๋Š” ์œ„์น˜๋ฅผ ๊ฒฐ์ •
    public float range = 100f;       // ๊ด‘์„ ์ด ์–ผ๋งˆ๋‚˜ ํˆฌ์‚ฌ๋˜๋Š”์ง€ ๊ฒฐ์ •, ๋ฌด๊ธฐ์˜ ๋ฒ”์œ„๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
    public float damage = 10f;       //์ ์—๊ฒŒ ์ฃผ๋Š” ํ”ผํ•ด๋Ÿ‰


    public float impactForce = 60f;     // Raycast๊ฐ€ Rigidbody ์š”์†Œ๊ฐ€ ๋ถ€์ฐฉ๋œ ๊ฐ์ฒด์™€ ๊ต์ฐจํ•˜๋Š” ๊ฒฝ์šฐ ์ •์˜๋˜๋Š” ์–‘๋งŒํผ ํž˜์„ ๊ฐ€ํ•œ๋‹ค.
    public AudioSource gunsound;        // ์ด๊ธฐ ์‚ฌ์šด๋“œ(๊ถŒ์ด)

    public ParticleSystem muzzleFlash;  // ์ด๊ตฌ ์ดํŽ™ํŠธ ํŒŒํ‹ฐํด
    public GameObject impactEffect;     // ์  ํ”ผ๊ฒฉ ํŒŒํ‹ฐํด (ํ˜ˆํ”, ์ด์•Œ์ด ๋ฐ•ํžŒ ์ž๊ตญ ๋“ฑ)


    //๋ฆฌํŒฉํ† ๋ง ์ง„ํ–‰
    public void shoot()
    {
        RaycastHit hit; // ๋ ˆ์ด์—์„œ ๋ฐ˜ํ™˜๋œ ์ •๋ณด๋ฅผ ๋ณด์œ ํ•˜๋Š” ๋ณ€์ˆ˜
        if (Physics.Raycast(fpsCamera.transform.position, fpsCamera.transform.forward, out hit, range))
        {   // ์ฝœ๋ผ์ด๋”๋ฅผ ๊ฐ€์ง„ ์˜ค๋ธŒ์ ํŠธ์™€ ์ถฉ๋Œ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•ฉ๋‹ˆ๋‹ค. ์ถฉ๋Œ์ด ๋˜๋ฉด True๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , RaycastHit๋กœ ์ถฉ๋Œ์ •๋ณด๋ฅผ ๋„˜๊ฒจ์คŒ.
            
            EnemyCube enemy = hit.transform.GetComponent<EnemyCube>();  // ์ถฉ๋Œ์„ ๊ฐ์ง€ํ•œ ์ถฉ๋Œ์ฒด์—์„œ EnemyCube์— ๋Œ€ํ•œ ์ปดํฌ๋„ŒํŠธ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
          
            if (enemy != null)  // ์ ์ด ๋งŒ์•ฝ ์กด์žฌํ•œ๋‹ค๋ฉด
            {
                Instantiate(impactEffect, hit.point, Quaternion.identity);  // ์ด์„ ์œ ๊ทธ ์œ„์น˜์— ํ”ผ๊ฒฉ ํŒŒํ‹ฐํด ์ƒ์„ฑ
                enemy.getdamage(damage);   // enemy์—๊ฒŒ ํ”ผํ•ด๋Ÿ‰์„ ์ž…ํžŒ๋‹ค.
            }

            if (hit.rigidbody != null)  // RayCast๋กœ ์ ์ค‘ํ•œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์— Rigidbody ๊ตฌ์„ฑ์š”์†Œ๊ฐ€ ์žˆ๋‹ค๋ฉด
            {
                hit.rigidbody.AddForce(-hit.normal * impactForce); // AddForce(๋ฐฉํ–ฅ * ํž˜ ๊ฐ’)
            }

        }
        gunsound.Play();    // ์ด๊ธฐ์‚ฌ์šด๋“œ ์žฌ์ƒ
        StartCoroutine("OnMuzzleFlashEffect");  // ์ด๊ตฌ ์ดํŽ™ํŠธ ์žฌ์ƒ
    }


    public IEnumerator OnMuzzleFlashEffect()
    {
        muzzleFlash.Play();
        yield return new WaitForSeconds(0.2f);  // play ์‹คํ–‰ ํ›„ 0.2์ดˆ ๋Œ€๊ธฐ
        muzzleFlash.Stop();
    }
}

 

ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋จผ์ €, RayCast(๋ ˆ์ด ์บ์ŠคํŠธ)์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

RayCast์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ๊ตฌ๊ธ€์— ๊ฒ€์ƒ‰ํ•ด๋ณด์‹œ๋ฉด ๋งŽ์€ ์ •๋ณด๊ฐ€ ๋‚˜์™€ ์žˆ์œผ๋ฏ€๋กœ ์งง๊ฒŒ ์„ค๋ช…ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

Physics.Raycast() ๋Š” ์‹œ์ž‘์ (origin)๊ณผ ๋ฐฉํ–ฅ(direction)์œผ๋กœ ๋ ˆ์ด๋ฅผ ์˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. ์ฆ‰, ์‹œ์ž‘์ ๊ณผ ๋ฐฉํ–ฅ์œผ๋กœ ๋ชจ๋“  ์ถฉ๋Œ์ฒด์— ๋Œ€ํ•ด ๋ ˆ์ด๋ฅผ ์˜๊ฒŒ๋˜๊ณ , ์ถฉ๋Œ์ด ๋˜๋ฉด True๋กœ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋˜๋ฉด์„œ ์ด์–ด์„œ RaycastHit๋กœ ์ถฉ๋Œ์ •๋ณด๋ฅผ ๋„˜๊ฒจ์ฃผ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

Physics.Raycast() ๊ตฌํ˜„ ์ฝ”๋“œ

Physics.Raycast() ํ•จ์ˆ˜์˜ ์ฒซ ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” (origin) ์‹œ์ž‘์  ์ž…๋‹ˆ๋‹ค. ์ฆ‰, ๊ด‘์„ ์ด ์‹œ์ž‘๋˜๋Š” ์ง€์ ์ด ๋ฉ๋‹ˆ๋‹ค. 
ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์กฐ์ค€ํ•˜๋Š” ์œ„์น˜๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๋ณ€์ˆ˜ fpsCamera๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ทธ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์‹œ์ž‘๋˜๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ (direction) ๋ฐฉํ–ฅ๋„ ํ”Œ๋ ˆ์ด์–ด์˜ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋ฐฉํ–ฅ์„ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค.
out hit๋Š” ์ถฉ๋Œํ•œ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
range๋Š” ๊ด‘์„ , ์ฆ‰ Ray๋ฅผ ๋ฐœ์‚ฌํ•˜๋Š” ๊ฑฐ๋ฆฌ, ๋ฒ”์œ„๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

https://learn.unity.com/tutorial/let-s-try-shooting-with-raycasts#5c7f8528edbc2a002053b469

 

Let's Try: Shooting with Raycasts - Unity Learn

In this Let's Try tutorial we will learn how to shoot using Raycasts. This tutorial provides both a video walkthrough and and article version of the instructions.

learn.unity.com

โ€ป ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์ฐธ๊ณ ํ•œ ์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค. ์˜์–ด๊ฐ€ ํž˜๋“œ์‹œ๋ฉด ํ•œ๊ตญ์–ด๋กœ ๋ฒˆ์—ญํ•˜๊ณ  ๋ณด์…”๋„ ๋„์›€์„ ๋งŽ์ด ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

๋ฐ˜๋“œ์‹œ, AR Camera ์ž์‹์œผ๋กœ ์—์…‹์„ ๋„ฃ์–ด์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์›€์ง์ด๋Š” ๋ฐฉํ–ฅ์— ๋”ฐ๋ผ ์—์…‹์ด ๊ฐ™์ด ์›€์ง์ด์ง€ ์•Š๊ณ , ๊ณ ์ •๋œ ์œ„์น˜์— ๋จธ๋ฌด๋ฅด๊ฒŒ ๋˜๋Š” ํ˜„์ƒ์„ ๊ฒช๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

HandGun - Hand Gun Fire.cs ์Šคํฌ๋ฆฝํŠธ ์‚ฝ์ž…

๋‹ค์Œ์€ HandGun ์ธ์ŠคํŽ™ํ„ฐ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค.  Fps Camera ์ฆ‰, ํ”Œ๋ ˆ์ด์–ด์˜ ์œ„์น˜๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ๋ณ€์ˆ˜์— AR Camera๋ฅผ ๋„ฃ์–ด์ค์‹œ๋‹ค.

 

 

ํ˜„์žฌ UI์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์˜ค๋ธŒ์ ํŠธ๋“ค

์œ„ ์‚ฌ์ง„์€ ๊ตฌํ˜„ํ•  ๊ฒŒ์ž„ UI์—์„œ ์‚ฌ์šฉํ•  ์˜ค๋ธŒ์ ํŠธ๋“ค ๋ชจ์Šต์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ๊ฒƒ์€ ๊ธ€์”จ๊ฐ€ ํ๋ฆฌ๊ฒŒ ๊ตฌ๋ถ„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€ Fire Panel ์•ˆ์— ์žˆ๋Š” Fire Button ์ž…๋‹ˆ๋‹ค. 

 

 

Fire Button ์ธ์ŠคํŽ™ํ„ฐ

Fire Button์˜ ์ธ์ŠคํŽ™ํ„ฐ ๋ชจ์Šต์ž…๋‹ˆ๋‹ค. Fire Button์„ ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค HandGunFire ํด๋ž˜์Šค ์•ˆ์— shoot()ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ฒ ๋‹ค๋Š” ์˜๋ฏธ๋กœ ์ดํ•ดํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

 

Fire ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ์œ„ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์ ์„ ๋ช…์ค‘ํ•  ๋•Œ ํ˜ˆํ” ํŒŒํ‹ฐํด์ด ์ƒ๊ธฐ๋ฉด์„œ HandGunFire ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๋Š” ๋ชจ์Šต์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


 

โ˜ž ํ”„๋กœ์ ํŠธ์—  ์ด๊ธฐ ๊ด€๋ จ ๋ชจ๋“  ์—์…‹์€  ์•„๋ž˜ ์‚ฌ์ดํŠธ์—์„œ ์ œ๊ณตํ•œ ๋ฌด๋ฃŒ ์œ ๋‹ˆํ‹ฐ ์—์…‹์„ ์‚ฌ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค. https://assetstore.unity.com/packages/3d/props/guns/guns-pack-low-poly-guns-collection-192553

 

 

๊ตฌํ˜„ ์š”์•ฝ์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ง€๊ธˆ๊นŒ์ง€ 1๋ฒˆ๊ณผ 2๋ฒˆ๊นŒ์ง€์˜ ๊ณผ์ •์„ ๋งˆ์ณค์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋‚จ์€ 3๋ฒˆ๊ณผ 4๋ฒˆ์˜ ๊ณผ์ •์„ ์ ์–ด๋‚˜๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

728x90
๋ฐ˜์‘ํ˜•