본문 바로가기
가상현실

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

by 세이박스 2016. 8. 29.
반응형

 

 

 

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

 

따라서, 이번 강의에서는 일정 시간동안 오브젝트를 바라 보았을때 동작하는 기능을 만들어 보겠습니다.
이전 예제에서 이용한 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로 비워주어야 합니다.

 

 

 

반응형