I_Jemin

Prepare for 1.2 release

- Rename VRInteractable
- Update Readme
- Adjust demo object positions
- Make gun burst
......@@ -38,7 +38,7 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.18028364, g: 0.22571398, b: 0.30692267, a: 1}
m_IndirectSpecularColor: {r: 0.18028378, g: 0.22571412, b: 0.30692285, a: 1}
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
......@@ -4254,7 +4254,7 @@ Transform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 1979091570}
- {fileID: 1979091566}
- {fileID: 869103185}
- {fileID: 313616115}
m_Father: {fileID: 0}
......@@ -4921,9 +4921,9 @@ GameObject:
- component: {fileID: 1179877082}
- component: {fileID: 1179877084}
- component: {fileID: 1179877083}
- component: {fileID: 1179877088}
- component: {fileID: 1179877085}
- component: {fileID: 1179877086}
- component: {fileID: 1179877088}
m_Layer: 5
m_Name: Interatable UI Image
m_TagString: Untagged
......@@ -12952,11 +12952,11 @@ Prefab:
objectReference: {fileID: 0}
- target: {fileID: 4323484768405676, guid: 2b7e4fd4c75ce4919831f6c6dc401deb, type: 2}
propertyPath: m_LocalPosition.y
value: -0.003309071
value: 0.696
objectReference: {fileID: 0}
- target: {fileID: 4323484768405676, guid: 2b7e4fd4c75ce4919831f6c6dc401deb, type: 2}
propertyPath: m_LocalPosition.z
value: 1.764
value: 4.218
objectReference: {fileID: 0}
- target: {fileID: 4323484768405676, guid: 2b7e4fd4c75ce4919831f6c6dc401deb, type: 2}
propertyPath: m_LocalRotation.x
......@@ -12978,6 +12978,10 @@ Prefab:
propertyPath: m_RootOrder
value: 2
objectReference: {fileID: 0}
- target: {fileID: 1514860329309504, guid: 2b7e4fd4c75ce4919831f6c6dc401deb, type: 2}
propertyPath: m_Name
value: Target Cube
objectReference: {fileID: 0}
m_RemovedComponents: []
m_ParentPrefab: {fileID: 100100000, guid: 2b7e4fd4c75ce4919831f6c6dc401deb, type: 2}
m_IsPrefabParent: 0
......@@ -13173,7 +13177,7 @@ GameObject:
m_PrefabInternal: {fileID: 0}
serializedVersion: 5
m_Component:
- component: {fileID: 1979091570}
- component: {fileID: 1979091566}
- component: {fileID: 1979091568}
- component: {fileID: 1979091567}
- component: {fileID: 1979091569}
......@@ -13196,12 +13200,25 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 2ed6c285bcc774470840d1967056436d, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Camera: {fileID: 1979091570}
m_Camera: {fileID: 1979091566}
m_ExclusionLayers:
serializedVersion: 2
m_Bits: 4
m_RayLength: 500
m_ShowDebugRay: 1
--- !u!4 &1979091566
Transform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1979091564}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 805204565}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!124 &1979091567
Behaviour:
m_ObjectHideFlags: 0
......@@ -13254,24 +13271,6 @@ AudioListener:
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1979091564}
m_Enabled: 1
--- !u!224 &1979091570
RectTransform:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1979091564}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 805204565}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 100, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &1998395652
GameObject:
m_ObjectHideFlags: 0
......
......@@ -12,7 +12,7 @@ public class GunController : MonoBehaviour {
void Update()
{
if(VRInput.GetVRButtonDown(VRInput.Button.RightIndex))
if(VRInput.GetVRButton(VRInput.Button.RightIndex))
{
gun.Fire();
}
......
......@@ -13,8 +13,8 @@ public class VREyeRaycaster : MonoBehaviour
[SerializeField] private bool m_ShowDebugRay; // Optionally show the debug ray. [SerializeField] private float m_RayLength = 500f; // How far into the scene the ray is cast.
private VRInteratable m_CurrentInteractible; //The current interactive item
private VRInteratable m_LastInteractible; //The last interactive item
private VRInteractable m_CurrentInteractible; //The current interactive item
private VRInteractable m_LastInteractible; //The last interactive item
void Update()
......@@ -47,7 +47,7 @@ public class VREyeRaycaster : MonoBehaviour
// Do the raycast forweards to see if we hit an interactive item
if (Physics.Raycast(ray, out hit, m_RayLength, ~m_ExclusionLayers))
{
VRInteratable interactible = hit.collider.GetComponent<VRInteratable>(); //attempt to get the VRInteractiveItem on the hit object
VRInteractable interactible = hit.collider.GetComponent<VRInteractable>(); //attempt to get the VRInteractiveItem on the hit object
m_CurrentInteractible = interactible;
// If we hit an interactive item and it's not the same as the last interactive item, then call Over
......
......@@ -3,7 +3,7 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class VRInteratable : MonoBehaviour {
public class VRInteractable : MonoBehaviour {
[SerializeField]
private UnityEvent onClick;
......
......@@ -22,9 +22,13 @@ Oculus VR 과 HTC Vive (Steam VR) 에 모두 대응합니다.
### VR 트래킹 기능
- 현실 부위 1:1 트래킹
- VR 컨트롤러 입력 대응 함수 제공
- 스테이셔너리 자동 키 설정
- 간결한 코드와 높은 확장성
### VR 인터렉션과 VR UI
- VR 카메라가 응시하는 사물과 상호작용 가능
- 상호작용 이벤트를 제공
- 상호작용 UI 예제 첨부
### 건 슈터 (FPS Shooter) 기능
- 단발/연사
- 피탄 이펙트
......@@ -35,9 +39,23 @@ Oculus VR 과 HTC Vive (Steam VR) 에 모두 대응합니다.
- Gun.Reload - 장전
- Gun.Fire - 발사
## 선행조건 ##
유니티 Input Manager 에 OpenVR에 대응되는 Axes 이름이 지정되어 있어야 합니다.<br>
각 스틱과 버튼에 대한 식별자는 [유니티 OpenVR 입력 테이블 문서](https://docs.unity3d.com/Manual/OpenVRControllers.html) 에서 찾을 수 있습니다.
이 템플릿 프로젝트에는 해당 설정이 미리 지정되어 있으므로 별다른 설정을 요구하지는 않습니다.<br>미리 설정된 VR Input 테이블은 Edit > Proejct Settings > Input Manager 에서 확인할 수 있습니다.
VR 컨트롤러에 대응하는 자세한 원리는 VRInput 스크립트의 주석에 있습니다.
## 동작과 사용 방법
미리 만들어진 예제 씬을 참고하면 좋습니다.
### 프리팹 Prefab
미리 만들어진 예제 프리팹을 제공합니다.
......@@ -49,7 +67,7 @@ Oculus VR 과 HTC Vive (Steam VR) 에 모두 대응합니다.
![트래킹1](https://imgur.com/NKPpcAc.png)
어떤 오브젝트든 VRControllerTracking 만 붙여주면, 현실의 VR 컨트롤러와 위치와 동기화됩니다.
![트래킹1](https://imgur.com/jgH8PFD.png)
![트래킹2](https://imgur.com/jgH8PFD.png)
부착한 다음, 원하는 추적 부위를 지정해주세요.
위치와 회전 동기화는 로컬 좌표계를 기준으로 합니다.
......@@ -57,42 +75,80 @@ Oculus VR 과 HTC Vive (Steam VR) 에 모두 대응합니다.
### VR 컨트롤러 입력 감지
어떤 스크립트든 VRInputController 를 상속하면, VR 컨트롤러의 입력을 받을 수 있습니다.
VRInput 를 통해 왼손과 오른손 VR 컨트롤러의 현재 입력을 확인할 수 있습니다.
두가지 정적 함수를 제공합니다.
- bool GetVRButtonDown(Button button)
- VR 컨트롤러의 방아쇠 버튼을 막 누른 그 한 순간에만 true 를 반환
- 클릭이나 단발 사격을 구현할때 사용할 수 있습니다
- bool GetVRButton(Button button)
- VR 컨트롤러의 방아쇠 버튼을 누르는 동안 지속적으로 true 를 반환
두가지 오버라이드 가능한 함수를 제공합니다. 이들은 VR 컨트롤러 입력이 감지되면 자동으로 호출됩니다.
- void OnIndexTriggerButton() - VR 컨트롤러 검지 방아쇠를 누르는 동안 발동
- void OnGripTriggerButton() - VR 컨트롤러 쥐는 방아쇠를 누르는 동안 발동
두 함수 모두 입력으로 방아쇠 버튼의 종류를 받습니다.
- LeftIndex: 왼손 VR 컨트롤러의 검지 방아쇠
- RightIndex: 오른손 VR 컨트롤러의 검지 방아쇠
- LeftGrip: 왼손 VR 컨트롤러의 그립(쥐는) 방아쇠
- RightGrip: 오른손 VR 컨트롤러의 그립(쥐는) 방아쇠
1. VRInputController 스크립트를 상속받습니다.
2. 원하는 입력에 따라 위의 함수 중 하나를 오버라이드 합니다.
3. 함수 내부에 입력에 대응할 동작을 구현합니다.
#### VR 입력 대응 예시 코드
예제의 GunController 스크립트는 VR 입력에 따라 Gun 을 제어하는 스크립트 입니다.
별다른 코드 없이, OnIndexTriggerButton 와 OnGripTriggerButton 를 오버라이드 하여 입력에 대응하고 있습니다.
예제의 GunController 스크립트는 VR 입력에 따라 Gun 을 제어하는 스크립트 입니다.<br>
별다른 코드 없이, GetVRButtonDown 와 GetVRButton 으로 입력을 체크하여 총을 제어합니다.
검지 방아쇠를 당기고 있는 동안 계속 총을 발사합니다.<br>그립 방아쇠는 Down 함수를 사용하여, 쥐는 그 한 순간에만 재장전을 합니다.
~~~
public class GunController : VRInputController {
~~~
public Gun gun;
public override void OnIndexTriggerButtonDown()
void Update()
{
if(VRInput.GetVRButton(VRInput.Button.RightIndex))
{
gun.Fire();
}
public override void OnGripTriggerButtonDown()
if(VRInput.GetVRButtonDown(VRInput.Button.RightGrip))
{
gun.Reload();
}
}
}
~~~
### VR 인터렉션과 VR UI ###
VR에서 UI와 상호작용하는 예제가 데모에 있습니다.<br>상호작용 자체는 UI가 아니더라도, 콜라이더를 가진 다른 모든 오브젝트와도 가능합니다.
데모의 VR UI Canvas 오브젝트에 있는, Interatable UI Image 를 플레이어가 응시하면 색이 바뀝니다.<br>다시 다른 곳을 바라보면 원래 색으로 돌아갑니다. 플레이어가 해당 오브젝트를 바라보는 상태에서 오른손 검지 방아쇠를 당기면 색이 무작위로 지정됩니다.
#### 사용법 ####
선행조건
- 레이캐스팅을 통해 감지하므로, 상호작용할 물체는 3D 콜라이더 컴포넌트를 가지고 있어야 합니다.
- UI 오브젝트도 예외없이 3D 콜라이더를 가져야 합니다.
절차
- 카메라 VREyeRaycaster 스크립트를 부착합니다.<br>![VRRaycaster](https://imgur.com/NAdS3z9.png)
- 해당 스크립트는 응시하고 있는 오브젝트가 가진 함수를 발동시킬 수 있습니다.
- 인터렉션이 필요한 오브젝트에게 콜라이더를 부착합니다.<br>![VRUICollider](https://imgur.com/1ZIStu5.png)
- 인터렉션할 오브젝트에게 VRInteractable 스크립트를 부착합니다.<br>![VRInteractable](https://imgur.com/RMaaOWp.png)
- 이 스크립트는 세가지 유니티 이벤트를 제공합니다. 이들은 VREyeRaycaster에 의해 자동으로 발동됩니다.
- OnClick: VR 오른손 컨트롤러의 검지 방아쇠를 클릭하면 발동됩니다.
- OnVREyeEnter: VREyeRaycaster 를 가진 카메라의 시선 중심에 오브젝트가 들어오는 순간 발동됩니다.
- OnVREyeExit: VREyeRaycaster 를 가진 카메라의 시선이 오브젝트를 벗어나는 순간 발동됩니다.
- 원하는 유니티 이벤트의 슬롯을 추가하고, 연동할 함수를 등록합니다.
### 건 슈터 Gun Shooter
캡슐화 되어있습니다. 그냥 프리팹을 가져다 쓰면 됩니다.
![총프리팹](https://imgur.com/T9ZJiT3.png)
외부 함수로 Gun.Fire 와 Gun.Reload 를 제공하여, 총을 쏘고 재장전 할 수 있습니다.
### 총알 데미지 처리
......@@ -116,20 +172,12 @@ public class HitCube : MonoBehaviour,IDamageable {
}
~~~
### 이외의 기능들 ###
작성중
## 기타 ##
### VR 컨트롤러 입력 설정
VR 컨트롤러의 입력을 InputManager 에서 제어하는 방법은 VRInputController 와 https://github.com/IJEMIN/Unity-OpenVR-Power-Blade-Example 의 Readme 문서를 참고.
# 크레딧
I_Jemin (i_jemin@hotmail.com, ijemin.com)
# 크레딧과 연락처
I_Jemin
- 메일: i_jemin@hotmail.com
- 블로그: ijemin.com
# 기타
유니티 애셋 스토어에서 제공되는 무료 애셋을 사용하였습니다.<br>
......