본문 바로가기
GameMaker강좌[GMS2]/3D기능강좌

[게임메이커 강좌-3D강좌][GMS2]1인칭 탈출게임-1-시점 설정

by 타락카얀 2018. 7. 30.
728x90

 

 

GAME MAKER 강좌

 

 

KAYAN

 

 

이번 강좌에서는 간단한 1인칭 탈출게임을 만들어 봅시다.


(▲ 강좌에서 만들 게임)




 

   ◈ 룸 설정

 

 

 

룸을 하나 만들고, 룸의 속성(Properties) 탭에서 룸의 크기를 설정합니다.
룸은 플레이어가 이동할 수 있는 공간이기 때문에 원하는 크기를 지정하시면 됩니다.
3D는 활용할 수 있는 좌표 범위가 넓어서 매우 작은 크기(1X1 px 이하)도로 공간을 활용할 수 있지요.

 

강좌에서는 32X32 크기 기준으로 구성하겠습니다.


(▲ 룸의 속성)


다음은 카메라 설정(Viewports and Cameras) 에서 뷰포트 사용(Enable Viewports)을 체크하고 사용할

뷰포트(Viewport)를 활성화(Visible 체크) 합니다.

카메라는 기본적으로 2D화면을 비춥니다.
하지만 이 카메라는 다음에 있을 3D설정을 통하여, 2D화면을 3D의 화면으로 전환하여 표시하는데

사용될 거에요.


(▲ 카메라 설정)


뷰포트는 화면에 출력시키는 부분으로 1개를 사용할 수도 있고, 2개 이상을 사용해 멀티뷰를

구성할 수도 있습니다. 게임메이커 스튜디오에서 뷰포트를 0~7 번 최대 8개를 사용할 수 있지요.


강좌에서는 뷰포트 0번 1개를 사용하겠습니다.

Viewport0Visible을 체크하고, 화면의 크기를 설정합니다.



 

 

   ◈ 게임 프레임



게임 프레임(룸 속도)은 기본값 30으로 맞춰져 있습니다.
게임 프레임을 변경하고 싶다면, 도구모음의 게임 옵션(Game Options)을 클릭하거나 오른쪽에 있는

리소스(Resources) 탭의 Options 폴더Main 을 클릭하여, GeneralGame frames per second값을

변경하시면 됩니다.


(▲ 게임 프레임 설정)


모니터 주사율에 맞게 게임 프레임 값을 설정(값이 클 수록 부드럽게 구동)하면 되는데, 보통 게임 프레임을

60으로 설정하면 원활하게 게임을 구동시킬 수 있습니다.

 

 

 

 

   ◈ 카메라 설정(obj_cam, obj_player)

 

3D 시점을 표현할 카메라 설정을 구성해 봅시다.
먼저 카메라 기능을 할 오브젝트(obj_cam)를 하나 만듭니다. 또한 카메라는 플레이어로 사용되기 때문에
관리하기 쉽게 부모 오브젝트(obj_player)를 하나 만들어 카메라(obj_cam)Parent 에 지정합니다.

카메라는 다른 오브젝트와 충돌을 체크하기 위해 마스크 이미지를 지정할 필요가 있어요.
카메라의 마스크로 쓰일 스프라이트 이미지를 하나 만들어 카메라 오브젝트의 스프라이트란에 지정합니다.
강좌에선 아래와 같은 이미지로 지정하죠.

 


(▲ 마스크로 사용할 이미지 16X16 )


만들게임은 3D 이지만, 기본적인 충돌 제어는 2D 좌표를 응용하기 때문에 마스크의 중심점을 가운데로

맞춥니다.


(▲ 마스크 이미지를 스프라이트 란에 지정하고 관리하기 쉽도록 parent를 지정하는 것이 좋음 )


이 이미지는 눈에 띄는 형태의 이미지로 구성하는 것이 룸에 배치할 때 좋습니다.


(▲ 카메라는 어디에 있는가?)


카메라에 필요할 것 같은 변수를 Create 이벤트에 선언해줍니다.
게임메이커에선 x, y 좌표만 미리 선언되어있기 때문에 먼저 Z 좌표가 필요하겠지요.

 



      ★ obj_cam - Create 이벤트

      z=0;//z좌표
      eye=25;//눈 높이

 

 

그리고 화면의 회전에 대한 변수가 필요합니다.

 


(▲ 마우스 드래그 방향에 따른 카메라 회전)


