
실습에 오큘러스 퀘스트 2 기기를 사용했음
대여받은 상태로 진행했던 실습이라 따로 영상을 촬영해두지 않아 실습 영상은 없음,,
유니티에 오큘러스 라이브러리를 추가하면 기본으로 주어지는 scene과 코드를 사용해서
간단한 컨트롤러 동작등을 수행할 수 있음
# ControllerMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ControllerMove : MonoBehaviour
{
void Start()
{
}
void Update()
{
float x = ARAVRInput.GetAxis("Horizontal", ARAVRInput.Controller.LTouch);
float z = ARAVRInput.GetAxis("Vertical", ARAVRInput.Controller.LTouch);
transform.Translate(new Vector3(x, 0, z) * 5 * Time.deltaTime);
float ry = ARAVRInput.GetAxis("Horizontal", ARAVRInput.Controller.RTouch);
transform.Rotate(new Vector3(0, ry, 0) * 45 * Time.deltaTime);
float v=OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger);
Debug.Log($"Trigger: {v:f4}");
if (ARAVRInput.GetDown(ARAVRInput.Button.IndexTrigger, ARAVRInput.Controller.LTouch))
{
Ray ray = new Ray(ARAVRInput.LHandPosition, ARAVRInput.LHandDirection);
RaycastHit hitinfo;
if (Physics.Raycast(ray, out hitinfo)==true)
{
GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); // sphere의 기본 오브젝트로 만들어줘라 (오브젝트 생성)
obj.transform.position = hitinfo.point; //ray가 닿은 위치에 오브젝트 위치
}
}
}
}
# CustomGrap.cs
컨트롤러의 트리거를 사용해서 오브젝트를 그랩
using OculusSampleFramework;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CustomGrap : OVRGrabber
{
[SerializeField]
int m_grabObjectsInLayer = 0;
[SerializeField]
float m_maxGrabDistance;
[SerializeField]
float m_noSnapThreshhold = 0.05f;
protected override void GrabBegin()
{
DistanceGrabbable closestGrabbable = null;
Collider closestGrabbableCollider = null;
Ray ray = new Ray(m_gripTransform.position, m_gripTransform.forward);
RaycastHit hitInfo;
int layer = (m_grabObjectsInLayer == -1) ? ~0 : 1 << m_grabObjectsInLayer;
if (Physics.Raycast(ray, out hitInfo, m_maxGrabDistance, layer))
{
if (hitInfo.collider != null)
{
closestGrabbable = hitInfo.collider.gameObject.GetComponentInParent<DistanceGrabbable>();
closestGrabbableCollider = closestGrabbable == null ? null : hitInfo.collider;
if (closestGrabbable != null && closestGrabbable != m_grabbedObj)
{
closestGrabbable.Targeted = true;
}
}
}
GrabVolumeEnable(false);
if (closestGrabbable != null)
{
if (closestGrabbable.isGrabbed)
{
((CustomGrap)closestGrabbable.grabbedBy).OffhandGrabbed(closestGrabbable);
}
m_grabbedObj = closestGrabbable;
m_grabbedObj.GrabBegin(this, closestGrabbableCollider);
m_lastPos = transform.position;
m_lastRot = transform.rotation;
Vector3 relPos = m_grabbedObj.transform.position - transform.position;
relPos = Quaternion.Inverse(transform.rotation) * relPos;
m_grabbedObjectPosOff = relPos;
Quaternion relOri = Quaternion.Inverse(transform.rotation) * m_grabbedObj.transform.rotation;
m_grabbedObjectRotOff = relOri;
SetPlayerIgnoreCollision(m_grabbedObj.gameObject, true);
}
}
protected override void OffhandGrabbed(OVRGrabbable grabbable)
{
base.OffhandGrabbed(grabbable);
}
}
# CustomLaser.cs
컨트롤러가 가리키는 방향으로 나오는 레이저 구현
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CustomLaser : MonoBehaviour
{
LineRenderer lineRenderer;
public GameObject player;
public OVRScreenFade fade;
RaycastHit hitinfo;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
}
void Update()
{
lineRenderer.SetPosition(0, ARAVRInput.RHandPosition); // 컨트롤러에서 나오는 레이저의 시작점 갱신
Ray ray = new Ray(ARAVRInput.RHandPosition, ARAVRInput.RHandDirection);
if (Physics.Raycast(ray, out hitinfo, 100, 1 << LayerMask.NameToLayer("Default")) == true) // << 숫자 1의 비트를 왼쪽으로 한칸만 이동
{
/*
lineRenderer.enabled = true;
lineRenderer.SetPosition(1, ARAVRInput.RHandPosition + ARAVRInput.RHandDirection * 100);
// 컨트롤러가 시작하는 위치 + 컨트롤러가 향하는 방향 -> 컨트롤러 위치에서 컨트롤러가 향하는 방향으로 2미터
lineRenderer.SetPosition(1, hitinfo.point); // 만약 큐브와 충돌시 마지막점을 충돌지점으로 두기 위해
*/
lineRenderer.material.color = Color.green;
if (ARAVRInput.GetDown(ARAVRInput.Button.IndexTrigger,ARAVRInput.Controller.RTouch)) // 충돌된 위치로 텔레포트
{
Vector3 pos = hitinfo.point; // hitinfo.transform.position 으로하면 그 영역의 중점으로 이동 -> 지정된 위치로만 이동이 가능
// hitinfo.point하면 어느 위치든? 이동이 가능
StartCoroutine(Teleport(pos));
}
} //어떤 물체에 부딪혔다면 부딪힌 곳까지만 ray
else
{
//lineRenderer.enabled = false;
lineRenderer.SetPosition(1, ARAVRInput.RHandPosition + ARAVRInput.RHandDirection * 10);
lineRenderer.material.color = Color.red;
} // 어떤 물체에 부딪히지 않았다면 컨트롤러가 향하는 방향으로 10미터
}
IEnumerator Teleport(Vector3 pos)
{
fade.FadeOut();
yield return new WaitForSeconds(1.5f); // fadeOut하고 난 다음 위치이동
player.transform.position = pos + new Vector3(0, 1, 0);
fade.FadeIn();
}
}
# CustomLaserPointer.cs
레이저와 충돌한 오브젝트의 테두리 변경 및 그랩 설정
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(LineRenderer))]
public class CustomLaserPointer : MonoBehaviour
{
private LineRenderer lineRenderer; // 라인
private RaycastHit Collided_object; // 충돌된 객체
private GameObject currentObject; // 가장 최근에 충돌한 객체를 저장하기 위한 객체
public OVRInput.Button clickKey = OVRInput.Button.Any;
public Color normalColor = new Color(0, 195, 255, 0.5f);
public Color selectColor = new Color(255, 255, 255, 0.5f);
public float raycastDistance = 100f; // 레이저 포인터 감지 거리
public LayerMask layerMask;
void Start()
{
// 스크립트가 포함된 객체에 라인 렌더러라는 컴포넌트를 찾는다
lineRenderer = gameObject.GetComponent<LineRenderer>();
// 라인의 꼭지점은 2개가 필요
lineRenderer.positionCount = 2;
// 라인 그림자 표현끄기
lineRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
lineRenderer.receiveShadows = false;
// 라인 굵기 표현
lineRenderer.startWidth = 0.01f;
lineRenderer.endWidth = 0.01f;
// 라인이 가지게될 색상 표현
Material material = new Material(Shader.Find("Standard"));
material.color = normalColor;
lineRenderer.material = material;
}
void Update()
{
// 라인 시작점
lineRenderer.SetPosition(0, transform.position); // 첫번째 시작점 위치
//Debug.DrawRay(transform.position, transform.forward * raycastDistance, Color.green, 0.5f);
// 충돌 감지시
if (Physics.Raycast(transform.position, transform.forward, out Collided_object, raycastDistance, layerMask))
{
// 라인 끝점
lineRenderer.SetPosition(1, Collided_object.point);
//// 충돌 객체의 태그가 Button인 경우
//if (Collided_object.collider.gameObject.CompareTag("Button"))
//{
// if (OVRInput.GetDown(OVRInput.Button.One))
// {
// // 버튼에 등록된 onClick 메소드를 실행한다.
// if (Collided_object.collider.gameObject.GetComponent<Button>())
// Collided_object.collider.gameObject.GetComponent<Button>().onClick.Invoke();
// }
// else
// {
// if (Collided_object.collider.gameObject.GetComponent<Button>())
// Collided_object.collider.gameObject.GetComponent<Button>().OnPointerEnter(null);
// currentObject = Collided_object.collider.gameObject;
// }
//}
}
else
{
// 충돌이 감지되지 않으면 라인 초기 설정 길이만큼 길게 만든다
lineRenderer.SetPosition(1, transform.position + (transform.forward * raycastDistance));
//// 최근 감지된 오브젝트가 Button인 경우
//// 버튼은 현재 눌려있는 상태이므로 이것을 풀어준다.
//if (currentObject != null)
//{
// if (currentObject.GetComponent<Button>())
// currentObject.GetComponent<Button>().OnPointerExit(null);
// currentObject = null;
//}
}
}
private void LateUpdate()
{
// 버튼을 누를 경우
if (OVRInput.GetDown(clickKey))
{
lineRenderer.material.color = selectColor;
}
// 버튼을 뗄 경우
else if (OVRInput.GetUp(clickKey))
{
lineRenderer.material.color = normalColor;
}
}
}
# PhysicsButton.cs
컨트롤러로 버튼을 눌렀을 때
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class PhysicsButton : MonoBehaviour
{
public ConfigurableJoint join;
public float beginClick = 0.5f;
public float endClick = 0.3f;
public UnityEvent onPressed;
public UnityEvent onReleased;
bool isPressed = false;
Vector3 startPos;
void Start()
{
startPos = join.transform.localPosition;
}
void Update()
{
float distance = Vector3.Distance(startPos, join.transform.localPosition) / join.linearLimit.limit;
if (isPressed == false)
{
if (distance >= beginClick) // 처음 버튼이 눌리지 않은 상태에서 30퍼이상 눌렸을 때
{
isPressed = true;
Debug.LogWarning("Pressed");
onPressed.Invoke(); // onPressed안에 들어있는 이벤트 전체가 실행됨
}
}
else
{
if (distance <= endClick)
{
isPressed = false;
Debug.LogWarning("release");
onReleased.Invoke(); // onReleased안에 들어있는 이벤트 전체가 실행됨
}
}
}
}
ARAVRInput.cs
0.01MB
ARAVRInput은 기본적으로 제공해주는 코드에 추가적으로 작성한 코든데
전체 코드가 너무 길기도 하고 코드 분석 내용도 주석으로 적어놔서 일단 파일로 첨부함
0727.txt
0.00MB
수업 내용 정리
'etc. > 🕹️unity' 카테고리의 다른 글
VR 개인 프로젝트 (0) | 2022.06.11 |
---|---|
VR UI 설정 (0) | 2022.06.11 |
2D Shooting (0) | 2022.06.11 |
3D FPS (0) | 2022.06.11 |
unity shader, effect, light & 지형 만들기 (0) | 2022.06.11 |
댓글