Life Archive

INTRO

VR 전시 프로젝트를 진행하면서 5분 동안 유저의 이동이 없을 때 시작 Scene으로 이동하는 기능을 개발하게 되었다.

기존 Input System을 이용한다면 UnityEngine 내부에 있는 Input.anyKeyDown을 이용하면 간단히 구현할 수 있지만,

XR Interaction Toolkit Package를 사용하면서 새로운 Input System에 대해서는 작동하지 않았다.

 

그래서 transform.position과 Coroutine을 이용하여 Input System없이 간단하게 구현해보았다.

 


CONTENT

먼저, TimeSceneChagne.cs의 전체 코드는 아래와 같다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class TimeSceneChange : MonoBehaviour
{
    private Transform playerTr;
    private Vector3 startPos;

    bool checking = false;
    Coroutine lastRoutine = null;

    private void Start()
    {
        playerTr = GetComponent<Transform>();
        startPos = transform.position;

        StartCoroutine(InputCheck());
    }

    IEnumerator InputCheck()
    {
        while (true)
        {
            yield return new WaitForSeconds(1.0f);

            if (playerTr.position == startPos)
            {
                if (!checking)
                {
                    lastRoutine = StartCoroutine(TimeCheck());
                }
            }
            else
            {
                startPos = playerTr.position;
                checking = false;
                StopCoroutine(lastRoutine);
            }
        }        
    }
    
    IEnumerator TimeCheck()
    {
        checking = true;
        yield return new WaitForSeconds(300.0f);

        SceneManager.LoadScene("Start");
    }
}

우선 코루틴 함수 2개와 위치를 비교할 2개의 변수를 이용하여 구현을 하였다.

 

① 1초 간격으로 위치 확인

 

playerTr라는 변수에는 GameObject의 Transform Component 연결해주고,

startPos 변수에는 처음 Play했을 때의 Position을 할당해준다.

 

그리고 InputCheck라는 코루틴을 실행시킨다. 

 

② InputCheck Coroutine

 

InputCheck Method에서는 1초 간격으로 반복문을 돌며 현재 오브젝트의 위치(playerTr)와

1초 전의 위치(startPos)를 비교해준다. 

두 변수가 같고, 5분 타이머가 돌아가고 있다는 것을 알려주는 Bool 타입 변수 checking이 false라면

(5분 타이머가 돌아가지 않을 때) 두 번째 코루틴 함수인 TimeCheck를 실행시켜준다.

 

※ lastCoroutine 변수를 StartCoroutine(TimeCheck())와 연결한 이유

: StopCoroutine을 사용할 때 인자로 TimeCheck()와 같이 메서드를 넣으면 정상작동하지 않는다. (타이머가 계속 돌아감)

String 타입으로 넣어주거나 위 코드와 같이 lastCoroutine이라는 별도의 변수를 지정하여 인자로 넣어야만 정상작동하게 된다.

 

만약 두 위치 변수가 같지 않고 다르다면, startPos(1초 이전 위치)에 playerTr.position(현재 위치)로 바꿔줌으로써

1초 간격으로 Check할 수 있도록 설정해준다.

 

또한, 5분 타이머가 중단되었음을 알려야하고 TimeCheck 코루틴을 정지해야하므로 checking 변수를 false로 바꾸고 StopCoroutine(lastCoroutine)을 사용하여 TimeCheck Coroutine을 정지한다.

 

③ TimeCheck Coroutine

 

TimeCheck Method로 넘어오면 checking 변수를 true로 변경하여 5분을 측정하고 있음을 알리고 yield return new WaitForSeconds(300.0f)를 이용하여 5분을 측정한다. 측정이 끝나기 전까지 다른 Method에서 StopCoroutine이

실행되지 않는다면 SceneManager.LoadScene("Start")로 Start Scene으로 이동하여 프로젝트를 Reset 시켜준다.

 


RESULT

Oculus Quest 2에 맞춰 새로운 Input System을 공부하면서, Input.anyKeyDown 대신 다른 방법으로 Input을 확인하고

타이머를 시작했다가 리셋하는 코드를 구현할 수도 있었다.

 

하지만, Input System말고도 가장 기본적인 transform.position을 이용하고 2개의 코루틴 함수를 이용해도

간단하게 구현할 수 있겠다 싶어 포스팅 내용처럼 개발하게 되었다. 

 

이후에는 프로젝트가 끝나고 리팩토링할 때, new Input System을 이용해서 구현하는 연습을 해볼 예정이다.