요즘 VR 핫하죠. 오큘러스, 기어 VR, 구글 카드보드 VR 같은 하드웨어 뿐 아니라 각종 컨텐츠까지… VR의 전성시대가 아닌가 싶습니다. 어지러움이나 VR 기기의 거추장스러움이 부담스럽기도 하지만, 적어도 VR이 사람들의 이목을 집중시키는데는 성공한 듯 합니다.

하지만 VR을 실제 체험해보면 아직도 사용자 인터페이스가 좀 불편합니다. 시선의 방향을 인식하고 NFC 또는 마그네틱을 버튼처럼 활용하는데 이것만으로는 컨텐츠내에서 다양한 액션을 하기엔 좀 모자랍니다. 그래서 별도의 컨트롤러를 팔기도 하는데 가격도 만만찮고, 컨텐츠에 따라 컨트롤러가 지원하지 못하는 기능도 있습니다.

그래서 이참에 (시류에도 편승할 겸) VR 게임을 하나 만들어 봤습니다. 그리고 게임을 편리하게 즐길 수 있도록 컨트롤러도 함께 만들어 게임과 연동되도록 해봤습니다. 게임 제목은 “VR Defense Game – destroyer in the dark” 입니다. 이 게임은 우주 공간을 배경으로 모함을 공격해오는 적 우주선을 최대한 격추시키는 게임입니다.

이 게임은 구글 카드보드 VR을 지원합니다. 몇 천원이면 구글 카드보드 VR 패키지를 구매해서 안드로이드 폰을 이용해 체험해볼 수 있습니다. 그리고 컨트롤러는 아두이노와 버튼, 블루투스 모듈(HC-06)을 이용해 간단히 제작할 수 있습니다. 게임 제작에 사용된 소스는 모두 GitHub에 공개되어 있습니다. 직접 VR 컨텐츠를 제작해보고 싶으신 분, 블루투스 컨트롤러를 이용해 VR의 사용자 체험을 향상시키고 싶으신 분은 참고할만 할겁니다.

.

구글 카드보드 VR

개인적으로 VR 업계의 가장 큰 혁신은 구글 카드보드 VR이라 생각합니다. 3천원~5천원 정도면 풀 패키지 구매해서 직접 조립이 가능하고 본인이 가진 안드로이드 폰을 이용해서 VR을 체험할 수 있으니까요. 골판지의 엉성함도 나름 매력이라면 매력입니다(?)

google_cardboard

그래서 아예 처음부터 이 녀석을 염두에 두고 게임을 만들었습니다. 구글은 이를 위해 Google VR SDK for Android 를 제공하고 있습니다. Google VR SDK 에서는 렌즈 왜곡 보정, 3D 오디오, 헤드 트랙킹, 양안 렌더링, 사용자 인터랙션 등등 VR을 위한 기본 작업들을 처리해줍니다.

하지만 Google VR SDK 에서는 VR을 위한 기본 작업들을 해줄 뿐, 실제 3D 모델을 게임내에 구성하고 오브젝트를 움직이는 작업은 프로그래머의 몫. 이를 위해서는 임베디드 장치용 3D 그래픽 라이브러리인 OpenGL ES를 상당 수준으로 다룰 수 있어야 합니다.

또는 3D 컨텐츠 제작 플랫폼인 Unity를 이용할 수도 있습니다. Google VR SDK for Unity 도 구글에서 배포하기 때문에 연동이 가능합니다. 하지만 이것도 어렵기는 매 한가지. 괜히 사람들이 OpenGL 과 Unity 로 밥벌어 먹고 사는게 아닙니다…

.

Rajawali 3D engine

상업용 컨텐츠를 제작할 것이 아니라면 굳이 OpenGL이나 Unity를 배울 필요까지는 없다 싶어서 선택한 것이 Rajawali 3D engine 입니다. OpenGL ES 를 더 쓰기 편하게 만든 3D 라이브러리라고 보면 됩니다. Rajawali를 이용하면 골치아픈 3D 프로그래밍을 조금 더 쉽게 할 수 있도록 도와주기 때문에 선택했습니다.

