unity Camera

카메라 워킹

FPS 게임은 주인공 시점에서 사물을 바라봅니다. 이와 같은 구성은 캐릭터와 카메라를 동기화시켜서 처리합니다. 이제 카메라가 탱크를 따라다니도록 할 것입니다. 이렇게 하려면 카메라를 제어하는 복잡한 알고리즘이 필요합니다. 그러나 걱정 없습니다. 복잡한 것은 유니티가 다 알아서 해주기 때문에 우리는 유니티가 제공하는 기능을 그냥 가져다 쓰면 됩니다. 

프로젝트 탭에서 마우스 오른쪽 버튼 누르고 [Import Package ▶ Scripts] 메뉴를 클릭합니다.


 
Importing Package 창이 나타나면 전체 항목을 선택한 후 Import 버튼을 누릅니다.



 
프로젝트 탭에 Standard Assets이 추가되는데 하위 폴더에 Camera Scripts가 있습니다. SmoothFollow를 찾아서 하이어라키 탭에 있는 Main Camera에 끌어다 놓습니다. 다음에는 카메라가 따라다닐 오브젝트(탱크)를 선택해서 인스펙터의 Target란에 끌어다 놓습니다. 그 아래에 있는 Distance와 Height는 카메라의 거리와 높이이므로 5와 1.5 정도로 입력합니다.



   
이제 게임을 실행하면 탱크가 가는대로 카메라가 따라다니는 것을 볼 수 있습니다.

   


Target을 포탑이나 포신으로 설정하면 포탑이 회전하는 방향으로 카메라가 따라갑니다. 둠과 같은 FPS 게임을 만들 경우에는 캐릭터를 권총 형태로 만들고 카메라가 그것을 따라가도록 하면 되겠죠?


오브젝트를 이동하거나 회전할 때 카메라가 출렁거리는 느낌과 따라오는 속도는 인스펙터의 Damping(완충 작용)으로 되어 있는 부분의 숫자를 조절합니다. 이 값이 클수록 출렁이는 속도가 줄어듭니다.


포구 앞의 화염 만들기

포탄을 발사할 때 포구 앞에서 화염이 일어나도록 해볼까요? 새로운 파티클을 프리팹으로 만들고 포탄을 발사할 때 그것을 보여주면 될 것입니다. 화염을 표시할 위치는 탱크에 설치해 둔 스판 포인트입니다. 포구의 화염은 폭파 불꽃과 다르게 처리해서 포구를 중심으로 사방으로 확산되는 푸른 불꽃 형태로 만듭니다. 

하이어라키 탭에서 Create 버튼을 눌러 Particle System을 하나 추가합니다. 화면에 하얀 민들레 씨앗 같은 것이 날아가는 것이 보입니다. 


 
   
인스펙터를 보면 앞에서 폭파 불꽃 작업했던 것과 사뭇 다른 속성이 나타납니다. 이 속성은 단발성 불꽃에는 맞지 않으므로 마우스 오른쪽 버튼을 눌러 Particle System 컴포넌트를 삭제합니다.

 
[Component ▶ Effects ▶ Legacy Particles] 메뉴에 우리가 사용할 수 있는 컴포넌트가 있으므로 세 개를 모두 파티클에 추가합니다. 추가한 파티클의 속성을 다음과 같이 설정하세요.

항 목
설정할 값
의 미
    Min, Max Size
    Min, Max Energy
    One Shot
    Ellipsoid x, y, z
    Particle Animator
    Rnd Force x, y, z
    Autodestruct
    Materials
    Stretch Particles
    프리팹
    0.5, 0.5
    0,4, 0.4
    On
    0, 0, 0
    파랑 ⇨ 하늘색
    0.2, 0.2, 0.2
    On
    Default-Particle
    Stretched
    pfExplosion2
    입자의 크기
    입자의 초단위 수명
    단발성으로 표시
    불꽃이 일렁이는 범위
    불꽃 색깔의 변화
    원형으로 확산되는 속도
    사용이 끝나면 자동 제거
    목록에서 설정
    입자를 길쭉한 형태로 표시
    새로운 프리팹을 만들고 등록


 
파티클의 매트리얼은 인스펙터의 ‘◉’ 버튼을 누르면 다음과 같이 Select Material 창이 나타나므로 여기에서 고릅니다.

          


다음에는 탱크에 연결된 스크립트 jsTank에 다음의 내용을 추가하고 변수 explosion과 snd에 위에서 만든 파티클 pfExplosion2와 오디오 클립을 연결합니다.

 
..................
var bullet : Transform;
var explosion: Transform;          // 추가
var snd : AudioClip;                 // 발사음 - 추가

      ........................
      var spPoint = GameObject.Find("spawnPoint");                                         // spawnPoint 정보 읽기
      Instantiate(explosion, spPoint.transform.position, Quaternion.identity);         // 추가
      AudioSource.PlayClipAtPoint(snd, spPoint.transform.position);                   // 추가
      var myBullet = Instantiate(bullet, spPoint.transform.position, Quaternion.identity);
      ...............
}


추가할 위치는 지난 강좌의 소스를 참조하세요.

이제 게임을 실행하면 포탄을 발사할 때 포구 앞의 푸른 불꽃을 볼 수 있습니다. 폭파 불꽃과는 다른 형태의 섬광입니다.


   
적군의 등장

