본문 바로가기

IT이야기/VR이야기

유니티 오큘러스 빌드, 인풋세팅

[ 유니티의 기본 인풋 ]

 

유니티 프로젝트를 생성하면

기본적으로 아래와 같이 기본 방향 축과 조이패드 용 방향 축이 동시에 설정되어있다.

 

 

 

 

이 중 invert값이 눈에 띄는데, 이 상태에서 연결했을 경우

 

    1. 샤오미 게임패드 등과 같은 블루투스 게임패드 : 정상

    2. XBOX 조이스틱 : 앞/뒤가 뒤바뀜

 

으로 나타난다. 때문에 2번의 경우 invert를 체크해제해야한다.



[ 유니티 인풋값 테스트 ]

 

https://www.assetstore.unity3d.com/kr/#!/content/43621 를 사용하는 것을 추천.

 



[ 유니티에서 오큘러스용 이동하는 캐릭터 설정 ]

오큘러스에서 제공하는 소스로 캐릭터를 쓸 수 있을거라 생각했지만, 오류 때문에 사용 불가능

(자체적으로 스크립트를 개발)

 

1. 플레이어와 카메라는 별도의 오브젝트로 준비한다.

 

 

각 오브젝트를 아래와 같이 세팅한다. 카메라는 아무런 설정이 되지않은 기본카메라다.

 

 

+rigid Body의 Freeze Rotation xyz를 각각 체크해줘야한다!

 

 

<Player에 붙이는 FirstPersonControl>

 

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

using UnityEngine.SceneManagement;

 

[RequireComponent (typeof(CharacterController))]

 

public class FirstPersonControl : MonoBehaviour {

 

[Header("Setting")]

public float movementSpeed = 5f;

public float mouseSensitivity = 2f;

public float upDownRange= 90;

public float jumpSpeed = 5;

public float downSpeed = 5;

public Transform cameraControlTransform;

 

[Header("Cache")]

[SerializeField]

private Transform cameraTransform;

private Vector3 speed;

private float footStepTime;

private float footSideStepTime;

private float forwardSpeed;

private float sideSpeed;

 

private float rotLeftRight;

private float rotUpDown;

private float verticalRotation = 0f;

private float verticalVelocity = 0f;

private int pressedCount = 0;

public bool isGround;

 

private CharacterController cc;

private Rigidbody rb;

 

void Start () {

cc = GetComponent<CharacterController> ();

rb = GetComponent<Rigidbody>();

Cursor.lockState = CursorLockMode.Locked;

}

 

void LateUpdate () {

FPRotate();

FPMove ();

}

 

//Player의 x축, z축 움직임을 담당

void FPMove()

{

forwardSpeed = Input.GetAxis ("Vertical") * movementSpeed;

               sideSpeed = Input.GetAxis ("Horizontal") * movementSpeed;

 

if (cc.isGrounded)

verticalVelocity = Physics.gravity.y;

 

else if (!cc.isGrounded)

verticalVelocity += Physics.gravity.y * Time.deltaTime;

 

speed = new Vector3(sideSpeed, 0, forwardSpeed);

speed = transform.rotation * speed;

 

transform.position += speed * Time.deltaTime;

}

 

//Player의 회전을 담당

void FPRotate()

{

/*

#if UNITY_EDITOR || UNITY_STANDALONE

 

//좌우 회전

rotLeftRight = Input.GetAxis ("Mouse X") * mouseSensitivity;

transform.Rotate (0f, rotLeftRight, 0f);

//상하 회전

verticalRotation -= Input.GetAxis ("Mouse Y") * mouseSensitivity;

verticalRotation = Mathf.Clamp (verticalRotation, -upDownRange, upDownRange);

cameraTransform.localRotation = Quaternion.Euler (verticalRotation, 0f, 0f);

transform.rotation = Quaternion.Euler(0f, transform.rotation.eulerAngles.y, 0f);

 

#elif UNITY_ANDROID          //안드로이드 빌드시 회전

*/

Vector3 newRotation = transform.eulerAngles;

newRotation.y = cameraTransform.eulerAngles.y;

newRotation.z = 0f;

newRotation.x = 0f;

transform.eulerAngles = newRotation;

 

   //    #endif

 

}

 

void Fall() {

transform.parent = null;

}

}

 

 

 

 

<CameraTransform에 붙이는 CameraControl>

 

using UnityEngine;

using System.Collections;

 

public class CameraControl_indigo : MonoBehaviour

{

public Transform player;

 

void LateUpdate()

{

transform.position = player.position;

 

#if UNITY_EDITOR || UNITY_STANDALONE

//transform.rotation = player.rotation;

#endif

}

}

 

위 두개의 스크립트는 PC Oculus나 Mobile Oculus로 인풋을 받을때 제대로 작동하며, 만약 에디터상에서 마우스를 통해 테스트하고 싶다면 모든 주석을 해제하면된다.