687474703a2f2f7777772e726f7a656e6761696e2e636f6d2f66696c65732f72616a6177616c692d6c6f676f2e6a7067

뭐, Rajawali 라고해서 마냥 쉬운건 아닙니다. 어느정도 안드로이드 프로그래밍에 경험이 있어야 써볼만 합니다. 그래도 Scene, Camera 및 3D object, Texture 들을 처리할 수 있는 기본 도구를 제공해주고 각종 애니매이션, 움직임을 만들기 쉽게 배려해뒀기 때문에 3D 프로그래밍 입문용으로 적절한 것 같습니다.

GitHub를 통해 배포되는 Rajawali 소스에는 다양한 예제들이 포함되어 있고 이중에는 VR 예제도 있습니다. 이번에 만든 게임도 VR 예제를 입맛에 맞게 대폭 수정해서 만들었습니다.

.

구글 카드보드 제작

요즘은 구글 카드보드가 아니라도 휴대폰을 이용한 다양한 VR 기기가 판매되므로 적당한 것을 선택해서 만들면 됩니다. 전 구글 카드보드 2.0 으로 판매되는 약 4천원 정도의 패키지를 사서 만들었습니다.

cardboard_parts

부품이 대충 위 이미지 상태로 오는데 조립 난이도는 엄청 쉬움. 이마저도 귀찮은 분을 위해 아예 완성된 카드보드를 보내주는 곳도 있습니다만…. 이 정도는 직접 할만 합니다.

.

VR 컨트롤러 제작

게임 내에서 적 비행선을 격추하기위해 미사일 발사 버튼이 필요합니다. 보통 휴대폰을 이용한 VR 기기들은 이를 위해 NFC 태그나 자석을 이용해서 휴대폰이 인식할 수 있도록 합니다. 하지만 손을 항상 휴대폰 근처에 둬야해서 불편하기도 하고 빠른 인식이 잘 안되기도 합니다. 그래서 아두이노를 이용해서 VR 컨트롤러를 직접 제작했습니다. 준비물부터 살펴보면…

엄청 단촐하죠. 아두이노 Nano 보드, 버튼 2개, 블루투스(HC-06), 브레드보드를 이용합니다. 버튼1은 미사일 발사용, 버튼 2는 back 버튼입니다. 연결선이 지저분하지 않게 U-shape jumper cable 을 사용했습니다.

연결은 아래처럼 하면 됩니다.

vr_controller_bb

아두이노 ==> 블루투스 (HC-06)

  • 5V –> VCC
  • GND –> GND
  • D2 –> TX
  • D3 –> RX

아두이노 ==> 버튼 1 (fire)

  • D6 –> 버튼 다리 1
  • GND –> 버튼 다리 2

아두이노 ==> 버튼 2 (cancel)

  • D7 –> 버튼 다리 1
  • GND –> 버튼 다리 2

모두 연결하고 휴대폰용 보조 배터리를 붙였습니다. 휴대폰용 보조 배터리 중 용량이 큰것들은 소모 전류가 작을 때 자동으로 전원을 차단하도록 되어 있어서, 오히려 저렴하고 작은 사이즈의 보조 배터리가 더 좋았습니다.

컨트롤러의 구성은 단촐하지만 본연의 역할을 충실히 수행합니다. fire 버튼을 누르면 아스키 코드 ‘b’ 를 전송하고, cancel 버튼을 누르면 아스키 코드 ‘c’를 전송하는게 전부라서 아두이노 코드도 굉장히 단순합니다. 너무 빠르게 버튼 데이터가 전송되지 않도록 200ms 간격으로 시간을 체크하는 코드만 더해줬을 뿐입니다.

#include <SoftwareSerial.h>

SoftwareSerial BTSerial(2, 3);  // Bluetooth's TX, RX

int firePin = 6;
int cancelPin = 7;

int lastB1 = HIGH;
int lastB2 = HIGH;

unsigned long lastSendTime = 0;
unsigned long RESEND_THRESHOLD = 200;