이제 적군이 등장할 차례입니다. 적군으로 사용할 탱크를 하나 있어야겠군요. 실제의 게임에서 어려운 부분은 바로 적군을 이동시키는 부분입니다. 적군이 너무 멍청해도 안되고, 죽자살자 아군만 쫓아다녀도 곤란합니다. 이 프로젝트에서는 좀 멍청하면서도 똑똑한 적이 등장합니다. 적군 탱크는 항상 아군을 주시하고 있다 아군 탱크가 사정거리 안에 들어오면 가차 없이 포를 발사하도록 할 것입니다.


적군 탱크 만들기

적군 탱크를 하나 만듭니다. 아군 탱크를 복제해서 적군으로 사용합니다. 하이어라키 탭에서 아군 탱크를 클릭한 후 [Ctrl + D] 키를 누르면 탱크가 복제됩니다. 탱크 이름을 적군 탱크로 바꾸고 화면의 적당한 곳에 배치합니다. 

다음에는 적군 탱크의 포신 앞에 설치되어 있는 spawnPoint를 spawnPoint2로 이름을 바꿉니다. 아군 탱크를 제어하는 스크립트에 Find("spawnPoint")라는 문장이 있기 때문입니다.

아군과 적군 둘 다 spawnPoint라는 오브젝트를 가지고 있으면 스크립트가 혼란을 일으킬 수 있습니다. 혼란이라는 것은 아군이 포를 발사할 때 자신의 스판 포인트가 아니라 적군 탱크의 스판 포인트에서 포를 발사하는 것입니다. 

하이어라키 탭을 보면 설치된 오브젝트가 이름순으로 정렬되어 표시되는데, 아마도 Find() 함수는 이 순서로 오브젝트를 찾을 것입니다. 하이어라키 탭에 적군 탱크가 아군 탱크 위에 등록되어 있으므로 Find("spawnPoint")는 적군 탱크의 spawnPoint를 찾을 확률이 매우 높습니다.

적군 탱크는 아군 탱크를 복사해서 만들었으므로 스크립트도 따라갈 것입니다. 적군 탱크의 스크립트는 다르게 작성해야 하므로 적군 탱크에 연결된 스크립트를 삭제합니다. 적군 탱크를 선택한 후 인스펙터의 Js Tank (Script) 항목을 마우스 오른쪽 버튼으로 클릭하고 Remove Component로 삭제합니다. 적군 탱크에 연결된 스크립트를 지우지 않으면 적군 탱크도 아군 탱크와 똑같이 키보드에 반응하겠죠?

아군 탱크와 적군 탱크를 구별할 수 있도록 적군 탱크에 색깔을 입힙니다. 매트리얼을 하나 만들어 색을 지정하고, 그것을 적군 탱크의 본체와 포탑, 포신에 각각 적용합니다.

마지막으로 메인 카메라가 아군을 따라다니는 기능을 정지시킵니다. 메인 카메라를 클릭한 후 인스펙터에서 Target으로 표시된 맨 오른쪽에 있는 ‘◉’ 아이콘을 클릭하면 다음과 같은 Select Transform 창이 나타나므로 여기에서 None를 지정합니다.


   
카메라 워킹을 정지시키는 이유는 화면을 3인칭 시점으로 전환해서 화면 전체를 보기 위해서 위해서입니다. 디자인 탭의 카메라의 위치와 각도 등을 잘 조절해서 화면에 아군 탱크와 적군 탱크가 모두 보이도록 합니다.


목표물 주시(LookAt)

적도 멍청하지는 않으므로 항상 아군을 주시하고 있습니다. 주시합니다는 것은 시선을 돌린다는 뜻입니다. 즉, Move가 아니라 Rotate입니다. 오브젝트가 특정한 오브젝트를 주시하도록 설정할 때에는 LookAt() 함수를 사용합니다.

         transform.LookAt(Transform);

위 형식에서 LookAt()으로 주시할 target은 GameObject가 아니라 Transform입니다(Instantiate도 인수로 Transform을 사용했죠?. 적군 탱크가 항상 아군을 주시할 수 있도록 다음과 같은 스크립트를 작성합니다.

∎파일명 : jsEnemy

#pragma strict
private var power = 1200;                // 포탄 발사 속도 -- ①
var bullet : Transform;                    // 포탄 -- ②
var target : Transform;                    // LookAt() 목표 -- ③
var spPoint : Transform;                 // spawnPoint -- ④
var explosion: Transform;               // 포구 앞의 화염 -- ⑤
var snd : AudioClip;                       // 발사음 -- ⑥

function Update () {
    transform.LookAt(target);             // 아군 방향으로 회전
}

        ① private로 선언한 변수는 인스펙터에 표시되지 않는 지역변수이다.
        ② bullet에는 프리팹으로 만들어 둔 pfBullet를 연결한다.
        ③ target에는 아군 탱크를 연결한다.
        ④ spPoint에는 적군 탱크의 포신 앞에 있는 spawnPoint2를 연결한다.
        ⑤ explosion에는 프리팹으로 만들어 둔 pfExplosion2를 연결한다.
        ⑥ snd에는 오디오 클립을 연결한다.


작성한 스크립트를 적군 탱크의 포탑에 연결합니다. 적군 탱크에 연결하면 탱크 자체가 회전할 것이고, 포탑에 연결하면 본체는 고정된 상태에서 포탑만 회전할 것입니다. 이제 게임을 실행하면 적의 포탑이 항상 아군의 움직임을 따라 회전하는 것을 볼 수 있습니다.


드디어 적군이 등장했군요. 다음 강좌에는 적군 탱크가 아군을 탐지하고 아군을 향해 발포하도록 하는 부분을 만들 것입니다. 아쉽지만 오늘 강좌는 여기서 마칩니다

Post a Comment

다음 이전