세이박스

[VR스쿨] VR 가상현실 컨트롤러 만들기 - 구글 카드보드 SDK를 이용해서 쳐다만 봐도 콘텐츠 선택되는 기능 만들기

가상현실

 

 

 

마그네틱 스위치를 이용해서 메뉴 선택이나 확인 버튼으로 이용할 수 있으나 마그네틱 스위치가 없을 경우 가장 기본적으로 적용할 수 있는 스위치 방법이 일정 시간동안 오브젝트를 바라 보았을 때, 오브젝트가 선택되는 방식을 기본적으로 이용할 수 있습니다.

 

따라서, 이번 강의에서는 일정 시간동안 오브젝트를 바라 보았을때 동작하는 기능을 만들어 보겠습니다.
이전 예제에서 이용한 BoxCtrl과 RayCast 개념을 그대로 사용하고, 여기에 타이머를 추가하여 응용할 수 있습니다.

 

 

a768a96a0edc3c0b70594024eb9eb9e1_1456887 

 

하이어라키 창에서 오른쪽 클릭 -> 3D Object -> Sphere로 구를 추가합니다.

이 구에 BoxCtrl 스크립트를 그대로 추가합니다.

Tag는 Ball을 추가하여 설정합니다.

 

마그네틱 스위치 인식과 오브젝트 선택 기억나지 않으면 아래 링크를 참고 합니다.

http://vrschool.co.kr/bbs/board.php?bo_table=leture&wr_id=12

 

 

a768a96a0edc3c0b70594024eb9eb9e1_1456887
 

프리팹으로 만든 후 여러 개 적당한 위치에 배치 해 봅시다.

 

 

a768a96a0edc3c0b70594024eb9eb9e1_1456887 

 

using UnityEngine;

using System.Collections;

 

public class TriggerTextCtrl : MonoBehaviour {

//결합할 텍스트 상수입니다.

private const string TEXT = "Count : ";

//접근 제어자를 public으로 하면 유니티 에디터에서 이 변수를 설정할 수 있습니다.

public Cardboard cardBoard;

//3DText의 글자는 TextMesh 컴포넌트에서 변경했기 때문에 TextMesh 컴포넌트를 가져와야 합니다.

private TextMesh textMesh;

//카운트 변수입니다.

private int count = 0;

    //Update 메소드가 호출되기 전 단 한 번 호출 됩니다. 보통 변수들을 초기화 하는것을 여기에다 작성합니다.

    private Vector3 screenCenter;

 

    // 몇 초간 바라보는 것으로 설정할 것인지에 대한 변수입니다. 에디터에서 수정가능하도록 했습니다.

    public float durTime = 3f;

    // 쳐다보고 있는 오브젝트가 저장됩니다.

    public GameObject recentObject;

    // 쳐다보기 시작한 시간을 저장합니다.

    private float startTime;

    void Start()

{

//gameObject에는 본 컴포넌트가 추가된 게임 오브젝트가 들어가 있습니다. GetComponent<가져올 컴포넌트>(); 를 이용하면 컴포넌트를 가져올 수 있습니다.

textMesh = gameObject.GetComponent<TextMesh>();

        screenCenter = new Vector3(Camera.main.pixelWidth / 2, Camera.main.pixelHeight / 2);

    }

 

//매 프레임마다 호출되는 메소드 입니다. 여기서 게임 오브젝트의 변화를 설정합니다.

void Update()

{

        Ray ray = Camera.main.ScreenPointToRay(screenCenter);

        RaycastHit hit;

        

        //레이저가 공을 맞췄는지에 대한 불리언 값입니다.

        bool isRayHitBox = Physics.Raycast(ray, out hit, 500f) && hit.collider.gameObject.tag == "Ball";

        if (isRayHitBox)

        {

            //최근 쳐다본 오브젝트가 비어있지 않고, 지금 레이저에 맞은 오브젝트와 같은지 여부를 불리언 값으로 저장합니다.

            bool isRecentObjEqualsCollObj = recentObject != null && recentObject.gameObject.Equals(hit.collider.gameObject);

            if (startTime + durTime < Time.time)

            {

                BoxCtrl ctrl = hit.collider.gameObject.GetComponent<BoxCtrl>();

                ctrl.Select();

            }

            else

            {

                recentObject = hit.collider.gameObject;

                startTime = Time.time;

            }

        }

        else

        {

            recentObject = null;

        }

 

        //카드보드에서 Triggered Getter는 트리거가 발생했는지 알 수 있습니다.

        if (cardBoard.Triggered)

{         

            //박스에 초점이고 

            if (Physics.Raycast(ray, out hit, 500f))

            {

                if (hit.collider.gameObject.tag == "Box")

                {

                    BoxCtrl boxCtrl = hit.collider.gameObject.GetComponent<BoxCtrl>();

                    boxCtrl.Select();

 

                    //TextMesh 컴포넌트의 text를 변경합니다.

                    count++;

                    textMesh.text = TEXT + count.ToString();

                }

            }            

        }

}

}

 

 

 

 

