feat: SongCreator 씬 완성 — Beat Sage URL 지원, info.dat 메타데이터 자동 추출

- BeatSageUploader: audio_url 지원(UploadFromUrl), PollAndDownload 공통화, ZIP 500 오류 3회 재시도
- BeatSageConverter: info.dat 파싱(SongMetadata), BPM 자동 감지 → 노트 타이밍 변환에 적용
- SongCreatorManager: title/BPM 필수 입력 제거, 난이도 4개 자동 선택, GenerateFlowFromUrl 버그 수정
- NasPublisher: audioPath null 허용(URL 흐름에서 로컬 파일 없는 경우 스킵)
- .gitignore/.gitattributes 초기 설정

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 23:37:34 +09:00
commit 4dad9e5d5b
1068 changed files with 175146 additions and 0 deletions
@@ -0,0 +1,7 @@
namespace VRSDK
{
public interface ISpeed
{
float Speed { get; }
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 5f9929385e7e6ca4fa4aa16a9d825248
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/ISpeed.cs
uploadId: 546658
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3ee52a0dda456384b93190008a446332
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,38 @@
using UnityEngine;
namespace VRSDK
{
/// <summary>
/// Supported Inputs
/// </summary>
public enum VR_InputButton
{
None,
Primary,
Secondary,
Trigger,
Grip,
TumbstickPress
}
public abstract class VR_InputDevice
{
protected VR_Controller InputController { get; private set; }
public VR_InputDevice(VR_Controller controller)
{
this.InputController = controller;
}
public abstract Quaternion GetRotationOffset();
public abstract Vector3 GetPositionOffset();
public abstract string GetDeviceName();
public abstract float GetAxis1D(VR_InputButton button);
public abstract Vector2 GetJoystick();
public abstract bool GetButtonDown(VR_InputButton button);
public abstract bool GetButtonUp(VR_InputButton button);
public abstract bool GetButton(VR_InputButton button);
public abstract bool IsConnected();
public abstract System.Enum GetControllerType();
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 14fe470127ef83b49901491fcbd88dac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Input/VR_InputDevice.cs
uploadId: 546658
@@ -0,0 +1,159 @@
using System;
using UnityEngine;
namespace VRSDK
{
public class VR_OculusInput : VR_InputDevice
{
#if SDK_OCULUS
private OVRInput.Controller OVRControllerType
{
get
{
return InputController.ControllerType == VR_ControllerType.Right ? OVRInput.Controller.RTouch : OVRInput.Controller.LTouch;
}
}
#endif
public VR_OculusInput(VR_Controller controller) : base(controller) { }
public override float GetAxis1D(VR_InputButton button)
{
#if SDK_OCULUS
OVRInput.Axis1D axis;
switch (button)
{
case VR_InputButton.Trigger:
axis = OVRInput.Axis1D.PrimaryIndexTrigger;
return OVRInput.Get(axis, OVRControllerType);
case VR_InputButton.Grip:
axis = OVRInput.Axis1D.PrimaryHandTrigger;
return OVRInput.Get(axis, OVRControllerType);
}
#endif
return 0.0f;
}
public override bool GetButton(VR_InputButton button)
{
#if SDK_OCULUS
switch (button)
{
case VR_InputButton.Grip:
return GetAxis1D( button ) > 0.25f;
case VR_InputButton.Trigger:
return GetAxis1D( button ) > 0.25f;
case VR_InputButton.Primary:
return OVRInput.Get(OVRInput.Button.One, OVRControllerType);
case VR_InputButton.Secondary:
return OVRInput.Get(OVRInput.Button.Two, OVRControllerType);
case VR_InputButton.TumbstickPress:
return OVRInput.Get(OVRInput.Button.PrimaryThumbstick, OVRControllerType);
}
#endif
return false;
}
public override bool GetButtonDown(VR_InputButton button)
{
#if SDK_OCULUS
switch (button)
{
case VR_InputButton.Grip:
return OVRInput.GetDown( OVRInput.Button.PrimaryHandTrigger , OVRControllerType );
case VR_InputButton.Trigger:
return OVRInput.GetDown(OVRInput.Button.PrimaryIndexTrigger, OVRControllerType);
case VR_InputButton.Primary:
return OVRInput.GetDown(OVRInput.Button.One, OVRControllerType);
case VR_InputButton.Secondary:
return OVRInput.GetDown(OVRInput.Button.Two, OVRControllerType);
case VR_InputButton.TumbstickPress:
return OVRInput.GetDown(OVRInput.Button.PrimaryThumbstick, OVRControllerType);
}
#endif
return false;
}
public override bool GetButtonUp(VR_InputButton button)
{
#if SDK_OCULUS
switch (button)
{
case VR_InputButton.Grip:
return OVRInput.GetUp(OVRInput.Button.PrimaryHandTrigger, OVRControllerType);
case VR_InputButton.Trigger:
return OVRInput.GetUp(OVRInput.Button.PrimaryIndexTrigger, OVRControllerType);
case VR_InputButton.Primary:
return OVRInput.GetUp(OVRInput.Button.One, OVRControllerType);
case VR_InputButton.Secondary:
return OVRInput.GetUp(OVRInput.Button.Two, OVRControllerType);
case VR_InputButton.TumbstickPress:
return OVRInput.GetUp(OVRInput.Button.PrimaryThumbstick, OVRControllerType);
}
#endif
return false;
}
public override string GetDeviceName()
{
#if SDK_OCULUS
return OVRControllerType.ToString();
#endif
return "";
}
public override Vector2 GetJoystick()
{
#if SDK_OCULUS
OVRInput.Axis2D axis = OVRInput.Axis2D.PrimaryThumbstick;
return OVRInput.Get(axis, OVRControllerType);
#endif
return Vector2.zero;
}
public override bool IsConnected()
{
#if SDK_OCULUS
return OVRInput.IsControllerConnected(OVRControllerType);
#endif
return false;
}
public override Quaternion GetRotationOffset()
{
#if SDK_OCULUS
return Quaternion.identity;
#endif
return Quaternion.identity;
}
public override Vector3 GetPositionOffset()
{
return Vector3.zero;
}
public override Enum GetControllerType()
{
#if SDK_OCULUS
return OVRControllerType;
#endif
return default;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: eb89955c58e54484cb2cfea809091f76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Input/VR_OculusInput.cs
uploadId: 546658
@@ -0,0 +1,180 @@
using System;
using UnityEngine;
#if SDK_STEAM_VR
using Valve.VR;
#endif
namespace VRSDK
{
public class VR_SteamVRInput : VR_InputDevice
{
#if SDK_STEAM_VR
private SteamVR_Action_Single grabAction = null;
private SteamVR_Action_Boolean triggerAction = null;
private SteamVR_Action_Boolean primaryButtonAction = null;
private SteamVR_Action_Boolean secondaryButtonAction = null;
private SteamVR_Action_Boolean joystickPressAction = null;
private SteamVR_Action_Vector2 joystickInputAction = null;
public SteamVR_Input_Sources SteamControllerType { get { return InputController.ControllerType == VR_ControllerType.Right ? SteamVR_Input_Sources.RightHand : SteamVR_Input_Sources.LeftHand; } }
private bool isConnected = false;
#endif
public VR_SteamVRInput(VR_Controller controller) : base(controller)
{
#if SDK_STEAM_VR
InitializeSteamVR_Actions();
SteamVR_Behaviour_Pose steamController = controller.GetComponentInParent<SteamVR_Behaviour_Pose>();
steamController.onConnectedChanged.AddListener(delegate (SteamVR_Behaviour_Pose poseController, SteamVR_Input_Sources sources, bool state) { isConnected = state; });
#endif
}
#if SDK_STEAM_VR
private void InitializeSteamVR_Actions()
{
grabAction = SteamVR_Input.GetAction<SteamVR_Action_Single>("VRShooterKit", "Grab");
triggerAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("VRShooterKit", "Shoot");
primaryButtonAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("VRShooterKit", "PrimaryButton");
secondaryButtonAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("VRShooterKit", "SecondaryButton");
joystickPressAction = SteamVR_Input.GetAction<SteamVR_Action_Boolean>("VRShooterKit", "JoystickPress");
joystickInputAction = SteamVR_Input.GetAction<SteamVR_Action_Vector2>("VRShooterKit", "Joystick");
}
#endif
public override float GetAxis1D(VR_InputButton button)
{
#if SDK_STEAM_VR
switch (button)
{
case VR_InputButton.Trigger:
return GetButton(button) ? 1.0f : 0.0f;
case VR_InputButton.Grip:
return grabAction.GetAxis(SteamControllerType);
}
#endif
return 0.0f;
}
public override bool GetButton(VR_InputButton button)
{
#if SDK_STEAM_VR
switch (button)
{
case VR_InputButton.Trigger:
return triggerAction.GetState(SteamControllerType);
case VR_InputButton.Grip:
return grabAction.GetAxis(SteamControllerType) > 0.65f;
case VR_InputButton.Primary:
return primaryButtonAction.GetState(SteamControllerType);
case VR_InputButton.Secondary:
return secondaryButtonAction.GetState(SteamControllerType);
case VR_InputButton.TumbstickPress:
return joystickPressAction.GetState(SteamControllerType);
}
#endif
return false;
}
public override bool GetButtonDown(VR_InputButton button)
{
#if SDK_STEAM_VR
switch (button)
{
case VR_InputButton.Trigger:
return triggerAction.GetStateDown(SteamControllerType);
case VR_InputButton.Grip:
return grabAction.GetAxis(SteamControllerType) > 0.65f;
case VR_InputButton.Primary:
return primaryButtonAction.GetStateDown(SteamControllerType);
case VR_InputButton.Secondary:
return secondaryButtonAction.GetStateDown(SteamControllerType);
case VR_InputButton.TumbstickPress:
return joystickPressAction.GetStateDown(SteamControllerType);
}
#endif
return false;
}
public override bool GetButtonUp(VR_InputButton button)
{
#if SDK_STEAM_VR
switch (button)
{
case VR_InputButton.Trigger:
return triggerAction.GetStateUp(SteamControllerType);
case VR_InputButton.Grip:
return grabAction.GetAxis(SteamControllerType) > 0.65f;
case VR_InputButton.Primary:
return primaryButtonAction.GetStateUp(SteamControllerType);
case VR_InputButton.Secondary:
return secondaryButtonAction.GetStateUp(SteamControllerType);
case VR_InputButton.TumbstickPress:
return joystickPressAction.GetStateUp(SteamControllerType);
}
#endif
return false;
}
public override string GetDeviceName()
{
#if SDK_STEAM_VR
return SteamControllerType.ToString();
#endif
return "";
}
public override Vector2 GetJoystick()
{
#if SDK_STEAM_VR
return joystickInputAction.GetAxis(SteamControllerType);
#endif
return Vector2.zero;
}
public override bool IsConnected()
{
#if SDK_STEAM_VR
return isConnected;
#endif
return false;
}
public override Quaternion GetRotationOffset()
{
return Quaternion.identity;
}
public override Vector3 GetPositionOffset()
{
return Vector3.zero;
}
public override Enum GetControllerType()
{
#if SDK_STEAM_VR
return SteamControllerType;
#endif
return default;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 1a75ba2a8a91f6e48a3bb20cd56723a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Input/VR_SteamVRInput.cs
uploadId: 546658
@@ -0,0 +1,161 @@
using UnityEngine;
using System.Collections.Generic;
using System;
#if UNITY_XR
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR;
#endif
namespace VRSDK
{
public class VR_XRInput : VR_InputDevice
{
private InputDevice thisInputDevice;
private XRInputHelper inputHelper = null;
private List<VR_InputButton> inputButtonTrackedList = new List<VR_InputButton>()
{
VR_InputButton.Grip ,
VR_InputButton.Primary ,
VR_InputButton.Secondary ,
VR_InputButton.Trigger ,
VR_InputButton.TumbstickPress
};
public VR_XRInput(VR_Controller controller) : base(controller)
{
GameObject go = new GameObject( "XRInputHelper" );
inputHelper = go.AddComponent<XRInputHelper>();
inputHelper.Construct(this , inputButtonTrackedList);
InputDevices.deviceConnected += RegisterDevice;
List<InputDevice> devices = new List<InputDevice>();
InputDevices.GetDevices(devices);
for (int i = 0; i < devices.Count; i++)
RegisterDevice(devices[i]);
}
private void RegisterDevice(InputDevice connectedDevice)
{
if (IsValidInputDeviceForController(InputController, connectedDevice))
{
thisInputDevice = connectedDevice;
}
}
private bool IsValidInputDeviceForController(VR_Controller controller , InputDevice inputDevice)
{
if (controller.ControllerType == VR_ControllerType.Right)
{
return InputDeviceIsRightController(inputDevice);
}
else
{
return InputDeviceIsLeftController(inputDevice);
}
}
private bool InputDeviceIsRightController(InputDevice inputDevice)
{
return (inputDevice.characteristics & InputDeviceCharacteristics.Right) != 0;
}
private bool InputDeviceIsLeftController(InputDevice inputDevice)
{
return (inputDevice.characteristics & InputDeviceCharacteristics.Left) != 0;
}
public override float GetAxis1D(VR_InputButton button)
{
float value = 0.0f;
switch (button)
{
case VR_InputButton.Trigger:
thisInputDevice.TryGetFeatureValue(CommonUsages.trigger, out value);
break;
case VR_InputButton.Grip:
thisInputDevice.TryGetFeatureValue(CommonUsages.grip, out value);
break;
}
return value;
}
public override bool GetButton(VR_InputButton button)
{
bool value = false;
switch (button)
{
case VR_InputButton.Grip:
return GetAxis1D(button) > 0.25f;
case VR_InputButton.Trigger:
return GetAxis1D(button) > 0.25f;
case VR_InputButton.Primary:
#if UNITY_XR
thisInputDevice.IsPressed(InputHelpers.Button.PrimaryButton, out value);
#endif
break;
case VR_InputButton.Secondary:
#if UNITY_XR
thisInputDevice.IsPressed(InputHelpers.Button.SecondaryButton, out value);
#endif
break;
case VR_InputButton.TumbstickPress:
#if UNITY_XR
thisInputDevice.IsPressed(InputHelpers.Button.Primary2DAxisClick, out value);
#endif
break;
}
return value;
}
public override bool GetButtonDown(VR_InputButton button)
{
return inputHelper.GetButtonDown(button);
}
public override bool GetButtonUp(VR_InputButton button)
{
return inputHelper.GetButtonUp(button);
}
public override string GetDeviceName()
{
return thisInputDevice.name;
}
public override Vector2 GetJoystick()
{
Vector2 joystick;
thisInputDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out joystick);
return joystick;
}
public override Vector3 GetPositionOffset()
{
return Vector3.zero;
}
public override Quaternion GetRotationOffset()
{
return Quaternion.identity;
}
public override bool IsConnected()
{
return true;
}
public override Enum GetControllerType()
{
return default;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 87cb4b9deb8252b4e957bdb497a4df0d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Input/VR_XRInput.cs
uploadId: 546658
@@ -0,0 +1,76 @@
using UnityEngine;
using System.Collections.Generic;
using VRSDK.Collections;
namespace VRSDK
{
public class XRInputHelper : MonoBehaviour
{
private List<VR_InputButton> trackingButtonList = null;
private Dictionary<VR_InputButton, Buffer<bool>> buttonStateHistory = new Dictionary<VR_InputButton, Buffer<bool>>();
private int historySize = 3;
private VR_InputDevice input = null;
public void Construct(VR_InputDevice input , List<VR_InputButton> trackingButtonList)
{
this.input = input;
this.trackingButtonList = trackingButtonList;
SetupButtonInfo();
}
private void SetupButtonInfo()
{
for (int n = 0; n < trackingButtonList.Count; n++)
{
buttonStateHistory.Add( trackingButtonList[n] , new Buffer<bool>(historySize) );
}
}
private void Update()
{
for (int n = 0; n < trackingButtonList.Count; n++)
{
Buffer<bool> buffer;
if ( buttonStateHistory.TryGetValue( trackingButtonList[n] , out buffer ) )
{
buffer.Add( input.GetButton(trackingButtonList[n]) );
}
}
}
public bool GetButtonDown(VR_InputButton button)
{
Buffer<bool> buffer;
if (buttonStateHistory.TryGetValue(button, out buffer))
{
if (buffer.Count >= historySize && !buffer[historySize - 2] && input.GetButton(button))
return true;
}
return false;
}
public bool GetButtonUp(VR_InputButton button)
{
Buffer<bool> buffer;
if (buttonStateHistory.TryGetValue(button, out buffer))
{
if (buffer.Count >= historySize && buffer[historySize - 2] && !input.GetButton(button))
return true;
}
return false;
}
}
public struct XRButtonInfo
{
public VR_InputButton button;
public bool state;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 62c8e9cfab020e64fbc32ff805442af3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Input/XRInputHelper.cs
uploadId: 546658
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 44739ec2a9f4d85459f0fb7332734174
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,20 @@
using UnityEngine;
namespace VRSDK.Integration
{
public abstract class VR_Integration
{
public VR_Controller RightController { get; }
public VR_Controller LeftController { get; }
public abstract Transform GetLeftHandTransform();
public abstract Transform GetRightHandTransform();
public abstract Transform GeTrackingSpaceTransform();
public abstract VR_Controller GetActiveController();
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 274d59c162ea3304b846c174270cdb2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Integration/VR_Integration.cs
uploadId: 546658
@@ -0,0 +1,28 @@
using UnityEngine;
namespace VRSDK.Integration
{
public class VR_OculusIntegration : VR_Integration
{
public override VR_Controller GetActiveController()
{
return VR_Manager.instance.Player.RightController;
}
public override Transform GetLeftHandTransform()
{
return GameObject.Find("LeftHandAnchor").transform;
}
public override Transform GeTrackingSpaceTransform()
{
return GameObject.Find("TrackingSpace").transform;
}
public override Transform GetRightHandTransform()
{
return GameObject.Find("RightHandAnchor").transform;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a450cee367a07b44fbe4c5d23f3189cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Integration/VR_OculusIntegration.cs
uploadId: 546658
@@ -0,0 +1,28 @@
using UnityEngine;
namespace VRSDK.Integration
{
public class VR_SteamVRIntegration : VR_Integration
{
public override VR_Controller GetActiveController()
{
return VR_Manager.instance.Player.RightController;
}
public override Transform GetLeftHandTransform()
{
return GameObject.Find("LeftHand").transform;
}
public override Transform GeTrackingSpaceTransform()
{
return GameObject.Find("SteamVRObjects").transform;
}
public override Transform GetRightHandTransform()
{
return GameObject.Find("RightHand").transform;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: cc25f779daa33bd499bbd4d7a321dc41
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Integration/VR_SteamVRIntegration.cs
uploadId: 546658
@@ -0,0 +1,34 @@
using UnityEngine;
namespace VRSDK.Integration
{
public class VR_XRIntegration : VR_Integration
{
public override VR_Controller GetActiveController()
{
return VR_Manager.instance.Player.RightController;
}
public override Transform GetLeftHandTransform()
{
return VR_Manager.instance.Player.LeftController.OriginalParent;
}
public override Transform GetRightHandTransform()
{
return VR_Manager.instance.Player.RightController.OriginalParent;
}
public override Transform GeTrackingSpaceTransform()
{
var cameraOffset = GameObject.Find("CameraOffset");
if (cameraOffset == null) return null;
return cameraOffset.transform;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a48e7a84122f4d7458fd032411b9dc2e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Integration/VR_XRIntegration.cs
uploadId: 546658
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f5be8739e0aadd7498ee8f91081ea4ca
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,55 @@
using UnityEngine;
namespace VRSDK.Locomotion
{
//this scripts handles aim marker position and rotation
public class VR_AimMarker : MonoBehaviour
{
[SerializeField] private GameObject marker = null;
[SerializeField] private BoxCollider collider = null;
[SerializeField] private float slopeLimit;
public GameObject Marker { get { return marker; } }
public BoxCollider Collider { get { return collider; } }
public float SlopeLimit { get { return slopeLimit; } }
private void Awake()
{
//disable marker
marker.gameObject.SetActive(false);
}
public void Hide()
{
marker.SetActive( false );
}
public void UpdatePositionAndRotation(VR_Controller controller, AimRaycastInfo info, bool active = true)
{
if (!marker.activeInHierarchy && active)
marker.SetActive( true );
marker.transform.position = info.hitPoint;
marker.transform.up = info.normal;
Vector2 controllerInput = controller.Input.GetJoystick().normalized;
Vector3 controllerDirection = new Vector3( controllerInput.x, 0.0f, controllerInput.y );
//get controller pointing direction in world space
controllerDirection = controller.transform.TransformDirection( controllerDirection );
//get marker forward in local space
Vector3 forward = marker.transform.InverseTransformDirection( marker.transform.forward);
//find the angle diference betwen the controller pointing direction and marker current forward
float angle = Vector2.SignedAngle( new Vector2( controllerDirection.x , controllerDirection.z ) , new Vector2( forward.x , forward.z ) );
//rotate marker in local space to match controller pointing direction
marker.transform.Rotate(Vector3.up , angle , Space.Self);
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8c846e854350b9545a191d7ce52fe1ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_AimMarker.cs
uploadId: 546658
@@ -0,0 +1,155 @@
using UnityEngine;
using System.Collections.Generic;
namespace VRSDK.Locomotion
{
//this scripts handle the raycasting part for teleporting
public abstract class VR_AimRaycaster : MonoBehaviour
{
[Tooltip( "How many subdivisions will have the teleport ray?, this could increase the numbers of linecast per frame, be careful." )]
[SerializeField] [Range(1 , 25)] protected int collisionAccuracy = 8;
[SerializeField] protected float validAngle = 60.0f;
[SerializeField] protected float invalidRayDistance = 2.0f;
[SerializeField] protected LayerMask validLayerMask;
public virtual AimRaycastInfo Raycast(List<Vector3> points , Transform rayController)
{
//get rayController angle
Vector3 rayControllerForward = rayController.forward;
Vector3 unalteredForward = new Vector3( rayController.forward.x, 0.0f, rayController.forward.z ).normalized;
float angle = Vector3.Angle( rayController.forward, unalteredForward );
//check if we are on a valid angle
if (angle > validAngle)
{
AimRaycastInfo info = new AimRaycastInfo();
info.hitPoint = Vector3.zero;
info.normal = Vector3.zero;
//clamp ray to a distance
info.validPoints = ClampToDistance(points , invalidRayDistance );
info.isValid = false;
return info;
}
//the points are valid?
if (points.Count <= 1)
return null;
RaycastHit hitInfo;
if (points.Count == 2)
{
if (Physics.Linecast( points[0], points[1] , out hitInfo , validLayerMask.value , QueryTriggerInteraction.Ignore))
{
return ProcessHitInfo(hitInfo , new List<Vector3> { points[0] , hitInfo.point } );
}
return null;
}
List<Vector3> validPoints = new List<Vector3>();
int subdivision = Mathf.CeilToInt( points.Count / collisionAccuracy);
int currentIndex = 0;
int nextIndex = subdivision;
for (int n = 0; n < subdivision; n++)
{
//check for collision in this segment
if (Physics.Linecast( points[currentIndex], points[nextIndex] , validLayerMask.value , QueryTriggerInteraction.Ignore))
{
//found a collision in this segment
//find collision in all points inside this segment
for (int j = currentIndex; j < nextIndex; j++)
{
validPoints.Add( points[j] );
if (Physics.Linecast( points[j], points[j + 1], out hitInfo , validLayerMask.value , QueryTriggerInteraction.Ignore))
{
validPoints.Add( hitInfo.point );
return ProcessHitInfo(hitInfo , validPoints);
}
}
}
else
{
//this segment dont has a collision, addall as valid points
for (int j = currentIndex; j <= nextIndex; j++)
{
validPoints.Add( points[j] );
}
}
//move to the next subdivision if we have one
currentIndex += subdivision;
nextIndex += subdivision;
//we found the end
if (currentIndex >= points.Count)
{
return null;
}
if (nextIndex >= points.Count)
nextIndex = points.Count - 1;
}
return null;
}
protected abstract AimRaycastInfo ProcessHitInfo(RaycastHit hitInfo, List<Vector3> validPoints);
private List<Vector3> ClampToDistance(List<Vector3> points , float d)
{
List<Vector3> validPoints = new List<Vector3>();
float currentSqrDistance = 0.0f;
for (int n = 0; n < points.Count - 1; n++)
{
float distance = (points[n] - points[n + 1]).sqrMagnitude;
validPoints.Add( points[n] );
if (distance + currentSqrDistance < d * d)
{
currentSqrDistance += distance;
}
else
{
Vector3 dir = ( points[n + 1] - points[n] ).normalized;
float diff = Mathf.Abs( Mathf.Abs( Mathf.Sqrt( currentSqrDistance ) ) - Mathf.Abs( d ) );
validPoints.Add( points[n] + (dir * diff) );
return validPoints;
}
}
return validPoints;
}
protected float GetSlopeAngle(Vector3 surfaceNormal)
{
return Vector3.Angle(surfaceNormal , Vector3.up);
}
}
public class AimRaycastInfo
{
public Vector3 hitPoint = Vector3.zero;
public Vector3 normal = Vector3.zero;
public List<Vector3> validPoints = new List<Vector3>();
public bool isValid = false;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4aced637571962d47a4b8ecb1f8e24a3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_AimRaycaster.cs
uploadId: 546658
@@ -0,0 +1,27 @@
using System.Collections.Generic;
using UnityEngine;
namespace VRSDK.Locomotion
{
public class VR_CharacterAimRaycaster : VR_AimRaycaster
{
[SerializeField] private float characterRadiusOffset = 1.5f;
[SerializeField] private CharacterController characterController = null;
[SerializeField] private float slopeLimit = 20.0f;
protected override AimRaycastInfo ProcessHitInfo(RaycastHit hitInfo, List<Vector3> validPoints)
{
Vector3 start = hitInfo.point + ( hitInfo.normal * characterController.radius * characterRadiusOffset ) + hitInfo.normal;
Vector3 end = start + ( hitInfo.normal * characterController.height );
AimRaycastInfo info = new AimRaycastInfo();
info.hitPoint = hitInfo.point;
info.normal = hitInfo.normal;
info.validPoints = validPoints;
//check if the character can fit in this place
info.isValid = GetSlopeAngle(info.normal) < slopeLimit && !Physics.CheckCapsule( start, end, characterController.radius * characterRadiusOffset , validLayerMask.value , QueryTriggerInteraction.Ignore );
return info;
}
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c74522154bbb4756af9570668ff48afc
timeCreated: 1601215740
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_CharacterAimRaycaster.cs
uploadId: 546658
@@ -0,0 +1,19 @@
using System.Collections.Generic;
using UnityEngine;
namespace VRSDK.Locomotion
{
//this is a preset for line teleport
[CreateAssetMenu( fileName = "LineTeleporPreset", menuName = "VRShooterKit/Create Line Teleport Preset" )]
public class VR_LineAimHandler : VR_TeleportAimHandler
{
public override List<Vector3> GetAllPoints(Ray aimRay)
{
Vector3 start = aimRay.origin;
Vector3 end = start + ( aimRay.direction * range );
return new List<Vector3>() {start , end };
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: bb5d9394e48fb6a46b092ad83be5e637
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_LineAimHandler.cs
uploadId: 546658
@@ -0,0 +1,40 @@
using UnityEngine;
using System.Collections.Generic;
namespace VRSDK.Locomotion
{
/// Class for handling rendering of a teleporting line
[RequireComponent(typeof(LineRenderer))]
public class VR_LineRenderer : MonoBehaviour
{
[SerializeField] private Gradient validTeleportGradient = null;
[SerializeField] private Gradient invalidTeleportGradient = null;
private LineRenderer lineRender = null;
private void Awake()
{
lineRender = GetComponent<LineRenderer>();
}
public virtual void CleanRender()
{
lineRender.positionCount = 0;
}
public virtual void Render(List<Vector3> points , bool suitableForTeleporting)
{
lineRender.positionCount = points.Count;
lineRender.colorGradient = suitableForTeleporting ? validTeleportGradient : invalidTeleportGradient;
for(int n = 0; n < points.Count; n++)
{
lineRender.SetPosition(n , points[n]);
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7022a95e98189194eb78c7579ad43acc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_LineRenderer.cs
uploadId: 546658
@@ -0,0 +1,47 @@
using UnityEngine;
using System.Collections.Generic;
namespace VRSDK.Locomotion
{
//this is a preset for a parabolic teleport
[CreateAssetMenu(fileName = "ParabolicTeleporPreset", menuName = "VRShooterKit/Create Parabolic Teleport Preset")]
public class VR_ParabolicAimHandler : VR_TeleportAimHandler
{
[SerializeField] protected float projectileSpeed = 15.0f;
[SerializeField] protected float gravity = 9.8f;
[Tooltip("The fps for the fake projectile use for generate a parabolic line, more fps will produce more points so be careful")]
[Range(10 , 75)]
[SerializeField] protected int simulatedFPS = 40;
public override List<Vector3> GetAllPoints(Ray aimRay)
{
//calculate the fake delta time
float deltaTime = 1.0f / (float) simulatedFPS;
//calculate initial speed
Vector3 m = aimRay.direction * projectileSpeed * deltaTime;
Vector3 projectilePos = aimRay.origin;
List<Vector3> points = new List<Vector3>();
//we calculate the distance of the fake projectil using just x,z so it looks better
float squareRange = range * range;
Vector2 origin = new Vector2(aimRay.origin.x , aimRay.origin.z);
while ( (origin - new Vector2( projectilePos.x , projectilePos.z )).sqrMagnitude < squareRange)
{
points.Add( projectilePos );
//add gravity
m -= Vector3.up * gravity * deltaTime;
//move our fake projectil
projectilePos += m;
}
return points;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 0388cd264756ae64ea86d7b60a3e6c1b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_ParabolicAimHandler.cs
uploadId: 546658
@@ -0,0 +1,174 @@
using UnityEngine;
using System.Collections.Generic;
namespace VRSDK.Locomotion
{
public enum TeleporState
{
WaitingInput,
PreTeleport,
PostTeleport
}
//this script makes use of all the teleport components and handles the logic for teleporting
public class VR_TeleporManager : MonoBehaviour
{
[SerializeField] private VR_LineRenderer teleportLineRender = null;
[SerializeField] private VR_TeleportAimHandler aimHandler = null;
[SerializeField] private VR_AimRaycaster aimRaycaster = null;
[SerializeField] private VR_AimMarker aimMarker = null;
[SerializeField] private VR_TeleportHandler teleportHandler = null;
[SerializeField] private CharacterController characterController = null;
private VR_Controller leftController = null;
private VR_Controller rightController = null;
private VR_Controller activeController = null;
private VR_Controller lastActiveController = null;
private AimRaycastInfo lastRaycastInfo = null;
private TeleporState currentTeleportState = TeleporState.WaitingInput;
private bool isTeleporting = false;
private void Start()
{
rightController = VR_Manager.instance.Player.RightController;
leftController = VR_Manager.instance.Player.LeftController;
}
private void LateUpdate()
{
switch (currentTeleportState)
{
case TeleporState.WaitingInput:
WaitingInputUpdate();
break;
case TeleporState.PreTeleport:
PreTeleportUpdate();
break;
case TeleporState.PostTeleport:
PostTeleportUpdate();
break;
}
}
private void WaitingInputUpdate()
{
if (isTeleporting)
return;
//wait for the teleport to start
if ( IsMovingJoystick(leftController) || IsMovingJoystick(rightController) )
{
UpdateActiveController();
currentTeleportState = TeleporState.PreTeleport;
}
}
private bool IsMovingJoystick(VR_Controller controller)
{
return controller.Input.GetJoystick().magnitude > 0.25f;
}
//set the controller that makes the teleport intent
private void UpdateActiveController()
{
activeController = GetActiveController();
lastActiveController = activeController;
}
private VR_Controller GetActiveController()
{
if (IsMovingJoystick(leftController) && IsMovingJoystick(rightController))
{
return lastActiveController == null ? rightController : lastActiveController;
}
if ( IsMovingJoystick(leftController) )
return leftController;
if (IsMovingJoystick(rightController))
return rightController;
return null;
}
//wait for the player to decide where to teleport
private void PreTeleportUpdate()
{
UpdateActiveController();
//there is no active controller try to do a teleport
if (activeController == null)
{
//if we can teleport to the last AimRaycast
if (IsAimRaycastInfoSuitableForTeleporting(lastRaycastInfo))
{
DoTeleport( lastRaycastInfo );
}
//clean the line inmediatly
teleportLineRender.CleanRender();
//go to post teleport
currentTeleportState = TeleporState.PostTeleport;
return;
}
Ray controllerRay = new Ray( activeController.transform.position, activeController.transform.forward );
//use the aimhandler to generate all the line points
List<Vector3> points = aimHandler.GetAllPoints( controllerRay );
//use the raycaster
AimRaycastInfo info = aimRaycaster.Raycast( points , activeController.transform );
if (info != null)
{
teleportLineRender.Render( info.validPoints, info.isValid );
}
else
{
teleportLineRender.Render( points , false );
}
if (IsAimRaycastInfoSuitableForTeleporting( info ))
{
aimMarker.UpdatePositionAndRotation( activeController, info );
}
else
{
aimMarker.Hide();
}
lastRaycastInfo = info;
}
private bool IsAimRaycastInfoSuitableForTeleporting(AimRaycastInfo info)
{
return info != null && info.isValid;
}
private void DoTeleport(AimRaycastInfo info)
{
isTeleporting = true;
teleportHandler.DoTeleport( characterController , aimMarker.Marker.transform , delegate { isTeleporting = false; } );
}
private void PostTeleportUpdate()
{
aimMarker.Hide();
lastActiveController = null;
lastRaycastInfo = null;
currentTeleportState = TeleporState.WaitingInput;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c9432419a55c7ce45b8f3cb8c6dc94da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_TeleporManager.cs
uploadId: 546658
@@ -0,0 +1,18 @@
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
namespace VRSDK.Locomotion
{
/// Basic class for creating the points of a teleporting line
/// this is a scritableobject so you can create diferent presets
public abstract class VR_TeleportAimHandler : ScriptableObject
{
[SerializeField] protected float range = 15.0f;
public abstract List<Vector3> GetAllPoints(Ray aimRay);
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 37d6bd64f39a6724d847793de196b5c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_TeleportAimHandler.cs
uploadId: 546658
@@ -0,0 +1,27 @@
using System.Collections.Generic;
using UnityEngine;
namespace VRSDK.Locomotion
{
public class VR_TeleportAimRaycaster : VR_AimRaycaster
{
[SerializeField] private float characterRadiusOffset = 1.5f;
[SerializeField] private CharacterController characterController = null;
[SerializeField] private float slopeLimit = 20.0f;
protected override AimRaycastInfo ProcessHitInfo(RaycastHit hitInfo, List<Vector3> validPoints)
{
Vector3 start = hitInfo.point + ( hitInfo.normal * characterController.radius * characterRadiusOffset ) + hitInfo.normal;
Vector3 end = start + ( hitInfo.normal * characterController.height );
AimRaycastInfo info = new AimRaycastInfo();
info.hitPoint = hitInfo.point;
info.normal = hitInfo.normal;
info.validPoints = validPoints;
//check if the character can fit in this place
info.isValid = GetSlopeAngle(info.normal) < slopeLimit && !Physics.CheckCapsule( start, end, characterController.radius * characterRadiusOffset , validLayerMask.value , QueryTriggerInteraction.Ignore );
return info;
}
}
}
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f3732281f0ab459096cd967e7d6bd4a1
timeCreated: 1601750964
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_TeleportAimRaycaster.cs
uploadId: 546658
@@ -0,0 +1,66 @@
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using System;
namespace VRSDK.Locomotion
{
//this script handles the position change part of the teleport system
public class VR_TeleportHandler : MonoBehaviour
{
[SerializeField] private VR_ScreenFader screenFader = null;
[SerializeField] private bool useBlink = true;
[SerializeField] private float blinkTime = 0.5f;
[SerializeField] private UnityEvent onTeleport = null;
private Vector3 characterPosition = Vector3.zero;
private Vector3 teleportFoward = Vector3.zero;
private CharacterController affectedCharacterController = null;
public UnityEvent OnTeleport { get { return onTeleport; } }
/// Teleport a charactercontroller to a new position and rotation
public void DoTeleport(CharacterController characterController , Transform to , Action onTeleportComplete)
{
affectedCharacterController = characterController;
characterPosition = to.position + ( Vector3.up * characterController.height * 0.5f ) + (characterController.center * -1.0f);
teleportFoward = to.forward;
teleportFoward.y = 0.0f;
if (useBlink)
{
StartCoroutine( TeleportRoutine(onTeleportComplete) );
}
else
{
SetTeleportPositionAndRotation();
if (onTeleportComplete != null)
onTeleportComplete();
}
}
//we use a routine if we want to use a screen fading effect
private IEnumerator TeleportRoutine(Action onTeleportComplete)
{
yield return StartCoroutine( screenFader.Fade(0.0f , 1.0f , blinkTime) );
SetTeleportPositionAndRotation();
onTeleport.Invoke();
yield return StartCoroutine( screenFader.Fade( 1.0f, 0.0f, blinkTime ) );
if (onTeleportComplete != null)
onTeleportComplete();
}
//set final teleport position and rotation
private void SetTeleportPositionAndRotation()
{
affectedCharacterController.transform.position = characterPosition;
affectedCharacterController.transform.forward = teleportFoward;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 92ef5427d00dc9f47b0d5a7c20dc5bd3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/Teleporting/VR_TeleportHandler.cs
uploadId: 546658
@@ -0,0 +1,29 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace VRSDK
{
public class VR_AutoDrop : MonoBehaviour
{
[SerializeField] private VR_Grabbable grabbable = null;
[SerializeField] private VR_DropZone dropzone = null;
private void Start()
{
grabbable.OnGrabStateChange.AddListener(OnGrabStateChange);
}
private void OnGrabStateChange(GrabState state)
{
if (state == GrabState.UnGrab)
{
dropzone.OnGrabStateChange(GrabState.Drop, grabbable, true);
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c7cde29cc97004648ac34818c98e1573
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_AutoDrop.cs
uploadId: 546658
@@ -0,0 +1,716 @@
using UnityEngine;
using System;
using VRSDK.Events;
namespace VRSDK
{
[RequireComponent(typeof(CharacterController))]
public class VR_CharacterController : MonoBehaviour, ISpeed
{
public Transform forwardTransform = null;
/// <summary>
/// The rate acceleration during movement.
/// </summary>
public float Acceleration = 0.1f;
public float AirSpeedControl = 0.5f;
/// <summary>
/// The rate of damping on movement.
/// </summary>
public float Damping = 0.3f;
/// <summary>
/// The rate of additional damping when moving sideways or backwards.
/// </summary>
public float BackAndSideDampen = 0.5f;
/// <summary>
/// The force applied to the character when jumping.
/// </summary>
public float JumpForce = 0.3f;
/// <summary>
/// The rate of rotation when using a gamepad.
/// </summary>
public float RotationAmount = 1.5f;
/// <summary>
/// The rate of rotation when using the keyboard.
/// </summary>
public float RotationRatchet = 45.0f;
/// <summary>
/// The player will rotate in fixed steps if Snap Rotation is enabled.
/// </summary>
[Tooltip("The player will rotate in fixed steps if Snap Rotation is enabled.")]
public bool SnapRotation = true;
/// <summary>
/// How many fixed speeds to use with linear movement? 0=linear control
/// </summary>
[Tooltip("How many fixed speeds to use with linear movement? 0=linear control")]
public int FixedSpeedSteps;
#if SDK_OCOLUS
/// <summary>
/// If true, reset the initial yaw of the player controller when the Hmd pose is recentered.
/// </summary>
public bool HmdResetsY = true;
/// <summary>
/// If true, tracking data from a child OVRCameraRig will update the direction of movement.
/// </summary>
public bool HmdRotatesY = true;
#endif
/// <summary>
/// Modifies the strength of gravity.
/// </summary>
public float GravityModifier = 0.379f;
#if SDK_OCULUS
/// <summary>
/// If true, each OVRPlayerController will use the player's physical height.
/// </summary>
public bool useProfileData = true;
#endif
/// <summary>
/// The CameraHeight is the actual height of the HMD and can be used to adjust the height of the character controller, which will affect the
/// ability of the character to move into areas with a low ceiling.
/// </summary>
[NonSerialized]
public float CameraHeight;
/// <summary>
/// This event is raised after the character controller is moved. This is used by the OVRAvatarLocomotion script to keep the avatar transform synchronized
/// with the OVRPlayerController.
/// </summary>
public event Action<Transform> TransformUpdated;
/// <summary>
/// This bool is set to true whenever the player controller has been teleported. It is reset after every frame. Some systems, such as
/// CharacterCameraConstraint, test this boolean in order to disable logic that moves the character controller immediately
/// following the teleport.
/// </summary>
[NonSerialized] // This doesn't need to be visible in the inspector.
public bool Teleported;
/// <summary>
/// This event is raised immediately after the camera transform has been updated, but before movement is updated.
/// </summary>
public event Action CameraUpdated;
/// <summary>
/// This event is raised right before the character controller is actually moved in order to provide other systems the opportunity to
/// move the character controller in response to things other than user input, such as movement of the HMD. See CharacterCameraConstraint.cs
/// for an example of this.
/// </summary>
public event Action PreCharacterMove;
/// <summary>
/// When true, user input will be applied to linear movement. Set this to false whenever the player controller needs to ignore input for
/// linear movement.
/// </summary>
public bool EnableLinearMovement = true;
/// <summary>
/// When true, user input will be applied to rotation. Set this to false whenever the player controller needs to ignore input for rotation.
/// </summary>
public bool EnableRotation { get; set; }
public Vector3 Velocity { get { return velocity; }
set
{
velocity = value;
}
}
#if SDK_OCULUS
public bool HmdRotatesY = true;
public bool HmdResetsY = true;
#endif
[SerializeField] private OnValueChangeEvent onPlayerRotation = null;
protected CharacterController Controller = null;
#if SDK_OCULUS
protected OVRCameraRig CameraRig = null;
private OVRPose? InitialPose;
private bool prevHatLeft = false;
private bool prevHatRight = false;
private bool HaltUpdateMovement = false;
#endif
private VR_Controller rightController = null;
private VR_Controller leftController = null;
private float MoveScale = 1.0f;
private Vector3 MoveThrottle = Vector3.zero;
private float FallSpeed = 0.0f;
public bool StopSimulation = false;
public float InitialYRotation { get; private set; }
public OnValueChangeEvent OnPlayerRotation { get { return onPlayerRotation; } }
public float Speed
{
get
{
return speed;
//return Acceleration * leftController.Input.GetJoystickInput().sqrMagnitude * Time.deltaTime;
}
}
private float MoveScaleMultiplier = 1.0f;
private float RotationScaleMultiplier = 1.0f;
private bool SkipMouseRotation = true; // It is rare to want to use mouse movement in VR, so ignore the mouse by default.
private float SimulationRate = 60f;
private float buttonRotation = 0f;
private bool ReadyToSnapTurn; // Set to true when a snap turn has occurred, code requires one frame of centered thumbstick to enable another snap turn.
private bool playerControllerEnabled = false;
private float moveInfluence = 0.0f;
public Vector3 lastPosition = Vector3.zero;
private Vector3 velocity = Vector3.zero;
private float originalGravity = 0.0f;
void Start()
{
#if SDK_OCULUS
// Add eye-depth as a camera offset from the player controller
var p = CameraRig.transform.localPosition;
p.z = OVRManager.profile.eyeDepth;
CameraRig.transform.localPosition = p;
#endif
originalGravity = GravityModifier;
}
void Awake()
{
EnableRotation = true;
Controller = gameObject.GetComponent<CharacterController>();
if (Controller == null)
Debug.LogWarning("VR_CharacterController: No CharacterController attached.");
#if SDK_OCULUS
// We use OVRCameraRig to set rotations to cameras,
// and to be influenced by rotation
OVRCameraRig[] CameraRigs = gameObject.GetComponentsInChildren<OVRCameraRig>();
if (CameraRigs.Length == 0)
Debug.LogWarning("OVRPlayerController: No OVRCameraRig attached.");
else if (CameraRigs.Length > 1)
Debug.LogWarning("OVRPlayerController: More then 1 OVRCameraRig attached.");
else
CameraRig = CameraRigs[0];
#endif
InitialYRotation = transform.rotation.eulerAngles.y;
rightController = VR_Manager.instance.Player.RightController;
leftController = VR_Manager.instance.Player.LeftController;
}
void OnEnable()
{
}
void OnDisable()
{
#if SDK_OCULUS
if (playerControllerEnabled)
{
OVRManager.display.RecenteredPose -= ResetOrientation;
if (CameraRig != null)
{
CameraRig.UpdatedAnchors -= UpdateTransform;
}
playerControllerEnabled = false;
}
#endif
}
float speed = 0.0f;
void Update()
{
if (StopSimulation)
{
lastPosition = transform.position;
FallSpeed = 0.0f;
return;
}
speed = Vector3.Distance(transform.position, lastPosition) / Time.deltaTime;
velocity = (transform.position - lastPosition) / Time.deltaTime;
lastPosition = transform.position;
#if SDK_OCULUS
if (!playerControllerEnabled)
{
if (OVRManager.OVRManagerinitialized)
{
OVRManager.display.RecenteredPose += ResetOrientation;
if (CameraRig != null)
{
CameraRig.UpdatedAnchors += UpdateTransform;
}
playerControllerEnabled = true;
}
else
return;
}
#endif
#if !UNITY_XR
//Use keys to ratchet rotation
if (Input.GetKeyDown(KeyCode.Q))
buttonRotation -= RotationRatchet;
if (Input.GetKeyDown(KeyCode.E))
buttonRotation += RotationRatchet;
#endif
#if SDK_OCULUS
UpdateController();
#endif
}
#if SDK_STEAM_VR || UNITY_XR
private void LateUpdate()
{
UpdateController();
}
#endif
private Vector3 moveDirection;
protected virtual void UpdateController()
{
#if SDK_OCULUS
if (useProfileData)
{
if (InitialPose == null)
{
// Save the initial pose so it can be recovered if useProfileData
// is turned off later.
InitialPose = new OVRPose()
{
position = CameraRig.transform.localPosition,
orientation = CameraRig.transform.localRotation
};
}
var p = CameraRig.transform.localPosition;
if (OVRManager.instance.trackingOriginType == OVRManager.TrackingOrigin.EyeLevel)
{
p.y = OVRManager.profile.eyeHeight - (0.5f * Controller.height) + Controller.center.y;
}
else if (OVRManager.instance.trackingOriginType == OVRManager.TrackingOrigin.FloorLevel)
{
p.y = -(0.5f * Controller.height) + Controller.center.y;
}
CameraRig.transform.localPosition = p;
}
else if (InitialPose != null)
{
// Return to the initial pose if useProfileData was turned off at runtime
CameraRig.transform.localPosition = InitialPose.Value.position;
CameraRig.transform.localRotation = InitialPose.Value.orientation;
InitialPose = null;
}
CameraHeight = CameraRig.centerEyeAnchor.localPosition.y;
#endif
if (CameraUpdated != null)
{
CameraUpdated();
}
UpdateMovement();
moveDirection = Vector3.zero;
float motorDamp = (1.0f + (Damping * SimulationRate * Time.deltaTime));
MoveThrottle.x /= motorDamp;
MoveThrottle.y = (MoveThrottle.y > 0.0f) ? (MoveThrottle.y / motorDamp) : MoveThrottle.y;
MoveThrottle.z /= motorDamp;
moveDirection += MoveThrottle * SimulationRate * Time.deltaTime;
// Gravity
if (Controller.isGrounded && FallSpeed <= 0)
FallSpeed = ((Physics.gravity.y * (GravityModifier * 0.002f)));
else
FallSpeed += ((Physics.gravity.y * (GravityModifier * 0.002f)) * SimulationRate * Time.deltaTime);
moveDirection.y += FallSpeed * SimulationRate * Time.deltaTime;
if (Controller.isGrounded && MoveThrottle.y <= transform.lossyScale.y * 0.001f)
{
// Offset correction for uneven ground
float bumpUpOffset = Mathf.Max(Controller.stepOffset, new Vector3(moveDirection.x, 0, moveDirection.z).magnitude);
moveDirection -= bumpUpOffset * Vector3.up;
}
if (PreCharacterMove != null)
{
PreCharacterMove();
Teleported = false;
}
Vector3 predictedXZ = Vector3.Scale((Controller.transform.localPosition + moveDirection), new Vector3(1, 0, 1));
// Move contoller
lastSpeed = moveDirection;
Controller.Move(moveDirection);
Vector3 actualXZ = Vector3.Scale(Controller.transform.localPosition, new Vector3(1, 0, 1));
if (predictedXZ != actualXZ)
MoveThrottle += (actualXZ - predictedXZ) / (SimulationRate * Time.deltaTime);
}
public Vector3 lastSpeed;
public virtual void UpdateMovement()
{
#if SDK_OCULUS
if (HaltUpdateMovement)
return;
#endif
if (EnableLinearMovement)
{
bool moveForward = false;
bool moveLeft = false;
bool moveRight = false;
bool moveBack = false;
#if !UNITY_XR
moveForward = Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow);
moveLeft = Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow);
moveRight = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);
moveBack = Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow);
#endif
bool dpad_move = false;
MoveScale = 1.0f;
if ((moveForward && moveLeft) || (moveForward && moveRight) || (moveBack && moveLeft) || (moveBack && moveRight))
MoveScale = 0.70710678f;
// No positional movement if we are in the air
if (!Controller.isGrounded)
MoveScale *= AirSpeedControl;
MoveScale *= SimulationRate * Time.deltaTime;
// Compute this for key movement
moveInfluence = Acceleration * 0.1f * MoveScale * MoveScaleMultiplier;
// Run!
#if !UNITY_XR
if (dpad_move || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
moveInfluence *= 2.0f;
#endif
Quaternion ort = forwardTransform.rotation;
Vector3 ortEuler = ort.eulerAngles;
ortEuler.z = ortEuler.x = 0f;
ort = Quaternion.Euler(ortEuler);
if (moveForward)
MoveThrottle += ort * (transform.lossyScale.z * moveInfluence * Vector3.forward);
if (moveBack)
MoveThrottle += ort * (transform.lossyScale.z * moveInfluence * BackAndSideDampen * Vector3.back);
if (moveLeft)
MoveThrottle += ort * (transform.lossyScale.x * moveInfluence * BackAndSideDampen * Vector3.left);
if (moveRight)
MoveThrottle += ort * (transform.lossyScale.x * moveInfluence * BackAndSideDampen * Vector3.right);
moveInfluence = Acceleration * 0.1f * MoveScale * MoveScaleMultiplier;
#if !UNITY_ANDROID // LeftTrigger not avail on Android game pad
moveInfluence *= 1.0f + (leftController.Input.GetButtonDown(VR_InputButton.TumbstickPress) ? 1.0f : 0.0f);
#endif
Vector2 primaryAxis = leftController.enabled? leftController.Input.GetJoystick() : Vector2.zero;
//Vector2 primaryAxis = new Vector2( Input.GetAxis("Horizontal") , Input.GetAxis("Vertical") );
if (primaryAxis.magnitude < 0.1f)
{
primaryAxis = Vector2.zero;
moveInfluence = 0.0f;
}
// If speed quantization is enabled, adjust the input to the number of fixed speed steps.
if (FixedSpeedSteps > 0)
{
primaryAxis.y = Mathf.Round(primaryAxis.y * FixedSpeedSteps) / FixedSpeedSteps;
primaryAxis.x = Mathf.Round(primaryAxis.x * FixedSpeedSteps) / FixedSpeedSteps;
}
if (primaryAxis.y > 0.0f)
MoveThrottle += ort * (primaryAxis.y * transform.lossyScale.z * moveInfluence * Vector3.forward);
if (primaryAxis.y < 0.0f)
MoveThrottle += ort * (Mathf.Abs(primaryAxis.y) * transform.lossyScale.z * moveInfluence *
BackAndSideDampen * Vector3.back);
if (primaryAxis.x < 0.0f)
MoveThrottle += ort * (Mathf.Abs(primaryAxis.x) * transform.lossyScale.x * moveInfluence *
BackAndSideDampen * Vector3.left);
if (primaryAxis.x > 0.0f)
MoveThrottle += ort * (primaryAxis.x * transform.lossyScale.x * moveInfluence * BackAndSideDampen *
Vector3.right);
}
if (rightController.Input.GetButtonDown(VR_InputButton.Primary))
Jump();
if (EnableRotation)
{
Vector3 euler = transform.rotation.eulerAngles;
float rotateInfluence = SimulationRate * Time.deltaTime * RotationAmount * RotationScaleMultiplier;
euler.y += buttonRotation;
buttonRotation = 0f;
#if !UNITY_ANDROID || UNITY_EDITOR
if (!SkipMouseRotation)
euler.y += Input.GetAxis("Mouse X") * rotateInfluence * 3.25f;
#endif
if (SnapRotation)
{
if (rightController.Input.GetJoystick().x < -0.25f)
{
if (ReadyToSnapTurn)
{
euler.y -= RotationRatchet;
ReadyToSnapTurn = false;
}
}
else if (rightController.Input.GetJoystick().x > 0.25f)
{
if (ReadyToSnapTurn)
{
euler.y += RotationRatchet;
ReadyToSnapTurn = false;
}
}
else
{
ReadyToSnapTurn = true;
}
}
else
{
Vector2 secondaryAxis = rightController.Input.GetJoystick();
euler.y += secondaryAxis.x * rotateInfluence;
}
//bool rotationChange = transform.rotation.eulerAngles != euler;
Vector3 previusFordward = transform.forward;
transform.rotation = Quaternion.Euler(euler);
Vector3 currentForward = transform.forward;
float angle = Vector2.SignedAngle(new Vector2(currentForward.x, currentForward.z), new Vector2(previusFordward.x, previusFordward.z));
if (Math.Abs(angle) > 0.0f)
{
onPlayerRotation.Invoke(angle);
}
}
}
#if SDK_OCULUS
/// <summary>
/// Invoked by OVRCameraRig's UpdatedAnchors callback. Allows the Hmd rotation to update the facing direction of the player.
/// </summary>
public void UpdateTransform(OVRCameraRig rig)
{
Transform root = CameraRig.trackingSpace;
Transform centerEye = CameraRig.centerEyeAnchor;
if (HmdRotatesY && !Teleported)
{
Vector3 prevPos = root.position;
Quaternion prevRot = root.rotation;
//transform.rotation = Quaternion.Euler(0.0f, centerEye.rotation.eulerAngles.y, 0.0f);
root.position = prevPos;
root.rotation = prevRot;
}
//UpdateController();
if (TransformUpdated != null)
{
TransformUpdated(root);
}
}
#endif
/// <summary>
/// Jump! Must be enabled manually.
/// </summary>
public bool Jump()
{
if (!Controller.isGrounded)
return false;
MoveThrottle += new Vector3(0, transform.lossyScale.y * JumpForce, 0);
return true;
}
/// <summary>
/// Stop this instance.
/// </summary>
public void Stop()
{
Controller.Move(Vector3.zero);
MoveThrottle = Vector3.zero;
FallSpeed = 0.0f;
}
/// <summary>
/// Gets the move scale multiplier.
/// </summary>
/// <param name="moveScaleMultiplier">Move scale multiplier.</param>
public void GetMoveScaleMultiplier(ref float moveScaleMultiplier)
{
moveScaleMultiplier = MoveScaleMultiplier;
}
/// <summary>
/// Sets the move scale multiplier.
/// </summary>
/// <param name="moveScaleMultiplier">Move scale multiplier.</param>
public void SetMoveScaleMultiplier(float moveScaleMultiplier)
{
MoveScaleMultiplier = moveScaleMultiplier;
}
/// <summary>
/// Gets the rotation scale multiplier.
/// </summary>
/// <param name="rotationScaleMultiplier">Rotation scale multiplier.</param>
public void GetRotationScaleMultiplier(ref float rotationScaleMultiplier)
{
rotationScaleMultiplier = RotationScaleMultiplier;
}
/// <summary>
/// Sets the rotation scale multiplier.
/// </summary>
/// <param name="rotationScaleMultiplier">Rotation scale multiplier.</param>
public void SetRotationScaleMultiplier(float rotationScaleMultiplier)
{
RotationScaleMultiplier = rotationScaleMultiplier;
}
/// <summary>
/// Gets the allow mouse rotation.
/// </summary>
/// <param name="skipMouseRotation">Allow mouse rotation.</param>
public void GetSkipMouseRotation(ref bool skipMouseRotation)
{
skipMouseRotation = SkipMouseRotation;
}
/// <summary>
/// Sets the allow mouse rotation.
/// </summary>
/// <param name="skipMouseRotation">If set to <c>true</c> allow mouse rotation.</param>
public void SetSkipMouseRotation(bool skipMouseRotation)
{
SkipMouseRotation = skipMouseRotation;
}
public void DisableGravity()
{
GravityModifier = 0.0f;
}
public void ResetGravity()
{
GravityModifier = originalGravity;
}
public void Disable()
{
enabled = false;
}
public void Enable()
{
enabled = true;
}
#if SDK_OCULUS
/// <summary>
/// Gets the halt update movement.
/// </summary>
/// <param name="haltUpdateMovement">Halt update movement.</param>
public void GetHaltUpdateMovement(ref bool haltUpdateMovement)
{
haltUpdateMovement = HaltUpdateMovement;
}
/// <summary>
/// Sets the halt update movement.
/// </summary>
/// <param name="haltUpdateMovement">If set to <c>true</c> halt update movement.</param>
public void SetHaltUpdateMovement(bool haltUpdateMovement)
{
HaltUpdateMovement = haltUpdateMovement;
}
public void ResetOrientation()
{
if (HmdResetsY && !HmdRotatesY)
{
Vector3 euler = transform.rotation.eulerAngles;
euler.y = InitialYRotation;
transform.rotation = Quaternion.Euler( euler );
}
}
#endif
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7cc308fb95a65c54b88a187089c5a790
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_CharacterController.cs
uploadId: 546658
@@ -0,0 +1,81 @@
using UnityEngine;
using System.Collections.Generic;
namespace VRSDK
{
public class VR_ColorHiglight : VR_Highlight
{
[SerializeField] private Color highlightColor = Color.black;
private MeshRenderer[] meshRenderArray = null;
private Dictionary<MeshRenderer, Color[]> meshRenderDic = new Dictionary<MeshRenderer, Color[]>();
protected override void Awake()
{
base.Awake();
meshRenderArray = GetComponentsInChildren<MeshRenderer>();
for (int j = 0; j < meshRenderArray.Length; j++)
{
Color[] colorArray = new Color[ meshRenderArray[j].materials.Length ];
for (int k = 0; k < meshRenderArray[j].materials.Length; k++)
{
colorArray[k] = meshRenderArray[j].materials[k].color;
}
meshRenderDic[meshRenderArray[j]] = colorArray;
}
}
public override void Highlight(VR_Controller controller)
{
base.Highlight( controller );
OverrideColor( highlightColor );
}
private void OverrideColor(Color c)
{
for (int j = 0; j < meshRenderArray.Length; j++)
{
if (meshRenderArray[j] != null)
{
for (int k = 0; k < meshRenderArray[j].materials.Length; k++)
{
meshRenderArray[j].materials[k].color = c;
}
}
}
}
public override void UnHighlight(VR_Controller controller)
{
base.UnHighlight( controller );
SetOriginalColor();
}
private void SetOriginalColor()
{
for (int j = 0; j < meshRenderArray.Length; j++)
{
if (meshRenderArray[j] != null)
{
for (int k = 0; k < meshRenderArray[j].materials.Length; k++)
{
meshRenderArray[j].materials[k].color = meshRenderDic[meshRenderArray[j]][k];
}
}
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: cfe652668d012d14b827f0d506817aaf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_ColorHiglight.cs
uploadId: 546658
@@ -0,0 +1,633 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
#if SDK_STEAM_VR
using Valve.VR;
#endif
namespace VRSDK
{
public enum VR_ControllerType
{
Left,
Right
}
public enum MotionControlMode
{
Free,
Engine
}
/// class to asbtrac controller input
public class VR_Controller : MonoBehaviour
{
#region INSPECTOR
[SerializeField] private Transform grabPoint = null;
[SerializeField] private Rigidbody grabPointRB = null;
[SerializeField] private VR_ControllerType controllerType = VR_ControllerType.Right;
[SerializeField] protected Animator animator = null;
[SerializeField] protected AnimationClip defaultInteractAnimationClip = null;
[SerializeField] private GameObject handGO = null;
[SerializeField] private VR_DistanceGrab distanceGrab = null;
#endregion
#region PUBLIC
public Transform GrabPoint { get { return grabPoint; } }
public Vector3 Position { get { return transform.position; } }
public Quaternion Rotation { get { return transform.rotation; } }
public VR_Grabbable CurrentGrab { get { return currentGrab; } private set { currentGrab = value; } }
public Vector3 AngularVelocity { get { return handPhysics.AngularVelocity; } }
public Vector3 Velocity { get { return handPhysics.Velocity; } }
public VR_ControllerType ControllerType { get { return controllerType; } }
public VR_ControllerGesture GestureScript { get { return gestureScript; } }
public OnJointBreakListener OnJointBreakListener
{
get
{
if (onJointBreakListener == null) onJointBreakListener = FindJointBreakListener();
return onJointBreakListener;
}
}
public Animator Animator { get { return animator; } }
public virtual Vector3 PositionOffset
{
set
{
positionOffset = value;
if (UsePositionOffset && controlPositionMode == MotionControlMode.Engine)
{
transform.localPosition = initialPosition + value;
}
}
get { return positionOffset; }
}
public virtual Quaternion RotationOffset
{
set
{
rotationOffset = value;
if (UseRotationOffset && controlRotationMode == MotionControlMode.Engine)
{
transform.localRotation = initialRotation * value;
}
}
get { return rotationOffset; }
}
public MotionControlMode ControlPositionMode { get { return controlPositionMode; } }
public MotionControlMode ControlRotationMode { get { return controlRotationMode; } }
public Transform OriginalParent { get { return originalParent; } }
public Collider Collider { get { return thisCollider; } }
public bool UsePositionOffset { get; set; }
public bool UseRotationOffset { get; set; }
public Vector3 InitialPosition { get { return initialPosition; } }
public VR_InputDevice Input { get; private set; }
public Rigidbody GrabPointRB
{
get
{
if (grabPointRB == null)
{
var rb = grabPoint.gameObject.GetOrAddComponent<Rigidbody>();
grabPointRB = rb;
}
return grabPointRB;
}
}
public VR_DistanceGrab DistanceGrab { get => distanceGrab; }
#endregion
#region PRIVATE
private bool initialized = false;
private HandPhysics handPhysics = null;
private Vector3 initialPosition = Vector3.zero;
protected Quaternion initialRotation = Quaternion.identity;
private List<VR_Interactable> interactList = null;
private List<VR_Highlight> highlightList = null;
protected VR_Grabbable currentGrab = null;
private VR_Highlight currentHighlight = null;
private OnJointBreakListener onJointBreakListener = null;
protected AnimatorOverrideController overrideAnimator = null;
private VR_ControllerGesture gestureScript = null;
private Transform originalParent = null;
protected string currentInteractAnimationName = null;
protected MotionControlMode controlPositionMode = MotionControlMode.Engine;
protected MotionControlMode controlRotationMode = MotionControlMode.Engine;
private Collider thisCollider = null;
protected Vector3 positionOffset = Vector3.zero;
protected Quaternion rotationOffset = Quaternion.identity;
private VR_Grabbable activeDistanceGrabbable = null;
private VR_Highlight activeDistanceHighlight = null;
private HistoryBuffer historyBuffer = null;
private VR_Controller otherController
{
get
{
if (controllerType == VR_ControllerType.Right)
return VR_Manager.instance.Player.LeftController;
else
return VR_Manager.instance.Player.RightController;
}
}
#endregion
private const int historySize = 20;
#region ANIMATION_HASHES
private int isGrabbingHash = -1;
#endregion
protected virtual void Awake()
{
FindOrCreate_VR_Manager();
Initialize();
GetComponents();
SetupInputDevice();
if (animator != null)
{
CreateOverrideAnimator();
SetupAnimatorHashes();
}
}
private void FindOrCreate_VR_Manager()
{
if (FindObjectOfType<VR_Manager>() == null)
{
Debug.LogError("you need a VR_Manager active in the scene in order to use VR Shooter Kit");
}
}
private void SetupInputDevice()
{
if (VR_Manager.instance.CurrentSDK == VR_SDK.Oculus)
{
Input = new VR_OculusInput(this);
}
else if (VR_Manager.instance.CurrentSDK == VR_SDK.Steam_VR)
{
Input = new VR_SteamVRInput(this);
}
else if (VR_Manager.instance.CurrentSDK == VR_SDK.UnityXR)
{
Input = new VR_XRInput(this);
}
}
private void Initialize()
{
UsePositionOffset = true;
UseRotationOffset = true;
controlPositionMode = MotionControlMode.Engine;
controlRotationMode = MotionControlMode.Engine;
SaveLocalPositionAndRotation();
originalParent = transform.parent;
}
private void GetComponents()
{
gestureScript = gameObject.GetOrAddComponent<VR_ControllerGesture>();
thisCollider = GetComponent<Collider>();
}
protected virtual void Start()
{
historyBuffer = transform.parent.GetComponent<HistoryBuffer>();
handPhysics = new HandPhysics( historyBuffer );
}
protected virtual void CreateOverrideAnimator()
{
if (animator == null)
return;
//create override animator controller so we can change the grab animations at running time
overrideAnimator = new AnimatorOverrideController( animator.runtimeAnimatorController );
animator.runtimeAnimatorController = overrideAnimator;
currentInteractAnimationName = defaultInteractAnimationClip.name;
}
protected virtual void SetupAnimatorHashes()
{
isGrabbingHash = Animator.StringToHash( "IsGrabbing" );
}
private void SaveLocalPositionAndRotation()
{
//we save this for recentering controllers back later
initialPosition = transform.localPosition;
initialRotation = transform.localRotation;
}
private OnJointBreakListener FindJointBreakListener()
{
OnJointBreakListener listener = grabPoint.GetComponent<OnJointBreakListener>();
if (listener == null)
listener = grabPoint.gameObject.AddComponent<OnJointBreakListener>();
return listener;
}
protected virtual void Update()
{
UpdateHighlightState();
if (animator != null) UpdateAnimator();
}
private void UpdateHighlightState()
{
if (CanHighlight())
{
VR_Highlight highlight = FindNearHighlight();
//if we lost the nearest object
if (highlight == null && currentHighlight != null)
{
currentHighlight.UnHighlight( this );
currentHighlight = null;
}
//if we found a new object and we dont have highlight
if (currentHighlight == null && highlight != null)
{
currentHighlight = highlight;
highlight.Highlight( this );
}
//if we found a new closer object
else if (highlight != null && highlight != currentHighlight)
{
currentHighlight.UnHighlight( this );
highlight.Highlight( this );
currentHighlight = highlight;
}
//update the current higlight object, be sure that it is always on
else if (highlight != null && currentHighlight == highlight && !currentHighlight.IsHighlight)
{
currentHighlight.Highlight( this );
}
}
else if (currentHighlight != null)
{
currentHighlight.UnHighlight( this );
currentHighlight = null;
}
}
protected virtual void UpdateAnimator()
{
if (animator.gameObject.activeInHierarchy)
animator.SetBool( isGrabbingHash, currentGrab != null );
}
private bool CanHighlight()
{
return currentGrab == null;
}
//change the interact animation in running time
public void OverrideInteractAnimation(AnimationClip animation)
{
if (animator == null)
return;
if (overrideAnimator == null)
{
CreateOverrideAnimator();
}
overrideAnimator[currentInteractAnimationName] = animation;
}
//back to the default grab animation
public void SetDefaultInteractAnimation()
{
if (animator == null)
return;
if (overrideAnimator == null)
{
CreateOverrideAnimator();
}
overrideAnimator[currentInteractAnimationName] = defaultInteractAnimationClip;
}
public void ApplyThrowVelocity(VR_Grabbable grabbable)
{
handPhysics.ApplyThrowVelocity(grabbable);
}
public void Recenter()
{
PositionOffset = Vector3.zero;
RotationOffset = Quaternion.identity;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="controllerType"></param>
/// <param name="grabbableList"></param>
public void Construct(ControllerGestureConfig config)
{
if (initialized) return;
initialized = true;
//set controller type and get a refenrece to the grabbableList
this.interactList = VR_Manager.instance.InteractList;
this.highlightList = VR_Manager.instance.HighlightList;
VR_ControllerGesture controllerGesture = GetComponent<VR_ControllerGesture>();
if (controllerGesture != null)
controllerGesture.Construct(config);
}
public void InteractWithNearesObject()
{
//we have something grabbe we should no interact
if (currentGrab != null)
return;
SetDefaultInteractAnimation();
//get the near interact object to this controller
VR_Interactable interact = FindNearInteract();
if (interact == null && activeDistanceGrabbable != null && (activeDistanceGrabbable != otherController.activeDistanceGrabbable || !ThereIsNearbyControllerInteraction(activeDistanceGrabbable)))
{
interact = activeDistanceGrabbable as VR_Interactable;
}
if (interact != null && interact.enabled && interact.CanInteractUsingController( this ))
{
VR_HandAnimationSettings settings = interact.GetHandAnimationSettings( this );
ProcessAnimationSettings( settings );
ProcessInteraction( interact );
}
}
private bool ThereIsNearbyControllerInteraction(VR_Interactable interactable)
{
if (!otherController.Input.GetButtonDown( interactable.InteractButton ))
{
return false;
}
float thisDistance = CalculateDistanceToInteractable(this , interactable );
float otherDistance = CalculateDistanceToInteractable( otherController, interactable );
return thisDistance > otherDistance;
}
private float CalculateDistanceToInteractable(VR_Controller controller , VR_Interactable interactable)
{
return Vector3.Distance( controller.OriginalParent.position , interactable.transform.position );
}
private void ProcessAnimationSettings(VR_HandAnimationSettings settings)
{
if (animator != null && settings != null && settings.animation != null)
{
//override the grabbing animation
OverrideInteractAnimation( settings.animation );
}
}
private void ProcessInteraction(VR_Interactable interact)
{
interact.Interact( this );
if (interact is VR_Grabbable)
{
currentGrab = interact as VR_Grabbable;
}
}
//force a grab no distance check, and drop whathever you have on the hand
public void ForceGrab(VR_Grabbable grabbable)
{
if (grabbable == null)
return;
if (currentGrab != null)
CleanCurrentGrab();
currentGrab = grabbable;
currentGrab.OnGrabSuccess( this );
}
public void CleanCurrentGrab()
{
currentGrab = null;
}
public List<Quaternion> GetRotationHistorySample(int sampleCount)
{
if (historyBuffer == null)
return null;
//return rotationHistory.GetRange( 0, sampleCount > rotationHistory.Count ? rotationHistory.Count : sampleCount);
return historyBuffer.RotationHistory.Sample(sampleCount);
}
/// <summary>
/// Find the near avalible grabbable to this controller
/// </summary>
/// <returns></returns>
private VR_Interactable FindNearInteract()
{
if (interactList.Count == 0)
return null;
VR_Interactable interact = null;
float minDistance = float.MaxValue;
for (int n = 0; n < interactList.Count; n++)
{
if (interactList[n].enabled && interactList[n].CanInteract && interactList[n].CanInteractUsingController( this ))
{
Transform highlightPoint = ( ControllerType == VR_ControllerType.Right ? interactList[n].HighlightPointRightHand : interactList[n].HighlightPointLeftHand );
if (highlightPoint != null)
{
float d = ( Position - highlightPoint.position ).magnitude;
if (d < minDistance && CanInteractWithInteractable(interactList[n], d))
{
interact = interactList[n];
minDistance = d;
}
}
}
}
return interact;
}
private bool CanInteractWithInteractable(VR_Interactable interactable, float distance)
{
if (interactable == null) return false;
if (interactable.InteractableType == InteractableType.Collider)
{
if (interactable.GrabCollider == null)
return false;
Vector3 closestPoint = interactable.GrabCollider.ClosestPoint(Position);
return (Position - closestPoint).magnitude < Mathf.Epsilon;
}
else if (interactable.InteractableType == InteractableType.Distance)
{
return interactable.InteractDistance >= distance;
}
return false;
}
/// <summary>
/// Find the near avalible grabbable to this controller
/// </summary>
/// <returns></returns>
private VR_Highlight FindNearHighlight()
{
if (highlightList.Count == 0)
return null;
VR_Highlight highlight = null;
float minDistance = float.MaxValue;
for (int n = 0; n < highlightList.Count; n++)
{
if (highlightList[n].enabled && highlightList[n].CanHighlight() && highlightList[n].CanHighlightUsingController( this ))
{
Transform highlightPoint = ControllerType == VR_ControllerType.Right ? highlightList[n].HighlightPointRightHand : highlightList[n].HighlightPointLeftHand;
if (highlightPoint != null)
{
float d = ( Position - highlightPoint.position ).magnitude;
if (d < minDistance && CanInteractWithInteractable(highlightList[n].Interactable, d))
{
highlight = highlightList[n];
minDistance = d;
}
}
}
}
if (highlight == null)
{
highlight = activeDistanceHighlight;
}
else if(activeDistanceHighlight != null)
{
activeDistanceHighlight.UnHighlight(this);
}
return highlight;
}
//should the position be controller by the engine or you want to control it manually,
//useful for snap the hand to certain positions
public void SetPositionControlMode(MotionControlMode controlMode)
{
controlPositionMode = controlMode;
transform.SetParent( controlMode == MotionControlMode.Free ? null : originalParent);
if (controlMode == MotionControlMode.Engine)
{
transform.localPosition = initialPosition;
transform.localRotation = initialRotation;
}
}
public void SetRotationControlMode(MotionControlMode controlMode)
{
controlRotationMode = controlMode;
}
public void SetPositionAndRotationControlMode(MotionControlMode positionControlMode , MotionControlMode rotationControlMode)
{
SetPositionControlMode(positionControlMode);
SetRotationControlMode(rotationControlMode);
}
public void SetVisibility(bool visibility)
{
if (handGO == null) return;
handGO.SetActive(visibility);
}
public void SetActiveDistanceGrabbable(VR_Grabbable grabbable)
{
activeDistanceGrabbable = grabbable;
if(activeDistanceHighlight != null)
activeDistanceHighlight.UnHighlight( this );
if (grabbable != null)
{
activeDistanceHighlight = grabbable.GetComponent<VR_Highlight>();
}
else
{
activeDistanceHighlight = null;
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d5313a95efbf5484f8a1269d74bf3fe4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Controller.cs
uploadId: 546658
@@ -0,0 +1,131 @@
using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using VRSDK.Events;
namespace VRSDK
{
public enum GesturePhase
{
Tracking,
Processing
}
//this script read gestures in the controller
//like a rotation a certain speed and angles
//this is being use for the weapon system for physics base reload, is beinguse in the revolver
public class VR_ControllerGesture : MonoBehaviour
{
private float minAcelerationThreshold = 0.0f;
private float maxAcelerationThreshold = 0.0f;
private int sampleCount = 0;
private VR_Controller controller = null;
private GesturePhase rotationGesturePhase = GesturePhase.Tracking;
private Quaternion rotationGesturefromQuaternion = Quaternion.identity;
private OnRotationGestureEvent OnRotationGestureEvent = new OnRotationGestureEvent();
private const int MAX_SAMPLING_HISTORY = 30;
private void Awake()
{
controller = GetComponent<VR_Controller>();
}
public void Construct(ControllerGestureConfig config)
{
minAcelerationThreshold = config.minAcelerationThreshold;
maxAcelerationThreshold = config.maxAcelerationThreshold;
}
private void Update()
{
UpdateRotationGesture();
}
// set a listener for a rotation gesture
public void ListenForRotationGesture(UnityAction<RotationGestureInfo> listener)
{
OnRotationGestureEvent.AddListener(listener);
}
//remove listener for a rotation gesture
public void RemoveRotationGestureListener(UnityAction<RotationGestureInfo> listener)
{
OnRotationGestureEvent.RemoveListener(listener);
}
private void UpdateRotationGesture()
{
switch (rotationGesturePhase)
{
case GesturePhase.Tracking:
RotationGestureTrackingUpdate();
break;
case GesturePhase.Processing:
RotationGestureProcessingUpdate();
break;
}
}
private void RotationGestureTrackingUpdate()
{
List<Quaternion> rotationHistory = GetRotationHistory();
if (rotationHistory == null || rotationHistory.Count <= 0)
return;
float rotAceleration = Quaternion.Angle( rotationHistory[0], rotationHistory[rotationHistory.Count - 1] );
//detect a fast rotation movement
if (rotAceleration > maxAcelerationThreshold)
{
rotationGesturePhase = GesturePhase.Processing;
}
}
private List<Quaternion> GetRotationHistory()
{
List<Quaternion> rotationHistory = controller.GetRotationHistorySample( MAX_SAMPLING_HISTORY );
return rotationHistory;
}
private void RotationGestureProcessingUpdate()
{
List<Quaternion> rotationHistory = GetRotationHistory();
if (rotationHistory == null || rotationHistory.Count <= 0)
return;
float rotAceleration = Quaternion.Angle( rotationHistory[0], rotationHistory[rotationHistory.Count - 1] );
//wait for the hand to stop
if (rotAceleration < minAcelerationThreshold)
{
OnRotationGestureEvent.Invoke( new RotationGestureInfo( rotationGesturefromQuaternion , rotationHistory[rotationHistory.Count - 1] ) );
rotationGesturePhase = GesturePhase.Tracking;
}
}
}
public class RotationGestureInfo
{
public Quaternion from;
public Quaternion to;
public RotationGestureInfo(Quaternion from , Quaternion to)
{
this.from = from;
this.to = to;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d132dc2cd22a34046bb10aa0e41d27bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_ControllerGesture.cs
uploadId: 546658
@@ -0,0 +1,234 @@
using System;
using UnityEngine;
namespace VRSDK
{
public class VR_DistanceGrab : MonoBehaviour
{
[SerializeField] private Transform pointerTransform = null;
[SerializeField] private float grabDistance = 5.0f;
[SerializeField] private float grabRadius = 0.2f;
[SerializeField] private bool checkForObstruction = false;
[SerializeField] private bool guideLineAlwaysVisible = false;
[SerializeField] private bool canTriggerLineRender = false;
[SerializeField] private VR_InputButton lineTriggerInput = VR_InputButton.Trigger;
[SerializeField] private LineRenderer lineRender = null;
[SerializeField] private LayerMask layerMask = new LayerMask();
private VR_Controller controller = null;
private VR_Grabbable activeGrabbable = null;
private Collider thisCollider = null;
public Ray GrabbableRay { get { return new Ray( pointerTransform.position , pointerTransform.forward ); } }
private void Awake()
{
controller = GetComponent<VR_Controller>();
thisCollider = GetComponent<Collider>();
}
private void Update()
{
if (controller.CurrentGrab != null)
{
if (activeGrabbable != null)
{
activeGrabbable.RemoveActiveDistanceGrabController( controller );
SetActiveGrabbable(null);
}
return;
}
//get the closer intersection grabbable
VR_Grabbable closerGrabbable = GrabbableRaycast();
if (closerGrabbable == null)
{
if (activeGrabbable != null)
{
activeGrabbable.RemoveActiveDistanceGrabController(controller);
}
SetActiveGrabbable( null );
return;
}
if (closerGrabbable != null && activeGrabbable == null)
{
SetActiveGrabbable(closerGrabbable);
activeGrabbable.AddActiveDistanceGrabController(controller);
}
else if (closerGrabbable != null && activeGrabbable != null && activeGrabbable != closerGrabbable)
{
activeGrabbable.RemoveActiveDistanceGrabController( controller );
activeGrabbable = closerGrabbable;
activeGrabbable.AddActiveDistanceGrabController( controller );
controller.SetActiveDistanceGrabbable(activeGrabbable);
}
else if (closerGrabbable == null && activeGrabbable != null)
{
activeGrabbable.RemoveActiveDistanceGrabController(controller);
SetActiveGrabbable( null );
}
}
private VR_Grabbable GrabbableRaycast()
{
RaycastHit[] hitArray = Physics.SphereCastAll( GrabbableRay, grabRadius, grabDistance, layerMask, QueryTriggerInteraction.Ignore);
float minDistance = Mathf.Infinity;
VR_Grabbable closerGrabbable = null;
RaycastHit closerHitInfo = new RaycastHit();
for (int n = 0; n < hitArray.Length; n++)
{
float d = hitArray[n].distance;
VR_Grabbable grabbable = VR_Manager.instance.GetGrabbableFromCollider( hitArray[n].collider );
if (d < minDistance && IsValidGrabbableRaycast( hitArray[n] ))
{
minDistance = d;
closerGrabbable = grabbable;
closerHitInfo = hitArray[n];
}
}
if ( ShouldCheckForObstruction(closerGrabbable) )
{
Collider col = GetFirstColliderIntersection( pointerTransform.position, ( closerHitInfo.point - pointerTransform.position ).normalized );
if (col != closerHitInfo.collider)
{
return null;
}
}
return closerGrabbable;
}
private bool ShouldCheckForObstruction(VR_Grabbable closerGrabbable)
{
return closerGrabbable != null && checkForObstruction;
}
private void LateUpdate()
{
if ( !HasSomethingToGrab() )
{
if ( ShouldRenderLineForward() )
{
RenderLineForward();
}
else
{
ClearLineRender();
}
return;
}
RenderLineToActiveGrabbable();
}
private bool HasSomethingToGrab()
{
return activeGrabbable != null;
}
private bool ShouldRenderLineForward()
{
return controller.CurrentGrab == null && ( guideLineAlwaysVisible || ( canTriggerLineRender && controller.Input.GetButton( lineTriggerInput ) ) );
}
private void RenderLineForward()
{
lineRender.useWorldSpace = false;
lineRender.positionCount = 2;
lineRender.SetPosition( 0, Vector3.zero );
lineRender.SetPosition( 1, Vector3.forward * ( grabDistance / transform.localScale.z ) );
}
private void OnDisable()
{
if (lineRender != null)
{
lineRender.enabled = false;
}
}
private void OnEnable()
{
if (lineRender != null)
{
lineRender.enabled = true;
}
}
private void RenderLineToActiveGrabbable()
{
Transform lineEnd = GetLineEndTransform();
if (lineEnd == null)
return;
lineRender.useWorldSpace = true;
lineRender.positionCount = 2;
lineRender.SetPosition( 0, pointerTransform.position );
lineRender.SetPosition( 1, lineEnd.position );
}
private Transform GetLineEndTransform()
{
Transform lineEnd = activeGrabbable.GetHandInteractionSettings(controller).highlightPoint;
if (lineEnd == null)
lineEnd = activeGrabbable.GetHandInteractionSettings(controller).interactPoint;
return lineEnd;
}
private void ClearLineRender()
{
lineRender.positionCount = 0;
}
private Collider GetFirstColliderIntersection(Vector3 origin , Vector3 dir)
{
RaycastHit hitInfo;
if (Physics.Raycast( origin, dir, out hitInfo, grabDistance , layerMask , QueryTriggerInteraction.Ignore))
return hitInfo.collider;
return null;
}
private bool IsValidGrabbableRaycast(RaycastHit hitInfo)
{
VR_Grabbable grabbable = VR_Manager.instance.GetGrabbableFromCollider(hitInfo.collider);
return hitInfo.collider != thisCollider && grabbable != null && grabbable.enabled && grabbable.UseDistanceGrab && grabbable.CurrentGrabState == GrabState.UnGrab;
}
private void SetActiveGrabbable(VR_Grabbable grabbable)
{
activeGrabbable = grabbable;
controller.SetActiveDistanceGrabbable( grabbable );
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 531a31c60e40e184396d09e60629788e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_DistanceGrab.cs
uploadId: 546658
@@ -0,0 +1,715 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using VRSDK.Events;
namespace VRSDK
{
public enum DropZoneMode
{
Collider,
Distance
}
//this script handles the dropzones
public class VR_DropZone : MonoBehaviour
{
[SerializeField] private DropZoneMode dropZoneMode = DropZoneMode.Distance;
[SerializeField] private Transform dropPoint = null;
[SerializeField] private Collider[] dropZoneColliderArray = new Collider[2];
[SerializeField] private VR_Grabbable startingDrop = null;
[SerializeField] private bool shouldFly = false;
[SerializeField] private float flyTime = 0.1f;
[SerializeField] private bool syncronizePosition = true;
[SerializeField] private bool syncronizeRot = true;
[SerializeField] private bool disableCollidersOnDrop = false;
[SerializeField] private float dropRadius = 0.0f;
[SerializeField] private bool usePreview = false;
[SerializeField] private bool canStack = true;
[SerializeField] private OnDropStateChangeEvent onDrop = null;
[SerializeField] private OnDropStateChangeEvent onUndrop = null;
[SerializeField] private List<VR_Grabbable> insideCollider = new List<VR_Grabbable>();
[SerializeField] private List<VR_Grabbable> trackedGrabbable = new List<VR_Grabbable>();
private List<VR_Grabbable> grabbableList = new List<VR_Grabbable>();
private List<VR_Grabbable> droppedGrabbableList = new List<VR_Grabbable>();
private VR_TagFilter tagFilter = null;
private GameObject preview = null;
private GameObject previewOwner = null;
private Material transparentMat = null;
private Dictionary<VR_Grabbable , UnityAction<GrabState>> onGrabStateChangeConnections = new Dictionary<VR_Grabbable, UnityAction<GrabState>>();
private Dictionary<VR_Grabbable, UnityAction<GrabState>> onGrabStateChangeTrackConnections = new Dictionary<VR_Grabbable, UnityAction<GrabState>>();
private VR_Controller rightController = null;
private VR_Controller leftController = null;
public VR_Grabbable StartingDrop { get { return startingDrop; } }
public Transform DropPoint { get { return dropPoint; } }
public OnDropStateChangeEvent OnDrop { get { return onDrop; } }
public OnDropStateChangeEvent OnUnDrop { get { return onUndrop; } }
public float FlyTime { get { return flyTime; } }
public bool ShouldFly { get { return shouldFly; } }
public List<VR_Grabbable> DroppedGrabbableList { get { return droppedGrabbableList; } }
public bool IsEmpty { get { return droppedGrabbableList.Count == 0; } }
public bool debugMode = false;
private void Awake()
{
//get the tag filter if we have one, this help us know what objects can be dropped in this dropzone
tagFilter = GetComponent<VR_TagFilter>();
//load the transparent material, just in case we want to use preview mode
transparentMat = Resources.Load( "TransparentMaterial" ) as Material;
//set initial drop grabbable
if (startingDrop != null)
{
OnGrabStateChange( GrabState.Drop, startingDrop );
}
onDrop.AddListener(OnThisDropStateChange);
}
private void Start()
{
grabbableList = VR_Manager.instance.GrabbableList;
rightController = VR_Manager.instance.Player.RightController;
leftController = VR_Manager.instance.Player.LeftController;
}
private void OnColliderGrabbableEnter(VR_Grabbable grabbable)
{
if (grabbable != null && !insideCollider.Contains( grabbable ))
{
insideCollider.Add(grabbable);
}
}
private void OnColliderGrabbableExit(VR_Grabbable grabbable)
{
if (grabbable != null && insideCollider.Contains( grabbable ))
{
insideCollider.Remove( grabbable );
}
}
private void OnThisDropStateChange(VR_Grabbable grabbable)
{
if (grabbable == null || !disableCollidersOnDrop)
return;
Collider[] collideraArray = grabbable.GetComponentsInChildren<Collider>();
for (int n = 0; n < collideraArray.Length; n++)
{
collideraArray[n].enabled = false;
}
}
private void Update()
{
RemoveEmptyFromDroppedList();
ProcessGrabbableList();
if (dropZoneMode == DropZoneMode.Collider)
{
UpdateColliderDropzone();
}
}
private void UpdateColliderDropzone()
{
VR_Grabbable rightGrabbable = VR_Manager.instance.Player.RightController.CurrentGrab;
VR_Grabbable leftGrabbable = VR_Manager.instance.Player.LeftController.CurrentGrab;
foreach (var collider in dropZoneColliderArray)
{
UpdateGrabbableDropState(collider, rightGrabbable, rightController.Position);
UpdateGrabbableDropState(collider, leftGrabbable, leftController.Position);
}
}
private void UpdateGrabbableDropState(Collider collider, VR_Grabbable grabbable, Vector3 handPosition)
{
if(collider == null || grabbable == null) return;
Vector3 closestPoint = collider.ClosestPoint(handPosition);
if ((handPosition - closestPoint).magnitude < Mathf.Epsilon)
{
OnColliderGrabbableEnter(grabbable);
}
else
{
OnColliderGrabbableExit(grabbable);
}
}
private void RemoveEmptyFromDroppedList()
{
for (int n = 0; n < droppedGrabbableList.Count; n++)
{
if (droppedGrabbableList[n] == null)
{
droppedGrabbableList.RemoveAt( n );
n--;
}
}
}
private void ProcessGrabbableList()
{
for (int n = 0; n < grabbableList.Count; n++)
{
if (grabbableList[n].CanUseDropZone)
{
ProccessGrabbable( grabbableList[n] );
}
}
}
private void ProccessGrabbable(VR_Grabbable grabbable)
{
if (!IsGrabbableTagValid( grabbable ))
{
return;
}
bool insideRange = IsInsideDropRange(grabbable);
//if the we dont have any object dropped and we are in range
if (insideRange && CanDropGrabbable( grabbable ))
{
HandleGrabbableEnterDropzone(grabbable);
}
//if the object is outside range and we was tracking it
else if (!insideRange && trackedGrabbable.Contains( grabbable ))
{
OnGrabbableExit( grabbable );
}
}
/// <summary>
/// can this grabbable be dropped in the dropzone?
/// </summary>
private bool IsGrabbableTagValid(VR_Grabbable grabbable)
{
if (droppedGrabbableList.Count > 0)
{
bool canStack = CanStackThisGrabbable( grabbable );
return canStack;
}
//if we have a tagfilter and the grabbable dont has a VR_Tag component
if (tagFilter != null && grabbable.GrabbableTag == null)
return false;
//if we have a tagfilter and the tag of the grabbable dont match in the tag filter ignore it
if (grabbable.GrabbableTag != null && tagFilter != null && !tagFilter.Check( grabbable.GrabbableTag.TagEnum ))
return false;
return true;
}
private bool CanStackThisGrabbable(VR_Grabbable grabbable)
{
if (droppedGrabbableList.Count == 0)
return true;
if (!canStack)
{
return false;
}
VR_Grabbable droppedGrabbble = droppedGrabbableList[0];
if (droppedGrabbble.GrabbableTag == null || grabbable.GrabbableTag == null)
return false;
//you can just stack objects that are of the same type
return droppedGrabbble.GrabbableTag.TagEnum == grabbable.GrabbableTag.TagEnum;
}
private bool IsInsideDropRange(VR_Grabbable grabbable)
{
bool insideRange = false;
if (dropZoneMode == DropZoneMode.Distance)
{
float distance = ( grabbable.transform.position - dropPoint.position ).magnitude;
insideRange = distance < dropRadius;
}
else
{
insideRange = insideCollider.Contains( grabbable );
}
return insideRange;
}
private bool CanDropGrabbable(VR_Grabbable grabbable)
{
if (grabbable == null || grabbable.GetComponent<BlockDrop>() != null)
return false;
return droppedGrabbableList.Count == 0 || CanStackThisGrabbable(grabbable);
}
private void HandleGrabbableEnterDropzone(VR_Grabbable grabbable)
{
//if the current grabbable is no being affected by any other dropzones juts call to grabbable enter
if (grabbable.AffectedDropZone == null)
{
OnGrabbableEnter( grabbable );
}
//if the grabbable is being affected by any other dropzone
else if (grabbable.AffectedDropZone != this && ShouldUpdateAffectedDropZone(grabbable) )
{
grabbable.AffectedDropZone.OnGrabbableExit( grabbable );
OnGrabbableEnter( grabbable );
}
}
public void OnGrabbableExit(VR_Grabbable grabbable)
{
if (grabbable != null && droppedGrabbableList.Contains(grabbable) )
{
Transform parent = grabbable.transform.parent;
grabbable.transform.parent = null;
grabbable.transform.localScale = CalculateOriginalScale( grabbable );
grabbable.transform.parent = parent;
}
if (grabbable.AffectedDropZone == this)
{
grabbable.AffectedDropZone = null;
}
StopTrackingGrabbable( grabbable );
if (previewOwner != null && previewOwner.gameObject == grabbable.gameObject)
{
DestroyPreview( grabbable );
VR_Grabbable closerGrabbable = GetCloserGrabbable();
if (closerGrabbable != null)
{
CreatePreviewFor( closerGrabbable );
}
}
}
private VR_Grabbable GetCloserGrabbable()
{
float minDistance = float.MaxValue;
VR_Grabbable closerGrabbable = null;
for (int n = 0; n < trackedGrabbable.Count; n++)
{
float d = Vector3.Distance( trackedGrabbable[n].transform.position , dropPoint.position );
if (d < minDistance)
{
closerGrabbable = trackedGrabbable[n];
minDistance = d;
}
}
return closerGrabbable;
}
private Vector3 CalculateOriginalScale(VR_Grabbable grabbable)
{
DropZoneInfo info = grabbable.GetComponent<DropZoneInfo>();
return info == null ? grabbable.transform.localScale : info.OriginalScale ;
}
private void StopTrackingGrabbable(VR_Grabbable grabbable)
{
if (grabbable != null && trackedGrabbable.Contains( grabbable ))
{
trackedGrabbable.Remove( grabbable );
grabbable.OnGrabStateChange.RemoveListener( onGrabStateChangeTrackConnections[grabbable] );
onGrabStateChangeTrackConnections.Remove(grabbable);
}
}
private void DestroyPreview(VR_Grabbable grabbable)
{
if (previewOwner == grabbable.gameObject)
Destroy( preview );
}
private bool ShouldUpdateAffectedDropZone(VR_Grabbable grabbable)
{
float distanceToThisDropZone = ( grabbable.transform.position - dropPoint.position ).magnitude;
float distanceToOtherDropzone = ( grabbable.AffectedDropZone.DropPoint.position - grabbable.transform.position ).magnitude;
return distanceToThisDropZone < distanceToOtherDropzone - 0.001f;
}
public void OnGrabbableEnter(VR_Grabbable grabbable, bool force = false)
{
if (force)
{
ProcessDrop(grabbable);
}
if (( grabbable != null && grabbable.CurrentGrabState == GrabState.Grab ) || force)
{
grabbable.AffectedDropZone = this;
StartTracking( grabbable );
if (!CanStackThisGrabbable( grabbable ))
return;
if (preview != null)
Destroy( preview );
if (usePreview && droppedGrabbableList.Count == 0)
{
CreatePreviewFor(grabbable);
}
}
}
private void CreatePreviewFor(VR_Grabbable grabbable)
{
previewOwner = grabbable.gameObject;
DropZoneInfo dropZoneInfo = grabbable.GetComponent<DropZoneInfo>();
preview = new GameObject(grabbable.gameObject.name + "_Preview");
MeshFilter[] meshFilters = grabbable.GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
int i = 0;
while (i < meshFilters.Length)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = grabbable.transform.worldToLocalMatrix * meshFilters[i].transform.localToWorldMatrix;
i++;
}
MeshFilter filter = preview.AddComponent<MeshFilter>();
filter.mesh = new Mesh();
filter.mesh.CombineMeshes( combine );
MeshRenderer renderer = preview.AddComponent<MeshRenderer>();
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
renderer.receiveShadows = false;
renderer.material = transparentMat;
renderer.material.color = new Color( 1.0f, 1.0f, 1.0f, 0.5f );
preview.transform.position = CalculateDropEndPosition(grabbable);
preview.transform.rotation = CalculateDropEndRotation(grabbable);
if (dropZoneInfo != null)
{
Vector3 scale = dropZoneInfo == null ? grabbable.transform.localScale : dropZoneInfo.OriginalScale;
scale *= dropZoneInfo.ScaleModifier;
preview.transform.localScale = scale;
}
else
{
preview.transform.localScale = grabbable.transform.lossyScale;
}
preview.transform.parent = dropPoint;
}
private Vector3 CalculateDropEndPosition(VR_Grabbable grabbable)
{
DropZoneInfo info = grabbable.GetComponent<DropZoneInfo>();
return info == null ? dropPoint.position : dropPoint.position + info.PositionOffset;
}
private Quaternion CalculateDropEndRotation(VR_Grabbable grabbable)
{
DropZoneInfo info = grabbable.GetComponent<DropZoneInfo>();
return info == null ? dropPoint.rotation : dropPoint.rotation * Quaternion.Euler( info.RotationOffset );
}
public void OnGrabStateChange(GrabState state, VR_Grabbable grabbable, bool force = false)
{
if (force || (state == GrabState.Drop && CanDropGrabbable(grabbable)) )
{
Rigidbody rb = grabbable.GetComponent<Rigidbody>();
if (rb != null)
rb.isKinematic = true;
ProcessDrop(grabbable);
DropZoneInfo dropZoneInfo = grabbable.GetComponent<DropZoneInfo>();
Vector3 dropScale = grabbable.transform.localScale;
if (dropZoneInfo != null)
{
dropScale = grabbable.transform.localScale * dropZoneInfo.ScaleModifier;
}
if (shouldFly)
{
grabbable.enabled = false;
if (dropZoneInfo != null && dropZoneInfo.ScaleModifier != 1.0f)
{
StartCoroutine( ModifyScaleRoutine( grabbable.transform, dropScale, flyTime ) );
}
StartCoroutine( FlyRoutine( grabbable ) );
}
else
{
onDrop.Invoke( grabbable );
if (syncronizePosition)
grabbable.transform.position = CalculateDropEndPosition(grabbable);
if (syncronizeRot)
grabbable.transform.rotation = CalculateDropEndRotation(grabbable);
if (preview != null)
preview.gameObject.SetActive( false );
if(dropZoneInfo != null)
grabbable.transform.localScale = dropScale;
}
}
else if (droppedGrabbableList.Contains(grabbable) && state == GrabState.Grab)
{
if (preview != null)
preview.SetActive( true );
OnGrabbableExit( grabbable );
}
else if (droppedGrabbableList.Contains(grabbable) && state == GrabState.Flying)
{
if ( ShouldModifyScale(grabbable) )
{
DropZoneInfo dropzoneInfo = grabbable.GetComponent<DropZoneInfo>();
StartCoroutine( ModifyScaleRoutine( grabbable.transform, dropzoneInfo.OriginalScale, grabbable.GrabFlyTime ) );
}
}
}
private void ProcessDrop(VR_Grabbable grabbable)
{
if (grabbable != null && !droppedGrabbableList.Contains(grabbable))
{
droppedGrabbableList.Add( grabbable );
//grabbable.OnGrabStateChange.AddListener( delegate (GrabState state){ OnDroppedGrabbableGrabStateChange( grabbable, state ); } );
UnityAction<GrabState> listener = delegate (GrabState state) { OnDroppedGrabbableGrabStateChange( grabbable, state ); };
onGrabStateChangeConnections[grabbable] = listener;
grabbable.OnGrabStateChange.AddListener(listener);
}
}
private bool ShouldModifyScale(VR_Grabbable grabbable)
{
DropZoneInfo info = grabbable.GetComponent<DropZoneInfo>();
return info != null && info.ScaleModifier != 1.0f;
}
private IEnumerator FlyRoutine(VR_Grabbable grabbable)
{
float elapseTime = 0.0f;
Vector3 startPosition = grabbable.transform.position;
Quaternion startRotation = grabbable.transform.rotation;
while (elapseTime < FlyTime)
{
elapseTime += Time.deltaTime;
float lerp = elapseTime / flyTime;
if (syncronizePosition)
grabbable.transform.position = Vector3.Lerp( startPosition , CalculateDropEndPosition(grabbable), lerp );
if (syncronizeRot)
grabbable.transform.rotation = Quaternion.Lerp( startRotation , CalculateDropEndRotation(grabbable), lerp );
yield return new WaitForSeconds(Time.deltaTime);
}
onDrop.Invoke( grabbable );
grabbable.enabled = true;
if (syncronizePosition)
grabbable.transform.position = CalculateDropEndPosition(grabbable);
if (syncronizeRot)
grabbable.transform.rotation = CalculateDropEndRotation(grabbable);
if (preview != null)
preview.gameObject.SetActive( false );
}
private IEnumerator ModifyScaleRoutine(Transform transform, Vector3 desireScale , float t)
{
float elapseTime = 0.0f;
while (elapseTime < t)
{
elapseTime += Time.deltaTime;
float lerp = elapseTime / t;
transform.localScale = Vector3.Lerp( transform.localScale , desireScale , lerp);
yield return new WaitForEndOfFrame();
}
}
private void StartTracking(VR_Grabbable grabbable)
{
if (!trackedGrabbable.Contains( grabbable ))
{
trackedGrabbable.Add( grabbable );
UnityAction<GrabState> unityAction = delegate (GrabState state)
{
if (trackedGrabbable.Contains( grabbable ))
OnGrabStateChange( state, grabbable );
};
grabbable.OnGrabStateChange.AddListener( unityAction );
onGrabStateChangeTrackConnections[grabbable] = unityAction;
}
}
//remove all the unnecessary code from the visual copies
private void RemoveComponents(GameObject go)
{
Component[] componentArray = go.GetComponentsInChildren<Component>();
for (int n = 0; n < componentArray.Length; n++)
{
if (componentArray[n] != null)
{
if (componentArray[n] is Canvas)
Destroy( componentArray[n].gameObject );
else if ( CanDestroyComponent( componentArray[n] ) )
Destroy( componentArray[n] );
}
}
}
private bool CanDestroyComponent(Component c)
{
return !( c is Transform ) && !( c is MeshRenderer ) && !( c is MeshFilter ) && !(c is VR_Outline);
}
/// <summary>
/// Called when the current dropped grabbable change his grab state
/// </summary>
/// <param name="state"></param>
private void OnDroppedGrabbableGrabStateChange(VR_Grabbable grabbable , GrabState state)
{
if (state == GrabState.Grab)
{
onUndrop.Invoke( grabbable );
//remove the listener
grabbable.OnGrabStateChange.RemoveListener( onGrabStateChangeConnections[grabbable] );
OnGrabbableExit( grabbable );
droppedGrabbableList.Remove(grabbable);
onGrabStateChangeConnections.Remove(grabbable);
if (dropZoneMode == DropZoneMode.Collider)
{
RemoveFromInsideCollider( grabbable );
}
}
}
private void RemoveFromInsideCollider(VR_Grabbable grabbable)
{
insideCollider.Remove(grabbable);
/*
List<Collider> allColliders = insideCollider.Keys.ToList();
for (int n = 0; n < allColliders.Count; n++)
{
if (insideCollider[allColliders[n]] == grabbable)
{
insideCollider.Remove( allColliders[n] );
}
}*/
}
public void SetDropRadiusViaInspector(float radius)
{
dropRadius = radius;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 738febf072f690c4ba45dddb5986a669
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_DropZone.cs
uploadId: 546658
@@ -0,0 +1,49 @@
using UnityEngine;
using UnityEngine.UI;
namespace VRSDK
{
public class VR_DropZoneUI : MonoBehaviour
{
[SerializeField] private Text countText = null;
[SerializeField] private VR_DropZone dropZone = null;
private int currentCounterValue = 0;
private void Awake()
{
countText.text = "";
dropZone.OnDrop.AddListener( OnDrop );
dropZone.OnUnDrop.AddListener( OnUnDrop );
}
private void OnDrop(VR_Grabbable grabbable)
{
currentCounterValue++;
UpdateText();
}
private void OnUnDrop(VR_Grabbable grabbbale)
{
currentCounterValue--;
UpdateText();
}
private void UpdateText()
{
if (currentCounterValue > 1)
{
countText.text = currentCounterValue.ToString();
}
else
{
countText.text = "";
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d141d72b74947dc46b9db8d9e34cdfc0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_DropZoneUI.cs
uploadId: 546658
@@ -0,0 +1,32 @@
using UnityEngine;
using System.Collections;
namespace VRSDK
{
public class VR_GrabCloner : MonoBehaviour
{
#region INSPECTOR
[SerializeField] private VR_Grabbable grabbablePrefab = null;
#endregion
#region PRIVATE
private VR_Grabbable currentGrab = null;
#endregion
private void Awake()
{
currentGrab = Instantiate( grabbablePrefab, transform.position, transform.rotation );
currentGrab.OnGrabStateChange.AddListener( OnGrabStateChange );
}
private void OnGrabStateChange(GrabState grabState)
{
currentGrab.OnGrabStateChange.RemoveListener( OnGrabStateChange );
currentGrab = Instantiate( grabbablePrefab, currentGrab.transform.position, currentGrab.transform.rotation );
currentGrab.OnGrabStateChange.AddListener( OnGrabStateChange );
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 06cba11399aed7c48b9cee058f6bb067
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_GrabCloner.cs
uploadId: 546658
@@ -0,0 +1,769 @@
using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using VRSDK.Events;
namespace VRSDK
{
public enum GrabState
{
UnGrab,
Flying,
Grab,
Drop,
None
}
//this script handles the grabbables
public class VR_Grabbable : VR_Interactable
{
#region INSPECTOR
[SerializeField] protected OnGrabStateChangeEvent onGrabStateChange = null;
[SerializeField] protected bool perfectGrab = false;
[SerializeField] protected float grabFlyTime = 0.5f;
[SerializeField] protected bool shouldFly = true;
[SerializeField] protected bool startOnRightController = false;
[SerializeField] protected bool startOnLeftController = false;
[SerializeField] protected bool autoGrab = false;
[SerializeField] protected bool enableColliderOnGrab = false;
[SerializeField] protected int grabLayer = 0;
[SerializeField] protected int unGrabLayer = 0;
[SerializeField] protected int bulletMaxBounce = 0;
[SerializeField] private bool preserveKinematicState = false;
[SerializeField] private bool toggleGrab = false;
[SerializeField] protected List<Collider> ignoreColliderList = new List<Collider>();
[SerializeField] protected List<Collider> colliderList = null;
[SerializeField] protected UnityEvent onAfterThrow = null;
#endregion
#region protected
protected Rigidbody rb = null;
protected GrabState currentGrabState = GrabState.UnGrab;
protected VR_Controller activeController = null;
protected float grabStartTime = 0.0f;
protected Vector3 grabStartPosition = Vector3.zero;
protected Quaternion grabStartRotation = Quaternion.identity;
protected Vector3 childrenPosition = Vector3.zero;
protected VR_Tag grabbableTag = null;
protected Vector3 initialPosition = Vector3.zero;
protected const float activeDistance = 5.0f;
protected bool isHighLight = false;
protected RigidbodyInterpolation originalInterpolateMode = RigidbodyInterpolation.None;
protected bool previousKinematicValue = false;
protected bool preventDefault = false;
protected float velocityChangeThreshold = 10f;
protected float angularVelocityChangeThreshold = 20f;
private bool previousUseGravityState = false;
private bool previousGravityState = false;
private VR_Controller lastInteractController = null;
private bool objectWasThrow = false;
protected bool canUseDropZone = true;
private bool waitAFrameForDrop = false;
private const float defaultMaxAngularVelocity = 10.0f;
private float distanceToLeftHand = 0.0f;
private float distanceToRightHand = 0.0f;
#endregion
#if UNITY_EDITOR
[SerializeField] private VR_GrabbableEditorPart editorPart = null;
public VR_GrabbableEditorPart EditorPart
{
get { return editorPart; }
}
public bool debug = false;
#endif
#region PUBLIC
public Rigidbody RB { get { return rb; } }
public List<Collider> ColliderList { get { return colliderList; } }
public VR_DropZone AffectedDropZone { get; set; }
public VR_Tag GrabbableTag { get { return grabbableTag; } }
public float GrabDistance { get { return interactDistance; } }
public bool IsGrabbed { get { return currentGrabState == GrabState.Grab; } }
public bool IsHighLight { get { return isHighLight; } }
public VR_Controller GrabController { get { return activeController; } }
public OnGrabStateChangeEvent OnGrabStateChange { get { return onGrabStateChange; } }
public Vector3 PositionOffset { get; set; }
public Quaternion RotationOffset { get; set; }
public VR_Controller LastInteractController { get { return lastInteractController; } }
public bool ObjectWasThrow { get { return objectWasThrow; } }
public bool CanUseDropZone { get { return canUseDropZone; } }
public UnityEvent OnAfterThrow { get { return onAfterThrow; } }
public GrabState CurrentGrabState
{
get
{
return currentGrabState;
}
private set
{
currentGrabState = value;
}
}
public Transform CurrentInteractPoint
{
get
{
return activeController.ControllerType == VR_ControllerType.Right ? rightHandSettings.interactPoint : leftHandSettings.interactPoint;
}
}
public float GrabFlyTime
{
get
{
if (shouldFly)
{
return grabFlyTime;
}
return 0.0f;
}
}
#endregion
#region UNITY_CALLBACKS
protected override void Awake()
{
base.Awake();
Construct();
SetLayer( unGrabLayer );
AddRigidBodyIfNeccesary();
SaveCurrentKinematicState();
CalculateDistanceToInteractPoint();
}
private void CalculateDistanceToInteractPoint()
{
distanceToLeftHand = Vector3.Distance( leftHandSettings.interactPoint.position, transform.position );
distanceToRightHand = Vector3.Distance( rightHandSettings.interactPoint.position, transform.position );
}
public void UpdateGrabPositionOffset()
{
CalculateDistanceToInteractPoint();
}
private void Construct()
{
grabbableTag = GetComponent<VR_Tag>();
colliderList = GetComponentsInChildren<Collider>().ToList();
rb = GetComponent<Rigidbody>();
}
protected void SetLayer(int layer)
{
gameObject.layer = layer;
for (int n = 0; n < colliderList.Count; n++)
{
if (colliderList[n] != null && !ignoreColliderList.Contains( colliderList[n] ))
{
colliderList[n].gameObject.layer = layer;
}
}
}
private void AddRigidBodyIfNeccesary()
{
if (rb == null)
{
Debug.LogWarning( "Grabbable component needs Rigidbody in order to work, adding one" );
rb = gameObject.AddComponent<Rigidbody>();
rb.isKinematic = true;
}
rb.maxAngularVelocity = defaultMaxAngularVelocity;
}
private void SaveCurrentKinematicState()
{
if (rb != null)
previousKinematicValue = rb.isKinematic;
}
protected override void Start()
{
base.Start();
//should this grabbable start on the right controller?
if (startOnRightController)
{
VR_Manager.instance.Player.RightController.ForceGrab( this );
}
//should this grabbable start on left controller?
else if (startOnLeftController)
{
VR_Manager.instance.Player.LeftController.ForceGrab( this );
}
}
protected override void Update()
{
base.Update();
//call the update
switch (CurrentGrabState)
{
case GrabState.UnGrab:
UngrabUpdate();
break;
case GrabState.Flying:
FlyUpdate();
break;
case GrabState.Grab:
GrabUpdate();
break;
case GrabState.Drop:
DropUpdate();
break;
}
}
/// <summary>
/// in this update the object will be making distance check to the controllers, and check if can be grabbed
/// </summary>
protected virtual void UngrabUpdate()
{
//wait to be grabbed
//handle by the VR_Interactable
}
/// <summary>
/// this update is called after a object has been grabbed so it will fly to the hand
/// </summary>
protected virtual void FlyUpdate()
{
if ( ShouldFlyToHandPositionAndRotation() )
{
MoveToHandPositionAndRotation();
return;
}
SetFinalGrabState();
CurrentGrabState = GrabState.Grab;
RaiseOnGrabStateChangeEvent( GrabState.Grab );
}
private bool ShouldFlyToHandPositionAndRotation()
{
float flyPercent = ( Time.time - grabStartTime ) / grabFlyTime;
return flyPercent < 1 && shouldFly;
}
private void MoveToHandPositionAndRotation()
{
float flyPercent = ( Time.time - grabStartTime ) / grabFlyTime;
transform.rotation = Quaternion.Slerp( grabStartRotation , CalculateGrabRotation() , flyPercent );
transform.position = Vector3.Lerp( grabStartPosition, CalculateGrabPosition(), flyPercent );
}
private Quaternion CalculateGrabRotation()
{
Quaternion baseRotation = activeController.GrabPoint.transform.rotation * Quaternion.Euler(GetCurrentHandInteractSettings().CalculateGrabRotationOffset());
return baseRotation * activeController.Input.GetRotationOffset();
}
public VR_HandInteractSettings GetCurrentHandInteractSettings()
{
return activeController.ControllerType == VR_ControllerType.Right ? rightHandSettings : leftHandSettings;
}
public VR_HandAnimationSettings GetCurrentHandAnimationSettings()
{
return activeController.ControllerType == VR_ControllerType.Right ? rightHandAnimationSettings : leftHandAnimationSettings;
}
private Vector3 CalculateGrabPosition()
{
Vector3 dir = ( GetCurrentHandInteractSettings().interactPoint.position - transform.position ).normalized;
Vector3 grabPosition = activeController.GrabPoint.transform.position + (dir * (CalculateDistanceToCurrentPoint() * -1.0f));
return grabPosition + activeController.Input.GetPositionOffset();
}
private float CalculateDistanceToCurrentPoint()
{
if (perfectGrab)
{
return Vector3.Distance( GetCurrentHandInteractSettings().interactPoint.position, transform.position );;
}
if (activeController.ControllerType == VR_ControllerType.Right) return distanceToRightHand;
return distanceToLeftHand;
}
private void SetFinalGrabState()
{
ChangeCollidersEnable( enableColliderOnGrab );
SetFinalHandPositionAndRotation();
SetupFixedJoint();
//should the hand be hide?
GrabController.SetVisibility( !GetCurrentHandAnimationSettings().hideHandOnGrab );
//parent the objects so they exist on the same space
transform.parent = activeController.transform;
}
private void ChangeCollidersEnable(bool enable)
{
for (int n = 0; n < colliderList.Count; n++)
{
if ( CanWeControlThisCollider( colliderList[n] ) )
{
colliderList[n].enabled = enable;
}
}
}
private bool CanWeControlThisCollider(Collider collider)
{
return collider != null && !ignoreColliderList.Contains( collider ) && collider.GetComponent<IgnoreColliderActivationFromGrabbable>() == null;
}
private void SetFinalHandPositionAndRotation()
{
transform.rotation = CalculateGrabRotation();
transform.position = CalculateGrabPosition();
}
public void SetupFixedJoint()
{
DestroyCurrentJoint();
CreateNewGrabJoint();
activeController.OnJointBreakListener.SetListener( OnJointBreak );
rb.isKinematic = false;
}
private void DestroyCurrentJoint()
{
FixedJoint joint = activeController.GrabPoint.gameObject.GetComponent<FixedJoint>();
if (joint != null)
Destroy( joint );
}
private void CreateNewGrabJoint()
{
var grabRB = activeController.GrabPoint.gameObject.GetComponent<Rigidbody>();
if (grabRB == null)
{
grabRB = activeController.GrabPoint.gameObject.AddComponent<Rigidbody>();
}
grabRB.isKinematic = true;
grabRB.useGravity = false;
FixedJoint joint = activeController.GrabPoint.gameObject.AddComponent<FixedJoint>();
joint.connectedBody = rb;
joint.breakForce = Mathf.Infinity;
joint.breakTorque = Mathf.Infinity;
}
/// <summary>
/// update when a this object is grabbed
/// </summary>
protected virtual void GrabUpdate()
{
//check if we should drop this grabbable
if (ShouldDropObject())
{
CurrentGrabState = GrabState.Drop;
return;
}
UpdatePositionAndRotationOffset();
}
private bool ShouldDropObject()
{
if (waitAFrameForDrop)
{
waitAFrameForDrop = false;
return false;
}
if (toggleGrab)
{
return activeController.Input.GetButtonDown( interactButton );
}
return !autoGrab && !activeController.Input.GetButton( interactButton );
}
protected void UpdatePositionAndRotationOffset()
{
activeController.PositionOffset = PositionOffset;
activeController.RotationOffset = RotationOffset;
}
/// <summary>
/// called when the object is dropped, this is just called a frame mainly it is a excuse to call RaiseOnGrabStateChangeEvent
/// </summary>
protected virtual void DropUpdate()
{
if (activeController == null)
{
//can be grabbed aigan
CanInteract = true;
TransitionToUnGrabState();
return;
}
ResetActiveControllerState();
//some componets stop the default behaivour of this component like the VR_TwoHandGrabbable.cs
if (!preventDefault)
{
ResetRigidBodyState();
ApplyControllerVelocity();
EnableHandCollision();
ChangeCollidersEnable( true );
transform.SetParent( null );
}
lastInteractController = activeController;
activeController = null;
//can be grabbed aigan
CanInteract = true;
TransitionToUnGrabState();
}
private void ResetActiveControllerState()
{
activeController.UsePositionOffset = true;
activeController.UseRotationOffset = true;
activeController.SetPositionAndRotationControlMode( MotionControlMode.Engine, MotionControlMode.Engine );
GrabController.SetVisibility( true );
if (activeController != null)
{
ResetControllerState( activeController );
}
}
private void ResetRigidBodyState()
{
if (rb != null)
rb.interpolation = originalInterpolateMode;
if (preserveKinematicState && rb != null)
{
rb.isKinematic = previousKinematicValue;
}
else if (rb != null)
{
rb.isKinematic = false;
}
}
private void EnableHandCollision()
{
if (activeController.Velocity.magnitude > 0.1f && activeController.Collider != null)
{
StartCoroutine( EnableCollisionRoutine( activeController.Collider, 0.1f ) );
}
else if (activeController.Collider != null)
{
EnableCollision( activeController.Collider );
}
}
private void TransitionToUnGrabState()
{
RaiseOnGrabStateChangeEvent( GrabState.Drop );
CurrentGrabState = GrabState.UnGrab;
RaiseOnGrabStateChangeEvent( GrabState.UnGrab );
}
private void SetRigidbodyVelocityToZero()
{
rb.angularVelocity = Vector3.zero;
rb.linearVelocity = Vector3.zero;
}
#endregion
//this is a feature what i am working you can ignore this function :)
public void SetEditorGrabPositionAndRotation(VR_Controller controller)
{
activeController = controller;
if (shareHandInteractionSettings)
{
leftHandSettings = handSettings;
rightHandSettings = handSettings;
}
transform.position = CalculateGrabPosition();
transform.rotation = activeController.GrabPoint.transform.rotation * Quaternion.Euler( GetCurrentHandInteractSettings().rotationOffset );
//SetupFixedJoint();
transform.parent = activeController.transform;
}
//this is a feature what i am working you can ignore this function :)
public void CopySettingsTo(VR_Grabbable grabbable)
{
grabbable.handSettings.rotationOffset = handSettings.rotationOffset;
grabbable.rightHandSettings.rotationOffset = rightHandSettings.rotationOffset;
grabbable.leftHandSettings.rotationOffset = leftHandSettings.rotationOffset;
}
private void ApplyControllerVelocity()
{
if (rb != null && activeController != null)
{
StartCoroutine(ApplyControllerVelocityRoutine(activeController));
}
}
private IEnumerator ApplyControllerVelocityRoutine(VR_Controller controller)
{
rb.linearVelocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
yield return new WaitForFixedUpdate();
controller.ApplyThrowVelocity(this);
while (rb.linearVelocity.magnitude < 0.25f)
yield return new WaitForFixedUpdate();
onAfterThrow.Invoke();
objectWasThrow = true;
}
private void ResetControllerState(VR_Controller controller)
{
//recenter controller
controller.Recenter();
controller.OnJointBreakListener.RemoveAllListeners();
FixedJoint joint = controller.GrabPoint.gameObject.GetComponent<FixedJoint>();
if (joint != null)
Destroy( joint );
controller.CleanCurrentGrab();
}
protected void RaiseOnGrabStateChangeEvent(GrabState grabState)
{
SetLayer( grabState == GrabState.Grab ? grabLayer : unGrabLayer );
onGrabStateChange.Invoke( grabState );
}
public void ForceDrop()
{
m_buttonWasPressedLeft = VR_Manager.instance.Player.LeftController.Input.GetButtonDown( interactButton );
m_buttonWasPressedRight = VR_Manager.instance.Player.RightController.Input.GetButtonDown( interactButton );
DropUpdate();
}
public override void Interact(VR_Controller controller)
{
OnGrabSuccess( controller );
}
/// <summary>
/// Called by VR_Input, to let know what we are grabbing this object
/// </summary>
/// <param name="controller"></param>
public virtual void OnGrabSuccess(VR_Controller controller)
{
if (preventDefault)
{
waitAFrameForDrop = true;
activeController = controller;
CurrentGrabState = GrabState.Grab;
RaiseOnGrabStateChangeEvent(CurrentGrabState);
return;
}
previousKinematicValue = rb.isKinematic;
//stop this object to be interactable
CanInteract = false;
//set the active controller
activeController = controller;
if (rb != null)
{
rb.isKinematic = true;
originalInterpolateMode = rb.interpolation;
rb.interpolation = RigidbodyInterpolation.None;
}
//disable collision with the grabbable and the hand
if (activeController.Collider != null)
{
IgnoreCollision(activeController.Collider);
}
//if this object shoudl fly to hand disable colliders while flying otherwise set desire collider state
if (shouldFly)
{
//disable colliders while flying
ChangeCollidersEnable( false );
}
else
{
waitAFrameForDrop = true;
ChangeCollidersEnable( enableColliderOnGrab );
}
//if we are using a perfect grab
if (perfectGrab)
{
//parent the objects so they exist on the same space
transform.parent = activeController.transform;
GrabController.SetVisibility( !GetCurrentHandAnimationSettings().hideHandOnGrab );
SetupFixedJoint();
//set the current grab state
CurrentGrabState = GrabState.Grab;
//raise grab state change event
RaiseOnGrabStateChangeEvent( CurrentGrabState );
return;
}
else
{
//set fly values
if (shouldFly)
{
grabStartTime = Time.time;
grabStartPosition = transform.position;
grabStartRotation = transform.rotation;
}
else
{
SetFinalGrabState();
}
CurrentGrabState = shouldFly ? GrabState.Flying : GrabState.Grab;
}
//raise the event
RaiseOnGrabStateChangeEvent( ( shouldFly ? GrabState.Flying : GrabState.Grab ) );
}
public void PreventDefault()
{
preventDefault = true;
}
/// <summary>
/// Called whena grabbed joints breaks
/// </summary>
private void OnJointBreak(float f)
{
//if the object is no grabbed ignore jojntbreak
if (CurrentGrabState != GrabState.Grab)
return;
FixedJoint joint = activeController.GrabPoint.gameObject.GetComponent<FixedJoint>();
if (joint != null && joint.connectedBody != null)
return;
m_buttonWasPressedLeft = VR_Manager.instance.Player.LeftController.Input.GetButtonDown( interactButton );
m_buttonWasPressedRight = VR_Manager.instance.Player.RightController.Input.GetButtonDown( interactButton );
CurrentGrabState = GrabState.Drop;
}
private void IgnoreCollision(Collider c)
{
for (int n = 0; n < colliderList.Count; n++)
{
if (colliderList[n] != null && c != null)
{
Physics.IgnoreCollision( colliderList[n], c );
}
}
}
private IEnumerator EnableCollisionRoutine(Collider c, float t)
{
yield return new WaitForSeconds( t );
IgnoreCollision( c );
}
private void EnableCollision(Collider c)
{
for (int n = 0; n < colliderList.Count; n++)
{
if (colliderList[n] != null)
{
Physics.IgnoreCollision( colliderList[n], c, false );
}
}
}
public void OnDropSuccess()
{
ChangeCollidersEnable( false );
}
public void IgnoreCollider(Collider c)
{
ignoreColliderList.Add( c );
}
public void SetStartOnLeftHand(bool value)
{
startOnLeftController = value;
}
public void SetStartOnRightHand(bool value)
{
startOnRightController = value;
}
protected override void OnDestroy()
{
base.OnDestroy();
onGrabStateChange.RemoveAllListeners();
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: fb45bf0516c7b9c4e8c6b8024599f45a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Grabbable.cs
uploadId: 546658
@@ -0,0 +1,58 @@
using UnityEngine;
using System.Collections;
namespace VRSDK
{
//this script is being use for the arrow grab zone when the hand is on range and you press the interact
//button it creates a the grabbable in your hand
public class VR_GrabbableZone : VR_Interactable
{
[SerializeField] private VR_Grabbable grabbable = null;
public VR_Grabbable Grabbable { get { return grabbable; } }
protected override void Awake()
{
shareHandInteractionSettings = true;
handSettings.canInteract = true;
handSettings.interactPoint = transform;
handSettings.highlightPoint = transform;
base.Awake();
}
public override void Interact(VR_Controller controller)
{
Debug.Log("interact");
StartCoroutine( GrabRoutine(controller) );
}
private IEnumerator GrabRoutine(VR_Controller controller)
{
VR_Grabbable clone = Instantiate( grabbable, transform.position, Quaternion.identity );
controller.ForceGrab( clone );
MeshRenderer[] renderArray = clone.transform.GetComponentsInChildren<MeshRenderer>();
for (int n = 0; n < renderArray.Length; n++)
{
renderArray[n].enabled = false;
}
yield return new WaitForEndOfFrame();
for (int n = 0; n < renderArray.Length; n++)
{
renderArray[n].enabled = true;
}
clone.gameObject.SetActive( true );
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 33735b8ea6586e34c8302c55eea9e792
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_GrabbableZone.cs
uploadId: 546658
@@ -0,0 +1,12 @@
using UnityEngine;
namespace VRSDK
{
[System.Serializable]
public class VR_HandAnimationSettings
{
public AnimationClip animation = null;
public bool hideHandOnGrab = false;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 9ec394700916d104c809ef70458c6bdc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_HandAnimationSettings.cs
uploadId: 546658
@@ -0,0 +1,20 @@
using UnityEngine;
namespace VRSDK
{
[System.Serializable]
public class VR_HandInteractSettings
{
public Transform interactPoint = null;
public Transform highlightPoint = null;
public Vector3 rotationOffset = Vector3.zero;
public bool canInteract = true;
public Vector3 CalculateGrabRotationOffset()
{
Vector3 handRotOffset = VR_Manager.instance.Player.HandGrabRotationOffset;
return rotationOffset + handRotOffset;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 360da7c48d6cc2142a2ade22fe007c9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_HandInteractSettings.cs
uploadId: 546658
@@ -0,0 +1,100 @@
using UnityEngine;
#if SDK_STEAM_VR
using Valve.VR;
#endif
namespace VRSDK
{
public class VR_Haptics : MonoBehaviour
{
[SerializeField] private float rate = 0.1f;
[SerializeField] private float multiplier = 1.0f;
private float lastHapticsFeedback = 0.0f;
private bool givingFeedback = false;
private VR_Controller activeController = null;
private VR_Grabbable grabbable = null;
#if SDK_STEAM_VR
private SteamVR_Action_Vibration hapticAction = null;
#endif
private const float MIN_HAPTICS_VALUE = 0.2f;
private void Awake()
{
#if SDK_STEAM_VR
hapticAction = SteamVR_Input.GetAction<SteamVR_Action_Vibration>( "VRShooterKit", "Haptic" );
#endif
grabbable = GetComponent<VR_Grabbable>();
grabbable.OnGrabStateChange.AddListener( OnGrabStateChange );
}
private void OnGrabStateChange(GrabState state)
{
if (state == GrabState.Grab)
{
activeController = grabbable.GrabController;
}
}
private void Update()
{
#if SDK_OCULUS
if (givingFeedback && Time.time - lastHapticsFeedback > rate)
Stop();
#endif
}
public void SetHaptics(float frequency, float amplitud , VR_Controller controller)
{
frequency *= multiplier;
amplitud *= multiplier;
if (amplitud < MIN_HAPTICS_VALUE)
amplitud = MIN_HAPTICS_VALUE;
if (Time.time - lastHapticsFeedback < rate)
return;
if (!givingFeedback)
givingFeedback = true;
lastHapticsFeedback = Time.time;
#if SDK_OCULUS
if(activeController == null) return;
OVRInput.SetControllerVibration(frequency , amplitud , (OVRInput.Controller) activeController.Input.GetControllerType() );
#endif
#if SDK_STEAM_VR
if(controller == null) return;
hapticAction.Execute( 0.0f, rate, Mathf.Min( frequency * 320.0f, 320.0f ), amplitud, (SteamVR_Input_Sources) controller.Input.GetControllerType() );
#endif
activeController = controller;
}
public void SetHaptics(float value , VR_Controller controller)
{
value *= multiplier;
SetHaptics(Random.Range(value / 2.0f , value) , value , controller);
}
public void Stop()
{
givingFeedback = false;
if(activeController == null) return;
#if SDK_OCULUS
OVRInput.SetControllerVibration( 0.0f, 0.0f, (OVRInput.Controller)activeController.Input.GetControllerType());
#endif
#if SDK_STEAM_VR
hapticAction.Execute(0.0f , 0.01f , 0.0f , 0.0f , (SteamVR_Input_Sources) activeController.Input.GetControllerType());
#endif
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: da59bbf59ba4d8443b4a546971922ac5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Haptics.cs
uploadId: 546658
@@ -0,0 +1,80 @@
using UnityEngine;
namespace VRSDK
{
//this is the basic class for highlight grabbables
//in used by the VR_OutlineHighlight and the VR_UIHighlight
public abstract class VR_Highlight : MonoBehaviour
{
private VR_Interactable interact = null;
public Transform HighlightPointRightHand { get { return interact.HighlightPointRightHand; } }
public Transform HighlightPointLeftHand { get { return interact.HighlightPointLeftHand; } }
public float HighlightDistance { get { return interact.InteractDistance; } }
public bool IsHighlight { get; private set; }
public VR_Interactable Interactable
{
get { return interact; }
}
protected virtual void Awake()
{
interact = GetComponent<VR_Interactable>();
if (interact == null)
{
Debug.LogError( "VR_Hightlight attached to " + gameObject.name + " needs a interactable script in order to work" );
}
VR_Manager.instance.RegisterHighlight( this );
}
protected virtual void OnDestroy()
{
//this object can be destroyed for 2 reasons
//the programmer calling destroy on the gameobject
// and the UnityEngine closing the game, so if Unity is closing the game
//dont do nothing the game is just closing
if (!VR_Manager.ApplicationIsQuitting)
VR_Manager.instance.RemoveHighlight( this );
}
protected virtual void OnEnable()
{
VR_Manager.instance.RegisterHighlight( this );
}
protected virtual void OnDisable()
{
//this object can be disable for 2 reasons
//the programmer calling destroy on the gameobject
// and the UnityEngine closing the game, so if Unity is closing the game
//dont do nothing the game is just closing
if (!VR_Manager.ApplicationIsQuitting)
VR_Manager.instance.RemoveHighlight( this );
}
public bool CanHighlight()
{
return interact == null || interact.CanInteract;
}
public bool CanHighlightUsingController(VR_Controller controller)
{
return interact == null || interact.CanInteractUsingController( controller );
}
public virtual void Highlight(VR_Controller controller)
{
IsHighlight = true;
}
public virtual void UnHighlight(VR_Controller controller)
{
IsHighlight = false;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: afe9b74dd1a7d5f43bf8de4636233886
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Highlight.cs
uploadId: 546658
@@ -0,0 +1,370 @@
using UnityEngine;
using System.Collections.Generic;
using VRSDK.Events;
namespace VRSDK
{
public enum InteractableType
{
Distance,
Collider
}
//basic class for all interactable components
public class VR_Interactable : MonoBehaviour
{
[SerializeField] protected InteractableType interactableType = InteractableType.Distance;
[SerializeField] protected VR_InputButton interactButton = VR_InputButton.Grip;
[SerializeField] protected float interactDistance = 1.0f;
[SerializeField] protected Collider grabCollider = null;
[SerializeField] protected VR_HandInteractSettings rightHandSettings = new VR_HandInteractSettings();
[SerializeField] protected VR_HandInteractSettings leftHandSettings = new VR_HandInteractSettings();
[SerializeField] protected VR_HandInteractSettings handSettings = new VR_HandInteractSettings();
[SerializeField] protected VR_HandAnimationSettings rightHandAnimationSettings = new VR_HandAnimationSettings();
[SerializeField] protected VR_HandAnimationSettings leftHandAnimationSettings = new VR_HandAnimationSettings();
[SerializeField] protected VR_HandAnimationSettings handAnimationSettings = new VR_HandAnimationSettings();
[SerializeField] protected OnInteractEvent onInteractEvent = null;
[SerializeField] protected bool shareHandInteractionSettings = false;
[SerializeField] protected bool shareHandAnimationSettings = false;
[SerializeField] protected bool useDistanceGrab = false;
public bool UseDistanceGrab { get { return useDistanceGrab; } }
public float DistanceToLeftHand { get; private set; }
public float DistanceToRightHand { get; private set; }
public float InteractDistance { get { return interactDistance; } }
public bool CanInteract
{
get
{
return canInteract;
}
protected set
{
canInteract = value;
if (!canInteract)
{
VR_Highlight h = GetComponent<VR_Highlight>();
if (h != null)
h.UnHighlight(null);
}
}
}
public OnInteractEvent OnInteractEvent { get { return onInteractEvent; } }
public InteractableType InteractableType => interactableType;
protected bool m_buttonWasPressedLeft = false;
protected bool m_buttonWasPressedRight = false;
private bool canInteract = true;
private VR_ControllerInfo rightControllerInfo = null;
private VR_ControllerInfo leftControllerInfo = null;
private List<VR_Controller> activeDistanceGrabControllerList = new List<VR_Controller>();
private Transform cacheTransform = null;
protected Transform thisTransform
{
get
{
if (cacheTransform == null)
{
cacheTransform = transform;
}
return cacheTransform;
}
}
public Transform HighlightPointRightHand
{
get
{
return rightHandSettings.highlightPoint == null ? rightHandSettings.interactPoint : rightHandSettings.highlightPoint;
}
}
public Transform HighlightPointLeftHand
{
get
{
return leftHandSettings.highlightPoint == null ? leftHandSettings.interactPoint : leftHandSettings.highlightPoint;
}
}
public Transform HighlightPointHandSettings
{
get
{
return handSettings.highlightPoint;
}
}
public Transform RightInteractPoint
{
get
{
if (!shareHandInteractionSettings)
return rightHandSettings.interactPoint;
else
return handSettings.interactPoint;
}
}
public Transform LeftInteractPoint
{
get
{
if (!shareHandInteractionSettings)
return rightHandSettings.interactPoint;
else
return handSettings.interactPoint;
}
}
public VR_HandInteractSettings HandSettings { get { return handSettings; } }
public VR_HandInteractSettings RightHandSettings { get { return rightHandSettings; } }
public VR_HandInteractSettings LeftHandSettings { get { return leftHandSettings; } }
public VR_HandAnimationSettings HandAnimationSettings { get { return handAnimationSettings; ; } }
public VR_HandAnimationSettings RightHandAnimationSettings { get { return rightHandAnimationSettings; } }
public VR_HandAnimationSettings LeftHandAnimationSettings { get { return leftHandAnimationSettings; } }
public VR_InputButton InteractButton { get { return interactButton; } }
public Collider GrabCollider => grabCollider;
protected virtual void Awake()
{
//if we dont use per hand settings set general settings as the settings for both hands
if (shareHandInteractionSettings)
{
rightHandSettings = handSettings;
leftHandSettings = handSettings;
}
if (shareHandAnimationSettings)
{
rightHandAnimationSettings = handAnimationSettings;
leftHandAnimationSettings = handAnimationSettings;
}
//register this interactable
VR_Manager.instance.RegisterInteract(this);
//create snap points if we need they
CreateAllSnapPoints();
}
protected virtual void Start()
{
CreateControllersInfo();
}
private void CreateAllSnapPoints()
{
if (rightHandSettings.interactPoint == null)
CreateSnapPoint(rightHandSettings);
if (leftHandSettings.interactPoint == null)
CreateSnapPoint(leftHandSettings);
if (handSettings.interactPoint == null)
CreateSnapPoint(handSettings);
}
private void CreateSnapPoint(VR_HandInteractSettings settings)
{
settings.interactPoint = new GameObject("SnapPoint").transform;
settings.interactPoint.parent = transform;
settings.interactPoint.localPosition = Vector3.zero;
settings.interactPoint.localRotation = Quaternion.identity;
}
private void CreateControllersInfo()
{
rightControllerInfo = new VR_ControllerInfo(VR_Manager.instance.Player.RightController);
leftControllerInfo = new VR_ControllerInfo(VR_Manager.instance.Player.LeftController);
}
private void OnDisable()
{
//this object can be destroyed for 2 reasons
//the programmer calling destroy on the gameobject
// and the UnityEngine closing the game, so if Unity is closing the game
//dont do nothing the game is just closing
if (!VR_Manager.ApplicationIsQuitting)
VR_Manager.instance.RemoveInteract(this);
}
private void OnEnable()
{
VR_Manager.instance.RegisterInteract(this);
}
protected virtual void OnDestroy()
{
//this object can be destroyed for 2 reasons
//the programmer calling destroy on the gameobject
// and the UnityEngine closing the game, so if Unity is closing the game
//dont do nothing the game is just closing
if (!VR_Manager.ApplicationIsQuitting)
VR_Manager.instance.RemoveInteract(this);
}
protected virtual void Update()
{
if (!CanInteract) return;
ProcessControllerInfoInteraction(rightControllerInfo);
ProcessControllerInfoInteraction(leftControllerInfo);
}
private void ProcessControllerInfoInteraction(VR_ControllerInfo info)
{
if (info?.controller == null)
{
return;
}
VR_HandInteractSettings settings = info.controller.ControllerType == VR_ControllerType.Right ? rightHandSettings : leftHandSettings;
Transform highlightPoint = info.controller.ControllerType == VR_ControllerType.Right ? HighlightPointRightHand : HighlightPointLeftHand;
bool ignoreDistance = interactableType == InteractableType.Collider;
//if we are trying to do a distance grab using this controller
if (!ignoreDistance && useDistanceGrab && activeDistanceGrabControllerList != null && activeDistanceGrabControllerList.Count > 0 && activeDistanceGrabControllerList.Contains(info.controller))
{
ignoreDistance = true;
}
if (settings.canInteract && highlightPoint != null)
{
CheckIfShouldInteractWithController(info, ignoreDistance);
}
}
private void CheckIfShouldInteractWithController(VR_ControllerInfo info, bool ignoreDistance)
{
float d = ignoreDistance ? 0.0f : GetDistanceToController(info.controller);
if (d <= interactDistance || ignoreDistance)
{
//the button was alredy pressed when the controller enter the grab range?
if (info.interactionButtonWasPressed)
{
info.UpdateButtonWasPressed(interactButton);
if (info.interactionButtonWasPressed)
{
return;
}
}
if (info.controller.enabled && info.controller.Input.GetButtonDown(interactButton))
{
info.controller.InteractWithNearesObject();
info.interactionButtonWasPressed = true;
}
}
else
{
info.UpdateButtonWasPressed(interactButton);
}
}
/// <summary>
/// Get the distance to the controller
/// </summary>
private float GetDistanceToController(VR_Controller controller)
{
float d = float.MaxValue;
Transform interactPoint = controller.ControllerType == VR_ControllerType.Right ? HighlightPointRightHand : HighlightPointLeftHand;
if (controller.Input.IsConnected() && controller.CurrentGrab == null)
{
d = (interactPoint.position - controller.Position).magnitude;
}
return d;
}
public virtual void Interact(VR_Controller controller)
{
onInteractEvent.Invoke(controller);
}
public bool CanInteractUsingController(VR_Controller controller)
{
if (controller.ControllerType == VR_ControllerType.Right)
return rightHandSettings.canInteract;
if (controller.ControllerType == VR_ControllerType.Left)
return leftHandSettings.canInteract;
return false;
}
public VR_HandInteractSettings GetHandInteractionSettings(VR_Controller controller)
{
if (controller.ControllerType == VR_ControllerType.Right)
return rightHandSettings;
if (controller.ControllerType == VR_ControllerType.Left)
return leftHandSettings;
return null;
}
public VR_HandAnimationSettings GetHandAnimationSettings(VR_Controller controller)
{
if (controller.ControllerType == VR_ControllerType.Right)
return rightHandAnimationSettings;
if (controller.ControllerType == VR_ControllerType.Left)
return leftHandAnimationSettings;
return null;
}
public void SetInteractDistanceViaInspector(float d)
{
interactDistance = d;
}
public void AddActiveDistanceGrabController(VR_Controller controller)
{
if (!useDistanceGrab)
return;
activeDistanceGrabControllerList.Add(controller);
}
public void RemoveActiveDistanceGrabController(VR_Controller controller)
{
if (!useDistanceGrab)
return;
activeDistanceGrabControllerList.Remove(controller);
}
}
public class VR_ControllerInfo
{
public VR_Controller controller = null;
public bool interactionButtonWasPressed = false;
public VR_ControllerInfo(VR_Controller controller)
{
this.controller = controller;
interactionButtonWasPressed = false;
}
public void UpdateButtonWasPressed(VR_InputButton interactButton)
{
interactionButtonWasPressed = controller.Input.GetButtonDown(interactButton);
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7f8f5525ec294f64aa1e3fac35826b1a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Interactable.cs
uploadId: 546658
@@ -0,0 +1,296 @@
using UnityEngine;
using VRSDK.Events;
namespace VRSDK
{
//this script controls the lever, the lever is completely based on physics so it can respond to any collision
public class VR_Lever : VR_Grabbable
{
[SerializeField] private Transform transformBase = null;
[SerializeField] private int solverIterations = 10;
[SerializeField] private OnValueChangeEvent onValueChange = null;
[SerializeField] private bool shouldBackToStartingPosition = false;
[SerializeField] private float backForce = 2.0f;
private HingeJoint joint = null;
private float initialAngle = 0.0f;
private float lastValue = -1.0f;
private Vector3 initialDir = Vector3.zero;
private float movementRange = 0.0f;
private Collider thisCollider = null;
private Collider triggerHandCollider = null;
private bool isIgnoringHandCollision = false;
private const float MAX_FORCE = 1000.0f;
public OnValueChangeEvent OnValueChange { get { return onValueChange; } }
protected override void Awake()
{
base.Awake();
canUseDropZone = false;
thisCollider = GetComponent<Collider>();
joint = GetComponent<HingeJoint>();
rb = GetComponent<Rigidbody>();
//solver iterations help to get a better physics behaviour
//but be careful this can slowdown the game
rb.solverIterations = solverIterations;
//we dont need this
shouldFly = false;
autoGrab = false;
//ignore base collision
Collider[] colliderArray = transformBase.GetComponentsInChildren<Collider>();
for (int n = 0; n < colliderArray.Length; n++)
{
Physics.IgnoreCollision( thisCollider, colliderArray[n] );
}
//initialize the joint
SetUpHingeJoint();
OnGrabStateChange.AddListener( OnGrabStateChangeCallback );
}
private void SetUpHingeJoint()
{
initialAngle = GetCurrentAngle();
movementRange = Mathf.Abs( joint.limits.min - joint.limits.max );
initialDir = transform.InverseTransformDirection( Vector3.up );
joint.useMotor = false;
joint.useSpring = shouldBackToStartingPosition;
//cancel all forces
rb.linearVelocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
//set back force
JointSpring spring = joint.spring;
spring.spring = backForce;
spring.targetPosition = 0.0f;
joint.spring = spring;
}
protected override void Update()
{
base.Update();
float newValue = Mathf.Clamp( GetClampAngle() / movementRange, 0.0f, 1.0f );
if (newValue != lastValue)
{
onValueChange.Invoke( newValue );
lastValue = newValue;
}
if (isIgnoringHandCollision && Vector3.Distance( triggerHandCollider.transform.position, RightInteractPoint.position ) > interactDistance)
{
Physics.IgnoreCollision( thisCollider, triggerHandCollider, false );
isIgnoringHandCollision = false;
}
}
private void OnGrabStateChangeCallback(GrabState state)
{
if (state == GrabState.Grab)
{
if (thisCollider != null)
{
thisCollider.enabled = false;
}
triggerHandCollider = activeController.GetComponent<Collider>();
JointSpring spring = joint.spring;
spring.spring = MAX_FORCE;
joint.spring = spring;
joint.useMotor = false;
joint.useSpring = true;
}
else if (state == GrabState.UnGrab)
{
if (triggerHandCollider != null)
{
Physics.IgnoreCollision( thisCollider, triggerHandCollider, true );
isIgnoringHandCollision = true;
}
else
{
isIgnoringHandCollision = false;
}
if (thisCollider != null)
{
thisCollider.enabled = true;
}
if (shouldBackToStartingPosition)
{
SetupBackLever();
}
}
}
private void SetupBackLever()
{
JointSpring spring = joint.spring;
spring.spring = backForce;
spring.targetPosition = 0.0f;
joint.spring = spring;
joint.useMotor = false;
joint.useSpring = true;
}
private float GetCurrentAngle()
{
if (joint.axis.x > 0.0f)
return WrapAngle( transform.rotation.eulerAngles.x );
else if (joint.axis.y > 0.0f)
return WrapAngle( transform.rotation.eulerAngles.y );
else if (joint.axis.z > 0.0f)
return WrapAngle( transform.rotation.eulerAngles.z );
return 0.0f;
}
//convert angle to human readable
private float WrapAngle(float angle)
{
angle %= 360;
if (angle > 180)
return angle - 360;
return angle;
}
protected override void GrabUpdate()
{
base.GrabUpdate();
UpdateJoint();
Transform highlightPoint = activeController.ControllerType == VR_ControllerType.Right ? HighlightPointRightHand : HighlightPointLeftHand;
float distance = ( highlightPoint.transform.position - activeController.GrabPoint.transform.position ).magnitude;
if (distance > interactDistance)
{
currentGrabState = GrabState.Drop;
RaiseOnGrabStateChangeEvent( GrabState.Drop );
}
}
protected override void DropUpdate()
{
GrabController.SetVisibility( true );
rb.linearVelocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
joint.useSpring = false;
activeController.CleanCurrentGrab();
activeController = null;
RaiseOnGrabStateChangeEvent( GrabState.Drop );
currentGrabState = GrabState.UnGrab;
RaiseOnGrabStateChangeEvent( GrabState.UnGrab );
}
public override void OnGrabSuccess(VR_Controller controller)
{
activeController = controller;
joint.useSpring = true;
currentGrabState = GrabState.Grab;
RaiseOnGrabStateChangeEvent( GrabState.Grab );
GrabController.SetVisibility( !GetCurrentHandAnimationSettings().hideHandOnGrab );
}
private float GetAngle()
{
if (joint.axis.x > 0.0f)
{
Vector3 dir = transformBase.transform.position - activeController.GrabPoint.transform.position;
Vector3 myDir = transformBase.up * -1.0f;
return Vector2.SignedAngle( new Vector2( dir.z, dir.y ), new Vector2( 0.0f, myDir.y ) );
}
else if (joint.axis.z > 0.0f)
{
Vector3 dir = transformBase.transform.position - activeController.GrabPoint.transform.position;
Vector3 myDir = transformBase.up * -1.0f;
return Vector2.SignedAngle( new Vector2( dir.x * -1.0f, dir.y ), new Vector2( myDir.x, myDir.y ) );
}
else if (joint.axis.y > 0.0f)
{
Vector3 dir = transformBase.transform.position - activeController.GrabPoint.transform.position;
Vector3 myDir = transformBase.right *-1.0f;
return Vector2.SignedAngle( new Vector2( dir.x, dir.z ), new Vector2( myDir.x, myDir.z ) );
}
return 0.0f;
}
private float GetClampAngle()
{
if (joint.axis.z > 0.0f)
return Vector2.Angle( new Vector2( transform.up.x, transform.up.y ), new Vector2( initialDir.x, initialDir.y ) );
if (joint.axis.x > 0.0f)
return Vector2.Angle( new Vector2( transform.up.z, transform.up.y ), new Vector2( initialDir.z, initialDir.y ) );
return 0.0f;
}
private void UpdateJoint()
{
float visualAngle = GetAngle() - initialAngle;
JointSpring spring = joint.spring;
spring.targetPosition = visualAngle;
joint.spring = spring;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d912716608467b548b0a0f817fdc06fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Lever.cs
uploadId: 546658
@@ -0,0 +1,143 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Platinio;
namespace VRSDK
{
public enum Axis
{
Horizontal,
Vertical,
Forward
}
public enum VR_SDK
{
None,
Oculus,
Steam_VR,
UnityXR
}
public class VR_Manager : Singleton<VR_Manager>
{
#region INSPECTOR
[SerializeField] private VR_SDK currentSDK = VR_SDK.None;
[SerializeField] private ControllerGestureConfig gestureConfig = null;
#endregion
#region PUBLIC
public VR_SDK CurrentSDK { get { return currentSDK; } }
public List<VR_Interactable> InteractList { get { return interactList; } }
public List<VR_Highlight> HighlightList { get { return highlightList; } }
public List<VR_Grabbable> GrabbableList { get { return grabbableList; } }
public VR_Player Player
{
get
{
if (player == null)
{
player = FindObjectOfType<VR_Player>();
player.Construct();
}
return player;
}
}
#endregion
#region PRIVATE
private List<VR_Interactable> interactList = new List<VR_Interactable>();
private List<VR_Highlight> highlightList = new List<VR_Highlight>();
private List<VR_Grabbable> grabbableList = new List<VR_Grabbable>();
private VR_Player player = null;
#endregion
protected override void Awake()
{
m_destroyOnLoad = false;
base.Awake();
}
public void SetCurrentPlayer(VR_Player player)
{
player.Construct();
}
/// <summary>
/// Register a grabbable object
/// </summary>
/// <param name="grabbable"></param>
public void RegisterInteract(VR_Interactable interact)
{
if (interactList.Contains( interact ))
return;
interactList.Add( interact );
//is this is a grabbable to lets have it on a diferent list
if (interact is VR_Grabbable)
grabbableList.Add( interact as VR_Grabbable );
}
/// <summary>
/// Remove a grabbable object
/// </summary>
/// <param name="grabbable"></param>
public void RemoveInteract(VR_Interactable interact)
{
interactList.Remove( interact );
//if this is a grabbable to remove it from grabbable list
if (interact is VR_Grabbable)
grabbableList.Remove( interact as VR_Grabbable );
}
public void RegisterHighlight(VR_Highlight h)
{
highlightList.Add( h );
}
public void RemoveHighlight(VR_Highlight h)
{
highlightList.Remove( h );
}
public VR_Grabbable GetGrabbableFromCollider(Collider c)
{
for (int n = 0; n < interactList.Count; n++)
{
VR_Grabbable grabbable = interactList[n] as VR_Grabbable;
if (grabbable != null && grabbable.ColliderList != null && grabbable.ColliderList.Count > 0 && grabbable.ColliderList.Contains( c ))
{
return grabbable;
}
}
return null;
}
public void SetCurrentSDKViaEditor(VR_SDK sdk)
{
currentSDK = sdk;
}
}
[System.Serializable]
public class ControllerGestureConfig
{
public float minAcelerationThreshold = 15.0f;
public float maxAcelerationThreshold = 40.0f;
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 7a4940ef41f15204f8af825724f71a3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Manager.cs
uploadId: 546658
@@ -0,0 +1,86 @@
using UnityEngine;
namespace VRSDK
{
public class VR_Outline : MonoBehaviour
{
[HideInInspector]
public float outlineActive = 0;
public float outlineThickness = 1f;
public Color outlineColor = new Color( 49.0f / 255.0f, 246.0f / 255.0f, 0 / 255.0f );
private Material outlineMaterial;
private GameObject outlineModel;
private Material outlineModelMaterial;
private float lastIsActive = 100;
void Start()
{
outlineMaterial = Resources.Load( "OutlineMaterial" ) as Material;
this.RefreshHighlightMesh();
}
void Update()
{
if (this.lastIsActive != this.outlineActive)
{
outlineModelMaterial.SetFloat( "_Alpha", this.outlineActive );
outlineModelMaterial.SetFloat( "_Thickness", this.outlineThickness );
outlineModelMaterial.SetColor( "_OutlineColor", (Color) this.outlineColor );
this.lastIsActive = this.outlineActive;
if (this.outlineActive > 0)
{
this.outlineModel.SetActive( true );
}
else
{
this.outlineModel.SetActive( false );
}
}
}
public void RefreshHighlightMesh()
{
if (this.outlineModel != null)
{
Destroy( outlineModel );
}
MeshFilter[] meshFilters = GetComponentsInChildren<MeshFilter>();
CombineInstance[] combine = new CombineInstance[meshFilters.Length];
int i = 0;
while (i < meshFilters.Length)
{
combine[i].mesh = meshFilters[i].sharedMesh;
combine[i].transform = gameObject.transform.worldToLocalMatrix * meshFilters[i].transform.localToWorldMatrix;
i++;
}
this.outlineModel = new GameObject( name + "OutlineModel" );
outlineModel.transform.SetParent( this.gameObject.transform, false );
MeshFilter filter = outlineModel.AddComponent<MeshFilter>();
filter.mesh = new Mesh();
filter.mesh.CombineMeshes( combine );
MeshRenderer renderer = outlineModel.AddComponent<MeshRenderer>();
renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
renderer.receiveShadows = false;
renderer.material = outlineMaterial;
this.outlineModelMaterial = renderer.material;
this.outlineModel.SetActive( false );
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 59c17a3a23582034da22aa3a326f5f6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Outline.cs
uploadId: 546658
@@ -0,0 +1,30 @@
using UnityEngine;
namespace VRSDK
{
[RequireComponent( typeof( VR_Outline ) )]
public class VR_OutlineHighlight : VR_Highlight
{
private VR_Outline outline = null;
protected override void Awake()
{
base.Awake();
outline = GetComponent<VR_Outline>();
}
public override void Highlight(VR_Controller controller)
{
base.Highlight( controller );
outline.outlineActive = 1.0f;
}
public override void UnHighlight(VR_Controller controller)
{
base.UnHighlight( controller );
outline.outlineActive = 0.0f;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8877bd0da2335e848b497f330e44a8fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_OutlineHighlight.cs
uploadId: 546658
@@ -0,0 +1,112 @@
using UnityEngine;
using UnityEngine.Events;
using VRSDK.Integration;
namespace VRSDK
{
public class VR_Player : MonoBehaviour
{
[SerializeField] private VR_Controller rightController = null;
[SerializeField] private VR_Controller leftController = null;
[SerializeField] private VR_CharacterController m_VRCharacterController = null;
[SerializeField] private Camera m_centerCamera = null;
[SerializeField] private ControllerGestureConfig gestureConfig = null;
[SerializeField] private UnityEvent onInitializeComplete = null;
[SerializeField] private Vector3 m_handGrabGrabRotationOffset = Vector3.zero;
private VR_Integration integration = null;
public VR_CharacterController VR_CharacterController => m_VRCharacterController;
public Camera CenterCamera => m_centerCamera;
public CharacterController CharacterController
{
get
{
return FindObjectOfType<CharacterController>();
}
}
public VR_Controller LeftController
{
get
{
return GetOrInitializeController(VR_ControllerType.Left);
}
}
public VR_Controller RightController
{
get
{
return GetOrInitializeController(VR_ControllerType.Right);
}
}
public VR_Controller GetActiveController { get { return integration.GetActiveController(); } }
public Transform TrackingSpace { get { return integration.GeTrackingSpaceTransform(); } }
public Transform RealLeftHandTransform { get { return integration.GetLeftHandTransform(); } }
public Transform RealRightHandTransform { get { return integration.GetRightHandTransform(); } }
public Vector3 HandGrabRotationOffset => m_handGrabGrabRotationOffset;
private VR_Controller GetOrInitializeController(VR_ControllerType controllerType)
{
VR_Controller controller = controllerType == VR_ControllerType.Right ? rightController : leftController;
controller.Construct(gestureConfig);
return controller;
}
protected virtual VR_Controller TryGetController(VR_ControllerType controllerType)
{
return controllerType == VR_ControllerType.Right ? rightController : leftController;
}
private Transform GetRealHandTransformForController(VR_ControllerType controllerType)
{
return controllerType == VR_ControllerType.Right ? RealRightHandTransform : RealLeftHandTransform;
}
public void Construct()
{
if (VR_Manager.instance.CurrentSDK == VR_SDK.Oculus)
{
integration = new VR_OculusIntegration();
}
else if (VR_Manager.instance.CurrentSDK == VR_SDK.Steam_VR)
{
integration = new VR_SteamVRIntegration();
}
else if (VR_Manager.instance.CurrentSDK == VR_SDK.UnityXR)
{
integration = new VR_XRIntegration();
}
else
{
Debug.LogError("[Critical Error] You have set CurrentSDK to None select VR_Manager GameObject in your current scene and please select a valid SDK");
Debug.Break();
return;
}
rightController = GetOrInitializeController(VR_ControllerType.Right);
leftController = GetOrInitializeController(VR_ControllerType.Left);
onInitializeComplete.Invoke();
}
private void Awake()
{
//notify a new player
VR_Manager.instance.SetCurrentPlayer(this);
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 528a541df82fb9549b2ccc19a863b14d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Player.cs
uploadId: 546658
@@ -0,0 +1,158 @@
using System.Collections;
using UnityEngine;
using System;
namespace VRSDK
{
public class VR_ScreenFader : MonoBehaviour
{
[Tooltip( "Screen color at maximum fade" )]
public Color fadeColor = new Color( 0.01f, 0.01f, 0.01f, 1.0f );
[SerializeField] private float startAlpha = 0.0f;
/// <summary>
/// The render queue used by the fade mesh. Reduce this if you need to render on top of it.
/// </summary>
public int renderQueue = 5000;
private float uiFadeAlpha = 0;
private MeshRenderer fadeRenderer;
private MeshFilter fadeMesh;
private Material fadeMaterial = null;
private bool isFading = false;
protected virtual void Start()
{
// create the fade material
fadeMaterial = new Material( Shader.Find( "VR/Unlit Transparent Color" ) );
fadeMesh = gameObject.GetComponent<MeshFilter>();
if (fadeMesh == null)
fadeMesh = gameObject.AddComponent<MeshFilter>();
fadeRenderer = gameObject.GetComponent<MeshRenderer>();
if (fadeRenderer == null)
fadeRenderer = gameObject.AddComponent<MeshRenderer>();
var mesh = new Mesh();
fadeMesh.mesh = mesh;
Vector3[] vertices = new Vector3[4];
float width = 2f;
float height = 2f;
float depth = 1f;
vertices[0] = new Vector3( -width, -height, depth );
vertices[1] = new Vector3( width, -height, depth );
vertices[2] = new Vector3( -width, height, depth );
vertices[3] = new Vector3( width, height, depth );
mesh.vertices = vertices;
int[] tri = new int[6];
tri[0] = 0;
tri[1] = 2;
tri[2] = 1;
tri[3] = 2;
tri[4] = 3;
tri[5] = 1;
mesh.triangles = tri;
Vector3[] normals = new Vector3[4];
normals[0] = -Vector3.forward;
normals[1] = -Vector3.forward;
normals[2] = -Vector3.forward;
normals[3] = -Vector3.forward;
mesh.normals = normals;
Vector2[] uv = new Vector2[4];
uv[0] = new Vector2( 0, 0 );
uv[1] = new Vector2( 1, 0 );
uv[2] = new Vector2( 0, 1 );
uv[3] = new Vector2( 1, 1 );
mesh.uv = uv;
SetMaterialAlpha(startAlpha);
}
/// <summary>
/// Cleans up the fade material
/// </summary>
void OnDestroy()
{
if (fadeRenderer != null)
Destroy( fadeRenderer );
if (fadeMaterial != null)
Destroy( fadeMaterial );
if (fadeMesh != null)
Destroy( fadeMesh );
}
public void FadeOut(float time , Action onComplete = null)
{
StartCoroutine( Fade( 1.0f , 0.0f , time , onComplete ) );
}
public void FadeIn(float time, Action onComplete = null)
{
StartCoroutine( Fade( 0.0f, 1.0f, time, onComplete ) );
}
/// <summary>
/// Fades alpha from 1.0 to 0.0
/// </summary>
public IEnumerator Fade(float startAlpha, float endAlpha , float time , Action onComplete = null)
{
float elapsedTime = 0.0f;
while (elapsedTime < time)
{
elapsedTime += Time.deltaTime;
float currentAlpha = Mathf.Lerp( startAlpha, endAlpha, Mathf.Clamp01( elapsedTime / time ) );
SetMaterialAlpha(currentAlpha);
yield return new WaitForEndOfFrame();
}
if (onComplete != null)
onComplete();
}
/// <summary>
/// Update material alpha. UI fade and the current fade due to fade in/out animations (or explicit control)
/// both affect the fade. (The max is taken)
/// </summary>
public void SetMaterialAlpha(float alpha)
{
Color color = fadeColor;
color.a = Mathf.Max( alpha, uiFadeAlpha );
isFading = color.a > 0;
if (fadeMaterial != null)
{
fadeMaterial.color = color;
fadeMaterial.renderQueue = renderQueue;
fadeRenderer.material = fadeMaterial;
fadeRenderer.enabled = isFading;
}
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 5cac8eaff32a70b469d475f9c91b96c0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_ScreenFader.cs
uploadId: 546658
@@ -0,0 +1,212 @@
using UnityEngine;
using VRSDK.Events;
namespace VRSDK
{
public class VR_Slider : VR_Grabbable
{
[SerializeField] private Axis slideAxis = Axis.Forward;
[SerializeField] private Transform slideStartMarker = null;
[SerializeField] private Transform slideEndMarker = null;
[SerializeField] private OnValueChangeEvent onValueChange = null;
private Vector3 initialLocalPosition = Vector3.zero;
private Vector3 slideStartMarkeLocalPosition = Vector3.zero;
private Vector3 slideEndMarkerLocalPosition = Vector3.zero;
private Vector3 calculateControllerLocalPosition = Vector3.zero;
private float movementRange = 0.0f;
private float currentValue = 0.0f;
public OnValueChangeEvent OnValueChange { get { return onValueChange; } }
protected override void Awake()
{
base.Awake();
initialLocalPosition = transform.localPosition;
slideStartMarkeLocalPosition = slideStartMarker.localPosition;
slideEndMarkerLocalPosition = slideEndMarker.localPosition;
movementRange = CalculateMovementRange();
}
private void LateUpdate()
{
if (activeController == null)
return;
Vector3 controllerPosition = activeController.OriginalParent.position;
calculateControllerLocalPosition = transform.parent.InverseTransformPoint( activeController.OriginalParent.position );
}
protected override void GrabUpdate ()
{
if (activeController == null)
return;
if (CanSlide(calculateControllerLocalPosition))
{
if (slideAxis == Axis.Horizontal)
{
transform.localPosition = new Vector3( calculateControllerLocalPosition.x, initialLocalPosition.y, initialLocalPosition.z );
}
else if (slideAxis == Axis.Vertical)
{
transform.localPosition = new Vector3( initialLocalPosition.x, calculateControllerLocalPosition.y, initialLocalPosition.z );
}
else if (slideAxis == Axis.Forward)
{
transform.localPosition = new Vector3( initialLocalPosition.x, initialLocalPosition.y, calculateControllerLocalPosition.z );
}
}
UpdateSlideValue(calculateControllerLocalPosition);
base.GrabUpdate();
}
private bool CanSlide(Vector3 controllerLocalPosition)
{
if (slideAxis == Axis.Horizontal)
{
return slideStartMarkeLocalPosition.x < controllerLocalPosition.x && slideEndMarkerLocalPosition.x > controllerLocalPosition.x;
}
if (slideAxis == Axis.Vertical)
{
return slideStartMarkeLocalPosition.y < controllerLocalPosition.y && slideEndMarkerLocalPosition.y > controllerLocalPosition.y;
}
if (slideAxis == Axis.Forward)
{
return slideStartMarkeLocalPosition.z < controllerLocalPosition.z && slideEndMarkerLocalPosition.z > controllerLocalPosition.z;
}
return false;
}
private void UpdateSlideValue(Vector3 controllerLocalPosition)
{
float distance = CalculateDistance( controllerLocalPosition );
float value = Mathf.Clamp01( distance / movementRange );
if (Mathf.Abs( value - currentValue ) > 0.01)
{
onValueChange.Invoke( value );
currentValue = value;
}
}
private float CalculateDistance(Vector3 controllerLocalPosition)
{
if (ControllerIsBeyondRange( controllerLocalPosition ))
return 1.0f;
else if (ControllerIsBelowRange( controllerLocalPosition ))
return 0.0f;
if (slideAxis == Axis.Horizontal)
{
return Mathf.Abs( slideStartMarkeLocalPosition.x - controllerLocalPosition.x );
}
if (slideAxis == Axis.Vertical)
{
return Mathf.Abs( slideStartMarkeLocalPosition.y - controllerLocalPosition.y );
}
if (slideAxis == Axis.Forward)
{
return Mathf.Abs( slideStartMarkeLocalPosition.z - controllerLocalPosition.z );
}
return 0.0f;
}
private float CalculateMovementRange()
{
if (slideAxis == Axis.Horizontal)
{
return Mathf.Abs( slideStartMarkeLocalPosition.x - slideEndMarkerLocalPosition.x );
}
if (slideAxis == Axis.Vertical)
{
return Mathf.Abs( slideStartMarkeLocalPosition.y - slideEndMarkerLocalPosition.y );
}
if (slideAxis == Axis.Forward)
{
return Mathf.Abs( slideStartMarkeLocalPosition.z - slideEndMarkerLocalPosition.z );
}
return 0.0f;
}
private bool ControllerIsBeyondRange(Vector3 controllerLocalPosition)
{
if (slideAxis == Axis.Horizontal)
{
return slideEndMarkerLocalPosition.x < controllerLocalPosition.x;
}
if (slideAxis == Axis.Vertical)
{
return slideEndMarkerLocalPosition.y < controllerLocalPosition.y;
}
if (slideAxis == Axis.Forward)
{
return slideEndMarkerLocalPosition.z < controllerLocalPosition.z;
}
return false;
}
private bool ControllerIsBelowRange(Vector3 controllerLocalPosition)
{
if (slideAxis == Axis.Horizontal)
{
return slideStartMarkeLocalPosition.x > controllerLocalPosition.x;
}
if (slideAxis == Axis.Vertical)
{
return slideStartMarkeLocalPosition.y > controllerLocalPosition.y;
}
if (slideAxis == Axis.Forward)
{
return slideStartMarkeLocalPosition.z > controllerLocalPosition.z;
}
return false;
}
public override void OnGrabSuccess(VR_Controller controller)
{
activeController = controller;
currentGrabState = GrabState.Grab;
RaiseOnGrabStateChangeEvent( GrabState.Grab );
GrabController.SetVisibility( !GetCurrentHandAnimationSettings().hideHandOnGrab );
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4d8d286a3e2a0f14c8e86f01e649043a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Slider.cs
uploadId: 546658
@@ -0,0 +1,42 @@
using UnityEngine;
using System.Collections;
namespace VRSDK
{
public class VR_Trowable : MonoBehaviour
{
[SerializeField] private float speedModifier = 1.5f;
[SerializeField] private float aungularSpeedModifier = 1.5f;
[SerializeField] private float maxAngularVelocity = 10.0f;
private Rigidbody rb = null;
public float SpeedModifier { get { return speedModifier; } }
public float AngularSpeedModifier { get { return aungularSpeedModifier; } }
bool throwed = false;
private void Awake()
{
rb = GetComponent<Rigidbody>();
rb.maxAngularVelocity = maxAngularVelocity;
VR_Grabbable grabbable = GetComponent<VR_Grabbable>();
if (grabbable == null)
{
Debug.LogError( "Trowable needs VR_Grabbable script in order to work!" );
return;
}
GetComponent<VR_Grabbable>().OnAfterThrow.AddListener( delegate
{
rb.linearVelocity *= speedModifier;
rb.angularVelocity *= aungularSpeedModifier;
} );
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 5ffdae6c5bdd6ce42a75994fccf91e91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_Trowable.cs
uploadId: 546658
@@ -0,0 +1,237 @@
using UnityEngine;
using UnityEngine.Events;
namespace VRSDK
{
public class VR_TwoHandGrabbable : MonoBehaviour
{
[SerializeField] private VR_Grabbable dominantGrabbable = null;
[SerializeField] private VR_Grabbable secondaryGrabbable = null;
[SerializeField] private UnityEvent onTwoHandGrabStart = null;
[SerializeField] private Vector3 rightHandRotOffset = Vector3.zero;
[SerializeField] private Vector3 leftHandRotOffset = Vector3.zero;
[SerializeField] private UnityEvent onTwoHandGrabEnd = null;
private VR_Controller secondaryController = null;
private Quaternion desireRotation = Quaternion.identity;
private Vector3 dir = Vector3.zero;
private bool applyTwoHandTransformManually = false;
public UnityEvent OnTwoHandGrabStart { get { return onTwoHandGrabStart; } }
public UnityEvent OnTwoHandGrabEnd { get { return onTwoHandGrabEnd; } }
private Quaternion HandRotOffset
{
get
{
if (dominantGrabbable.GrabController.ControllerType == VR_ControllerType.Right)
return Quaternion.Euler( rightHandRotOffset );
return Quaternion.Euler( leftHandRotOffset );
}
}
private void Awake()
{
//disable secondary grabbable while dominat grabbable is dropped
secondaryGrabbable.enabled = false;
dominantGrabbable.OnGrabStateChange.AddListener( OnDominantGrabbableGrabStateChange );
secondaryGrabbable.OnGrabStateChange.AddListener( OnSecondaryGrabbableGrabStateChange );
//prevent the VR_Grabbable for making changes in the object, so we can control it
secondaryGrabbable.PreventDefault();
}
private void Update()
{
if (CanUpdate())
return;
//set the desire rotation to the dominanthand
dominantGrabbable.GrabController.transform.rotation = desireRotation;
}
private void LateUpdate()
{
if (!applyTwoHandTransformManually)
{
TwoHandUpdate();
}
}
public void TwoHandUpdate()
{
if (CanUpdate())
{
//for some reason the secondary controller should be dropped now
if (SecondaryGrabbableShouldBeDropped())
{
ReleaseSecondaryGrabbable();
}
//dominantGrabbable.IsUsingTwoHandGrabbable = false;
return;
}
//dominantGrabbable.IsUsingTwoHandGrabbable = true;
desireRotation = CalculateDesireRotation();
/*
if (dominantGrabbable.GrabMode == GrabMode.Physics)
{
dominantGrabbable.TwoHandGrabbableDesireRotation = desireRotation;
}*/
if (dominantGrabbable.GrabController.transform.parent == null)
{
return;
}
Quaternion rotOffset = dominantGrabbable.GrabController.RotationOffset;
if (rotOffset.eulerAngles.magnitude > 0.001f)
{
desireRotation = desireRotation * dominantGrabbable.RotationOffset;
}
//desireRotation = desireRotation * Quaternion.Euler( dominantGrabbable.GetCurrentHandInteractSettings().rotationOffset);
//set the desire rotation to the dominanthand
dominantGrabbable.GrabController.transform.rotation = desireRotation;
dominantGrabbable.GrabController.transform.localPosition = dominantGrabbable.GrabController.InitialPosition + ( dominantGrabbable.GrabController.transform.parent.InverseTransformDirection( dir * -1.0f ) * ( dominantGrabbable.GrabController.PositionOffset.magnitude ) );
}
private bool CanUpdate()
{
return dominantGrabbable.CurrentGrabState != GrabState.Grab || secondaryGrabbable.CurrentGrabState != GrabState.Grab;
}
private Quaternion CalculateDesireRotation()
{
dir = ( secondaryGrabbable.GrabController.OriginalParent.transform.position - GetDominatGrabbableGrabPosition() ).normalized;
Vector3 customDir = dominantGrabbable.GrabController.OriginalParent.forward;
float angle = Vector2.Angle( new Vector2( dir.x, dir.z ), new Vector2( customDir.x, customDir.z ) );
Quaternion result = Quaternion.LookRotation( dir ) * Quaternion.Euler( 0.0f, 0.0f, dominantGrabbable.GrabController.OriginalParent.localEulerAngles.z * ( angle > 90.0f && angle < 180.0f ? -1.0f : 1.0f ) );
return result * HandRotOffset;
}
private bool SecondaryGrabbableShouldBeDropped()
{
return dominantGrabbable.CurrentGrabState == GrabState.UnGrab && secondaryGrabbable.CurrentGrabState == GrabState.Grab;
}
private bool ShouldCalculateRotationFromOriginalPosition()
{
return false;
}
private Vector3 GetDominatGrabbableGrabPosition()
{
return ShouldCalculateRotationFromOriginalPosition() ? dominantGrabbable.GrabController.OriginalParent.position : dominantGrabbable.GrabController.transform.position;
}
private void OnDominantGrabbableGrabStateChange(GrabState state)
{
if (state == GrabState.Drop)
{
if (secondaryGrabbable.CurrentGrabState == GrabState.Grab || secondaryGrabbable.CurrentGrabState == GrabState.Drop)
{
ReleaseSecondaryGrabbable();
}
secondaryGrabbable.enabled = false;
}
else if (state == GrabState.Grab)
{
secondaryGrabbable.enabled = true;
}
}
private void ReleaseSecondaryGrabbable()
{
if (secondaryController == null)
{
secondaryGrabbable.ForceDrop();
if(OnTwoHandGrabEnd != null)
OnTwoHandGrabEnd.Invoke();
return;
}
secondaryGrabbable.ForceDrop();
secondaryController.SetVisibility( true );
//dominantGrabbable.GrabController.UsePositionOffset = true;
secondaryController.SetPositionControlMode( MotionControlMode.Engine );
secondaryController.SetRotationControlMode( MotionControlMode.Engine );
if(OnTwoHandGrabEnd != null)
OnTwoHandGrabEnd.Invoke();
}
private void OnSecondaryGrabbableGrabStateChange( GrabState state)
{
if (state == GrabState.Grab)
{
dominantGrabbable.GrabController.UsePositionOffset = false;
secondaryController = secondaryGrabbable.GrabController;
Transform interactPoint = secondaryGrabbable.GetCurrentHandInteractSettings().interactPoint;
secondaryController.SetVisibility( !secondaryGrabbable.GetCurrentHandAnimationSettings().hideHandOnGrab );
secondaryController.SetPositionControlMode( MotionControlMode.Free );
secondaryController.SetRotationControlMode( MotionControlMode.Free );
secondaryController.transform.parent = interactPoint;
secondaryController.transform.localPosition = Vector3.zero;
secondaryController.transform.rotation = interactPoint.rotation * Quaternion.Euler( secondaryGrabbable.GetCurrentHandInteractSettings().rotationOffset );
if (OnTwoHandGrabStart != null)
OnTwoHandGrabStart.Invoke();
}
else if(state == GrabState.Drop && dominantGrabbable.CurrentGrabState == GrabState.Grab)
{
dominantGrabbable.GrabController.UsePositionOffset = true;
secondaryController.SetPositionControlMode( MotionControlMode.Engine );
secondaryController.SetRotationControlMode( MotionControlMode.Engine );
secondaryController.SetVisibility( true);
if (OnTwoHandGrabEnd != null)
OnTwoHandGrabEnd.Invoke();
}
}
public void SetApplyTwoHandTransformManually(bool value)
{
applyTwoHandTransformManually = value;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 090b3e3f25146ee47a4aa527bc198e25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_TwoHandGrabbable.cs
uploadId: 546658
@@ -0,0 +1,80 @@
using UnityEngine;
using System.Collections;
namespace VRSDK
{
public class VR_UIHighlight : VR_Highlight
{
#region INSPECTOR
[SerializeField] private Canvas canvas = null;
[SerializeField] private Transform grabbableMarker = null;
[SerializeField] private float scaleTime = 0.2f;
[SerializeField] private float radius = 0.2f;
#endregion
private Coroutine scaleCoroutine = null;
private void Update()
{
LookAtCamera();
if (CanHighlight())
{
if (!canvas.gameObject.activeInHierarchy)
canvas.gameObject.SetActive( true );
}
else
{
if (canvas.gameObject.activeInHierarchy)
canvas.gameObject.SetActive( false );
grabbableMarker.localScale = Vector3.one;
}
}
private void LookAtCamera()
{
canvas.transform.position = canvas.transform.parent.position + ( ( Camera.main.transform.position - transform.position ).normalized * radius );
}
public override void Highlight(VR_Controller controller)
{
ScaleTween( 1.2f );
}
public override void UnHighlight(VR_Controller controller)
{
ScaleTween( 1.0f );
}
private void ScaleTween(float scale)
{
if (scaleCoroutine != null)
StopCoroutine( scaleCoroutine );
scaleCoroutine = StartCoroutine( ScaleRoutine( scale ) );
}
private IEnumerator ScaleRoutine(float scale)
{
float currentTime = 0.0f;
while (currentTime <= scaleTime)
{
currentTime += Time.deltaTime;
grabbableMarker.transform.localScale = Vector3.Lerp( grabbableMarker.transform.localScale , Vector3.one * scale , currentTime / scaleTime );
yield return new WaitForEndOfFrame();
}
grabbableMarker.transform.localScale = Vector3.one * scale;
}
}
}
@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 824e26edb4f057f4896419b222577cec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 168243
packageName: VR Beats Kit
packageVersion: 2.0
assetPath: Assets/VRBeatsKit/Modules/VRSDK/VR/VR_UIHighlight.cs
uploadId: 546658