좌-우 드래그는 Z 회전, 상-하 드래그는 Y 회전에 대한 변수 또한 추가해줍니다.

 



      ★ obj_cam - Create 이벤트

      cam_zang=0;//카메라 좌우 각도
      cam_yang=0;//카메라 상하 각도

      cam_dis=128;//목표 시점과의 거리

 

 

이 카메라 오브젝트는 다른 오브젝트들과 다른 레이어에 있는 요소들 보다 먼저 실행되어야 하기
때문에 depth를 높게 설정해야합니다.

 



      ★ obj_cam - Create 이벤트


      //깊이 설정
      depth=99999;

 
 
 
      //z버퍼 사용
      gpu_set_ztestenable(true);
      gpu_set_zwriteenable(true);

 

 

이벤트를 구성할 때, 이 변수는 필요한 것 같다고 생각하면 그때마다 추가하시면 됩니다.

다음은 카메라 설정을 해봅시다.
카메라는 원근법(perspective) 설정과 카메라 뷰 설정이 필요합니다.

 



      원근법 설정:
      camera_set_proj_mat(camera_id, matrix)

      행렬(matrix):

      matrix_build_projection_perspective_fov(fov_y, aspect, znear, zfar)
    

           fov_y : 시야각 (-90 ~ 90 사이의 값. 보통 음수값으로 지정하며 -45으로 설정.)
          aspect : 시야의 비율(가로/세로 비율의 음수값으로 지정.)
          znear :근평면(렌더링이 보이는 최소거리)
           zfar :원평면(렌더링이 보이는 최대거리)


      카메라 뷰 설정:
      camera_set_view_mat(camera_id, matrix)

      행렬(matrix):

      matrix_build_lookat(xfrom, yfrom, zfrom, xto, yto, zto, xup, yup, zup)

           xfrom,yfrom,zfrom : 카메라의 위치
          xto,yto,zto : 카메라가 바라보는 위치
          xup,yup,zup : 위축이 되는 축을 설정. z축이 위로 향할 경우 (0,0,1)을 설정함

 

 

카메라 오브젝트(obj_cam)Draw 이벤트를 추가하고 원근법(perspective) 설정부터 해봅시다.

 



   ★ obj_cam - Draw 이벤트

   var projmat = matrix_build_projection_perspective_fov(-45, -view_wport[0]/view_hport[0], 1, 32000);
   camera_set_proj_mat(view_camera[0],projmat);//원근법 설정

 

 

fov_y는 음수값으로 기본 시야인 -45를 지정하고, aspect 는 화면 비율의 -(가로/세로) 로 설정합니다.
znear에 렌더링이 보이는 최소거리, zfar는 렌더링이 보이는 최대거리를 각각 지정하면 됩니다.

이제 카메라 뷰 설정을 해봅시다.

 


(▲ 카메라 뷰 위치)


카메라 뷰는 어느 위치(xfrom,yfrom,zfrom)에서 어디를 보는가(xto,yto,zto)로 설정합니다.

 



   ★ obj_cam - Draw 이벤트

   var xto,yto,zto;
   xto=x+lengthdir_x(lengthdir_x(cam_dis,cam_yang),cam_zang);
   yto=y+lengthdir_y(lengthdir_x(cam_dis,cam_yang),cam_zang);
   zto=z+eye-lengthdir_y(cam_dis,cam_yang);//카메라를 상하-좌우회전치만큼 좌표를 설정함.

   var viewmat = matrix_build_lookat(x,y,z+eye,xto,yto,zto, 0, 0, 1);
   camera_set_view_mat(view_camera[0],viewmat);//카메라 설정

 

 

강좌에서는 (x,y,눈높이) 의 위치에서 마우스 드래그 방향으로 바라보도록 설정하겠습니다.

마지막으로 활성화중인 카메라에 이 설정을 적용해주면 됩니다.

 



   ★ obj_cam - Draw 이벤트

   camera_apply(view_camera[0]);//카메라에 적용

 

 


이제 마우스 드래그 방향에 따라 카메라가 회전하는 설정을 만들어 보도록 해요.


(▲ 마우스 드래그 방향에 따른 카메라 회전)


먼저 좌우 회전을 설정해봅시다. 카메라 오브젝트(obj_cam)End Step 이벤트추가하고,