TriggerTextCtrl 스크립트를 그대로 사용합니다.

위 처럼 코드를 추가 해 주세요.
추가 된 부분을 설명 하겠습니다.

 

// 몇 초간 바라보는 것으로 설정할 것인지에 대한 변수입니다. 에디터에서 수정가능하도록 했습니다.
public float durTime = 3f;

// 쳐다보고 있는 오브젝트가 저장됩니다.

public GameObject recentObject;

// 쳐다보기 시작한 시간을 저장합니다.

private float startTime;

    

bool isRayHitBox = Physics.Raycast(ray, out hit, 500f) && hit.collider.gameObject.tag == "Ball";

레이저가 공을 맞췄는지에 대한 불리언 값입니다.


bool isRecentObjEqualsCollObj = recentObject != null && recentObject.gameObject.Equals(hit.collider.gameObject);

최근 쳐다본 오브젝트가 비어있지 않고, 지금 레이저에 맞은 오브젝트와 같은지 여부를 불리언 값으로 저장합니다.

 

if (startTime + durTime < Time.time)

{

    BoxCtrl ctrl = hit.collider.gameObject.GetComponent<BoxCtrl>();

    ctrl.Select();

}

 

Time.time은 게임이 시작된 후 경과된 시간이 저장되어 있습니다.

보기 시작한 시간과 바라 볼 시간을 더한 값이 경과 시간보다 작아질 경우, 그러니까 durTime만큼 시간이 지나면

오브젝트에서 BoxCtrl 컴포넌트를 얻어 색을 변경합니다.


else

{

    recentObject = hit.collider.gameObject;

    startTime = Time.time;

}

 

최근 쳐다본 오브젝트가 비어있지 않고, 지금 레이저에 맞은 오브젝트가 같지 않다면 지금 쳐다보고 있는 오브젝트로 변경 해 주고, 시작 시간을 다시 초기화 합니다.


else

{

    recentObject = null;

}

 

레이캐스트에 적중한 오브젝트가 없고, 적중했더라도 태그가 Ball이 아니라면 recentObject 는 null로 비워주어야 합니다.

 

 

 

[VR스쿨] 구글 카드보드 SDK를 이용한 VR 가상현실 콘텐츠 만들기1

가상현실

 

 

 

구글에서 제공하는 카드보드용 유니티 SDK를 다운받아서 안드로이드 폰에 설치할 VR 앱을 만들어 보겠습니다.
유니티의 무료 Asset Store를 이용해서 간단하게 VR 가상공간 모델링을 따라 하는 과정으로 진행해 봅니다.
 
 
349b64f238a157e9fca2a5a5cc7a1894_1456115
 
로 접속해서 구글에서 제공하는 카드보드용 유니티 SDK를 다운 받습니다.
빨간 밑줄 그어놓은 링크 클릭 하시면 됩니다.
(* 2016.06.02 최근 구글 SDK가 업데이트 되었습니다. 아래 실습을 위해서는 첨부파일을 이용해 주세요!)

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
유니티에서 프로젝트 만드시고
프로젝트 에셋 탐색기에서
마우스 오른쪽 클릭 -> Import Package -> Custom Package...를 선택합니다.

 
349b64f238a157e9fca2a5a5cc7a1894_1456115

위 링크에서 다운받은 패키지를 선택해서 열기를 합니다.
 
 

349b64f238a157e9fca2a5a5cc7a1894_1456115



패키지 파일 목록이 뜨는데 그대로 Import 버튼을 눌러줍니다.
 

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
 