void setup() {
  pinMode(firePin, INPUT_PULLUP);
  pinMode(cancelPin, INPUT_PULLUP);
  BTSerial.begin(9600);
}

void loop() {
  int curB1 = digitalRead(firePin);
  int curB2 = digitalRead(cancelPin);
  
  unsigned long curTime = millis();
  if(curTime > lastSendTime + RESEND_THRESHOLD) {
    if(curB1 == LOW) {
      BTSerial.write('b');
      lastSendTime = curTime;      
    } else if(curB2 == LOW) {
      BTSerial.write('c');
      lastSendTime = curTime;      
    }
  }
  
  lastB1 = curB1;
  lastB2 = curB2;
}

단순한 컨트롤러지만 이걸 확장하면 다양한 센서나 모터, 모듈을 VR과 연동할 수 있습니다. 다음에 좋은 아이디어 떠오르면 확장을 한번 해봐야겠습니다.

.

안드로이드 프로그래밍

카드보드 조립하고 아두이노로 컨트롤러 만드는 것이야 재료만 준비되면 금방입니다. 하지만 VR 게임을 만드는 것은 차원이 다르네요;;; 블루투스 통신을 통해 컨트롤러로 부터 받은 버튼 데이터 처리하는 부분도 꽤 손이 가고… 어쨌든 Rajawali 3D engine 에서 제공하는VR example 코드로부터 하나씩 구현해서 완성을 했습니다.

banner

Rajawali 3D engine 을 이용해 VR 프로그래밍을 하는 방법에 관해서는 아래 링크에 연재글을 올릴 예정입니다. 안드로이드 스튜디오 개발환경에서 Rajawali 설정 및 사용법과, 3D 물체들의 움직임 제어방법, 카메라 이동 및 시점 제어방법, 블루투스 통신을 이용한 컨트롤러 연동 방법을 다룰겁니다. 양이 좀 돼서 시간이 꽤 걸릴것 같긴 합니다만…

.

게임 진행

게임은 구글 플레이스토어에서 받을 수 있습니다. “VR Defense Game”으로 검색하면 됩니다.

ic_launcher_256x256

게임을 시작하면 아래처럼 메인 화면이 나옵니다.

Screenshot_2016-06-09-23-21-06

먼저 SETUP BLUETOOTH 버튼을 눌러 앞서 제작한 블루투스 컨트롤러와 페어링을 시켜줍니다. 페어링이 완료되면 우측에 connected 라고 뜰겁니다.

그리고 START GAME 버튼을 누르면 게임 시작…

title_original

주위를 둘러보면 위 이미지의 우주선이 보일겁니다. 우리가 보호해야할 모함입니다. 곧 주위에서 적 우주선들이 몰려오는데 미사일을 발사해서 우주선들을 격추해야 합니다. 미사일이 모함에 맞지 않게 주의하세요. (스코어 차감되고 모함 체력이 빠집니다.)

aaaaa

주위를 다시 둘러보면 적 모함(스타워즈의 destroyer)도 보입니다. 실제로는 굉장히 크게 렌더링 되어 있는데 멀리 있어서 그리 크게 안보입니다.

abbb

아군과 적 모함은 서로 미사일을 주고 받기도 하는데.. 실제 게임에 영향을 미치지는 않고.. 그냥 시각적 효과입니다;;; 적 모함에게 미사일 쏴도 꿈쩍도 않습니다.

addd

아군 모함의 체력이 고갈되거나 cancel 버튼을 누르면 게임이 중단되고 메인 화면으로 나가게 됩니다.

현실감과 속도감을 높이기 위해 적 우주선이 꽤 빠르게 움직이도록 설정해둬서 게임이 어렵습니다. 너무 적 우주선 쫓아다니면 멀미납니다. 여유를 갖고 예측샷으로 떨구시길…

담번엔 더 재밌는 게임이나 컨텐츠를 제작해서 공유하도록 하겠습니다. 틈틈히 Rajawali 를 이용한 VR 제작 강좌도 업데이트 할 예정입니다.

참고자료