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:
@@ -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
|
||||
Reference in New Issue
Block a user