아래와 같이 설정합니다.

 



   ★ obj_cam - End Step 이벤트

   //기본적으로 필요한 변수 선언
   var vw,vh,mx,my,_x,_y;

   vw=window_get_width( );//게임창의 가로크기
   vh=window_get_height( );//게임창의 세로크기
   mx=window_mouse_get_x( );//마우스의 위치
   my=window_mouse_get_y( );//마우스의 위치


   _x=vw/2;//윈도우의 가운데 x좌표
   _y=vh/2;//윈도우의 가운데 y좌표

   //설정
   spd=3;
   d=min(abs(_x-mx),16)/16; //마우스 포인터가 좌우로 흔들리는 값을 적당하게 분배함.

   if _x<mx{cam_zang-=spd*d;}
   if _x>mx{cam_zang+=spd*d;}//d의 값으로 좌우회전 각도를 설정함.

 

 

이것은 x좌표를 이용하여 게임 윈도우 중심 위치를 기준으로 마우스 포인터 위치가 윈쪽에 있으면

왼쪽으로, 회전 오른쪽에 있으면 오른쪽으로 회전하게 됩니다.

다음 y좌표를 이용한 상하 회전을 추가 설정합니다.

 



   ★ obj_cam - End Step 이벤트

   d=min(abs(_y-my),16)/16; // 마우스 포인터가 상하로 흔들리는 값을 적당하게 분배함.

   if _y>my{if cam_yang<80{cam_yang+=spd*d;}}//정면에서 80각도까지만 올려다 볼 수 있게 함.
   if _y<my{if cam_yang>-80{cam_yang-=spd*d;}}//d의 값으로 상하회전 각도를 설정함.

 

 

마지막으로 마우스의 위치를 화면 가운데 위치로 이동 시켜 다음 회전을 적용하도록 초기화합니다.

 



   ★ obj_cam - End Step 이벤트

   window_mouse_set(vw/2,vh/2);
   //마우스 포인터를 화면 중앙에 위치하게 함.

 

 

마우스 포인터가 가운데 위치하게 되기 때문에, 게임을 종료 시킬 수가 없죠.
그러니 아래와 같이 [ESC]키나 별도로 게임을 종료시킬 수 있는 이벤트를 추가로 구성해야 합니다.

 


   ★ obj_cam - End Step 이벤트

   if keyboard_check(vk_escape){game_end( );}

 

 

가장 기본적인 카메라 설정이 끝났네요.


카메라가 제대로 작동하는지 룸에 카메라를 배치하고, 테스트 해봅시다.
오브젝트는 룸의 인스턴스(Instance) 레이어에서만 배치할 수 있습니다.


(▲ 오브젝트는 인스턴스 레이어에서만 배치할 수 있음)


오브젝트 배치는 배치할 오브젝트를 리소스 탭에서 선택해 마우스 드래그하여 룸에 끌어놓거나,
오브젝트를 선택후 [Alt]키를 누른채 마우스 왼쪽 키로 룸에 배치할 수 있습니다.

일단 룸에는 아무것도 없는 상태라 카메라를 통해 볼 수 있는 것이 없기 때문에 타일과 같은

그래픽 요소라도 배치 후 테스트 해봅시다.


 

 


 

룸 꾸미기 - 타일 배치(Tiles_1, Tiles_2)



강좌에서는 간단하게 타일 이미지를 통해 바닥과 천장을 구성해볼 것입니다.
먼저 타일로 사용할 스프라이트 이미지를 추가합니다.

 


(▲ 타일로 사용할 이미지)


그리고 타일셋 폴더에서 타일셋을 추가후, 준비한 타일 이미지를 지정합니다.

 


(▲ 타일셋)


강좌에서는 타일 크기를 32X32로 구성했습니다.
이제 이 타일을 룸에 배치하면 됩니다.

[참고] 3D 기본 모델로 바닥과 천장을 표현하고 싶다면, 아래 강좌를 참고해보세요.

http://kayanworld.tistory.com/210

물론 다음 강좌에서 이 3D 기본 모델을 활용해 벽과 같은 입체적 모델을 표시해보려 합니다.

 


룸에 타일 레이어 2개를 추가하고, 배치하고 싶은 타일을 배치합니다.
강좌에서는 바닥 타일 레이어"Tiles_2", 천장 타일 레이어"Tiles_1"로 설정했습니다.


(▲ 바닥 타일)

 


(▲ 타일 탭에서 배치할 타일을 선택하여 룸에 배치)

 


(▲ 천장 타일)