정리를 쉽게 하기 위해서 다운 받은 패키지들은 한 폴더 안에 넣도록 합니다.
프로젝트 에셋 뷰에서 오른쪽 클릭 -> Create -> Folder 를 선택하여 폴더를 만듭니다.
 

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
앞으로 다운받은 패키지는 모두 AssetStore에 넣도록 합니다.
옮길 폴더를 드래그 하여 AssetStore에 끌어다 놓으면 됩니다.

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
땅을 추가해 보겠습니다.
적당한 땅을 다운받아보도록 하겠습니다.
도구 모음 -> Winodow -> Asset Store 를 선택해 에셋 스토어 창을 엽니다.


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
카테고리를 환경-> 지형으로 선택 하시고


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
필터를 Free Only(무료 에셋만)로 선택합니다.


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
찾아보시면 Snow Mountain이 있을겁니다 다운 받습니다.


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
이제 월드에 땅과 VR 카메라를 배치 해 보겠습니다.
MainCamera는 VR에서 사용하는 카메라가 있으므로 선택한 후 Del키를 눌러 삭제 해 줍니다.
하이어라키 뷰는 월드에 배치 된 오브젝트 목록을 계층 구조로 보여줍니다.
프로젝트 뷰에서 AssetStore -> Cardboard -> Prefabs -> CardboardMain 과AssetStore -> For_sale -> snow_mountain -> Snow_mountain 을  찾아 하이어라키 뷰에 끌어다 놓습니다.
 

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
다음은 하늘이 없어서 허전하니까 하늘을 추가해 보겠습니다.
에셋 스토어 창을 열어서 skybox 키워드로 검색하고 필터는 역시 무료로 해서 걸러줍니다
 

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
Wispy Skybox를 다운받아 보겠습니다.
창을 열어두면 다운받고 난 후 자동으로 임포트 하는 창이 뜹니다.


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
도구 모음에서 -> Window -> Lighting 으로 라이팅 창을 엽니다.
창에서 보시면 Skybox라고 있는데 오른쪽에 ⊙ 모양을 클릭하시면 사용가능한 하늘 머테리얼(재질) 목록이 뜹니다.
원하는 것을 선택하면

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
다음과 같이 하늘을 그리기 시작합니다.


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
너무 허전하니까 효과를 추가 해 보겠습니다.
Sky FX Pack을 찾아서 다운받은 후 임포트 후 월드에 배치해 주세요

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
혹시나 중간에 유니티가 오류가 발생 해 꺼질 수 있으니 씬(Scene)을 저장합니다.
 

349b64f238a157e9fca2a5a5cc7a1894_1456115
 
File -> Build Setting을 선택 하시면 다음과 같은 창이 나타 납니다.
플랫폼을 안드로이드로 선택 하시고 빌드를 하시면 잠시 컴파일 하다가 오류가 발생 합니다.


349b64f238a157e9fca2a5a5cc7a1894_1456115
 
패키지 이름을 정해주지 않아서 발생하는 오류인데 콘솔에서 오류를 더블클릭 해주신 후 Bundle Identifier 의 패키지 이름을 변경해 주신 후 다시 Build And Run 해주시면 됩니다.
 
 

안드로이드 개발의 시작 Android SDK 설치 과정 설명

모바일앱개발
사용자 삽입 이미지

안드로이드 개발의 기본은 Android SDK 설치부터 시작 하셔야 합니다.

안드로이드 개발 사이트 방문하시면 SDK를 Windows, Mac OS X (intel), Linux (i386) 에 한해서 제공하고 있습니다.

윈도우용 파일이 대략 22MB 정도 되며 다른 OS는 16MB~19MB 정도 입니다.
전 사용중인 컴이 윈도우XP라서 윈도우 개열을 받았습니다.

다운로드 : http://developer.android.com/sdk/index.html

다운 받으신 android-sdk_r06-windows.zip 파일을 압축 푸시고 SDK Setup.exe 파일을 실행 합니다.

설치단계 :
1. Prepare your development computer
2. Download and install the SDK starter package
3. Install the ADT Plugin for Eclipse
4. Add Android platforms and other components to your SDK

사용자 삽입 이미지



Setup 실행시 검정색 Command 창이 잠시 뜬뒤에 설치 창이 뜰겁니다.

사용자 삽입 이미지


헉! 설치 초기 부터 오류 ㅡㅡ;

Failed to fetch URL https://dl-ssl.google.com/android/repository/repository.xml, reason: HTTPS SSL error. You might want to force download through HTTP in the settings.

자! 흔히 나타날 수 있는 오류이니 당황하지 말고 설치 창에서 좌측메뉴 "Settings"를 선택후 "Misc"에 "Force https://... sources to be fetched using http://..."를 체크합니다.
체크와 동시에 팻치 되는것을 확인 하실 수 있습니다.
즉, 보안 웹 프로토콜(https)로 접속하지 않고 일반 접속 웹 프로토콜(http) 방식으로 팻치를 받겠다라는 그런 체크 같습니다.

사용자 삽입 이미지


다음은 설치할 패키지를 선택하라고 하는군요.

사용자 삽입 이미지



전 그냥 "Accept All" 체크후 "Install" 했습니다.
개발중 부분적인 제약으로 인해 추가 설치하는걸 귀찮아 해서 그렇지 기본적인 기능은 "Accept" 만으로도 문제 없을 겁니다.

사용자 삽입 이미지


이제 SDK 최신 버전을 다운로드 및 설치 과정이 나타 나는군요.
Accept All 설치시 대략 40분 정도 걸리는군요. (컴사양 및 인터넷 속도에 따라 다소 차이가 날겁니다.)