[ 오큘러스 빌드 ]

 

- Oculus에서 SDK를 받아서 프로젝트에 포함시킨 뒤, Player Setting에서 VirtualReality를 켜주면 된다

- 자동으로 게임내에서는 메인카메라가 오큘러스 카메라로 변환되며 해당 카메라의 포지션 값 및 회전값은 손대지 못하한다. 조작하고 싶을 경우 상위그룹에서 조작하면 반영된다.

 


- First Person Control 스크립트의 확장버전 (사운드추가, L/R 버튼으로 시선회전)

 

using UnityEngine;

using System.Collections;

using System.Collections.Generic;

using UnityEngine.SceneManagement;

 

[RequireComponent (typeof(CharacterController))]

 

public class FirstPersonControl : MonoBehaviour {

 

[Header("Setting")]

public float movementSpeed = 5f;

public float mouseSensitivity = 2f;

public float upDownRange= 90;

public float jumpSpeed = 5;

public float downSpeed = 5;

public Transform cameraControlTransform;

 

[Header("Cache")]

[SerializeField]

private List<AudioSource> footStepSound;

[SerializeField]

private Transform cameraTransform;

private Vector3 speed;

private float footStepTime;

private float footSideStepTime;

private float forwardSpeed;

private float sideSpeed;

 

private float rotLeftRight;

private float rotUpDown;

private float verticalRotation = 0f;

private float verticalVelocity = 0f;

private int pressedCount = 0;

public bool isGround;

 

private CharacterController cc;

private Rigidbody rb;

 

void Start () {

cc = GetComponent<CharacterController> ();

rb = GetComponent<Rigidbody>();

Cursor.lockState = CursorLockMode.Locked;

}

 

void LateUpdate () {

FPRotate();

FPMove ();

FootStepSound();

}

 

//Player의 x축, z축 움직임을 담당

void FPMove()

{

forwardSpeed = Input.GetAxis ("Vertical") * movementSpeed;

sideSpeed = Input.GetAxis ("Horizontal") * movementSpeed;

 

#if UNITY_EDITOR || UNITY_STANDALONE

 

#elif UNITY_ANDROID

 

if (Input.GetButtonDown("Gamepad_Xbutton"))

{

if (isGround)

GetComponent<Rigidbody>().AddForce(0f, 200f, 0f);

}

 

#endif

 

if (cc.isGrounded)

verticalVelocity = Physics.gravity.y;

 

else if (!cc.isGrounded)

verticalVelocity += Physics.gravity.y * Time.deltaTime;

 

speed = new Vector3(sideSpeed, 0, forwardSpeed);

speed = transform.rotation * speed;

 

transform.position += speed * Time.deltaTime;

}

 

//Player의 회전을 담당

void FPRotate()

{

/*

#if UNITY_EDITOR || UNITY_STANDALONE

 

//좌우 회전

rotLeftRight = Input.GetAxis ("Mouse X") * mouseSensitivity;

transform.Rotate (0f, rotLeftRight, 0f);

 

//상하 회전

verticalRotation -= Input.GetAxis ("Mouse Y") * mouseSensitivity;

verticalRotation = Mathf.Clamp (verticalRotation, -upDownRange, upDownRange);

cameraTransform.localRotation = Quaternion.Euler (verticalRotation, 0f, 0f);

transform.rotation = Quaternion.Euler(0f, transform.rotation.eulerAngles.y, 0f);

 

#elif UNITY_ANDROID          //안드로이드 빌드시 회전

*/

Vector3 newRotation = transform.eulerAngles;

newRotation.y = cameraTransform.eulerAngles.y;

newRotation.z = 0f;

newRotation.x = 0f;

transform.eulerAngles = newRotation;

 

// #endif

if (Input.GetKey(KeyCode.Q) || Input.GetButton("Gamepad_L1button"))

{

cameraTransform.Rotate(0f, -2f, 0f);

}

 

if (Input.GetKey(KeyCode.E) || Input.GetButton("Gamepad_R1button"))

{

cameraTransform.Rotate(0f, 2f, 0f);

}

}

 

void Fall()

{

transform.parent = null;

}

 

//발걸음 소리

void FootStepSound()

{

if (!isGround)

return;

 

if (forwardSpeed > 0)

footStepTime += forwardSpeed * Time.deltaTime;

else

footStepTime -= forwardSpeed * Time.deltaTime;

 

if (sideSpeed > 0)

footSideStepTime += sideSpeed * Time.deltaTime;

else

footSideStepTime -= sideSpeed * Time.deltaTime;

 

if (footStepTime > 1.2f || footSideStepTime > 1.2f)

{

GenerateRandomSound();

footStepTime = 0f;

footSideStepTime = 0f;

}

}

 

//발자국 소리 랜덤하게 생성

void GenerateRandomSound()

{

int randSound = Random.Range(0,4);

footStepSound[randSound].Play();

}

}