이 타일은 타일 레이어의 깊이(depth)가 z축 좌표가 되어 표시됩니다.


(▲ 타일 레이어의 깊이가 z축에 반영됨)


이것을 이용하여 타일 레이어의 깊이값을 수정하면, 깊이 값만으로도 레이어의 높이를 결정하여

표현할 수 있습니다.


(▲ 타일 레이어의 잠금을 풀고 레이어의 depth 값을 수정할 수 있음)


다만, 레이어 값을 수정하다보면 다른 레이어들의 depth값이 변경 될 수도 있지요.
물론 변경된 다른 레이어들의 깊이 값을 수정하면 됩니다만, 약간 번거로울 수 있습니다.
그래서 원하는 위치에 표시하려면 위치를 재조정하여 재표시할 필요가 있을 수 있지요.

일단 강좌에서 지정한 높이의 타일을 표시할 방법은 2가지 입니다.
첫번째는 타일 레이어의 깊이(depth)를 수정해 z축에 반영하여 표시하는 방법이 있습니다.
단점이라면 현재 레이어의 깊이를 수정했을 때 다른 레이어의 값도 변경될 수 있고, 깊이 값을 소수점 단위로

지정할 수 없는 부분이 있지만, 룸에 배치하는대로 3D에 적용할 수 있다는 장점이 있습니다.

두번째는 타일 레이어를 오브젝트의 Draw 이벤트를 통하여 지정한 z높이에 표시하는 방법이 있습니다.

별도의 오브젝트를 통해 표시해야하지만, 첫번째보다 다양한 높이 또는 위치를 변경하여 여러개를 표시 할 수

있다는 장점이 있지요.

강좌에서는 두번째 방법으로 진행해보겠습니다.


 

 


 

타일 레이어를 z축을 변경하여 재표시(obj_map01)

 

오브젝트를 통해 타일을 표시할 것이기 때문에 룸의 타일 레이어는 비표시로 변경합니다.

 


(▲ 타일 레이어 비표시)


타일을 원하는 위치로 재조정하기 위해 오브젝트(obj_map01)를 하나 만듭니다.

 


(▲ 타일 오브젝트)


그리고 타일 오브젝트(obj_map01)Draw End 이벤트를 추가하고, 바닥과 천장 타일 레이어의

이름 알아두고, 아래와 같이 설정해줍니다.

 



   ★ obj_map01 - Draw End 이벤트

   //강좌에서 바닥 타일 레이어는 "Tiles_2" 이고, 천장 타일 레이어는 "Tiles_1"로 설정

   //바닥
   matrix_set(matrix_world,matrix_build(0,0,0,0,0,0,1,1,1));//바닥 높이는 0
   draw_tilemap(layer_tilemap_get_id(layer_get_id("Tiles_2")),0,0);

   //"Tiles_2" 이름의 타일 레이어 표시
   matrix_set(matrix_world, matrix_build_identity());




   //천장
   matrix_set(matrix_world,matrix_build(0,0,32,0,0,0,1,1,1));//천장 높이인 z값을 32로 설정
   draw_tilemap(layer_tilemap_get_id(layer_get_id("Tiles_1")),0,0);

   //"Tiles_1" 이름의 타일 레이어 표시
   matrix_set(matrix_world, matrix_build_identity());

 

 

강좌에서는 천장의 높이를 32로 설정하겠습니다.

[참고]위치, 회전, 또는 크기를 변형시킬 수 있는 행렬은 아래와 같습니다.

 



   행렬 적용:
   matrix_set(type,matrix)


     type : matrix_view(카메라 뷰), matrix_projection(원근법), matrix_world(변형)


   행렬(matrix): 변형(위치, 회전, 또는 크기)
   matrix_build(x,y,z,xrotation,yrotation,zrotation,xscale,yscale,zscale)


     x,y,z : 위치
     xrotation,yrotation,zrotation : 회전
     xscale,yscale,zscale : 확대


   행렬(matrix): 변형 종료
   matrix_build_identity( )

 

 

그리고 모두 끝났으면 이 오브젝트를 룸에 배치합니다.

 

이제 [F5]키나 도구모음 Run 버튼(메뉴 ▶ Build ▶ Run)을 눌러 카메라를 설정한대로 제대로 작동하는지

테스트 해봅시다.

 


(▲ 실행 버튼)

 


(▲ 테스트 화면)

 

 

- 다음 편에 계속 -

 

 

 

 

300x250

댓글