티스토리 뷰

안녕하세요. Base Of Coding입니다.
AR을 벗어나.. 이직을 해서 현재 VR을 처음 손을 대면서 공부를 하고 있습니다.
그래서, Steam VR Sample에 나와있는 부분들을 코드 분석하고 있는데.. 역시 낯설어서 그런 지 많이 어려워보이네요ㅠ
일단 LaserPointer를 코드 분석을 해봤는데, 만약 보시다가 틀린 부분이 있거나 수정 할 부분이 있거나 가르쳐주실 내용이 있으시다면, 댓글로 많은 글 부탁드립니다!
//======= Copyright (c) Valve Corporation, All rights reserved. ===============
using UnityEngine;
using System.Collections;
// 짐작으로 작성하고 있는 코드 분석
namespace Valve.VR.Extras
{
public class SteamVR_LaserPointer : MonoBehaviour
{
public SteamVR_Behaviour_Pose pose; // 사용자의 포즈 관련 스크립트
//public SteamVR_Action_Boolean interactWithUI = SteamVR_Input.__actions_default_in_InteractUI;
public SteamVR_Action_Boolean interactWithUI = SteamVR_Input.GetBooleanAction("InteractUI"); // InteractUI란 액션, 즉 Delegate의 함수 이름을 대입?
public bool active = true; // active라는 bool값의 변수인데, 쓰이지 않는 듯 함.
public Color color; // 기본 Pointer Color값
public float thickness = 0.002f; // Pointer의 두께
public Color clickColor = Color.green; // 클릭했을 때(Trigger)의 Color값
public GameObject holder; // Pointer Cube를 가지고 있는 부모 게임 오브젝트
public GameObject pointer; // 포인터 Cube
bool isActive = false; // isActive, 그냥 false
public bool addRigidBody = false; // 포인터에 리지드바디를 붙이느냐 안 붙이느냐에 관련 된 bool값
public Transform reference; // reference, 참조라는 거 같은데 뭘 참조하는 지.. 참조할 수 있는 값도 없음. 필요없어 보이는 듯함.
public event PointerEventHandler PointerIn; // 포인터가 안에 들어왔을 경우 이벤트
public event PointerEventHandler PointerOut; // 포인터가 밖으로 빠져나갔을 경우의 이벤트
public event PointerEventHandler PointerClick; // 포인터로 클릭했을 때의 이벤트
Transform previousContact = null; // 이전의 충돌 된 오브젝트 변수
private void Start()
{
if (pose == null) // Pose가 null값이면, 해당 스크립트를 가지고 있는 게임오브젝트에, SteamVR_Behaviour_Pose 컴포넌트를 부착
pose = this.GetComponent<SteamVR_Behaviour_Pose>();
if (pose == null) // 그래도 null값이라면, LogError 출력
Debug.LogError("No SteamVR_Behaviour_Pose component found on this object");
if (interactWithUI == null) // interactWithUI가 null값이라면, LogError 출력
Debug.LogError("No ui interaction action has been set on this component.");
holder = new GameObject(); // holder, 빈 게임오브젝트로 생성한다. Pointer의 부모 오브젝트이다.
holder.transform.parent = this.transform; // 그리고 해당 holder의 부모는, 컨트롤러 최상위 부모 오브젝트이다.
holder.transform.localPosition = Vector3.zero;
holder.transform.localRotation = Quaternion.identity; // 포지션값과 회전값을 0,0,0으로 초기화
pointer = GameObject.CreatePrimitive(PrimitiveType.Cube); // MeshRenderer 및 해당 모형에 알맞는 Collider를 부착한 게임오브젝트를 만든다.
pointer.transform.parent = holder.transform; // 이 포인터의 부모는 holder이며
pointer.transform.localScale = new Vector3(thickness, thickness, 100f); // 앞으로 쭉 나와있는 얇은 두께를 가진 포인터로 크기를 만들어주고
pointer.transform.localPosition = new Vector3(0f, 0f, 50f); // x,y,z 기준으로, z값을 50으로 한다.
pointer.transform.localRotation = Quaternion.identity; // 회전값은 기본값인 0,0,0이다.
BoxCollider collider = pointer.GetComponent<BoxCollider>(); // 포인터에 BoxCollider 컴포넌트를 collider로 사용한다.
if (addRigidBody) // 리지드 바디를 추가해야 된다면
{
if (collider) // 콜라이더가 있다면, 콜라이더의 isTrigger를 켜준다.
{
collider.isTrigger = true;
}
Rigidbody rigidBody = pointer.AddComponent<Rigidbody>(); // 포인터에, 리지드바디 컴포넌트를 추가하고
rigidBody.isKinematic = true; // isKinematic을 켜준다.
}
else
{
if (collider) // collider가 있다면, collider 컴포넌트를 없앤다.
{
Object.Destroy(collider);
}
}
Material newMaterial = new Material(Shader.Find("Unlit/Color")); // 새로운 메터리얼을 만들고, 해당 메터리얼은, Unlit/Color라는 쉐이더 종류로 만든다.
newMaterial.SetColor("_Color", color); // 컬러값, 즉 검은색을 메터리얼의 컬러값으로 만든다.
pointer.GetComponent<MeshRenderer>().material = newMaterial; // 그리고, Pointer의 MeshRenderer의, 메터리얼 쪽에 넣어준다.
}
public virtual void OnPointerIn(PointerEventArgs e) // 포인터가 안에 들어오면
{
if (PointerIn != null)
PointerIn(this, e); // 해당 클래스와, 매개변수 e값을 넣는다? 아직 파악이 안됨.
}
public virtual void OnPointerClick(PointerEventArgs e) // 포인터 클릭 시 이벤트
{
if (PointerClick != null)
PointerClick(this, e); // 해당 클래스와, 매개변수 e값을 넣는다? 아직 파악이 안됨.
}
public virtual void OnPointerOut(PointerEventArgs e) // 포인터가 밖으로 빠져나갔을 경우?
{
if (PointerOut != null)
PointerOut(this, e); // 해당 클래스와, 매개변수 e값을 넣는다? 이것 또한 아직 파악이 안됨.
}
private void Update()
{
if (!isActive) // isActive가 false일 경우
{
isActive = true; // isActive는, true로 만들고,
this.transform.GetChild(0).gameObject.SetActive(true); // 해당 스크립트가 있는 오브젝트에서, 첫 번째 자식의 오브젝트를 켜준다.
}
float dist = 100f; // 거리
Ray raycast = new Ray(transform.position, transform.forward); // RayCast 생성, 정면으로
RaycastHit hit; // RaycastHit형 hit 변수 선언
bool bHit = Physics.Raycast(raycast, out hit); // Raycast를 만들어서, 정면으로 쏘고 hit가 되었는 지 안 되었는 지 판단하여, hit면, true, nonHit면, false
if (previousContact && previousContact != hit.transform) // 전에 충돌한 물체가 있고, 이전에 충돌한 물체와 충돌된 물체가 다르다면, 포인터가 밖으로 빠져나간 것
{
PointerEventArgs args = new PointerEventArgs(); // 구조체 동적할당
args.fromInputSource = pose.inputSource; // pose.inputSource를 fromInputSource에 대입
args.distance = 0f; // 거리는 0으로 초기화
args.flags = 0; // flag는 0, 이건 모든 이벤트 동일한 듯.
args.target = previousContact; // target은, 이전에 충돌한 물체를 대입한다.
OnPointerOut(args); // OnPointerOut 함수 실행
previousContact = null; // 이전에 충돌한 물체는, 없으니 null
}
if (bHit && previousContact != hit.transform) // hit가 되었고, 이전에 충돌한 물체가 충돌한 물체와 다르다면, 예 ) null != Sphere, 어떠한 물체와 부딪혔다는 뜻.
{
PointerEventArgs argsIn = new PointerEventArgs(); // 구조체 동적할당
argsIn.fromInputSource = pose.inputSource; // pose.inputSource를 fromInputSource에 대입
argsIn.distance = hit.distance; // 거리는 충돌 된 거리로 변경
argsIn.flags = 0; // flag는 0, 이건 모든 이벤트 동일
argsIn.target = hit.transform; // target은, 현재 충돌한 물체를 대입
OnPointerIn(argsIn); // OnPointerIn 함수 실행
previousContact = hit.transform; // 이전에 충돌한 물체는 현재 충돌한 물체로 대입
}
if (!bHit) // hit가 되지 않았다면
{
previousContact = null; // 이전에 충돌한 물체는 null값.
}
if (bHit && hit.distance < 100f) // hit가 되었고, hit가 된 거리가, 100f보다 작다면
{
dist = hit.distance; // 거리값은, hit가 된 거리로 변경
}
if (bHit && interactWithUI.GetStateUp(pose.inputSource)) // hit가 되었고, 트리거 클릭하고 뗄 경우, ( 누르고 있을 때 X )
{
PointerEventArgs argsClick = new PointerEventArgs(); // 구조체 동적할당
argsClick.fromInputSource = pose.inputSource; // pose.inputSource를 fromInputSource에 대입
argsClick.distance = hit.distance; // 거리는 충돌 된 거리로 변경
argsClick.flags = 0; // flag는 0, 이건 모든 이벤트 동일
argsClick.target = hit.transform; // target은, 현재 충돌한 물체를 대입
OnPointerClick(argsClick); // OnPointerClick 함수 실행
previousContact = hit.transform;
}
if (interactWithUI != null && interactWithUI.GetState(pose.inputSource)) // 상호작용, 즉 트리거를 눌렀다 뗐을 때, Sphere와 충돌이 되면
{
pointer.transform.localScale = new Vector3(thickness * 5f, thickness * 5f, dist); // 두께는, 기본 두께보다 x5배만큼 늘려준다. dist는, 충돌되었을 때의 거리로 변경이 된다.
pointer.GetComponent<MeshRenderer>().material.color = clickColor; // 메터리얼의 Color값은, 클릭했을 때의 Color값으로 변경
}
else // 상호작용이 안되었다면, 아무것도 충돌이 되지 않는다면
{
pointer.transform.localScale = new Vector3(thickness, thickness, dist); // 기본 두께와 기본 거리만큼의 포인터로 변경이 되고
pointer.GetComponent<MeshRenderer>().material.color = color; // 포인터의 Color값도 Black으로 변경한다.
}
pointer.transform.localPosition = new Vector3(0f, 0f, dist / 2f); // pointer의 지역 위치는, 0,0,거리/2로 만들어준다.
}
}
public struct PointerEventArgs
{
public SteamVR_Input_Sources fromInputSource;
public uint flags;
public float distance;
public Transform target;
}
public delegate void PointerEventHandler(object sender, PointerEventArgs e);
}
글에 도움이 되셨거나, 고쳐야 될 부분이 있다면, 댓글로 글 남겨주세요! 감사합니다.
지금까지 Base Of Coding이였습니다.
'게임 프로그래밍 ( 이제 안함 ) > 일에 대한 끄적끄적' 카테고리의 다른 글
Final IK - VRIK.cs 주석 작성 (0) | 2019.11.14 |
---|---|
VR - Steam VR SteamVR_Behaviour_Pose.cs 주석 작성 ( 틀린부분은 말씀해주세요! ) (0) | 2019.11.05 |
VR - Steam VR UIElement 스크립트 주석달아보기 (0) | 2019.11.04 |
코드를 작성하다가 주석을 달아놓는게 좋을까? 아닐까? (0) | 2018.12.13 |
아이폰6 망할것 (0) | 2018.12.12 |
- Total
- Today
- Yesterday
- VR
- 유니티로 배우는 C#
- 안드로이드
- Git
- Java
- 서블릿
- 프로그래밍
- 유니티3D
- MVC
- Servlet
- Controller
- 게임프로그래밍
- GitHub
- 비지니스 로직
- JSP
- Base Of Coding
- baseofcoding
- c#
- unity3d
- 스프링
- Spring
- spring boot
- Unity
- Vuforia
- 뷰포리아
- HTML
- Next.js
- 프리젠테이션 로직
- CSS
- 유니티
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |