VR 컨트롤러 만들기 – 쳐다만 봐도 콘텐츠 선택되는 기능 만들기

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

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

하이어라키 창에서 오른쪽 클릭 -> 3D Object -> Sphere로 구를 추가합니다.
이 구에 BoxCtrl 스크립트를 그대로 추가합니다.
Tag는 Ball을 추가하여 설정합니다.
마그네틱 스위치 인식과 오브젝트 선택 기억나지 않으면 아래 링크를 참고 합니다.

구글 카드보드의 마그네틱 스위치 인식과 오브젝트 선택

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

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;
}

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.