NEW HVR 2.9.1f
This commit is contained in:
@@ -5,6 +5,10 @@ using UnityEngine.Events;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Basic button check for travel along a defined axis, requires the user to have setup their own constraint system.
|
||||
/// Superceded by the new HVRPhysicsButton component which helps create joints and limits for you
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRButton : MonoBehaviour
|
||||
{
|
||||
@@ -38,11 +42,6 @@ namespace HurricaneVR.Framework.Components
|
||||
Rigidbody = GetComponent<Rigidbody>();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
var distance = (StartPosition - transform.localPosition).magnitude;
|
||||
|
||||
@@ -2,18 +2,12 @@
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Tags a grabbable object as climbable which is then used by the player controller to know if they can climb or not.
|
||||
/// For the hexabody integration it will kick in the climbing strength override set on the HexaHands component.
|
||||
/// </summary>
|
||||
public class HVRClimbable : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ using UnityEngine.Events;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper component used to propogate a collision if a force or velocity threshold was met.
|
||||
/// </summary>
|
||||
public class HVRCollisionEvents : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
|
||||
+16
-8
@@ -5,6 +5,10 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles offsettings the physics hand target based on the connected device. Also offsets the target based on grab point settings if desired.
|
||||
/// To manage custom offsets please use the SetMiscPositionOffset(Vector3 position, Vector3 rotation) and ResetGrabPointOffsets() functions.
|
||||
/// </summary>
|
||||
public class HVRControllerOffset : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
@@ -30,16 +34,20 @@ namespace HurricaneVR.Framework.Components
|
||||
public Vector3 ControllerRotationOffset => _offsets != null ? _offsets.Rotation : Vector3.zero;
|
||||
|
||||
[Header("Debugging")]
|
||||
public Vector3 TargetGrabPointPositionOffset;
|
||||
public Vector3 TargetGrabPointRotationOffset;
|
||||
|
||||
public Vector3 GrabPointPositionOffset;
|
||||
public Vector3 GrabPointRotationOffset;
|
||||
|
||||
public Vector3 MiscPositionOffset;
|
||||
public Vector3 MiscRotationOffset;
|
||||
|
||||
[Tooltip("Enable to test live updating of the Misc offset fields.")]
|
||||
public bool LiveUpdateOffsets;
|
||||
|
||||
[SerializeField] private Vector3 TargetGrabPointPositionOffset;
|
||||
[SerializeField] private Vector3 TargetGrabPointRotationOffset;
|
||||
|
||||
[SerializeField] private Vector3 GrabPointPositionOffset;
|
||||
[SerializeField] private Vector3 GrabPointRotationOffset;
|
||||
|
||||
[SerializeField] private Vector3 MiscPositionOffset;
|
||||
[SerializeField] private Vector3 MiscRotationOffset;
|
||||
|
||||
|
||||
private Quaternion _teleportStartRotation;
|
||||
|
||||
public bool _updatingRotation;
|
||||
|
||||
+18
-2
@@ -15,10 +15,13 @@ namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
[Header("Unity XR")]
|
||||
public HVRDevicePoseOffset Oculus;
|
||||
|
||||
public HVRDevicePoseOffset WMR;
|
||||
public HVRDevicePoseOffset Pico;
|
||||
|
||||
[Header("SteamVR")]
|
||||
public HVRDevicePoseOffset OculusSteamVR;
|
||||
|
||||
public HVRDevicePoseOffset WMRSteamVR;
|
||||
public HVRDevicePoseOffset ReverbG2SteamVR;
|
||||
public HVRDevicePoseOffset CosmosSteamVR;
|
||||
@@ -27,11 +30,13 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
[Header("OpenXR")]
|
||||
public HVRDevicePoseOffset OculusOpenXR;
|
||||
|
||||
public HVRDevicePoseOffset WMROpenXR;
|
||||
public HVRDevicePoseOffset ReverbG2OpenXR;
|
||||
public HVRDevicePoseOffset ViveOpenXR;
|
||||
public HVRDevicePoseOffset CosmosOpenXR;
|
||||
public HVRDevicePoseOffset KnucklesOpenXR;
|
||||
public HVRDevicePoseOffset PicoOpenXR;
|
||||
|
||||
public HVRDevicePoseOffset GetDeviceOffset(HVRHandSide side)
|
||||
{
|
||||
@@ -47,7 +52,6 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
switch (type)
|
||||
{
|
||||
|
||||
case HVRControllerType.Oculus:
|
||||
if (steamVR)
|
||||
{
|
||||
@@ -83,6 +87,7 @@ namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
return ViveOpenXR;
|
||||
}
|
||||
|
||||
break;
|
||||
case HVRControllerType.Knuckles:
|
||||
if (steamVR)
|
||||
@@ -93,6 +98,7 @@ namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
return KnucklesOpenXR;
|
||||
}
|
||||
|
||||
break;
|
||||
case HVRControllerType.Cosmos:
|
||||
if (steamVR)
|
||||
@@ -103,6 +109,7 @@ namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
return CosmosOpenXR;
|
||||
}
|
||||
|
||||
break;
|
||||
case HVRControllerType.ReverbG2:
|
||||
if (steamVR)
|
||||
@@ -113,7 +120,14 @@ namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
return ReverbG2OpenXR;
|
||||
}
|
||||
|
||||
break;
|
||||
case HVRControllerType.Pico:
|
||||
if (steamVR) //is there a way to detect pico when using steamvr? it's emulated as a oculus device
|
||||
return null;
|
||||
if (openXr)
|
||||
return PicoOpenXR;
|
||||
return Pico;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -124,7 +138,9 @@ namespace HurricaneVR.Framework.Components
|
||||
public class HVRDevicePoseOffset
|
||||
{
|
||||
public Vector3 Position;
|
||||
[FormerlySerializedAs("_rotation")] [SerializeField]
|
||||
|
||||
[FormerlySerializedAs("_rotation")]
|
||||
[SerializeField]
|
||||
public Vector3 Rotation;
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,6 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
public HVRDestructible Desctructible;
|
||||
|
||||
|
||||
|
||||
void Start()
|
||||
{
|
||||
Rigidbody = GetComponent<Rigidbody>();
|
||||
|
||||
@@ -4,6 +4,9 @@ using UnityEngine.Events;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Publishes the destroyed event so others may know, used by the hand grabber to know if the held object is destroyed
|
||||
/// </summary>
|
||||
public class HVRDestroyListener : MonoBehaviour
|
||||
{
|
||||
public HVRDestroyedEvent Destroyed = new HVRDestroyedEvent();
|
||||
|
||||
@@ -3,6 +3,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Destroys this game object after a timeout
|
||||
/// </summary>
|
||||
public class HVRDestroyTimer : MonoBehaviour
|
||||
{
|
||||
public void StartTimer(float timeout)
|
||||
|
||||
@@ -3,6 +3,11 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper component that spawns a prefab game object when the Destroy function is called.
|
||||
/// If the spawned game object has a rigidbodies then they will have force added to them based on the
|
||||
/// fields provided.
|
||||
/// </summary>
|
||||
public class HVRDestructible : MonoBehaviour
|
||||
{
|
||||
public GameObject DestroyedVersion;
|
||||
@@ -17,8 +22,12 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
public bool IgnorePlayerCollision = true;
|
||||
|
||||
public bool Destroyed { get; protected set; }
|
||||
|
||||
public virtual void Destroy()
|
||||
{
|
||||
if (Destroyed) return;
|
||||
|
||||
if (DestroyedVersion)
|
||||
{
|
||||
var destroyed = Instantiate(DestroyedVersion, transform.position, transform.rotation);
|
||||
@@ -59,6 +68,7 @@ namespace HurricaneVR.Framework.Components
|
||||
}
|
||||
}
|
||||
|
||||
Destroyed = true;
|
||||
Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Deprecated and left in for older projects. Superceded by HVRPhysicsDial and HVRRotationTracker
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(HVRGrabbable))]
|
||||
public class HVRDial : MonoBehaviour
|
||||
{
|
||||
|
||||
+25
-1
@@ -1,18 +1,42 @@
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using HurricaneVR.Framework.Core.Player;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
|
||||
public class HVRHandImpactHaptics : HVRImpactHapticsBase
|
||||
{
|
||||
public HVRHandGrabber Hand;
|
||||
|
||||
[Tooltip("If true and the hand is holding something, haptics will not play.")]
|
||||
public bool HandGrabbingPrevents = true;
|
||||
|
||||
[Tooltip("If true the max force for the haptic amplitude calc will use the hand's default max force.")]
|
||||
public bool UseHandMaxStrength = true;
|
||||
|
||||
private HVRJointHand _hand;
|
||||
|
||||
public override float MaxForce
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UseHandMaxStrength)
|
||||
{
|
||||
if ( _hand && _hand.JointSettings)
|
||||
return _hand.JointSettings.XDrive.MaxForce;
|
||||
}
|
||||
|
||||
return base.MaxForce;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
if (!Hand) TryGetComponent(out Hand);
|
||||
|
||||
TryGetComponent(out _hand);
|
||||
}
|
||||
|
||||
protected override void Vibrate(float duration, float amplitude, float frequency)
|
||||
|
||||
+4
-4
@@ -46,10 +46,10 @@ namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
Folder = DateTime.Now.ToString("yyyyMMdd_HH_mm");
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
void Update()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
|
||||
if (DisablePhysics && !_previousDisable)
|
||||
{
|
||||
@@ -79,9 +79,9 @@ namespace HurricaneVR.Framework.Components
|
||||
_previousDisable = DisablePhysics;
|
||||
|
||||
CheckSnapshot();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
private void CheckSnapshot()
|
||||
{
|
||||
HVRPosableHand hand = null;
|
||||
|
||||
@@ -12,10 +12,19 @@ namespace HurricaneVR.Framework.Components
|
||||
public class HVRImpactHaptics : ScriptableObject
|
||||
{
|
||||
public float Timeout = .3f;
|
||||
|
||||
[Tooltip("Collision Velocity Square Magnitude cut off filter")]
|
||||
public float SqrMagThreshold = .30f;
|
||||
public float MaxForce = 600f;
|
||||
|
||||
[Tooltip("Collision force divided by this and fed into the AmpCurve. ")]
|
||||
public float MaxForce = 300f;
|
||||
|
||||
public AnimationCurve AmpCurve;
|
||||
|
||||
[Tooltip("Duration fed into haptics API.")]
|
||||
public float Duration = .25f;
|
||||
|
||||
[Tooltip("Frequency fed into haptics API")]
|
||||
public float Frequency = 150f;
|
||||
|
||||
public void Reset()
|
||||
|
||||
+3
-1
@@ -16,6 +16,8 @@ namespace HurricaneVR.Framework.Components
|
||||
private float _lastHaptic;
|
||||
private Rigidbody Rb;
|
||||
|
||||
public virtual float MaxForce => Data.MaxForce;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
TryGetComponent(out Rb);
|
||||
@@ -50,7 +52,7 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
Force = impulse / Time.fixedDeltaTime;
|
||||
|
||||
var amp = Data.AmpCurve.Evaluate(Force / Data.MaxForce);
|
||||
var amp = Data.AmpCurve.Evaluate(Force / MaxForce);
|
||||
|
||||
Vibrate(Data.Duration, amp, Data.Frequency);
|
||||
|
||||
|
||||
@@ -6,7 +6,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Depecrecated and left in for older projects, superceded by HVRPhysicsLever and HVRRotationTracker
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(HVRGrabbable))]
|
||||
[RequireComponent(typeof(HingeJoint))]
|
||||
public class HVRLever : MonoBehaviour
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper component to parent this transform to the assigned transform on game start
|
||||
/// </summary>
|
||||
public class HVRParentOnStart : MonoBehaviour
|
||||
{
|
||||
public Transform Parent;
|
||||
|
||||
@@ -7,13 +7,24 @@ using UnityEngine.Events;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a joint constrained along one axis with limits based on start and end points defined in the inspector editor.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRPhysicsButton : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
|
||||
[Tooltip("Axis the button will travel on in local space.")]
|
||||
public HVRAxis Axis;
|
||||
|
||||
[Tooltip("Rigidbody this button will connect to with a joint.")]
|
||||
public Rigidbody ConnectedBody;
|
||||
|
||||
[Tooltip("Spring value of the joint")]
|
||||
public float Spring = 1000f;
|
||||
|
||||
[Tooltip("Damper of the joint")]
|
||||
public float Damper = 50f;
|
||||
|
||||
|
||||
|
||||
@@ -8,11 +8,12 @@ using UnityEngine.Serialization;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple component to help setup a joint constrained on one axis. With bonus rotation friction option when held.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRPhysicsDial : MonoBehaviour
|
||||
{
|
||||
[SerializeField] public HVRGrabbable Grabbable;
|
||||
|
||||
[Header("Settings")]
|
||||
[Tooltip("Local axis of rotation")]
|
||||
public HVRAxis Axis;
|
||||
@@ -23,6 +24,7 @@ namespace HurricaneVR.Framework.Components
|
||||
[Tooltip("If true the angular velocity will be zero'd out on release.")]
|
||||
public bool StopOnRelease = true;
|
||||
|
||||
[Tooltip("Defaults to true to prevent rotation when not held")]
|
||||
public bool DisableGravity = true;
|
||||
|
||||
[Header("Joint Limits")]
|
||||
@@ -41,6 +43,7 @@ namespace HurricaneVR.Framework.Components
|
||||
[Tooltip("Angular Damper when the dial is not grabbed")]
|
||||
public float Damper = 3;
|
||||
|
||||
[Tooltip("Optional spring value of the joint to return to starting rotation if desired")]
|
||||
public float Spring;
|
||||
|
||||
[Header("Editor")]
|
||||
@@ -52,6 +55,8 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
public Rigidbody Rigidbody { get; private set; }
|
||||
|
||||
public HVRGrabbable Grabbable { get; private set; }
|
||||
|
||||
public ConfigurableJoint Joint { get; set; }
|
||||
|
||||
protected virtual void Awake()
|
||||
@@ -60,26 +65,14 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
Rigidbody.useGravity = !DisableGravity;
|
||||
|
||||
if (!Grabbable) Grabbable = GetComponent<HVRGrabbable>();
|
||||
|
||||
Grabbable = GetComponent<HVRGrabbable>();
|
||||
if (Grabbable)
|
||||
{
|
||||
Grabbable.HandGrabbed.AddListener(OnDialGrabbed);
|
||||
Grabbable.HandReleased.AddListener(OnDialReleased);
|
||||
}
|
||||
|
||||
if (MinAngle > 0)
|
||||
{
|
||||
MinAngle *= -1;
|
||||
}
|
||||
|
||||
if (MaxAngle < 0)
|
||||
{
|
||||
MaxAngle *= -1;
|
||||
}
|
||||
|
||||
MinAngle = Mathf.Clamp(MinAngle, MinAngle, 0);
|
||||
MaxAngle = Mathf.Clamp(MaxAngle, 0, MaxAngle);
|
||||
FixAngle(ref MinAngle, ref MaxAngle);
|
||||
|
||||
SetupJoint();
|
||||
AfterJointCreated(Joint);
|
||||
@@ -95,7 +88,7 @@ namespace HurricaneVR.Framework.Components
|
||||
if (TargetAngularVelocity > 0f || TargetAngularVelocity < 0f) Joint.targetAngularVelocity = new Vector3(TargetAngularVelocity, 0f, 0f);
|
||||
}
|
||||
|
||||
private void OnDialReleased(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
protected virtual void OnDialReleased(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
{
|
||||
Joint.SetAngularXDrive(Spring, Damper, 10000f);
|
||||
if (StopOnRelease)
|
||||
@@ -104,7 +97,7 @@ namespace HurricaneVR.Framework.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDialGrabbed(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
protected virtual void OnDialGrabbed(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
{
|
||||
Joint.SetAngularXDrive(0f, GrabbedDamper, 10000f);
|
||||
}
|
||||
@@ -143,18 +136,53 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the rotation limits on the Joint's main rotation axis
|
||||
/// </summary>
|
||||
public void SetLimits(float minAngle, float maxAngle)
|
||||
{
|
||||
FixAngle(ref minAngle, ref maxAngle);
|
||||
|
||||
Joint.LimitAngularXMotion();
|
||||
Joint.SetAngularXHighLimit(minAngle);
|
||||
Joint.SetAngularXLowLimit(maxAngle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the limit's to the -MinAngle and MaxAngle values of this component.
|
||||
/// </summary>
|
||||
public void ResetLimits()
|
||||
{
|
||||
Joint.LimitAngularXMotion();
|
||||
Joint.SetAngularXHighLimit(-MinAngle);
|
||||
Joint.SetAngularXLowLimit(-MaxAngle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees the axis of rotation
|
||||
/// </summary>
|
||||
public void RemoveLimits()
|
||||
{
|
||||
Joint.angularXMotion = ConfigurableJointMotion.Free;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sanity check on the angles for the joint high and low settings
|
||||
/// </summary>
|
||||
private void FixAngle(ref float min, ref float max)
|
||||
{
|
||||
if (min > 0)
|
||||
{
|
||||
min *= -1;
|
||||
}
|
||||
|
||||
if (max < 0)
|
||||
{
|
||||
max *= -1;
|
||||
}
|
||||
|
||||
min = Mathf.Clamp(min, min, 0);
|
||||
max = Mathf.Clamp(max, 0, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,42 +7,76 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// This component helps setup the basic functionality of a hinged door.
|
||||
/// Includes locking and latching capability. Handle required rotation for unlatching.
|
||||
/// </summary>
|
||||
[HelpURL("https://cloudwalker2020.github.io/HurricaneVR-Docs/manual/components/door.html")]
|
||||
[RequireComponent(typeof(HVRRotationTracker))]
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRPhysicsDoor : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
[Tooltip("Local axis of rotation")]
|
||||
[Header("Settings")] [Tooltip("Local axis of rotation")]
|
||||
public HVRAxis Axis;
|
||||
public float Mass = 10f;
|
||||
|
||||
[Tooltip("Door's rigidbody mass.")] public float Mass = 10f;
|
||||
|
||||
public bool DisableGravity = true;
|
||||
|
||||
[Tooltip("If true the door and it's handle will have their joint limit's locked on start.")]
|
||||
public bool StartLocked;
|
||||
|
||||
[Tooltip("Rigidbody to connect the joint to")]
|
||||
public Rigidbody ConnectedBody;
|
||||
|
||||
[Header("Door Closing Settings")]
|
||||
[Header("Door Closing Settings")] [Tooltip("Angle threshold to determine if the door is closed or not.")]
|
||||
public float CloseAngle = 5f;
|
||||
|
||||
[Tooltip("The door will automatically shut over this amount of time once it's close enough to be closed.")]
|
||||
public float CloseOverTime = .25f;
|
||||
|
||||
[Tooltip("How long the door angle must be below 'CloseAngle' to become closed.")]
|
||||
public float CloseDetectionTime = .5f;
|
||||
|
||||
[Header("SFX")]
|
||||
[Header("SFX")] [Tooltip("Angle threshold to play opening and closing sound effects.")]
|
||||
public float SFXThresholdAngle = 2.5f;
|
||||
|
||||
public float SFXResetThreshold = 1f;
|
||||
public AudioClip SFXOpened;
|
||||
public AudioClip SFXClosed;
|
||||
|
||||
[Tooltip("Delay before the open / close sfx can be played again")]
|
||||
public float SFXTimeout = 1f;
|
||||
|
||||
[Tooltip("Optional transform to define the position of the open / close sound fx.")]
|
||||
public Transform SFXPosition;
|
||||
|
||||
[Header("Handle")]
|
||||
[Header("Handle")] [Tooltip("If true the handle must rotate beyond 'HandThreshold' amount of degrees before it will unlatch, if false the door will not latch automatically.")]
|
||||
public bool HandleRequiresRotation;
|
||||
|
||||
[Tooltip("Required handle rotation to unlatch the door.")]
|
||||
public float HandleThreshold = 45f;
|
||||
|
||||
[Tooltip("The rotation tracker that reports the amount of rotation of the handle.")]
|
||||
public HVRRotationTracker HandleRotationTracker;
|
||||
|
||||
[Tooltip("If provided (and held) the door will not automatically shut when it is below 'CloseAngle' in degrees.")]
|
||||
public HVRGrabbable HandleGrabbable;
|
||||
|
||||
[Tooltip("Rotational physics component that let's this door component lock the door handle's rotation when the door locks.")]
|
||||
public HVRPhysicsDial DoorKnob;
|
||||
|
||||
|
||||
[Header("Joint Limits")]
|
||||
public bool LimitRotation = true;
|
||||
[Tooltip("The rotation tracker that reports the amount of rotation of the handle.")]
|
||||
public HVRRotationTracker SecondHandleRotationTracker;
|
||||
|
||||
[Tooltip("If provided (and held) the door will not automatically shut when it is below 'CloseAngle' in degrees.")]
|
||||
public HVRGrabbable SecondHandleGrabbable;
|
||||
|
||||
[Tooltip("Rotational physics component that let's this door component lock the door handle's rotation when the door locks.")]
|
||||
public HVRPhysicsDial SecondDoorKnob;
|
||||
|
||||
[Header("Joint Limits")] public bool LimitRotation = true;
|
||||
|
||||
[Tooltip("Minimum Angle about the axis of rotation")]
|
||||
public float MinAngle;
|
||||
@@ -50,19 +84,17 @@ namespace HurricaneVR.Framework.Components
|
||||
[Tooltip("Maximum rotation about the axis of rotation")]
|
||||
public float MaxAngle;
|
||||
|
||||
[Header("Joint Settings")]
|
||||
|
||||
[Tooltip("Angular Damper when the dial is not grabbed")]
|
||||
[Header("Joint Settings")] [Tooltip("Angular Damper of the door hinge.")]
|
||||
public float Damper = 10;
|
||||
|
||||
[Tooltip("Angular Spring that will return the door to it's starting rotation")]
|
||||
public float Spring;
|
||||
|
||||
//[Header("Editor")]
|
||||
//[SerializeField]
|
||||
//protected Quaternion JointStartRotation;
|
||||
|
||||
[Header("Debugging")]
|
||||
public float TargetAngularVelocity = 0f;
|
||||
[Header("Debugging")] public float TargetAngularVelocity = 0f;
|
||||
public bool DoorLatched;
|
||||
public bool DoorClosed;
|
||||
public bool Opened;
|
||||
@@ -161,7 +193,7 @@ namespace HurricaneVR.Framework.Components
|
||||
DoorClosed = false;
|
||||
}
|
||||
|
||||
if (HandleGrabbable && HandleGrabbable.IsBeingHeld)
|
||||
if (HandleGrabbable && HandleGrabbable.IsBeingHeld || SecondHandleGrabbable && SecondHandleGrabbable.IsBeingHeld)
|
||||
{
|
||||
_detectionTimer = 0f;
|
||||
}
|
||||
@@ -209,11 +241,14 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
if (HandleRequiresRotation)
|
||||
{
|
||||
if (HandleRotationTracker.UnsignedAngle >= HandleThreshold)
|
||||
if (HandleRotationTracker.UnsignedAngle >= HandleThreshold ||
|
||||
(SecondHandleRotationTracker && SecondHandleRotationTracker.UnsignedAngle >= HandleThreshold))
|
||||
{
|
||||
DoorLatched = false;
|
||||
}
|
||||
else if (HandleRotationTracker.UnsignedAngle < HandleThreshold && Tracker.UnsignedAngle < CloseAngle)
|
||||
else if (HandleRotationTracker.UnsignedAngle < HandleThreshold &&
|
||||
(!SecondHandleRotationTracker || SecondHandleRotationTracker.UnsignedAngle < HandleThreshold) &&
|
||||
Tracker.UnsignedAngle < CloseAngle)
|
||||
{
|
||||
DoorLatched = true;
|
||||
}
|
||||
@@ -235,7 +270,7 @@ namespace HurricaneVR.Framework.Components
|
||||
PreviousClosed = DoorClosed;
|
||||
}
|
||||
|
||||
private Vector3 GetSFXPosition()
|
||||
protected virtual Vector3 GetSFXPosition()
|
||||
{
|
||||
var position = transform.position;
|
||||
if (SFXPosition)
|
||||
@@ -248,31 +283,30 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
protected virtual void PlayClosedSFX()
|
||||
{
|
||||
|
||||
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXClosed, GetSFXPosition());
|
||||
if (SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXClosed, GetSFXPosition());
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected virtual void PlayOpenedSFX()
|
||||
{
|
||||
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXOpened, GetSFXPosition());
|
||||
if (SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXOpened, GetSFXPosition());
|
||||
}
|
||||
|
||||
protected virtual void OnDoorUnLatched()
|
||||
public virtual void OnDoorUnLatched()
|
||||
{
|
||||
if (VerboseLogging)
|
||||
Debug.Log($"OnDoorUnLatched");
|
||||
UnlockDoorJoint();
|
||||
}
|
||||
|
||||
protected virtual void OnDoorLatched()
|
||||
public virtual void OnDoorLatched()
|
||||
{
|
||||
if (VerboseLogging)
|
||||
Debug.Log($"OnDoorLatched");
|
||||
LockDoorJoint();
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected virtual void OnDoorClosed()
|
||||
{
|
||||
if (VerboseLogging)
|
||||
@@ -281,6 +315,7 @@ namespace HurricaneVR.Framework.Components
|
||||
StartCoroutine(DoorCloseRoutine());
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected virtual void OnDoorOpened()
|
||||
{
|
||||
if (VerboseLogging)
|
||||
@@ -302,6 +337,9 @@ namespace HurricaneVR.Framework.Components
|
||||
Joint.SetAngularXLowLimit(-MaxAngle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the door joint, and the door knob's joint.
|
||||
/// </summary>
|
||||
public virtual void Lock()
|
||||
{
|
||||
Locked = true;
|
||||
@@ -309,6 +347,9 @@ namespace HurricaneVR.Framework.Components
|
||||
LockDoorKnob();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlocks the door and allows the door handle to rotate.
|
||||
/// </summary>
|
||||
public virtual void Unlock()
|
||||
{
|
||||
Locked = false;
|
||||
@@ -323,18 +364,14 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
protected virtual void LockDoorKnob()
|
||||
{
|
||||
if (DoorKnob)
|
||||
{
|
||||
DoorKnob.SetLimits(0, 0);
|
||||
}
|
||||
if (DoorKnob) DoorKnob.SetLimits(0, 0);
|
||||
if (SecondDoorKnob) SecondDoorKnob.SetLimits(0, 0);
|
||||
}
|
||||
|
||||
protected virtual void UnlockDoorKnob()
|
||||
{
|
||||
if (DoorKnob)
|
||||
{
|
||||
DoorKnob.ResetLimits();
|
||||
}
|
||||
if (DoorKnob) DoorKnob.ResetLimits();
|
||||
if (SecondDoorKnob) SecondDoorKnob.ResetLimits();
|
||||
}
|
||||
|
||||
protected IEnumerator DoorCloseRoutine()
|
||||
@@ -353,7 +390,7 @@ namespace HurricaneVR.Framework.Components
|
||||
_doorClosing = false;
|
||||
}
|
||||
|
||||
private void SetupJoint()
|
||||
protected virtual void SetupJoint()
|
||||
{
|
||||
var currentRotation = transform.localRotation;
|
||||
//transform.localRotation = JointStartRotation;
|
||||
@@ -362,7 +399,7 @@ namespace HurricaneVR.Framework.Components
|
||||
Joint.LockLinearMotion();
|
||||
Joint.LockAngularYMotion();
|
||||
Joint.LockAngularZMotion();
|
||||
|
||||
Joint.anchor = Vector3.zero;
|
||||
Joint.axis = Axis.GetVector();
|
||||
|
||||
if (LimitRotation)
|
||||
|
||||
@@ -6,16 +6,28 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper component to constrain a drawer along the desired movement axis handling the joint creation and limiting for you.
|
||||
/// Joint is constrained between the start and end position which is defined in the component inspector.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRPhysicsDrawer : MonoBehaviour
|
||||
{
|
||||
[Header("Settings")]
|
||||
[Tooltip("Axis the drawer will travel on in local space.")]
|
||||
public HVRAxis Axis;
|
||||
|
||||
[Tooltip("Rigidbody to joint to.")]
|
||||
public Rigidbody ConnectedBody;
|
||||
|
||||
[Tooltip("Optional spring that will return to the starting position")]
|
||||
public float Spring = 0;
|
||||
|
||||
[Tooltip("Damper to provide 'friction' to the drawer.")]
|
||||
public float Damper = 10;
|
||||
|
||||
[Header("SFX")] public float SFXResetThreshold = .02f;
|
||||
[Header("SFX")]
|
||||
public float SFXResetThreshold = .02f;
|
||||
public AudioClip SFXOpened;
|
||||
public AudioClip SFXClosed;
|
||||
|
||||
|
||||
@@ -7,23 +7,14 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Lever behaves similar to the dial in rigidbody joint behaviour at this time...
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRPhysicsLever : HVRPhysicsDial
|
||||
{
|
||||
public bool DrawGizmos = true;
|
||||
public ConfigurableJoint preJoint;
|
||||
|
||||
protected override void SetupJoint()
|
||||
{
|
||||
if(!preJoint)
|
||||
{
|
||||
base.SetupJoint();
|
||||
}
|
||||
else
|
||||
{
|
||||
Joint = preJoint;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDrawGizmosSelected()
|
||||
{
|
||||
|
||||
+5
-2
@@ -3,6 +3,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper component to override various rigidbody properties
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class HVRRigidBodyOverrides : MonoBehaviour
|
||||
{
|
||||
@@ -22,7 +25,7 @@ namespace HurricaneVR.Framework.Components
|
||||
[Header("Debug")]
|
||||
public Vector3 COMGizmoSize = new Vector3(.02f, .02f, .02f);
|
||||
public bool LiveUpdate;
|
||||
|
||||
public bool ShowCOMGizmo;
|
||||
public Rigidbody Rigidbody;
|
||||
|
||||
void Awake()
|
||||
@@ -75,7 +78,7 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
void OnDrawGizmosSelected()
|
||||
{
|
||||
//if (OverrideCOM)
|
||||
if (ShowCOMGizmo)
|
||||
{
|
||||
Gizmos.color = Color.yellow;
|
||||
if (OverrideCOM)
|
||||
|
||||
@@ -3,6 +3,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Helps constrain loose joints on the desired axis.
|
||||
/// </summary>
|
||||
public class HVRRigidbodyLocker : MonoBehaviour
|
||||
{
|
||||
public LockOptions Locks;
|
||||
|
||||
@@ -10,17 +10,22 @@ namespace HurricaneVR.Framework.Components
|
||||
public Transform Camera;
|
||||
|
||||
[Header("Settings")]
|
||||
|
||||
[Tooltip("Ring must be within this distance from the camera to be displayed")]
|
||||
public float Distance = 5f;
|
||||
|
||||
|
||||
[Header("Line of Sight Settings")]
|
||||
|
||||
[Tooltip("Use ray cast to the camera collider to determine if we should show")]
|
||||
public bool RequireLineOfSight = true;
|
||||
|
||||
[Tooltip("Layer mask for checking line of sight, include the layer of the camera(default is Player)")]
|
||||
public LayerMask LayerMask;
|
||||
|
||||
[Tooltip("Check line of sight only if distance greater than this")]
|
||||
public float LineOfSightThreshold = 1.5f;
|
||||
|
||||
[Tooltip("Timeout to check line of sight")]
|
||||
public float Delay = 1f;
|
||||
|
||||
@@ -30,7 +35,7 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
if (!Camera)
|
||||
if (!Camera && HVRManager.Instance)
|
||||
{
|
||||
Camera = HVRManager.Instance.Camera;
|
||||
}
|
||||
|
||||
@@ -7,15 +7,26 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to limit rotations beyond the default Physx limit of 177 degrees. Joint is recreated at certain thresholds to allow the wider
|
||||
/// range of motion, only use this if you need range of motion beyond 177 degrees.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
[RequireComponent(typeof(HVRRotationTracker))]
|
||||
public class HVRRotationLimiter : MonoBehaviour
|
||||
{
|
||||
public const float PhysxMaxLimit = 177f;
|
||||
|
||||
[Tooltip("Connected Body of the Joint")]
|
||||
public Rigidbody ConnectedBody;
|
||||
|
||||
[Tooltip("Minimum angle of rotation")]
|
||||
public int MinAngle;
|
||||
|
||||
[Tooltip("Maximum angle of rotation")]
|
||||
public int MaxAngle;
|
||||
|
||||
[Tooltip("Distance traveled before the joint is recreated with new limits")]
|
||||
public float JointResetThreshold = 90f;
|
||||
|
||||
|
||||
|
||||
@@ -3,11 +3,18 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in conjunction with the HVRRotationTracker to play SFX based on rotation amount.
|
||||
/// </summary>
|
||||
public class HVRRotationSFX : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Tracker required to know how far something has rotated")]
|
||||
public HVRRotationTracker Tracker;
|
||||
|
||||
[Tooltip("Clip chosen at random from this list when rotated beyond 'AngleThreshold'")]
|
||||
public AudioClip[] SFX;
|
||||
|
||||
[Tooltip("Rotation distance must exceed this to play another sfx clip")]
|
||||
public float AngleThreshold = 30f;
|
||||
|
||||
[Header("Debug")]
|
||||
@@ -41,11 +48,6 @@ namespace HurricaneVR.Framework.Components
|
||||
}
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void PlaySFX(AudioClip sfx)
|
||||
{
|
||||
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(sfx, transform.position);
|
||||
|
||||
@@ -7,6 +7,10 @@ using UnityEngine.Events;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to track the rotation in degrees about a defined axis of rotation.
|
||||
/// Degrees are reported from the starting rotation of the transform.
|
||||
/// </summary>
|
||||
public class HVRRotationTracker : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Local axis of rotation")]
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Specialized hover behaviour that scales this transform over time when a hand or force grabber is hovering it.
|
||||
/// </summary>
|
||||
public class HVRScaleHighlight : HVRGrabbableHoverBase
|
||||
{
|
||||
public Vector3 HoverScale = new Vector3(1.3f, 1.3f, 1.3f);
|
||||
|
||||
+4
@@ -4,6 +4,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to define center of mass of the controller relative to the hand for bonus throwing velocity calculations
|
||||
/// </summary>
|
||||
public class HVRThrowingCenterOfMass : MonoBehaviour
|
||||
{
|
||||
public HVRHandSide HandSide;
|
||||
@@ -36,6 +39,7 @@ namespace HurricaneVR.Framework.Components
|
||||
|
||||
switch (controller.ControllerType)
|
||||
{
|
||||
case HVRControllerType.Pico:
|
||||
case HVRControllerType.Oculus:
|
||||
CenterOfMass = Oculus;
|
||||
break;
|
||||
|
||||
+21
-2
@@ -19,6 +19,7 @@ namespace HurricaneVR.Framework.Components
|
||||
Grabbable = GetComponent<HVRGrabbable>();
|
||||
|
||||
Grabbable.HandGrabbed.AddListener(OnHandGrabbed);
|
||||
Grabbable.HandReleased.AddListener(OnHandReleased);
|
||||
|
||||
if (Others != null)
|
||||
{
|
||||
@@ -33,6 +34,11 @@ namespace HurricaneVR.Framework.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHandReleased(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
{
|
||||
Grabbable.ForceTwoHandSettings = false;
|
||||
}
|
||||
|
||||
private void OnHandGrabbed(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
{
|
||||
foreach (var other in Others)
|
||||
@@ -45,9 +51,22 @@ namespace HurricaneVR.Framework.Components
|
||||
}
|
||||
}
|
||||
|
||||
private void OnOtherGrabbableHandReleased(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
private void OnOtherGrabbableHandReleased(HVRHandGrabber arg0, HVRGrabbable g)
|
||||
{
|
||||
Grabbable.ForceTwoHandSettings = false;
|
||||
//handle scenario if two "others" are held, then one was released.
|
||||
var force = false;
|
||||
for (int i = 0; i < Others.Length; i++)
|
||||
{
|
||||
var other = Others[i];
|
||||
if (other == g || other.HandGrabbers.Count == 0)
|
||||
continue;
|
||||
|
||||
force = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!force)
|
||||
Grabbable.ForceTwoHandSettings = false;
|
||||
}
|
||||
|
||||
private void OnOtherGrabbableHandGrabbed(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
|
||||
+27
-31
@@ -33,7 +33,9 @@ using Valve.VR;
|
||||
namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
[Serializable]
|
||||
public class HVRControllerEvent : UnityEvent<HVRController> { }
|
||||
public class HVRControllerEvent : UnityEvent<HVRController>
|
||||
{
|
||||
}
|
||||
|
||||
public class HVRInputManager : MonoBehaviour
|
||||
{
|
||||
@@ -50,15 +52,16 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
public const string Reverb = "reverb";
|
||||
public const string G2 = "g2";
|
||||
public const string OpenXR_G2 = "hp reverb g2 controller";
|
||||
public const string Pico = "pico";
|
||||
|
||||
public const string LegacyOpenVRName = "OpenVR";
|
||||
public const string LegacyOculusName = "Oculus";
|
||||
public const string LegacyNone = "None";
|
||||
|
||||
|
||||
|
||||
[Header("XR Plugin Detection Names")]
|
||||
public string OpenVRLoader = "Open VR Loader";
|
||||
|
||||
public string OculusLoader = "Oculus Loader";
|
||||
public string OpenXRLoader = "Open XR Loader";
|
||||
public string WMRLoader = "Windows MR Loader";
|
||||
@@ -70,9 +73,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
public static HVRInputManager Instance { get; private set; }
|
||||
|
||||
|
||||
|
||||
[Header("Oculus - Requires Oculus Asset + Integration")]
|
||||
|
||||
[Tooltip("If true ovrinputs will be used")]
|
||||
public bool UseOVRInputs;
|
||||
|
||||
@@ -84,10 +85,10 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
[Header("SteamVR - Requires SteamVR + Integration")]
|
||||
public bool InitializeSteamVR = true;
|
||||
|
||||
public bool InitializeSteamVRActions = true;
|
||||
|
||||
[Header("Input Settings")]
|
||||
|
||||
[Tooltip("If true uses the new input system bindings")]
|
||||
public bool UseNewInputSystem;
|
||||
|
||||
@@ -105,8 +106,10 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
[Header("Device Specific Settings")]
|
||||
public HVRInputSettings WMRInputMap;
|
||||
|
||||
[FormerlySerializedAs("WMRWithButtonsInputMap")]
|
||||
public HVRInputSettings ReverbG2InputMap;
|
||||
|
||||
public HVRInputSettings OculusInputMap;
|
||||
public HVRInputSettings ViveInputMap;
|
||||
public HVRInputSettings KnucklesInputMap;
|
||||
@@ -178,8 +181,11 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
public string RightManufacturer;
|
||||
public string RightControllerName;
|
||||
|
||||
[SerializeField] private HVRControllerType LeftXRInputSystem = HVRControllerType.None;
|
||||
[SerializeField] private HVRControllerType RightControllerType = HVRControllerType.None;
|
||||
[SerializeField]
|
||||
private HVRControllerType LeftControllerType = HVRControllerType.None;
|
||||
|
||||
[SerializeField]
|
||||
private HVRControllerType RightControllerType = HVRControllerType.None;
|
||||
|
||||
public List<string> LeftFeatures = new List<string>();
|
||||
public List<string> RightFeatures = new List<string>();
|
||||
@@ -243,7 +249,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
if (!HMDActive)
|
||||
return false;
|
||||
|
||||
@@ -258,8 +263,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
#elif !UNITY_2020_1_OR_NEWER
|
||||
|
||||
|
||||
//https://stackoverflow.com/questions/51372771/how-to-check-if-a-hmd-in-unity-2018-is-in-use
|
||||
#pragma warning disable 0618
|
||||
//if xr management wasn't detected use the old API for legacy VR
|
||||
@@ -287,6 +290,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
private InputDevice _leftDevice;
|
||||
|
||||
public InputDevice LeftDevice
|
||||
{
|
||||
get
|
||||
@@ -299,6 +303,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
private InputDevice _rightDevice;
|
||||
|
||||
public InputDevice RightDevice
|
||||
{
|
||||
get
|
||||
@@ -311,8 +316,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private bool _isHMDFirstActivationReported;
|
||||
|
||||
|
||||
@@ -392,7 +395,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
#if HVR_OCULUS
|
||||
|
||||
if (UseOVRInputs && ForceOVRInputUpdate && (LeftXRInputSystem == HVRControllerType.Oculus || RightControllerType == HVRControllerType.Oculus))
|
||||
if (UseOVRInputs && ForceOVRInputUpdate && (LeftControllerType == HVRControllerType.Oculus || RightControllerType == HVRControllerType.Oculus))
|
||||
{
|
||||
HVROculusController.UpdateOVRInput();
|
||||
}
|
||||
@@ -552,7 +555,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
RightController = UpdateController(RightControllerType, device, HVRHandSide.Right);
|
||||
if (device.isValid)
|
||||
RightControllerConnected.Invoke(RightController);
|
||||
|
||||
}
|
||||
|
||||
private void UpdateLeftController(InputDevice device)
|
||||
@@ -574,8 +576,8 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
}
|
||||
|
||||
LeftXRInputSystem = GetController(LeftDevice.manufacturer?.ToLower(), LeftDevice.name?.ToLower());
|
||||
LeftController = UpdateController(LeftXRInputSystem, device, HVRHandSide.Left);
|
||||
LeftControllerType = GetController(LeftDevice.manufacturer?.ToLower(), LeftDevice.name?.ToLower());
|
||||
LeftController = UpdateController(LeftControllerType, device, HVRHandSide.Left);
|
||||
if (device.isValid)
|
||||
LeftControllerConnected.Invoke(LeftController);
|
||||
}
|
||||
@@ -613,6 +615,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
inputMap = WMRInputMap;
|
||||
deadZone = WMRDeadzone;
|
||||
break;
|
||||
case HVRControllerType.Pico:
|
||||
case HVRControllerType.Oculus:
|
||||
inputMap = OculusInputMap;
|
||||
deadZone = OculusDeadzone;
|
||||
@@ -801,7 +804,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (manufaturerToLower.Contains(Oculus))
|
||||
{
|
||||
return HVRControllerType.Oculus;
|
||||
@@ -832,6 +834,8 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
return HVRControllerType.WMR;
|
||||
}
|
||||
|
||||
if (nameToLower.Contains(Pico))
|
||||
return HVRControllerType.Pico;
|
||||
return HVRControllerType.None;
|
||||
}
|
||||
|
||||
@@ -896,6 +900,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
Debug.LogWarning($"HVR: {OpenVRLoader} active without SteamVR installed or HVR_STEAMVR define set.");
|
||||
}
|
||||
|
||||
CurrentSDK = InputSDK.SteamVR;
|
||||
return;
|
||||
}
|
||||
@@ -906,7 +911,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
//legacy vr
|
||||
if (LeftXRInputSystem == HVRControllerType.Oculus || RightControllerType == HVRControllerType.Oculus)
|
||||
if (LeftControllerType == HVRControllerType.Oculus || RightControllerType == HVRControllerType.Oculus)
|
||||
{
|
||||
CurrentSDK = UseOVRInputs ? InputSDK.Oculus : InputSDK.XRInput;
|
||||
return;
|
||||
@@ -926,7 +931,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
#if !OPENVR_DESKTOP && !OPENVR_XR
|
||||
return false;
|
||||
#else
|
||||
|
||||
#if OPENVR_DESKTOP
|
||||
|
||||
if (!Valve.VR.SteamVR.usingNativeSupport)
|
||||
@@ -977,13 +981,12 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
#else
|
||||
loaders = string.Join(",", XRGeneralSettings.Instance.Manager.loaders.Select(e => e.name));
|
||||
#endif
|
||||
Debug.Log($"{ XRGeneralSettings.Instance.Manager.automaticLoading}");
|
||||
Debug.Log($"XRGeneralSettings.Instance.Manager.isInitializationComplete { XRGeneralSettings.Instance.Manager.isInitializationComplete}");
|
||||
Debug.Log($"{XRGeneralSettings.Instance.Manager.automaticLoading}");
|
||||
Debug.Log($"XRGeneralSettings.Instance.Manager.isInitializationComplete {XRGeneralSettings.Instance.Manager.isInitializationComplete}");
|
||||
Debug.Log($"XRPlugin Detected | XRSettings.enabled {XRSettings.enabled} | Loader : {XRPluginLoader} | Loaders Enabled: {loaders}");
|
||||
|
||||
XRPluginActive = XRSettings.enabled && XRGeneralSettings.Instance.Manager.isInitializationComplete;
|
||||
#elif !UNITY_2020_1_OR_NEWER
|
||||
|
||||
var legacyDevices = "";
|
||||
foreach (var t in XRSettings.supportedDevices)
|
||||
{
|
||||
@@ -1025,7 +1028,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void StopXR()
|
||||
{
|
||||
#if USING_XR_MANAGEMENT
|
||||
@@ -1059,10 +1061,8 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
Debug.LogWarning($"XR Plugin Management is in use. Cannot load Legacy VR");
|
||||
return;
|
||||
#elif !UNITY_2020_1_OR_NEWER
|
||||
|
||||
StartCoroutine(LoadLegacy(callback));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1101,6 +1101,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
callback(false);
|
||||
}
|
||||
|
||||
LegacyActive = false;
|
||||
}
|
||||
}
|
||||
@@ -1152,7 +1153,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
IsSteamVR = true;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private void StopSteamVR()
|
||||
@@ -1198,8 +1198,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
#elif !UNITY_2020_1_OR_NEWER
|
||||
|
||||
|
||||
if (originFlags == TrackingOriginModeFlags.Floor)
|
||||
{
|
||||
#pragma warning disable 0618
|
||||
@@ -1220,7 +1218,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1229,5 +1226,4 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
Legacy,
|
||||
XRPlugin
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+57
-19
@@ -16,6 +16,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
[Header("Grab Settings")]
|
||||
public bool CanDistanceGrab = true;
|
||||
|
||||
public bool CanTriggerGrab;
|
||||
|
||||
[Tooltip("For non flick style force grabber")]
|
||||
@@ -26,6 +27,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
[Header("Inputs Debugging")]
|
||||
public Vector2 MovementAxis;
|
||||
|
||||
public Vector2 TurnAxis;
|
||||
|
||||
public bool IsTeleportActivated;
|
||||
@@ -88,6 +90,15 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
AfterInputUpdate();
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
protected virtual void UpdateInput()
|
||||
{
|
||||
if (!UpdateInputs)
|
||||
@@ -130,11 +141,9 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
protected virtual void AfterInputUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void ResetState(ref HVRButtonState buttonState)
|
||||
{
|
||||
buttonState.JustDeactivated = false;
|
||||
@@ -172,7 +181,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
if (RightController.ControllerType == HVRControllerType.Vive)
|
||||
{
|
||||
return false;//todo
|
||||
return false; //todo
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -180,10 +189,11 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
protected virtual void GetForceGrabActivated(out bool left, out bool right)
|
||||
{
|
||||
left = false;
|
||||
right = false;
|
||||
|
||||
if (!CanDistanceGrab)
|
||||
{
|
||||
left = false;
|
||||
right = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -192,24 +202,52 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
left = LeftController.GripButtonState.JustActivated;
|
||||
right = RightController.GripButtonState.JustActivated;
|
||||
}
|
||||
else
|
||||
else if (ForceGrabActivation == HVRForceGrabActivation.GripAndTrigger)
|
||||
{
|
||||
left = LeftController.GripButtonState.Active && LeftController.TriggerButtonState.JustActivated || LeftController.TriggerButtonState.Active && LeftController.GripButtonState.JustActivated;
|
||||
right = RightController.GripButtonState.Active && RightController.TriggerButtonState.JustActivated || RightController.TriggerButtonState.Active && RightController.GripButtonState.JustActivated;
|
||||
left = LeftController.GripButtonState.Active && LeftTriggerGrabState.JustActivated || LeftTriggerGrabState.Active && LeftController.GripButtonState.JustActivated;
|
||||
right = RightController.GripButtonState.Active && RightTriggerGrabState.JustActivated || RightTriggerGrabState.Active && RightController.GripButtonState.JustActivated;
|
||||
}
|
||||
else if (ForceGrabActivation == HVRForceGrabActivation.Trigger)
|
||||
{
|
||||
left = LeftTriggerGrabState.JustActivated;
|
||||
right = RightTriggerGrabState.JustActivated;
|
||||
}
|
||||
else if (ForceGrabActivation == HVRForceGrabActivation.GripOrTrigger)
|
||||
{
|
||||
left = LeftController.GripButtonState.JustActivated || LeftTriggerGrabState.JustActivated;
|
||||
right = RightController.GripButtonState.JustActivated || RightTriggerGrabState.JustActivated;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected virtual void GetForceGrabActive(out bool left, out bool right)
|
||||
{
|
||||
left = false;
|
||||
right = false;
|
||||
|
||||
if (!CanDistanceGrab)
|
||||
{
|
||||
left = false;
|
||||
right = false;
|
||||
return;
|
||||
}
|
||||
|
||||
left = LeftController.GripButtonState.Active;
|
||||
right = RightController.GripButtonState.Active;
|
||||
if (ForceGrabActivation == HVRForceGrabActivation.Grip)
|
||||
{
|
||||
left = LeftController.GripButtonState.Active;
|
||||
right = RightController.GripButtonState.Active;
|
||||
}
|
||||
else if (ForceGrabActivation == HVRForceGrabActivation.GripAndTrigger || ForceGrabActivation == HVRForceGrabActivation.GripOrTrigger)
|
||||
{
|
||||
left = LeftController.GripButtonState.Active || LeftTriggerGrabState.Active;
|
||||
right = RightController.GripButtonState.Active || RightTriggerGrabState.Active;
|
||||
}
|
||||
else if (ForceGrabActivation == HVRForceGrabActivation.Trigger)
|
||||
{
|
||||
left = LeftTriggerGrabState.Active;
|
||||
right = RightTriggerGrabState.Active;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public bool GetForceGrabActivated(HVRHandSide side)
|
||||
@@ -237,11 +275,6 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
return side == HVRHandSide.Left ? IsLeftGrabActivated : IsRightGrabActivated;
|
||||
}
|
||||
|
||||
public bool GetHoldActive(HVRHandSide side)
|
||||
{
|
||||
return side == HVRHandSide.Left ? IsLeftHoldActive : IsRightHoldActive;
|
||||
}
|
||||
|
||||
public bool GetGripHoldActive(HVRHandSide side)
|
||||
{
|
||||
return side == HVRHandSide.Left ? IsLeftGripHoldActive : IsRightGripHoldActive;
|
||||
@@ -266,6 +299,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return LeftController.GripButtonState.Active;
|
||||
}
|
||||
|
||||
@@ -283,6 +317,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return RightController.GripButtonState.Active;
|
||||
}
|
||||
|
||||
@@ -358,6 +393,7 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
{
|
||||
return LeftController.TrackpadAxis;
|
||||
}
|
||||
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
@@ -371,9 +407,9 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
|
||||
if (RightController.TrackpadButtonState.Active)
|
||||
{
|
||||
|
||||
return RightController.TrackpadAxis;
|
||||
}
|
||||
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
@@ -458,6 +494,8 @@ namespace HurricaneVR.Framework.ControllerInput
|
||||
public enum HVRForceGrabActivation
|
||||
{
|
||||
Grip,
|
||||
GripHoldTriggerPress
|
||||
GripAndTrigger,
|
||||
Trigger,
|
||||
GripOrTrigger
|
||||
}
|
||||
}
|
||||
+391
-304
@@ -1,7 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was auto-generated by com.unity.inputsystem:InputActionCodeGenerator
|
||||
// version 1.3.0
|
||||
// version 1.5.0
|
||||
// from Assets/HurricaneVR/Framework/Scripts/ControllerInput/InputSystem/HVRInputActions.inputactions
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
@@ -15,7 +15,7 @@ using System.Collections.Generic;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.InputSystem.Utilities;
|
||||
|
||||
public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
public partial class @HVRInputActions: IInputActionCollection2, IDisposable
|
||||
{
|
||||
public InputActionAsset asset { get; }
|
||||
public @HVRInputActions()
|
||||
@@ -275,6 +275,28 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
""isComposite"": false,
|
||||
""isPartOfComposite"": false
|
||||
},
|
||||
{
|
||||
""name"": """",
|
||||
""id"": ""692f48f9-3f21-406f-b2d5-5b5e0c4c2761"",
|
||||
""path"": ""<OculusTouchController>{LeftHand}/menu"",
|
||||
""interactions"": """",
|
||||
""processors"": """",
|
||||
""groups"": """",
|
||||
""action"": ""Menu"",
|
||||
""isComposite"": false,
|
||||
""isPartOfComposite"": false
|
||||
},
|
||||
{
|
||||
""name"": """",
|
||||
""id"": ""d55f9044-c561-4b40-957b-ad0bd93adc50"",
|
||||
""path"": ""<WMRSpatialController>{LeftHand}/menu"",
|
||||
""interactions"": """",
|
||||
""processors"": """",
|
||||
""groups"": """",
|
||||
""action"": ""Menu"",
|
||||
""isComposite"": false,
|
||||
""isPartOfComposite"": false
|
||||
},
|
||||
{
|
||||
""name"": """",
|
||||
""id"": ""54ac7ab0-8ca9-4cbc-a6d1-da5ee0b055cb"",
|
||||
@@ -738,6 +760,17 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
""isComposite"": false,
|
||||
""isPartOfComposite"": false
|
||||
},
|
||||
{
|
||||
""name"": """",
|
||||
""id"": ""0c608bc0-1dda-4d95-8e76-add87e298bcc"",
|
||||
""path"": ""<WMRSpatialController>{LeftHand}/menu"",
|
||||
""interactions"": """",
|
||||
""processors"": """",
|
||||
""groups"": """",
|
||||
""action"": ""Menu"",
|
||||
""isComposite"": false,
|
||||
""isPartOfComposite"": false
|
||||
},
|
||||
{
|
||||
""name"": """",
|
||||
""id"": ""488857b2-965c-486c-b24e-e21628ad2a07"",
|
||||
@@ -1167,12 +1200,14 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
{
|
||||
asset.Disable();
|
||||
}
|
||||
|
||||
public IEnumerable<InputBinding> bindings => asset.bindings;
|
||||
|
||||
public InputAction FindAction(string actionNameOrId, bool throwIfNotFound = false)
|
||||
{
|
||||
return asset.FindAction(actionNameOrId, throwIfNotFound);
|
||||
}
|
||||
|
||||
public int FindBinding(InputBinding bindingMask, out InputAction action)
|
||||
{
|
||||
return asset.FindBinding(bindingMask, out action);
|
||||
@@ -1180,7 +1215,7 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
|
||||
// LeftHand
|
||||
private readonly InputActionMap m_LeftHand;
|
||||
private ILeftHandActions m_LeftHandActionsCallbackInterface;
|
||||
private List<ILeftHandActions> m_LeftHandActionsCallbackInterfaces = new List<ILeftHandActions>();
|
||||
private readonly InputAction m_LeftHand_TriggerPress;
|
||||
private readonly InputAction m_LeftHand_Trigger;
|
||||
private readonly InputAction m_LeftHand_PrimaryButton;
|
||||
@@ -1230,142 +1265,155 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
public void Disable() { Get().Disable(); }
|
||||
public bool enabled => Get().enabled;
|
||||
public static implicit operator InputActionMap(LeftHandActions set) { return set.Get(); }
|
||||
public void AddCallbacks(ILeftHandActions instance)
|
||||
{
|
||||
if (instance == null || m_Wrapper.m_LeftHandActionsCallbackInterfaces.Contains(instance)) return;
|
||||
m_Wrapper.m_LeftHandActionsCallbackInterfaces.Add(instance);
|
||||
@TriggerPress.started += instance.OnTriggerPress;
|
||||
@TriggerPress.performed += instance.OnTriggerPress;
|
||||
@TriggerPress.canceled += instance.OnTriggerPress;
|
||||
@Trigger.started += instance.OnTrigger;
|
||||
@Trigger.performed += instance.OnTrigger;
|
||||
@Trigger.canceled += instance.OnTrigger;
|
||||
@PrimaryButton.started += instance.OnPrimaryButton;
|
||||
@PrimaryButton.performed += instance.OnPrimaryButton;
|
||||
@PrimaryButton.canceled += instance.OnPrimaryButton;
|
||||
@PrimaryTouch.started += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled += instance.OnPrimaryTouch;
|
||||
@Menu.started += instance.OnMenu;
|
||||
@Menu.performed += instance.OnMenu;
|
||||
@Menu.canceled += instance.OnMenu;
|
||||
@Primary2DAxis.started += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled += instance.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled += instance.OnSecondary2DAxisTouch;
|
||||
@Grip.started += instance.OnGrip;
|
||||
@Grip.performed += instance.OnGrip;
|
||||
@Grip.canceled += instance.OnGrip;
|
||||
@GripPress.started += instance.OnGripPress;
|
||||
@GripPress.performed += instance.OnGripPress;
|
||||
@GripPress.canceled += instance.OnGripPress;
|
||||
@GripForce.started += instance.OnGripForce;
|
||||
@GripForce.performed += instance.OnGripForce;
|
||||
@GripForce.canceled += instance.OnGripForce;
|
||||
@SecondaryButton.started += instance.OnSecondaryButton;
|
||||
@SecondaryButton.performed += instance.OnSecondaryButton;
|
||||
@SecondaryButton.canceled += instance.OnSecondaryButton;
|
||||
@SecondaryTouch.started += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled += instance.OnSecondaryTouch;
|
||||
@TriggerTouch.started += instance.OnTriggerTouch;
|
||||
@TriggerTouch.performed += instance.OnTriggerTouch;
|
||||
@TriggerTouch.canceled += instance.OnTriggerTouch;
|
||||
@ControllerPosition.started += instance.OnControllerPosition;
|
||||
@ControllerPosition.performed += instance.OnControllerPosition;
|
||||
@ControllerPosition.canceled += instance.OnControllerPosition;
|
||||
@ControllerRotation.started += instance.OnControllerRotation;
|
||||
@ControllerRotation.performed += instance.OnControllerRotation;
|
||||
@ControllerRotation.canceled += instance.OnControllerRotation;
|
||||
@Haptics.started += instance.OnHaptics;
|
||||
@Haptics.performed += instance.OnHaptics;
|
||||
@Haptics.canceled += instance.OnHaptics;
|
||||
}
|
||||
|
||||
private void UnregisterCallbacks(ILeftHandActions instance)
|
||||
{
|
||||
@TriggerPress.started -= instance.OnTriggerPress;
|
||||
@TriggerPress.performed -= instance.OnTriggerPress;
|
||||
@TriggerPress.canceled -= instance.OnTriggerPress;
|
||||
@Trigger.started -= instance.OnTrigger;
|
||||
@Trigger.performed -= instance.OnTrigger;
|
||||
@Trigger.canceled -= instance.OnTrigger;
|
||||
@PrimaryButton.started -= instance.OnPrimaryButton;
|
||||
@PrimaryButton.performed -= instance.OnPrimaryButton;
|
||||
@PrimaryButton.canceled -= instance.OnPrimaryButton;
|
||||
@PrimaryTouch.started -= instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed -= instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled -= instance.OnPrimaryTouch;
|
||||
@Menu.started -= instance.OnMenu;
|
||||
@Menu.performed -= instance.OnMenu;
|
||||
@Menu.canceled -= instance.OnMenu;
|
||||
@Primary2DAxis.started -= instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed -= instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled -= instance.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started -= instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed -= instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled -= instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started -= instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed -= instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled -= instance.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started -= instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed -= instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled -= instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started -= instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed -= instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled -= instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started -= instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed -= instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled -= instance.OnSecondary2DAxisTouch;
|
||||
@Grip.started -= instance.OnGrip;
|
||||
@Grip.performed -= instance.OnGrip;
|
||||
@Grip.canceled -= instance.OnGrip;
|
||||
@GripPress.started -= instance.OnGripPress;
|
||||
@GripPress.performed -= instance.OnGripPress;
|
||||
@GripPress.canceled -= instance.OnGripPress;
|
||||
@GripForce.started -= instance.OnGripForce;
|
||||
@GripForce.performed -= instance.OnGripForce;
|
||||
@GripForce.canceled -= instance.OnGripForce;
|
||||
@SecondaryButton.started -= instance.OnSecondaryButton;
|
||||
@SecondaryButton.performed -= instance.OnSecondaryButton;
|
||||
@SecondaryButton.canceled -= instance.OnSecondaryButton;
|
||||
@SecondaryTouch.started -= instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed -= instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled -= instance.OnSecondaryTouch;
|
||||
@TriggerTouch.started -= instance.OnTriggerTouch;
|
||||
@TriggerTouch.performed -= instance.OnTriggerTouch;
|
||||
@TriggerTouch.canceled -= instance.OnTriggerTouch;
|
||||
@ControllerPosition.started -= instance.OnControllerPosition;
|
||||
@ControllerPosition.performed -= instance.OnControllerPosition;
|
||||
@ControllerPosition.canceled -= instance.OnControllerPosition;
|
||||
@ControllerRotation.started -= instance.OnControllerRotation;
|
||||
@ControllerRotation.performed -= instance.OnControllerRotation;
|
||||
@ControllerRotation.canceled -= instance.OnControllerRotation;
|
||||
@Haptics.started -= instance.OnHaptics;
|
||||
@Haptics.performed -= instance.OnHaptics;
|
||||
@Haptics.canceled -= instance.OnHaptics;
|
||||
}
|
||||
|
||||
public void RemoveCallbacks(ILeftHandActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_LeftHandActionsCallbackInterfaces.Remove(instance))
|
||||
UnregisterCallbacks(instance);
|
||||
}
|
||||
|
||||
public void SetCallbacks(ILeftHandActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_LeftHandActionsCallbackInterface != null)
|
||||
{
|
||||
@TriggerPress.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTriggerPress;
|
||||
@TriggerPress.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTriggerPress;
|
||||
@TriggerPress.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTriggerPress;
|
||||
@Trigger.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTrigger;
|
||||
@Trigger.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTrigger;
|
||||
@Trigger.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTrigger;
|
||||
@PrimaryButton.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimaryButton;
|
||||
@PrimaryButton.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimaryButton;
|
||||
@PrimaryButton.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimaryButton;
|
||||
@PrimaryTouch.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimaryTouch;
|
||||
@Menu.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnMenu;
|
||||
@Menu.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnMenu;
|
||||
@Menu.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnMenu;
|
||||
@Primary2DAxis.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondary2DAxisTouch;
|
||||
@Grip.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGrip;
|
||||
@Grip.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGrip;
|
||||
@Grip.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGrip;
|
||||
@GripPress.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGripPress;
|
||||
@GripPress.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGripPress;
|
||||
@GripPress.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGripPress;
|
||||
@GripForce.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGripForce;
|
||||
@GripForce.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGripForce;
|
||||
@GripForce.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnGripForce;
|
||||
@SecondaryButton.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondaryButton;
|
||||
@SecondaryButton.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondaryButton;
|
||||
@SecondaryButton.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondaryButton;
|
||||
@SecondaryTouch.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnSecondaryTouch;
|
||||
@TriggerTouch.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTriggerTouch;
|
||||
@TriggerTouch.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTriggerTouch;
|
||||
@TriggerTouch.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnTriggerTouch;
|
||||
@ControllerPosition.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnControllerPosition;
|
||||
@ControllerPosition.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnControllerPosition;
|
||||
@ControllerPosition.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnControllerPosition;
|
||||
@ControllerRotation.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnControllerRotation;
|
||||
@ControllerRotation.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnControllerRotation;
|
||||
@ControllerRotation.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnControllerRotation;
|
||||
@Haptics.started -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnHaptics;
|
||||
@Haptics.performed -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnHaptics;
|
||||
@Haptics.canceled -= m_Wrapper.m_LeftHandActionsCallbackInterface.OnHaptics;
|
||||
}
|
||||
m_Wrapper.m_LeftHandActionsCallbackInterface = instance;
|
||||
if (instance != null)
|
||||
{
|
||||
@TriggerPress.started += instance.OnTriggerPress;
|
||||
@TriggerPress.performed += instance.OnTriggerPress;
|
||||
@TriggerPress.canceled += instance.OnTriggerPress;
|
||||
@Trigger.started += instance.OnTrigger;
|
||||
@Trigger.performed += instance.OnTrigger;
|
||||
@Trigger.canceled += instance.OnTrigger;
|
||||
@PrimaryButton.started += instance.OnPrimaryButton;
|
||||
@PrimaryButton.performed += instance.OnPrimaryButton;
|
||||
@PrimaryButton.canceled += instance.OnPrimaryButton;
|
||||
@PrimaryTouch.started += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled += instance.OnPrimaryTouch;
|
||||
@Menu.started += instance.OnMenu;
|
||||
@Menu.performed += instance.OnMenu;
|
||||
@Menu.canceled += instance.OnMenu;
|
||||
@Primary2DAxis.started += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled += instance.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled += instance.OnSecondary2DAxisTouch;
|
||||
@Grip.started += instance.OnGrip;
|
||||
@Grip.performed += instance.OnGrip;
|
||||
@Grip.canceled += instance.OnGrip;
|
||||
@GripPress.started += instance.OnGripPress;
|
||||
@GripPress.performed += instance.OnGripPress;
|
||||
@GripPress.canceled += instance.OnGripPress;
|
||||
@GripForce.started += instance.OnGripForce;
|
||||
@GripForce.performed += instance.OnGripForce;
|
||||
@GripForce.canceled += instance.OnGripForce;
|
||||
@SecondaryButton.started += instance.OnSecondaryButton;
|
||||
@SecondaryButton.performed += instance.OnSecondaryButton;
|
||||
@SecondaryButton.canceled += instance.OnSecondaryButton;
|
||||
@SecondaryTouch.started += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled += instance.OnSecondaryTouch;
|
||||
@TriggerTouch.started += instance.OnTriggerTouch;
|
||||
@TriggerTouch.performed += instance.OnTriggerTouch;
|
||||
@TriggerTouch.canceled += instance.OnTriggerTouch;
|
||||
@ControllerPosition.started += instance.OnControllerPosition;
|
||||
@ControllerPosition.performed += instance.OnControllerPosition;
|
||||
@ControllerPosition.canceled += instance.OnControllerPosition;
|
||||
@ControllerRotation.started += instance.OnControllerRotation;
|
||||
@ControllerRotation.performed += instance.OnControllerRotation;
|
||||
@ControllerRotation.canceled += instance.OnControllerRotation;
|
||||
@Haptics.started += instance.OnHaptics;
|
||||
@Haptics.performed += instance.OnHaptics;
|
||||
@Haptics.canceled += instance.OnHaptics;
|
||||
}
|
||||
foreach (var item in m_Wrapper.m_LeftHandActionsCallbackInterfaces)
|
||||
UnregisterCallbacks(item);
|
||||
m_Wrapper.m_LeftHandActionsCallbackInterfaces.Clear();
|
||||
AddCallbacks(instance);
|
||||
}
|
||||
}
|
||||
public LeftHandActions @LeftHand => new LeftHandActions(this);
|
||||
|
||||
// RightHand
|
||||
private readonly InputActionMap m_RightHand;
|
||||
private IRightHandActions m_RightHandActionsCallbackInterface;
|
||||
private List<IRightHandActions> m_RightHandActionsCallbackInterfaces = new List<IRightHandActions>();
|
||||
private readonly InputAction m_RightHand_TriggerPress;
|
||||
private readonly InputAction m_RightHand_Trigger;
|
||||
private readonly InputAction m_RightHand_PrimaryButton;
|
||||
@@ -1415,142 +1463,155 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
public void Disable() { Get().Disable(); }
|
||||
public bool enabled => Get().enabled;
|
||||
public static implicit operator InputActionMap(RightHandActions set) { return set.Get(); }
|
||||
public void AddCallbacks(IRightHandActions instance)
|
||||
{
|
||||
if (instance == null || m_Wrapper.m_RightHandActionsCallbackInterfaces.Contains(instance)) return;
|
||||
m_Wrapper.m_RightHandActionsCallbackInterfaces.Add(instance);
|
||||
@TriggerPress.started += instance.OnTriggerPress;
|
||||
@TriggerPress.performed += instance.OnTriggerPress;
|
||||
@TriggerPress.canceled += instance.OnTriggerPress;
|
||||
@Trigger.started += instance.OnTrigger;
|
||||
@Trigger.performed += instance.OnTrigger;
|
||||
@Trigger.canceled += instance.OnTrigger;
|
||||
@PrimaryButton.started += instance.OnPrimaryButton;
|
||||
@PrimaryButton.performed += instance.OnPrimaryButton;
|
||||
@PrimaryButton.canceled += instance.OnPrimaryButton;
|
||||
@PrimaryTouch.started += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled += instance.OnPrimaryTouch;
|
||||
@Menu.started += instance.OnMenu;
|
||||
@Menu.performed += instance.OnMenu;
|
||||
@Menu.canceled += instance.OnMenu;
|
||||
@Primary2DAxis.started += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled += instance.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled += instance.OnSecondary2DAxisTouch;
|
||||
@Grip.started += instance.OnGrip;
|
||||
@Grip.performed += instance.OnGrip;
|
||||
@Grip.canceled += instance.OnGrip;
|
||||
@GripPress.started += instance.OnGripPress;
|
||||
@GripPress.performed += instance.OnGripPress;
|
||||
@GripPress.canceled += instance.OnGripPress;
|
||||
@GripForce.started += instance.OnGripForce;
|
||||
@GripForce.performed += instance.OnGripForce;
|
||||
@GripForce.canceled += instance.OnGripForce;
|
||||
@SecondaryButton.started += instance.OnSecondaryButton;
|
||||
@SecondaryButton.performed += instance.OnSecondaryButton;
|
||||
@SecondaryButton.canceled += instance.OnSecondaryButton;
|
||||
@SecondaryTouch.started += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled += instance.OnSecondaryTouch;
|
||||
@TriggerTouch.started += instance.OnTriggerTouch;
|
||||
@TriggerTouch.performed += instance.OnTriggerTouch;
|
||||
@TriggerTouch.canceled += instance.OnTriggerTouch;
|
||||
@ControllerPosition.started += instance.OnControllerPosition;
|
||||
@ControllerPosition.performed += instance.OnControllerPosition;
|
||||
@ControllerPosition.canceled += instance.OnControllerPosition;
|
||||
@ControllerRotation.started += instance.OnControllerRotation;
|
||||
@ControllerRotation.performed += instance.OnControllerRotation;
|
||||
@ControllerRotation.canceled += instance.OnControllerRotation;
|
||||
@Haptics.started += instance.OnHaptics;
|
||||
@Haptics.performed += instance.OnHaptics;
|
||||
@Haptics.canceled += instance.OnHaptics;
|
||||
}
|
||||
|
||||
private void UnregisterCallbacks(IRightHandActions instance)
|
||||
{
|
||||
@TriggerPress.started -= instance.OnTriggerPress;
|
||||
@TriggerPress.performed -= instance.OnTriggerPress;
|
||||
@TriggerPress.canceled -= instance.OnTriggerPress;
|
||||
@Trigger.started -= instance.OnTrigger;
|
||||
@Trigger.performed -= instance.OnTrigger;
|
||||
@Trigger.canceled -= instance.OnTrigger;
|
||||
@PrimaryButton.started -= instance.OnPrimaryButton;
|
||||
@PrimaryButton.performed -= instance.OnPrimaryButton;
|
||||
@PrimaryButton.canceled -= instance.OnPrimaryButton;
|
||||
@PrimaryTouch.started -= instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed -= instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled -= instance.OnPrimaryTouch;
|
||||
@Menu.started -= instance.OnMenu;
|
||||
@Menu.performed -= instance.OnMenu;
|
||||
@Menu.canceled -= instance.OnMenu;
|
||||
@Primary2DAxis.started -= instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed -= instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled -= instance.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started -= instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed -= instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled -= instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started -= instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed -= instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled -= instance.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started -= instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed -= instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled -= instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started -= instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed -= instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled -= instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started -= instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed -= instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled -= instance.OnSecondary2DAxisTouch;
|
||||
@Grip.started -= instance.OnGrip;
|
||||
@Grip.performed -= instance.OnGrip;
|
||||
@Grip.canceled -= instance.OnGrip;
|
||||
@GripPress.started -= instance.OnGripPress;
|
||||
@GripPress.performed -= instance.OnGripPress;
|
||||
@GripPress.canceled -= instance.OnGripPress;
|
||||
@GripForce.started -= instance.OnGripForce;
|
||||
@GripForce.performed -= instance.OnGripForce;
|
||||
@GripForce.canceled -= instance.OnGripForce;
|
||||
@SecondaryButton.started -= instance.OnSecondaryButton;
|
||||
@SecondaryButton.performed -= instance.OnSecondaryButton;
|
||||
@SecondaryButton.canceled -= instance.OnSecondaryButton;
|
||||
@SecondaryTouch.started -= instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed -= instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled -= instance.OnSecondaryTouch;
|
||||
@TriggerTouch.started -= instance.OnTriggerTouch;
|
||||
@TriggerTouch.performed -= instance.OnTriggerTouch;
|
||||
@TriggerTouch.canceled -= instance.OnTriggerTouch;
|
||||
@ControllerPosition.started -= instance.OnControllerPosition;
|
||||
@ControllerPosition.performed -= instance.OnControllerPosition;
|
||||
@ControllerPosition.canceled -= instance.OnControllerPosition;
|
||||
@ControllerRotation.started -= instance.OnControllerRotation;
|
||||
@ControllerRotation.performed -= instance.OnControllerRotation;
|
||||
@ControllerRotation.canceled -= instance.OnControllerRotation;
|
||||
@Haptics.started -= instance.OnHaptics;
|
||||
@Haptics.performed -= instance.OnHaptics;
|
||||
@Haptics.canceled -= instance.OnHaptics;
|
||||
}
|
||||
|
||||
public void RemoveCallbacks(IRightHandActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_RightHandActionsCallbackInterfaces.Remove(instance))
|
||||
UnregisterCallbacks(instance);
|
||||
}
|
||||
|
||||
public void SetCallbacks(IRightHandActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_RightHandActionsCallbackInterface != null)
|
||||
{
|
||||
@TriggerPress.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTriggerPress;
|
||||
@TriggerPress.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTriggerPress;
|
||||
@TriggerPress.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTriggerPress;
|
||||
@Trigger.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTrigger;
|
||||
@Trigger.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTrigger;
|
||||
@Trigger.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTrigger;
|
||||
@PrimaryButton.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimaryButton;
|
||||
@PrimaryButton.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimaryButton;
|
||||
@PrimaryButton.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimaryButton;
|
||||
@PrimaryTouch.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimaryTouch;
|
||||
@Menu.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnMenu;
|
||||
@Menu.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnMenu;
|
||||
@Menu.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnMenu;
|
||||
@Primary2DAxis.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondary2DAxisTouch;
|
||||
@Grip.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGrip;
|
||||
@Grip.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGrip;
|
||||
@Grip.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGrip;
|
||||
@GripPress.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGripPress;
|
||||
@GripPress.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGripPress;
|
||||
@GripPress.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGripPress;
|
||||
@GripForce.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGripForce;
|
||||
@GripForce.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGripForce;
|
||||
@GripForce.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnGripForce;
|
||||
@SecondaryButton.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondaryButton;
|
||||
@SecondaryButton.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondaryButton;
|
||||
@SecondaryButton.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondaryButton;
|
||||
@SecondaryTouch.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnSecondaryTouch;
|
||||
@TriggerTouch.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTriggerTouch;
|
||||
@TriggerTouch.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTriggerTouch;
|
||||
@TriggerTouch.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnTriggerTouch;
|
||||
@ControllerPosition.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnControllerPosition;
|
||||
@ControllerPosition.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnControllerPosition;
|
||||
@ControllerPosition.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnControllerPosition;
|
||||
@ControllerRotation.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnControllerRotation;
|
||||
@ControllerRotation.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnControllerRotation;
|
||||
@ControllerRotation.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnControllerRotation;
|
||||
@Haptics.started -= m_Wrapper.m_RightHandActionsCallbackInterface.OnHaptics;
|
||||
@Haptics.performed -= m_Wrapper.m_RightHandActionsCallbackInterface.OnHaptics;
|
||||
@Haptics.canceled -= m_Wrapper.m_RightHandActionsCallbackInterface.OnHaptics;
|
||||
}
|
||||
m_Wrapper.m_RightHandActionsCallbackInterface = instance;
|
||||
if (instance != null)
|
||||
{
|
||||
@TriggerPress.started += instance.OnTriggerPress;
|
||||
@TriggerPress.performed += instance.OnTriggerPress;
|
||||
@TriggerPress.canceled += instance.OnTriggerPress;
|
||||
@Trigger.started += instance.OnTrigger;
|
||||
@Trigger.performed += instance.OnTrigger;
|
||||
@Trigger.canceled += instance.OnTrigger;
|
||||
@PrimaryButton.started += instance.OnPrimaryButton;
|
||||
@PrimaryButton.performed += instance.OnPrimaryButton;
|
||||
@PrimaryButton.canceled += instance.OnPrimaryButton;
|
||||
@PrimaryTouch.started += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.performed += instance.OnPrimaryTouch;
|
||||
@PrimaryTouch.canceled += instance.OnPrimaryTouch;
|
||||
@Menu.started += instance.OnMenu;
|
||||
@Menu.performed += instance.OnMenu;
|
||||
@Menu.canceled += instance.OnMenu;
|
||||
@Primary2DAxis.started += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.performed += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxis.canceled += instance.OnPrimary2DAxis;
|
||||
@Primary2DAxisClick.started += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.performed += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisClick.canceled += instance.OnPrimary2DAxisClick;
|
||||
@Primary2DAxisTouch.started += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.performed += instance.OnPrimary2DAxisTouch;
|
||||
@Primary2DAxisTouch.canceled += instance.OnPrimary2DAxisTouch;
|
||||
@Secondary2DAxis.started += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.performed += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxis.canceled += instance.OnSecondary2DAxis;
|
||||
@Secondary2DAxisClick.started += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.performed += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisClick.canceled += instance.OnSecondary2DAxisClick;
|
||||
@Secondary2DAxisTouch.started += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.performed += instance.OnSecondary2DAxisTouch;
|
||||
@Secondary2DAxisTouch.canceled += instance.OnSecondary2DAxisTouch;
|
||||
@Grip.started += instance.OnGrip;
|
||||
@Grip.performed += instance.OnGrip;
|
||||
@Grip.canceled += instance.OnGrip;
|
||||
@GripPress.started += instance.OnGripPress;
|
||||
@GripPress.performed += instance.OnGripPress;
|
||||
@GripPress.canceled += instance.OnGripPress;
|
||||
@GripForce.started += instance.OnGripForce;
|
||||
@GripForce.performed += instance.OnGripForce;
|
||||
@GripForce.canceled += instance.OnGripForce;
|
||||
@SecondaryButton.started += instance.OnSecondaryButton;
|
||||
@SecondaryButton.performed += instance.OnSecondaryButton;
|
||||
@SecondaryButton.canceled += instance.OnSecondaryButton;
|
||||
@SecondaryTouch.started += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.performed += instance.OnSecondaryTouch;
|
||||
@SecondaryTouch.canceled += instance.OnSecondaryTouch;
|
||||
@TriggerTouch.started += instance.OnTriggerTouch;
|
||||
@TriggerTouch.performed += instance.OnTriggerTouch;
|
||||
@TriggerTouch.canceled += instance.OnTriggerTouch;
|
||||
@ControllerPosition.started += instance.OnControllerPosition;
|
||||
@ControllerPosition.performed += instance.OnControllerPosition;
|
||||
@ControllerPosition.canceled += instance.OnControllerPosition;
|
||||
@ControllerRotation.started += instance.OnControllerRotation;
|
||||
@ControllerRotation.performed += instance.OnControllerRotation;
|
||||
@ControllerRotation.canceled += instance.OnControllerRotation;
|
||||
@Haptics.started += instance.OnHaptics;
|
||||
@Haptics.performed += instance.OnHaptics;
|
||||
@Haptics.canceled += instance.OnHaptics;
|
||||
}
|
||||
foreach (var item in m_Wrapper.m_RightHandActionsCallbackInterfaces)
|
||||
UnregisterCallbacks(item);
|
||||
m_Wrapper.m_RightHandActionsCallbackInterfaces.Clear();
|
||||
AddCallbacks(instance);
|
||||
}
|
||||
}
|
||||
public RightHandActions @RightHand => new RightHandActions(this);
|
||||
|
||||
// HMD
|
||||
private readonly InputActionMap m_HMD;
|
||||
private IHMDActions m_HMDActionsCallbackInterface;
|
||||
private List<IHMDActions> m_HMDActionsCallbackInterfaces = new List<IHMDActions>();
|
||||
private readonly InputAction m_HMD_hmdPosition;
|
||||
private readonly InputAction m_HMD_hmdRotation;
|
||||
public struct HMDActions
|
||||
@@ -1564,34 +1625,47 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
public void Disable() { Get().Disable(); }
|
||||
public bool enabled => Get().enabled;
|
||||
public static implicit operator InputActionMap(HMDActions set) { return set.Get(); }
|
||||
public void AddCallbacks(IHMDActions instance)
|
||||
{
|
||||
if (instance == null || m_Wrapper.m_HMDActionsCallbackInterfaces.Contains(instance)) return;
|
||||
m_Wrapper.m_HMDActionsCallbackInterfaces.Add(instance);
|
||||
@hmdPosition.started += instance.OnHmdPosition;
|
||||
@hmdPosition.performed += instance.OnHmdPosition;
|
||||
@hmdPosition.canceled += instance.OnHmdPosition;
|
||||
@hmdRotation.started += instance.OnHmdRotation;
|
||||
@hmdRotation.performed += instance.OnHmdRotation;
|
||||
@hmdRotation.canceled += instance.OnHmdRotation;
|
||||
}
|
||||
|
||||
private void UnregisterCallbacks(IHMDActions instance)
|
||||
{
|
||||
@hmdPosition.started -= instance.OnHmdPosition;
|
||||
@hmdPosition.performed -= instance.OnHmdPosition;
|
||||
@hmdPosition.canceled -= instance.OnHmdPosition;
|
||||
@hmdRotation.started -= instance.OnHmdRotation;
|
||||
@hmdRotation.performed -= instance.OnHmdRotation;
|
||||
@hmdRotation.canceled -= instance.OnHmdRotation;
|
||||
}
|
||||
|
||||
public void RemoveCallbacks(IHMDActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_HMDActionsCallbackInterfaces.Remove(instance))
|
||||
UnregisterCallbacks(instance);
|
||||
}
|
||||
|
||||
public void SetCallbacks(IHMDActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_HMDActionsCallbackInterface != null)
|
||||
{
|
||||
@hmdPosition.started -= m_Wrapper.m_HMDActionsCallbackInterface.OnHmdPosition;
|
||||
@hmdPosition.performed -= m_Wrapper.m_HMDActionsCallbackInterface.OnHmdPosition;
|
||||
@hmdPosition.canceled -= m_Wrapper.m_HMDActionsCallbackInterface.OnHmdPosition;
|
||||
@hmdRotation.started -= m_Wrapper.m_HMDActionsCallbackInterface.OnHmdRotation;
|
||||
@hmdRotation.performed -= m_Wrapper.m_HMDActionsCallbackInterface.OnHmdRotation;
|
||||
@hmdRotation.canceled -= m_Wrapper.m_HMDActionsCallbackInterface.OnHmdRotation;
|
||||
}
|
||||
m_Wrapper.m_HMDActionsCallbackInterface = instance;
|
||||
if (instance != null)
|
||||
{
|
||||
@hmdPosition.started += instance.OnHmdPosition;
|
||||
@hmdPosition.performed += instance.OnHmdPosition;
|
||||
@hmdPosition.canceled += instance.OnHmdPosition;
|
||||
@hmdRotation.started += instance.OnHmdRotation;
|
||||
@hmdRotation.performed += instance.OnHmdRotation;
|
||||
@hmdRotation.canceled += instance.OnHmdRotation;
|
||||
}
|
||||
foreach (var item in m_Wrapper.m_HMDActionsCallbackInterfaces)
|
||||
UnregisterCallbacks(item);
|
||||
m_Wrapper.m_HMDActionsCallbackInterfaces.Clear();
|
||||
AddCallbacks(instance);
|
||||
}
|
||||
}
|
||||
public HMDActions @HMD => new HMDActions(this);
|
||||
|
||||
// UI
|
||||
private readonly InputActionMap m_UI;
|
||||
private IUIActions m_UIActionsCallbackInterface;
|
||||
private List<IUIActions> m_UIActionsCallbackInterfaces = new List<IUIActions>();
|
||||
private readonly InputAction m_UI_Click;
|
||||
private readonly InputAction m_UI_pointerPosition;
|
||||
private readonly InputAction m_UI_pointerRotation;
|
||||
@@ -1607,33 +1681,46 @@ public partial class @HVRInputActions : IInputActionCollection2, IDisposable
|
||||
public void Disable() { Get().Disable(); }
|
||||
public bool enabled => Get().enabled;
|
||||
public static implicit operator InputActionMap(UIActions set) { return set.Get(); }
|
||||
public void AddCallbacks(IUIActions instance)
|
||||
{
|
||||
if (instance == null || m_Wrapper.m_UIActionsCallbackInterfaces.Contains(instance)) return;
|
||||
m_Wrapper.m_UIActionsCallbackInterfaces.Add(instance);
|
||||
@Click.started += instance.OnClick;
|
||||
@Click.performed += instance.OnClick;
|
||||
@Click.canceled += instance.OnClick;
|
||||
@pointerPosition.started += instance.OnPointerPosition;
|
||||
@pointerPosition.performed += instance.OnPointerPosition;
|
||||
@pointerPosition.canceled += instance.OnPointerPosition;
|
||||
@pointerRotation.started += instance.OnPointerRotation;
|
||||
@pointerRotation.performed += instance.OnPointerRotation;
|
||||
@pointerRotation.canceled += instance.OnPointerRotation;
|
||||
}
|
||||
|
||||
private void UnregisterCallbacks(IUIActions instance)
|
||||
{
|
||||
@Click.started -= instance.OnClick;
|
||||
@Click.performed -= instance.OnClick;
|
||||
@Click.canceled -= instance.OnClick;
|
||||
@pointerPosition.started -= instance.OnPointerPosition;
|
||||
@pointerPosition.performed -= instance.OnPointerPosition;
|
||||
@pointerPosition.canceled -= instance.OnPointerPosition;
|
||||
@pointerRotation.started -= instance.OnPointerRotation;
|
||||
@pointerRotation.performed -= instance.OnPointerRotation;
|
||||
@pointerRotation.canceled -= instance.OnPointerRotation;
|
||||
}
|
||||
|
||||
public void RemoveCallbacks(IUIActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_UIActionsCallbackInterfaces.Remove(instance))
|
||||
UnregisterCallbacks(instance);
|
||||
}
|
||||
|
||||
public void SetCallbacks(IUIActions instance)
|
||||
{
|
||||
if (m_Wrapper.m_UIActionsCallbackInterface != null)
|
||||
{
|
||||
@Click.started -= m_Wrapper.m_UIActionsCallbackInterface.OnClick;
|
||||
@Click.performed -= m_Wrapper.m_UIActionsCallbackInterface.OnClick;
|
||||
@Click.canceled -= m_Wrapper.m_UIActionsCallbackInterface.OnClick;
|
||||
@pointerPosition.started -= m_Wrapper.m_UIActionsCallbackInterface.OnPointerPosition;
|
||||
@pointerPosition.performed -= m_Wrapper.m_UIActionsCallbackInterface.OnPointerPosition;
|
||||
@pointerPosition.canceled -= m_Wrapper.m_UIActionsCallbackInterface.OnPointerPosition;
|
||||
@pointerRotation.started -= m_Wrapper.m_UIActionsCallbackInterface.OnPointerRotation;
|
||||
@pointerRotation.performed -= m_Wrapper.m_UIActionsCallbackInterface.OnPointerRotation;
|
||||
@pointerRotation.canceled -= m_Wrapper.m_UIActionsCallbackInterface.OnPointerRotation;
|
||||
}
|
||||
m_Wrapper.m_UIActionsCallbackInterface = instance;
|
||||
if (instance != null)
|
||||
{
|
||||
@Click.started += instance.OnClick;
|
||||
@Click.performed += instance.OnClick;
|
||||
@Click.canceled += instance.OnClick;
|
||||
@pointerPosition.started += instance.OnPointerPosition;
|
||||
@pointerPosition.performed += instance.OnPointerPosition;
|
||||
@pointerPosition.canceled += instance.OnPointerPosition;
|
||||
@pointerRotation.started += instance.OnPointerRotation;
|
||||
@pointerRotation.performed += instance.OnPointerRotation;
|
||||
@pointerRotation.canceled += instance.OnPointerRotation;
|
||||
}
|
||||
foreach (var item in m_Wrapper.m_UIActionsCallbackInterfaces)
|
||||
UnregisterCallbacks(item);
|
||||
m_Wrapper.m_UIActionsCallbackInterfaces.Clear();
|
||||
AddCallbacks(instance);
|
||||
}
|
||||
}
|
||||
public UIActions @UI => new UIActions(this);
|
||||
|
||||
+33
@@ -233,6 +233,28 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "692f48f9-3f21-406f-b2d5-5b5e0c4c2761",
|
||||
"path": "<OculusTouchController>{LeftHand}/menu",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Menu",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "d55f9044-c561-4b40-957b-ad0bd93adc50",
|
||||
"path": "<WMRSpatialController>{LeftHand}/menu",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Menu",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "54ac7ab0-8ca9-4cbc-a6d1-da5ee0b055cb",
|
||||
@@ -676,6 +698,17 @@
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "0c608bc0-1dda-4d95-8e76-add87e298bcc",
|
||||
"path": "<WMRSpatialController>{LeftHand}/menu",
|
||||
"interactions": "",
|
||||
"processors": "",
|
||||
"groups": "",
|
||||
"action": "Menu",
|
||||
"isComposite": false,
|
||||
"isPartOfComposite": false
|
||||
},
|
||||
{
|
||||
"name": "",
|
||||
"id": "488857b2-965c-486c-b24e-e21628ad2a07",
|
||||
|
||||
@@ -7,6 +7,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Bags
|
||||
{
|
||||
/// <summary>
|
||||
/// Used by the hand to detect sockets for removing objects from them
|
||||
/// </summary>
|
||||
public class HVRSocketBag : MonoBehaviour, IComparer<HVRSocket>
|
||||
{
|
||||
private readonly Dictionary<HVRSocket, HashSet<Collider>> _map = new Dictionary<HVRSocket, HashSet<Collider>>();
|
||||
@@ -53,6 +56,9 @@ namespace HurricaneVR.Framework.Core.Bags
|
||||
Calculate();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Causes the bag to ignore the provided socket when it's trigger collider overlaps ours.
|
||||
/// </summary>
|
||||
public void IgnoreSocket(HVRSocket socket)
|
||||
{
|
||||
if (_ignoredSockets == null)
|
||||
@@ -63,6 +69,14 @@ namespace HurricaneVR.Framework.Core.Bags
|
||||
_ignoredSockets.Add(socket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops ignoring the provided socket
|
||||
/// </summary>
|
||||
public void UnIgnoreSocket(HVRSocket socket)
|
||||
{
|
||||
_ignoredSockets.Remove(socket);
|
||||
}
|
||||
|
||||
protected void AddSocket(HVRSocket socket)
|
||||
{
|
||||
if (AllSockets.Contains(socket))
|
||||
|
||||
+26
-11
@@ -209,6 +209,9 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public override bool CanGrab(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!grabbable.CanHandGrab(HandGrabber))
|
||||
return false;
|
||||
|
||||
if (grabbable.IsSocketed)
|
||||
return false;
|
||||
|
||||
@@ -267,6 +270,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
args.Grabbable.IsBeingForcedGrabbed = true;
|
||||
IsForceGrabbing = true;
|
||||
if (GrabStyle == HVRForceGrabMode.GravityGloves)
|
||||
{
|
||||
@@ -288,6 +292,13 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
OnGrabbedHaptics();
|
||||
}
|
||||
|
||||
protected override void OnReleased(HVRGrabbable grabbable)
|
||||
{
|
||||
base.OnReleased(grabbable);
|
||||
|
||||
grabbable.IsBeingForcedGrabbed = false;
|
||||
}
|
||||
|
||||
protected override void OnHoverEnter(HVRGrabbable grabbable)
|
||||
{
|
||||
base.OnHoverEnter(grabbable);
|
||||
@@ -366,7 +377,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
rb.angularDrag = 0f;
|
||||
rb.drag = 0f;
|
||||
|
||||
grabbable.IsBeingForcedGrabbed = true;
|
||||
IsHoldActive = true;
|
||||
|
||||
var grabPoint = grabbable.GetGrabPointTransform(HandGrabber, GrabpointFilter.ForceGrab);
|
||||
@@ -434,7 +444,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
var delta = JointAnchorWorldPosition - grabbableAnchor;
|
||||
distance = delta.magnitude;
|
||||
|
||||
if (isPhysicsGrab && distance < DynamicGrabThreshold && HandGrabber.TryAutoGrab(grabbable, posableGrabPoint))
|
||||
if (isPhysicsGrab && distance < DynamicGrabThreshold && HandGrabber.TryTransferDistanceGrab(grabbable, posableGrabPoint))
|
||||
{
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
rb.velocity = Vector3.zero;
|
||||
@@ -513,12 +523,13 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
rb.velocity = Vector3.ClampMagnitude(rb.velocity, settings.MaxMissSpeed);
|
||||
rb.angularVelocity = Vector3.ClampMagnitude(rb.angularVelocity, settings.MaxMissAngularSpeed);
|
||||
rb.centerOfMass = com;
|
||||
|
||||
|
||||
if (IsGrabbing)
|
||||
{
|
||||
if (distance < limit)
|
||||
{
|
||||
if (HandGrabber.TryAutoGrab(grabbable, posableGrabPoint))
|
||||
if (HandGrabber.TryTransferDistanceGrab(grabbable, posableGrabPoint))
|
||||
{
|
||||
rb.angularVelocity = Vector3.zero;
|
||||
rb.velocity = Vector3.zero;
|
||||
@@ -529,9 +540,14 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
ForceRelease();
|
||||
}
|
||||
}
|
||||
|
||||
grabbable.IsBeingForcedGrabbed = false;
|
||||
else
|
||||
{
|
||||
HandGrabber.EnableHandCollision(grabbable);
|
||||
ForceRelease();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -558,7 +574,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
_grabbableCollided = false;
|
||||
IsHoldActive = true;
|
||||
|
||||
grabbable.IsBeingForcedGrabbed = true;
|
||||
|
||||
grabbable.Rigidbody.useGravity = false;
|
||||
grabbable.Rigidbody.drag = 0f;
|
||||
grabbable.Rigidbody.angularDrag = 0f;
|
||||
@@ -621,7 +637,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
if (AutoGrab && HandGrabber.IsValidGrabbable(GrabbedTarget) && HandGrabber.TryAutoGrab(GrabbedTarget, posableGrabPoint))
|
||||
if (AutoGrab && HandGrabber.IsValidGrabbable(GrabbedTarget) && HandGrabber.TryTransferDistanceGrab(GrabbedTarget, posableGrabPoint))
|
||||
{
|
||||
grabbed = true;
|
||||
IsForceGrabbing = false;
|
||||
@@ -630,7 +646,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
if (AutoGrab && (JointAnchorWorldPosition - grabPoint.position).magnitude < AutoGrabDistance)
|
||||
{
|
||||
if (HandGrabber.TryAutoGrab(GrabbedTarget, posableGrabPoint))
|
||||
if (HandGrabber.TryTransferDistanceGrab(GrabbedTarget, posableGrabPoint))
|
||||
{
|
||||
grabbed = true;
|
||||
IsForceGrabbing = false;
|
||||
@@ -697,7 +713,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
rb.useGravity = useGrav;
|
||||
rb.drag = drag;
|
||||
rb.angularDrag = angularDrag;
|
||||
grabbable.IsBeingForcedGrabbed = false;
|
||||
grabbable.Collided.RemoveListener(OnGrabbableCollided);
|
||||
grabbable.Grabbed.RemoveListener(OnGrabbableGrabbed);
|
||||
}
|
||||
@@ -731,7 +746,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
if ((JointAnchorWorldPosition - t.position).magnitude < AutoGrabDistance)
|
||||
{
|
||||
if (HandGrabber.TryAutoGrab(grabbable, grabPoint))
|
||||
if (HandGrabber.TryTransferDistanceGrab(grabbable, grabPoint))
|
||||
{
|
||||
grabbable.Rigidbody.angularVelocity = Vector3.zero;
|
||||
grabbable.Rigidbody.velocity = Vector3.zero;
|
||||
@@ -761,7 +776,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
private void UpdateGrabIndicator()
|
||||
{
|
||||
if (!IsHovering || !_grabIndicator)
|
||||
if (!IsHovering || !_grabIndicator || !HoverTarget.ShowForceGrabIndicator)
|
||||
return;
|
||||
|
||||
if (_grabIndicator.LookAtCamera && HVRManager.Instance.Camera)
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
public HVRGrabbable HeldObject => GrabbedTarget;
|
||||
|
||||
public HVRGrabbable GrabbedTarget
|
||||
{
|
||||
@@ -453,7 +454,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
var closestValid = ClosestValidHover();
|
||||
if (closestValid == null)
|
||||
if (!closestValid )
|
||||
return false;
|
||||
|
||||
HoverGrabbable(this, closestValid);
|
||||
@@ -513,6 +514,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public virtual bool CanGrab(HVRGrabbable grabbable)
|
||||
{
|
||||
if (grabbable.MasterGrabbable && grabbable.MasterGrabbable.IsSocketed)
|
||||
return false;
|
||||
return AllowGrabbing && !IsGrabbing;
|
||||
}
|
||||
|
||||
@@ -553,15 +556,19 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected virtual void OnHoverEnter(HVRGrabbable grabbable)
|
||||
{
|
||||
// Debug.Log($"OnHoverEnter {gameObject.name}");
|
||||
if(HVRSettings.Instance.VerboseGrabbableEvents)
|
||||
Debug.Log($"OnHoverEnter {gameObject.name} -> {grabbable.name}");
|
||||
grabbable.Destroyed.AddListener(OnHoverGrabbableDestroyed);
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected virtual void OnHoverExit(HVRGrabbable grabbable)
|
||||
{
|
||||
// Debug.Log($"OnHoverExit {gameObject.name}");
|
||||
if(HVRSettings.Instance.VerboseGrabbableEvents)
|
||||
Debug.Log($"OnHoverExit {gameObject.name}-> {grabbable.name}");
|
||||
grabbable.Destroyed.RemoveListener(OnHoverGrabbableDestroyed);
|
||||
}
|
||||
|
||||
@@ -577,6 +584,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
return false;
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
private bool CheckLineOfSight(Vector3 rayOrigin, HVRGrabbable grabbable, LayerMask RaycastLayermask, float rayMaxDistance, List<Collider> colliders, QueryTriggerInteraction queryTrigger, bool useClosestPoint = true)
|
||||
{
|
||||
_lineOfSightRay.origin = rayOrigin;
|
||||
@@ -588,7 +596,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
if (!grabbableCollider)
|
||||
continue;
|
||||
|
||||
if (!useClosestPoint || grabbable.HasConcaveColliders && grabbableCollider is MeshCollider meshCollider && !meshCollider.convex)
|
||||
if (!useClosestPoint || grabbable.HasConcaveColliders && grabbableCollider is MeshCollider meshCollider && !meshCollider.convex ||
|
||||
grabbable.HasWheelCollider && grabbableCollider is WheelCollider)
|
||||
{
|
||||
_lineOfSightRay.direction = grabbableCollider.bounds.center - _lineOfSightRay.origin;
|
||||
}
|
||||
|
||||
+8
-6
@@ -4,6 +4,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
/// <summary>
|
||||
/// Example code to grab an object in code on start
|
||||
/// </summary>
|
||||
public class HVRHandGrabOnStart : MonoBehaviour
|
||||
{
|
||||
public HVRHandGrabber Grabber;
|
||||
@@ -14,14 +17,13 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
if (Grabbable && Grabber)
|
||||
{
|
||||
if (Grabber.GrabTrigger == HVRGrabTrigger.Active ||
|
||||
Grabbable.OverrideGrabTrigger && Grabbable.GrabTrigger == HVRGrabTrigger.Active)
|
||||
Grabber.Grab(Grabbable, HVRGrabTrigger.Toggle);
|
||||
if (!Grabber.GrabbedTarget)
|
||||
{
|
||||
Debug.LogWarning($"{Grabber.name} and {Grabbable.name} GrabTrigger is set to Active. The object will fall immediately if the user isn't holding the grab button.");
|
||||
Grabbable.MainTransform.position = Grabber.transform.position;
|
||||
Grabber.TryGrab(Grabbable, true);
|
||||
Grabber.GrabToggleActive = true;
|
||||
}
|
||||
|
||||
Grabbable.transform.position = Grabber.transform.position;
|
||||
Grabber.TryGrab(Grabbable, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+198
-184
@@ -27,7 +27,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public HVRSocketBag SocketBag;
|
||||
|
||||
[Header("HandSettings")]
|
||||
|
||||
[Tooltip("Set to true if the HandModel is an IK target")]
|
||||
public bool InverseKinematics;
|
||||
|
||||
@@ -35,7 +34,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public bool ApplyHandLayer = true;
|
||||
|
||||
[Header("Grab Settings")]
|
||||
|
||||
[Tooltip("If true the hand will move to the grabbable instead of pulling the grabbable to the hand")]
|
||||
public bool HandGrabs;
|
||||
|
||||
@@ -60,7 +58,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
[Tooltip("If true the hand model will be cloned for collision use, and colliders removed off the original hand. This will prevent" +
|
||||
"unwanted center of mass and inertia tensor recalculations on grabbable objects due to hand model parenting.")]
|
||||
public bool CloneHandModel = true;
|
||||
public bool CloneHandModel;
|
||||
|
||||
[Tooltip("Ignores hand model parenting distance check.")]
|
||||
public bool IgnoreParentingDistance;
|
||||
@@ -84,7 +82,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public float PushoutTime = .1f;
|
||||
|
||||
[Header("Pull Settings")]
|
||||
|
||||
[Tooltip("Lerps between grabbable starting position and final hand posed position over this amount of time")]
|
||||
public float PullLerpTime = .06f;
|
||||
|
||||
@@ -92,12 +89,12 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public float MoveThreshold = 10f;
|
||||
|
||||
[Header("Components")]
|
||||
|
||||
[Tooltip("The hand animator component, loads from children on startup if not supplied.")]
|
||||
public HVRHandAnimator HandAnimator;
|
||||
|
||||
[Tooltip("Component that holds collider information about the hands. Auto populated from children if not set.")]
|
||||
public HVRHandPhysics HandPhysics;
|
||||
|
||||
public HVRPlayerInputs Inputs;
|
||||
public HVRPhysicsPoser PhysicsPoser;
|
||||
public HVRForceGrabber ForceGrabber;
|
||||
@@ -110,6 +107,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
[Header("Grab Indicators")]
|
||||
public HVRGrabbableHoverBase GrabIndicator;
|
||||
|
||||
public HVRGrabbableHoverBase TriggerGrabIndicator;
|
||||
public HVRGrabbableHoverBase DynamicPoseIndicator;
|
||||
public DynamicPoseGrabIndicator DynamicPoseIndicatorMode = DynamicPoseGrabIndicator.Palm;
|
||||
@@ -118,7 +116,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public HVRHandPoser FallbackPoser;
|
||||
|
||||
[Header("Required Transforms")]
|
||||
|
||||
[Tooltip("Object holding the hand model.")]
|
||||
public Transform HandModel;
|
||||
|
||||
@@ -134,8 +131,10 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
[Tooltip("Sphere collider that checks when collisions should be re-enabled between a released grabbable and this hand.")]
|
||||
public Transform OverlapSizer;
|
||||
|
||||
[Header("Throw Settings")]
|
||||
[Tooltip("Player controller transform, used to find the correct relative velocity of the hands")]
|
||||
public Transform PlayerController;
|
||||
|
||||
[Header("Throw Settings")]
|
||||
[Tooltip("Factor to apply to the linear velocity of the throw.")]
|
||||
public float ReleasedVelocityFactor;
|
||||
|
||||
@@ -154,6 +153,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
[Tooltip("If true throwing takes only the top peak velocities for throwing.")]
|
||||
public bool TakePeakVelocities;
|
||||
|
||||
[DrawIf("TakePeakVelocities", true)]
|
||||
public int CountPeakVelocities = 3;
|
||||
|
||||
@@ -164,13 +164,16 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public VRHandGrabberEvent BreakDistanceReached = new VRHandGrabberEvent();
|
||||
|
||||
[Header("Debugging")]
|
||||
|
||||
[Tooltip("If enabled displays vectors involved in throwing calculation.")]
|
||||
public bool DrawCenterOfMass;
|
||||
|
||||
public bool GrabToggleActive;
|
||||
|
||||
[SerializeField]
|
||||
private HVRGrabbable _triggerHoverTarget;
|
||||
|
||||
public HVRSocket HoveredSocket;
|
||||
|
||||
[SerializeField]
|
||||
private HVRGrabbable _hoverTarget;
|
||||
|
||||
@@ -182,6 +185,9 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public override bool IsHandGrabber => true;
|
||||
|
||||
public bool IsLeftHand => HandSide == HVRHandSide.Left;
|
||||
public bool IsRightHand => HandSide == HVRHandSide.Right;
|
||||
|
||||
public HVRHandStrengthHandler StrengthHandler { get; set; }
|
||||
|
||||
public Transform HandModelParent { get; private set; }
|
||||
@@ -238,6 +244,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public HVRPosableGrabPoint PosableGrabPoint { get; private set; }
|
||||
|
||||
private Transform _triggerGrabPoint;
|
||||
|
||||
public Transform TriggerGrabPoint
|
||||
{
|
||||
get => _triggerGrabPoint;
|
||||
@@ -270,10 +277,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
/// </summary>
|
||||
public Quaternion PoseWorldRotation
|
||||
{
|
||||
get
|
||||
{
|
||||
return GrabbedTarget.transform.rotation * PoseLocalRotation;
|
||||
}
|
||||
get { return GrabbedTarget.transform.rotation * PoseLocalRotation; }
|
||||
}
|
||||
|
||||
public Vector3 PoseWorldPosition
|
||||
@@ -344,6 +348,12 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public bool CanRelease { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// ignores the next overlap check and enabling of collision with the released grabbable. Useful if grabbing something
|
||||
/// requires collision to remain disabled with the object that is next released.
|
||||
/// </summary>
|
||||
public bool IgnoreNextCollisionCheck { get; set; }
|
||||
|
||||
protected Vector3 LineGrabHandVector => transform.rotation * HandModelRotation * _lineGrabHandRelativeDirection;
|
||||
|
||||
protected Vector3 LineGrabVector => PosableGrabPoint.WorldLine.normalized * (_flippedLinePose ? -1f : 1f);
|
||||
@@ -370,12 +380,13 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
private bool _socketGrab;
|
||||
private HVRPosableHand _posableHand;
|
||||
private HVRPosableHand _collisionHand;
|
||||
private bool _hasForceGrabber;
|
||||
private HVRHandPoseData _physicsPose;
|
||||
private HVRHandPoseData _savedPose;
|
||||
private Vector3 _lineGrabHandRelativeDirection;
|
||||
private WaitForFixedUpdate _wffu;
|
||||
private bool _moveGrab;
|
||||
private Vector3 _lastPlayerPos;
|
||||
private Vector3 _playerVel;
|
||||
protected bool IsGripGrabActivated;
|
||||
protected bool IsTriggerGrabActivated;
|
||||
protected bool IsGripGrabActive;
|
||||
@@ -396,8 +407,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
@@ -415,7 +424,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
@@ -433,15 +441,14 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
//created in awake of the hand components if not exist, snapshot in start
|
||||
StrengthHandler = GetComponent<HVRHandStrengthHandler>();
|
||||
|
||||
if (!Inputs)
|
||||
if (!Inputs && transform.root)
|
||||
{
|
||||
Inputs = GetComponentInParent<HVRPlayerInputs>();
|
||||
Inputs = transform.root.GetComponentInChildren<HVRPlayerInputs>();
|
||||
}
|
||||
|
||||
if (!ForceGrabber)
|
||||
{
|
||||
ForceGrabber = GetComponentInChildren<HVRForceGrabber>();
|
||||
_hasForceGrabber = ForceGrabber;
|
||||
}
|
||||
|
||||
if (!HandAnimator)
|
||||
@@ -515,7 +522,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
//removing colliders from the original hand model
|
||||
foreach (var col in HandModel.GetComponentsInChildren<Collider>())
|
||||
{
|
||||
Destroy(col);
|
||||
if (!col.isTrigger) Destroy(col);
|
||||
}
|
||||
|
||||
_collisionTransform = handClone.transform;
|
||||
@@ -605,7 +612,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
protected override void FixedUpdate()
|
||||
{
|
||||
if(PullingGrabbable) UpdatePullGrabbable();
|
||||
if (PullingGrabbable) UpdatePullGrabbable();
|
||||
UpdateLineGrab();
|
||||
UpdatePostMoveGrab();
|
||||
UpdatePushing();
|
||||
@@ -814,7 +821,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
var closestValid = ClosestValidHover(false);
|
||||
if (closestValid == null)
|
||||
if (!closestValid)
|
||||
return false;
|
||||
|
||||
HoverGrabbable(this, closestValid);
|
||||
@@ -850,7 +857,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
var closestValid = ClosestValidHover(true);
|
||||
if (closestValid == null)
|
||||
if (!closestValid)
|
||||
return false;
|
||||
|
||||
OnTriggerHoverEnter(this, closestValid);
|
||||
@@ -858,7 +865,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void CheckUntoggleGrab()
|
||||
{
|
||||
if (GrabToggleActive && !_checkingSwap)
|
||||
@@ -913,37 +919,37 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
switch (grabTrigger)
|
||||
{
|
||||
case HVRGrabTrigger.Active:
|
||||
{
|
||||
if (GrabToggleActive)
|
||||
{
|
||||
if (GrabToggleActive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsLineGrab)
|
||||
{
|
||||
return IsGripGrabActive || IsTriggerGrabActive;
|
||||
}
|
||||
|
||||
var grabActive = false;
|
||||
switch (_currentGrabControl)
|
||||
{
|
||||
case HVRGrabControls.GripOrTrigger:
|
||||
grabActive = IsGripGrabActive || (IsTriggerGrabActive && Inputs.CanTriggerGrab);
|
||||
break;
|
||||
case HVRGrabControls.GripOnly:
|
||||
grabActive = IsGripGrabActive;
|
||||
break;
|
||||
case HVRGrabControls.TriggerOnly:
|
||||
grabActive = IsTriggerGrabActive;
|
||||
break;
|
||||
}
|
||||
|
||||
return grabActive;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsLineGrab)
|
||||
{
|
||||
return IsGripGrabActive || IsTriggerGrabActive;
|
||||
}
|
||||
|
||||
var grabActive = false;
|
||||
switch (_currentGrabControl)
|
||||
{
|
||||
case HVRGrabControls.GripOrTrigger:
|
||||
grabActive = IsGripGrabActive || (IsTriggerGrabActive && Inputs.CanTriggerGrab);
|
||||
break;
|
||||
case HVRGrabControls.GripOnly:
|
||||
grabActive = IsGripGrabActive;
|
||||
break;
|
||||
case HVRGrabControls.TriggerOnly:
|
||||
grabActive = IsTriggerGrabActive;
|
||||
break;
|
||||
}
|
||||
|
||||
return grabActive;
|
||||
}
|
||||
case HVRGrabTrigger.Toggle:
|
||||
{
|
||||
return GrabToggleActive;
|
||||
}
|
||||
{
|
||||
return GrabToggleActive;
|
||||
}
|
||||
case HVRGrabTrigger.ManualRelease:
|
||||
return true;
|
||||
}
|
||||
@@ -953,7 +959,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
protected override void CheckGrab()
|
||||
{
|
||||
|
||||
if (!AllowGrabbing || IsGrabbing || GrabbedTarget)
|
||||
{
|
||||
return;
|
||||
@@ -999,7 +1004,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
GrabPoint = null;
|
||||
|
||||
var gp = HoveredSocket.GrabbedTarget.GetGrabPointTransform(this, GrabpointFilter.Socket);
|
||||
if (!gp)//in case any socket grab point is invalid, deleted, inactive
|
||||
if (!gp) //in case any socket grab point is invalid, deleted, inactive
|
||||
gp = HoveredSocket.GrabbedTarget.GetGrabPointTransform(this, GrabpointFilter.Normal);
|
||||
|
||||
GrabPoint = gp;
|
||||
@@ -1072,7 +1077,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
protected virtual void UpdateGrabIndicator()
|
||||
{
|
||||
if (!IsHovering || !_grabIndicator)
|
||||
if (!IsHovering || !_grabIndicator || !HoverTarget.ShowGrabIndicator)
|
||||
return;
|
||||
|
||||
if (_grabIndicator.LookAtCamera && HVRManager.Instance.Camera)
|
||||
@@ -1146,7 +1151,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
protected virtual void UpdateTriggerGrabIndicator()
|
||||
{
|
||||
if (!IsTriggerHovering || !_triggerIndicator || IsGrabbing || TriggerHoverTarget == HoverTarget)
|
||||
if (!IsTriggerHovering || !_triggerIndicator || IsGrabbing || TriggerHoverTarget == HoverTarget || !TriggerHoverTarget.ShowTriggerGrabIndicator)
|
||||
return;
|
||||
|
||||
if (_triggerIndicator.LookAtCamera && HVRManager.Instance.Camera)
|
||||
@@ -1185,7 +1190,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
if (grabPoint.IsLineGrab && !useGrabPoint && grabPoint.LineInitialCanReposition)
|
||||
{
|
||||
return grabbable.transform.TransformPoint(GetLocalLineGrabPoint(grabbable, transform.TransformPoint(GetLineGrabHandAnchor(PosableGrabPoint))));
|
||||
return grabbable.transform.TransformPoint(GetLocalLineGrabPoint(grabbable, transform.TransformPoint(GetLineGrabHandAnchor(grabPoint)), grabPoint));
|
||||
}
|
||||
|
||||
if (grabPoint.GrabIndicatorPosition)
|
||||
@@ -1243,6 +1248,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
ResetAnimator();
|
||||
}
|
||||
}
|
||||
|
||||
private void EnableGrabIndicator()
|
||||
{
|
||||
if (_grabIndicatorEnabled) return;
|
||||
@@ -1324,6 +1330,10 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
private void TrackVelocities()
|
||||
{
|
||||
_playerVel = Vector3.zero;
|
||||
if (PlayerController)
|
||||
_playerVel = (PlayerController.position - _lastPlayerPos) / Time.deltaTime;
|
||||
|
||||
var deltaRotation = transform.rotation * Quaternion.Inverse(_previousRotation);
|
||||
deltaRotation.ToAngleAxis(out var angle, out var axis);
|
||||
angle *= Mathf.Deg2Rad;
|
||||
@@ -1331,6 +1341,9 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
RecentVelocities.Enqueue(Rigidbody.velocity);
|
||||
RecentAngularVelocities.Enqueue(angularVelocity);
|
||||
|
||||
if (PlayerController)
|
||||
_lastPlayerPos = PlayerController.position;
|
||||
}
|
||||
|
||||
protected virtual void CheckSocketUnhover()
|
||||
@@ -1352,7 +1365,12 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
protected virtual bool CanGrabFromSocket(HVRSocket socket)
|
||||
{
|
||||
if (!socket)
|
||||
if (!socket || !socket.GrabbedTarget)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!socket.GrabbedTarget.CanHandGrab(this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1362,7 +1380,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
return false;
|
||||
}
|
||||
|
||||
return socket.GrabDetectionType == HVRGrabDetection.Socket && socket.GrabbedTarget;
|
||||
return socket.GrabDetectionType == HVRGrabDetection.Socket;
|
||||
}
|
||||
|
||||
protected virtual void CheckSocketHover()
|
||||
@@ -1493,7 +1511,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
var done = false;
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1520,7 +1538,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
else if (_distanceComplete && !_posJoint)
|
||||
{
|
||||
_posJoint = grabbable.gameObject.AddComponent<ConfigurableJoint>();
|
||||
_posJoint = grabbable.Rigidbody.gameObject.AddComponent<ConfigurableJoint>();
|
||||
_posJoint.LockLinearMotion();
|
||||
_posJoint.connectedBody = Rigidbody;
|
||||
_posJoint.autoConfigureConnectedAnchor = false;
|
||||
@@ -1529,13 +1547,14 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
_posJoint.anchor = BaseLineGrabAnchor + _lineOffset;
|
||||
}
|
||||
|
||||
_posJoint.connectedAnchor = HandAnchorLocal;
|
||||
PullJoint.SetLinearDrive(0f, 0f, 0f);
|
||||
}
|
||||
else if (angleComplete && !_rotJoint)
|
||||
{
|
||||
grabbable.transform.rotation = deltaRot * grabbable.transform.rotation;
|
||||
_rotJoint = grabbable.gameObject.AddComponent<ConfigurableJoint>();
|
||||
_rotJoint = grabbable.Rigidbody.gameObject.AddComponent<ConfigurableJoint>();
|
||||
_rotJoint.LockAllAngularMotion();
|
||||
_rotJoint.connectedBody = Rigidbody;
|
||||
_rotJoint.autoConfigureConnectedAnchor = false;
|
||||
@@ -1544,6 +1563,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
_posJoint.anchor = BaseLineGrabAnchor + _lineOffset;
|
||||
}
|
||||
|
||||
_rotJoint.connectedAnchor = HandAnchorLocal;
|
||||
PullJoint.SetSlerpDrive(0f, 0f, 0f);
|
||||
}
|
||||
@@ -1579,13 +1599,14 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
Debug.Log($"{name} break distance reached on {GrabbedTarget.name}.");
|
||||
}
|
||||
|
||||
BreakDistanceReached.Invoke(this, GrabbedTarget);
|
||||
ForceRelease();
|
||||
}
|
||||
|
||||
protected virtual bool CheckBreakDistanceReached(HVRGrabbable grabbable)
|
||||
{
|
||||
if(grabbable.BreakDistanceSource == BreakDistanceSource.Hand)
|
||||
if (grabbable.BreakDistanceSource == BreakDistanceSource.Hand)
|
||||
return Vector3.Distance(GrabAnchorWorld, JointAnchorWorldPosition) > grabbable.BreakDistance;
|
||||
if (grabbable.BreakDistanceSource == BreakDistanceSource.Controller)
|
||||
return Vector3.Distance(GrabAnchorWorld, TrackedController.position) > grabbable.BreakDistance;
|
||||
@@ -1651,7 +1672,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
ParentHandModel(GrabPoint);
|
||||
}
|
||||
|
||||
SetAnimatorPose(poser, parent);
|
||||
if (CloneHandModel && _collisionAnimator) _collisionAnimator.SetHeldPoser(poser);
|
||||
if (HandAnimator) HandAnimator.SetHeldPoser(poser);
|
||||
}
|
||||
|
||||
private void ParentHandModel(Transform parent)
|
||||
@@ -1672,9 +1694,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
HandModel.parent = parent;
|
||||
|
||||
if (InverseKinematics && PosableGrabPoint)
|
||||
if (PosableGrabPoint)
|
||||
{
|
||||
//posable hand not on the IK target, need to set pos / rot manually
|
||||
var pose = PosableGrabPoint.HandPoser.PrimaryPose.Pose.GetPose(HandSide);
|
||||
HandModel.localRotation = pose.Rotation;
|
||||
HandModel.localPosition = pose.Position;
|
||||
@@ -1682,14 +1703,20 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
_hasPosed = true;
|
||||
|
||||
var listener = parent.gameObject.AddComponent<HVRDestroyListener>();
|
||||
var listener = parent.gameObject.EnsureComponent<HVRDestroyListener>();
|
||||
listener.Destroyed.AddListener(OnGrabPointDestroyed);
|
||||
}
|
||||
|
||||
public void SetAnimatorPose(HVRHandPoser poser, bool poseHand = false, bool poseHandClone = false)
|
||||
public void SetAnimatorPose(HVRHandPoser poser)
|
||||
{
|
||||
if (CloneHandModel && _collisionAnimator) _collisionAnimator.SetCurrentPoser(poser, poseHandClone);
|
||||
if (HandAnimator) HandAnimator.SetCurrentPoser(poser, poseHand);
|
||||
if (CloneHandModel && _collisionAnimator) _collisionAnimator.SetCurrentPoser(poser);
|
||||
if (HandAnimator) HandAnimator.SetCurrentPoser(poser);
|
||||
}
|
||||
|
||||
public void SetAnimatorOverridePose(HVRHandPoser poser)
|
||||
{
|
||||
if (CloneHandModel && _collisionAnimator) _collisionAnimator.SetOverridePoser(poser);
|
||||
if (HandAnimator) HandAnimator.SetOverridePoser(poser);
|
||||
}
|
||||
|
||||
public void ResetAnimator()
|
||||
@@ -1718,11 +1745,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
public void OverrideHandSettings(HVRJointSettings settings)
|
||||
{
|
||||
StrengthHandler.OverrideHandSettings(settings);
|
||||
}
|
||||
|
||||
public override bool CanHover(HVRGrabbable grabbable)
|
||||
{
|
||||
if (IsForceGrabbing || (IsGripGrabActive && (!HoverTarget || HoverTarget != grabbable)))
|
||||
@@ -1731,13 +1753,16 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
return CanGrab(grabbable);
|
||||
}
|
||||
|
||||
private bool IsForceGrabbing => _hasForceGrabber && (ForceGrabber.IsForceGrabbing || ForceGrabber.IsAiming);
|
||||
private bool IsForceGrabbing => ForceGrabber && (ForceGrabber.IsForceGrabbing || ForceGrabber.IsAiming);
|
||||
|
||||
public override bool CanGrab(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!base.CanGrab(grabbable))
|
||||
return false;
|
||||
|
||||
if (!grabbable.CanHandGrab(this))
|
||||
return false;
|
||||
|
||||
if ((!AllowMultiplayerSwap && !grabbable.AllowMultiplayerSwap) && grabbable.HoldType != HVRHoldType.ManyHands && grabbable.AnyGrabberNotMine())
|
||||
{
|
||||
return false;
|
||||
@@ -1752,7 +1777,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GrabbedTarget != null && GrabbedTarget != grabbable)
|
||||
if (GrabbedTarget && GrabbedTarget != grabbable)
|
||||
return false;
|
||||
|
||||
if (grabbable.IsSocketed && grabbable.Socket.GrabDetectionType == HVRGrabDetection.Socket)
|
||||
@@ -1808,9 +1833,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
if (_socketGrab)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1933,9 +1955,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
var isStatic = grabbable.Stationary ||
|
||||
(grabbable.IsJointGrab && (!grabbable.Rigidbody || (grabbable.RemainsKinematic && grabbable.Rigidbody.isKinematic)));
|
||||
|
||||
var isStatic = grabbable.Stationary || (grabbable.IsJointGrab && (!grabbable.Rigidbody || grabbable.Rigidbody.isKinematic));
|
||||
|
||||
var linkedHeld = grabbable.MasterGrabbable && grabbable.MasterGrabbable.IsHandGrabbed || grabbable.AnyLinkedHandHeld();
|
||||
|
||||
@@ -1956,7 +1976,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static bool IsV1Closest(Vector3 v, Vector3 v1, Vector3 v2)
|
||||
{
|
||||
var vNorm = v.normalized;
|
||||
@@ -1993,7 +2012,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
var mid = grabbable.transform.InverseTransformPoint(PosableGrabPoint.WorldLineMiddle);
|
||||
var point = IsInitialLineGrab ? transform.TransformPoint(GetLineGrabHandAnchor(PosableGrabPoint)) : GrabPoint.position;
|
||||
_lineOffset = GetLocalLineGrabPoint(grabbable, point) - mid;
|
||||
_lineOffset = GetLocalLineGrabPoint(grabbable, point, PosableGrabPoint) - mid;
|
||||
|
||||
if (PosableGrabPoint.CanLineFlip)
|
||||
{
|
||||
@@ -2016,10 +2035,10 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
private Vector3 GetLocalLineGrabPoint(HVRGrabbable grabbable, Vector3 point)
|
||||
private Vector3 GetLocalLineGrabPoint(HVRGrabbable grabbable, Vector3 point, HVRPosableGrabPoint grabPoint)
|
||||
{
|
||||
var start = grabbable.transform.InverseTransformPoint(PosableGrabPoint.LineStart.position);
|
||||
var end = grabbable.transform.InverseTransformPoint(PosableGrabPoint.LineEnd.position);
|
||||
var start = grabbable.transform.InverseTransformPoint(grabPoint.LineStart.position);
|
||||
var end = grabbable.transform.InverseTransformPoint(grabPoint.LineEnd.position);
|
||||
var testPoint = grabbable.transform.InverseTransformPoint(point);
|
||||
return HVRUtilities.FindNearestPointOnLine(start, end, testPoint);
|
||||
}
|
||||
@@ -2038,12 +2057,13 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
for (var i = 0; i < grabbable.Colliders.Count; i++)
|
||||
{
|
||||
var gc = grabbable.Colliders[i];
|
||||
if (!gc.enabled || !gc.gameObject.activeInHierarchy || gc.isTrigger)
|
||||
if (!gc || !gc.enabled || !gc.gameObject.activeInHierarchy || gc.isTrigger)
|
||||
continue;
|
||||
|
||||
var anchor = Palm.transform.position;
|
||||
Vector3 point;
|
||||
if (grabbable.HasConcaveColliders && gc is MeshCollider meshCollider && !meshCollider.convex)
|
||||
if (grabbable.HasConcaveColliders && gc is MeshCollider meshCollider && !meshCollider.convex ||
|
||||
grabbable.HasWheelCollider && gc is WheelCollider wheelCollider)
|
||||
{
|
||||
if (!gc.Raycast(new Ray(anchor, Palm.transform.forward), out var hit, .3f))
|
||||
{
|
||||
@@ -2085,7 +2105,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
return false;
|
||||
}
|
||||
|
||||
return GrabbedTarget.PoseType == PoseType.PhysicPoser || ((GrabPoint == null || GrabPoint == GrabbedTarget.transform) && GrabbedTarget.PhysicsPoserFallback);
|
||||
return GrabbedTarget.PoseType == PoseType.PhysicPoser || ((!GrabPoint || GrabPoint == GrabbedTarget.transform) && GrabbedTarget.PhysicsPoserFallback);
|
||||
}
|
||||
|
||||
private IEnumerator MoveGrab()
|
||||
@@ -2177,7 +2197,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
SetupGrab(grabbable);
|
||||
IsClimbing = grabbable.GetComponent<HVRClimbable>();
|
||||
if (grabbable.HandGrabbedClip)
|
||||
if (SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(grabbable.HandGrabbedClip, transform.position);
|
||||
if (SFXPlayer.Instance)
|
||||
SFXPlayer.Instance.PlaySFX(grabbable.HandGrabbedClip, transform.position);
|
||||
}
|
||||
|
||||
public void SetupGrab(HVRGrabbable grabbable)
|
||||
@@ -2195,8 +2216,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
//determine if a pull to hand joint should be enabled, or should the final strong joint be enabled
|
||||
final = grabbable.PoseType == PoseType.Offset || grabbable.Stationary ||
|
||||
(grabbable.RemainsKinematic && grabbable.Rigidbody.isKinematic)
|
||||
|| _moveGrab || _forceFullyGrabbed
|
||||
grabbable.Rigidbody.isKinematic ||
|
||||
_moveGrab || _forceFullyGrabbed
|
||||
|| _socketGrab && HoveredSocket.InstantHandPose;
|
||||
_moveGrab = false;
|
||||
}
|
||||
@@ -2209,12 +2230,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
StartPull();
|
||||
}
|
||||
|
||||
if (grabbable.Rigidbody && (!grabbable.Rigidbody.isKinematic || !grabbable.RemainsKinematic))
|
||||
{
|
||||
grabbable.Rigidbody.isKinematic = false;
|
||||
grabbable.Rigidbody.collisionDetectionMode = grabbable.CollisionDetection;
|
||||
}
|
||||
}
|
||||
|
||||
if (GrabPoint)
|
||||
@@ -2335,18 +2350,12 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public Quaternion JointRotation
|
||||
{
|
||||
get
|
||||
{
|
||||
return Quaternion.Inverse(GrabbedTarget.transform.rotation) * CachedWorldRotation * Quaternion.Inverse(PoseLocalRotation);
|
||||
}
|
||||
get { return Quaternion.Inverse(GrabbedTarget.transform.rotation) * CachedWorldRotation * Quaternion.Inverse(PoseLocalRotation); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void SetupConfigurableJoint(HVRGrabbable grabbable)
|
||||
{
|
||||
|
||||
|
||||
var axis = Vector3.right;
|
||||
var secondaryAxis = Vector3.up;
|
||||
|
||||
@@ -2453,7 +2462,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
UpdateGrabbableCOM(grabbable);
|
||||
OnHandAttached();
|
||||
BreakDistanceCooldown(2f);
|
||||
_finalJointCreated = true;
|
||||
@@ -2478,25 +2486,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateGrabbableCOM(HVRGrabbable grabbable)
|
||||
{
|
||||
if (grabbable.Rigidbody && grabbable.PalmCenterOfMass)
|
||||
{
|
||||
//Debug.Log($"updating grabbable com { grabbable.HandGrabbers.Count}");
|
||||
if (grabbable.HandGrabbers.Count == 1)
|
||||
{
|
||||
var p1 = grabbable.HandGrabbers[0].JointAnchorWorldPosition;
|
||||
grabbable.Rigidbody.centerOfMass = grabbable.transform.InverseTransformPoint(p1);
|
||||
}
|
||||
else if (grabbable.HandGrabbers.Count == 2)
|
||||
{
|
||||
var p1 = grabbable.HandGrabbers[0].JointAnchorWorldPosition;
|
||||
var p2 = grabbable.HandGrabbers[1].JointAnchorWorldPosition;
|
||||
grabbable.Rigidbody.centerOfMass = grabbable.transform.InverseTransformPoint((p1 + p2) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLineGrab()
|
||||
{
|
||||
if (!IsLineGrab || PullingGrabbable || !_finalJointCreated || !Joint)
|
||||
@@ -2516,7 +2505,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
(GrabTrigger == HVRGrabTrigger.Toggle || GrabToggleActive || !CanRelease) && !IsTriggerGrabActive;
|
||||
|
||||
loosen = GrabTrigger == HVRGrabTrigger.Active && !IsGripGrabActive && !GrabToggleActive && CanRelease ||
|
||||
(GrabTrigger == HVRGrabTrigger.Toggle || GrabToggleActive || !CanRelease) && IsTriggerGrabActive;
|
||||
(GrabTrigger == HVRGrabTrigger.Toggle || GrabToggleActive || !CanRelease) && IsTriggerGrabActive;
|
||||
}
|
||||
|
||||
if (PosableGrabPoint.LineCanReposition || PosableGrabPoint.LineCanRotate)
|
||||
@@ -2533,10 +2522,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
var mid = GrabbedTarget.transform.InverseTransformPoint(PosableGrabPoint.WorldLineMiddle);
|
||||
_lineOffset = GetLocalLineGrabPoint(GrabbedTarget, transform.TransformPoint(HandAnchorLocal)) - mid;
|
||||
_lineOffset = GetLocalLineGrabPoint(GrabbedTarget, transform.TransformPoint(HandAnchorLocal), PosableGrabPoint) - mid;
|
||||
Joint.anchor = BaseLineGrabAnchor + _lineOffset;
|
||||
|
||||
UpdateGrabbableCOM(GrabbedTarget);
|
||||
}
|
||||
else if (_tightlyHeld && loosen)
|
||||
{
|
||||
@@ -2561,7 +2548,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
xDrive.positionDamper = PosableGrabPoint.LooseDamper;
|
||||
xDrive.maximumForce = 100000f;
|
||||
Joint.xDrive = xDrive;
|
||||
|
||||
}
|
||||
|
||||
if (PosableGrabPoint.LineCanRotate || PosableGrabPoint.LineFreeRotation)
|
||||
@@ -2575,15 +2561,16 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
xDrive.maximumForce = 100000f;
|
||||
Joint.angularXDrive = xDrive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected override void OnReleased(HVRGrabbable grabbable)
|
||||
{
|
||||
if (HVRSettings.Instance.VerboseHandGrabberEvents)
|
||||
{
|
||||
Debug.Log($"{name}:OnReleased");
|
||||
}
|
||||
|
||||
base.OnReleased(grabbable);
|
||||
|
||||
if (ControllerOffset)
|
||||
@@ -2597,6 +2584,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
StartPushing();
|
||||
}
|
||||
|
||||
|
||||
_checkingEnableCollision = false;
|
||||
_primaryGrabPointGrab = false;
|
||||
_socketGrab = false;
|
||||
@@ -2606,7 +2594,17 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
IsLineGrab = false;
|
||||
|
||||
TriggerGrabPoint = null;
|
||||
ResetHandModel();
|
||||
|
||||
if (HandModel && HandModel.parent && HandModel.parent.TryGetComponent(out HVRDestroyListener listener))
|
||||
{
|
||||
listener.Destroyed.RemoveListener(OnGrabPointDestroyed);
|
||||
}
|
||||
|
||||
_hasPosed = false;
|
||||
ResetHandTransform(HandModel);
|
||||
ResetHandTransform(_collisionTransform);
|
||||
HandAnimator.OnHeldObjectReleased();
|
||||
if (_collisionAnimator) _collisionAnimator.OnHeldObjectReleased();
|
||||
|
||||
IsPhysicsPose = false;
|
||||
_physicsPose = null;
|
||||
@@ -2623,26 +2621,33 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
if (grabbable.Rigidbody && !grabbable.Rigidbody.isKinematic)
|
||||
{
|
||||
var throwVelocity = ComputeThrowVelocity(grabbable, out var angularVelocity, true);
|
||||
grabbable.Rigidbody.velocity = throwVelocity;
|
||||
grabbable.Rigidbody.angularVelocity = angularVelocity;
|
||||
var throwVelocity = ComputeThrowVelocity(grabbable, out var angularVelocity);
|
||||
if(!throwVelocity.IsInvalid())
|
||||
grabbable.Rigidbody.velocity = throwVelocity;
|
||||
if(!throwVelocity.IsInvalid())
|
||||
grabbable.Rigidbody.angularVelocity = angularVelocity;
|
||||
//prevent clipping on throw
|
||||
if (timeout < .2f && grabbable.Rigidbody.velocity.magnitude > 2f) timeout = .2f;
|
||||
}
|
||||
|
||||
if (grabbable.Rigidbody && !grabbable.Rigidbody.isKinematic && (grabbable.RequireOverlapClearance || timeout > 0f))
|
||||
if (!IgnoreNextCollisionCheck)
|
||||
{
|
||||
var routine = StartCoroutine(CheckReleasedOverlap(grabbable, timeout));
|
||||
OverlappingGrabbables[grabbable] = routine;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableHandCollision(grabbable);
|
||||
if (grabbable.Rigidbody && !grabbable.Rigidbody.isKinematic && (grabbable.RequireOverlapClearance || timeout > 0f))
|
||||
{
|
||||
var routine = StartCoroutine(CheckReleasedOverlap(grabbable, timeout));
|
||||
OverlappingGrabbables[grabbable] = routine;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnableHandCollision(grabbable);
|
||||
}
|
||||
}
|
||||
|
||||
grabbable.HeldGrabPoints.Remove(GrabPoint);
|
||||
}
|
||||
|
||||
IgnoreNextCollisionCheck = false;
|
||||
|
||||
GrabToggleActive = false;
|
||||
GrabPoint = null;
|
||||
Released.Invoke(this, grabbable);
|
||||
@@ -2678,14 +2683,15 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
internal static Vector3 GetAverageVelocity(int frames, int start, CircularBuffer<Vector3> recentVelocities, bool takePeak = false, int nPeak = 3)
|
||||
{
|
||||
if (frames == 0)
|
||||
return Vector3.zero;
|
||||
|
||||
var sum = Vector3.zero;
|
||||
for (var i = start; i < start + frames; i++)
|
||||
{
|
||||
sum += recentVelocities[i];
|
||||
}
|
||||
|
||||
if (Mathf.Approximately(frames, 0f))
|
||||
return Vector3.zero;
|
||||
|
||||
var average = sum / frames;
|
||||
|
||||
@@ -2695,7 +2701,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
for (var i = start; i < start + frames; i++)
|
||||
{
|
||||
|
||||
//removing any vectors not going in the direction of the average vector
|
||||
var dot = Vector3.Dot(average.normalized, recentVelocities[i].normalized);
|
||||
if (dot < .2)
|
||||
@@ -2736,8 +2741,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Vector3 ComputeThrowVelocity(HVRGrabbable grabbable, out Vector3 angularVelocity, bool isThrowing = false)
|
||||
public Vector3 ComputeThrowVelocity(HVRGrabbable grabbable, out Vector3 angularVelocity, bool playerRelative = false)
|
||||
{
|
||||
if (!grabbable.Rigidbody)
|
||||
{
|
||||
@@ -2749,8 +2753,16 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
var grabbableAngular = grabbable.GetAverageAngularVelocity(ThrowLookback, ThrowLookbackStart);
|
||||
|
||||
var handVelocity = GetAverageVelocity(ThrowLookback, ThrowLookbackStart);
|
||||
|
||||
if (playerRelative)
|
||||
{
|
||||
handVelocity -= _playerVel;
|
||||
grabbableVelocity -= _playerVel;
|
||||
}
|
||||
|
||||
var handAngularVelocity = GetAverageAngularVelocity(ThrowLookback, ThrowLookbackStart);
|
||||
|
||||
//var throwVelocity = handVelocity * (ReleasedVelocityFactor * grabbable.ReleasedVelocityFactor);
|
||||
var throwVelocity = ReleasedVelocityFactor * handVelocity + grabbableVelocity * grabbable.ReleasedVelocityFactor;
|
||||
|
||||
//Debug.Log($"{handAngularVelocity.magnitude}");
|
||||
@@ -2758,7 +2770,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
if (handAngularVelocity.magnitude > ReleasedAngularThreshold)
|
||||
{
|
||||
//compute linear velocity from wrist rotation
|
||||
var grabbableCom = GrabPoint != null ? GrabPoint.position : grabbable.Rigidbody.worldCenterOfMass;
|
||||
var grabbableCom = GrabPoint ? GrabPoint.position : grabbable.Rigidbody.worldCenterOfMass;
|
||||
|
||||
Vector3 centerOfMass;
|
||||
if (ThrowingCenterOfMass && ThrowingCenterOfMass.CenterOfMass)
|
||||
@@ -2770,12 +2782,14 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
centerOfMass = Rigidbody.worldCenterOfMass;
|
||||
}
|
||||
|
||||
var cross = Vector3.Cross(handAngularVelocity, grabbableCom - centerOfMass) * grabbable.ReleasedAngularConversionFactor * ReleasedAngularConversionFactor;
|
||||
var cross = Vector3.Cross(handAngularVelocity, grabbableCom - centerOfMass) * (grabbable.ReleasedAngularConversionFactor * ReleasedAngularConversionFactor);
|
||||
throwVelocity += cross;
|
||||
}
|
||||
|
||||
angularVelocity = grabbableAngular * grabbable.ReleasedAngularFactor;
|
||||
|
||||
|
||||
|
||||
return throwVelocity;
|
||||
}
|
||||
|
||||
@@ -2934,9 +2948,9 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryAutoGrab(HVRGrabbable grabbable, HVRPosableGrabPoint grabPoint)
|
||||
public bool TryTransferDistanceGrab(HVRGrabbable grabbable, HVRPosableGrabPoint grabPoint)
|
||||
{
|
||||
if (GrabTrigger == HVRGrabTrigger.Active && !Inputs.GetHoldActive(HandSide))
|
||||
if (GrabTrigger == HVRGrabTrigger.Active && !Inputs.GetForceGrabActive(HandSide))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -2956,7 +2970,24 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
//if (grabPoint) OrientGrabbable(grabbable, grabPoint, true, false);
|
||||
if (TryGrab(grabbable))
|
||||
{
|
||||
_currentGrabControl = grabbable.GrabControl;
|
||||
if (Inputs.ForceGrabActivation == HVRForceGrabActivation.Grip)
|
||||
{
|
||||
_currentGrabControl = HVRGrabControls.GripOnly;
|
||||
}
|
||||
else if (Inputs.ForceGrabActivation == HVRForceGrabActivation.Trigger)
|
||||
{
|
||||
_currentGrabControl = HVRGrabControls.TriggerOnly;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsGripGrabActive)
|
||||
_currentGrabControl = HVRGrabControls.GripOnly;
|
||||
else
|
||||
_currentGrabControl = HVRGrabControls.TriggerOnly;
|
||||
}
|
||||
|
||||
CheckGrabControlSwap();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2964,6 +2995,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
_isForceAutoGrab = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2975,36 +3007,18 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
if (!HandModel)
|
||||
return;
|
||||
|
||||
if (HandModel.parent)
|
||||
{
|
||||
var listener = HandModel.parent.GetComponent<HVRDestroyListener>();
|
||||
if (listener)
|
||||
{
|
||||
listener.Destroyed.RemoveListener(OnGrabPointDestroyed);
|
||||
Destroy(listener);
|
||||
}
|
||||
}
|
||||
|
||||
ResetHand(HandModel, HandAnimator);
|
||||
ResetHandTransform(HandModel);
|
||||
if (HandAnimator) HandAnimator.ResetToDefault();
|
||||
if (_collisionTransform)
|
||||
{
|
||||
ResetHand(_collisionTransform, _collisionAnimator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void ResetHand(Transform hand, HVRHandAnimator animator)
|
||||
{
|
||||
ResetHandTransform(hand);
|
||||
if (animator)
|
||||
{
|
||||
animator.ResetToDefault();
|
||||
ResetHandTransform(_collisionTransform);
|
||||
if (_collisionAnimator) _collisionAnimator.ResetToDefault();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetHandTransform(Transform hand)
|
||||
{
|
||||
if (!hand) return;
|
||||
hand.parent = HandModelParent;
|
||||
hand.localPosition = HandModelPosition;
|
||||
hand.localRotation = HandModelRotation;
|
||||
@@ -3036,6 +3050,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
_collisionHand.Pose(HVRHandPoseData.FromByteArray(data, HandSide), GrabbedTarget.ParentHandModel);
|
||||
}
|
||||
|
||||
_posableHand.Pose(HVRHandPoseData.FromByteArray(data, HandSide), GrabbedTarget.ParentHandModel);
|
||||
}
|
||||
|
||||
@@ -3048,7 +3063,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected virtual IEnumerator SwapGrabPoint(HVRPosableGrabPoint grabPoint, float time, HVRAxis axis)
|
||||
{
|
||||
var grabbable = GrabbedTarget;
|
||||
@@ -3136,7 +3150,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Will grab the provided object using the provided grab point, if the grab point isn't provided then the first valid one on the object will be used.
|
||||
/// If there are no grab points that are allowed to be grabbed by this hand you shouldn't use this method.
|
||||
@@ -3186,8 +3199,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
public void OrientGrabbable(HVRGrabbable grabbable, HVRPosableGrabPoint grabPoint, bool position = true, bool rotation = true)
|
||||
{
|
||||
var deltaRot = CachedWorldRotation * Quaternion.Inverse(grabPoint.GetPoseWorldRotation(HandSide));
|
||||
if (rotation) grabbable.transform.rotation = deltaRot * grabbable.transform.rotation;
|
||||
if (position) grabbable.transform.position += (HandModel.position - grabPoint.GetPoseWorldPosition(HandSide));
|
||||
if (rotation) grabbable.MainTransform.rotation = deltaRot * grabbable.MainTransform.rotation;
|
||||
if (position) grabbable.MainTransform.position += (HandModel.position - grabPoint.GetPoseWorldPosition(HandSide));
|
||||
}
|
||||
|
||||
public override void ForceRelease()
|
||||
@@ -3197,7 +3210,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
@@ -3244,6 +3256,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public enum DynamicPoseGrabIndicator
|
||||
{
|
||||
Transform, Palm, None
|
||||
Transform,
|
||||
Palm,
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
public class HVRSocket : HVRGrabberBase
|
||||
{
|
||||
|
||||
[Header("Grab Settings")]
|
||||
public HVRGrabControls GrabControl = HVRGrabControls.GripOrTrigger;
|
||||
|
||||
@@ -77,6 +76,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
[Tooltip("Fallback grabbed sfx to play if the socketable doesn't have one.")]
|
||||
public AudioClip AudioGrabbedFallback;
|
||||
|
||||
[Tooltip("Fallback released sfx to play if the socketable doesn't have one.")]
|
||||
public AudioClip AudioReleasedFallback;
|
||||
|
||||
@@ -92,6 +92,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
[Tooltip("If supplied the hand will use this point when sorting distance to the closest socket instead of the socket position")]
|
||||
public Transform DistanceSource;
|
||||
|
||||
[Tooltip("Used by the socketable to decide which saved pose to use.")]
|
||||
public string PoseTag;
|
||||
|
||||
[Tooltip("If false, the socketed object colliders remain active, only works for static or kinematic rb sockets.")]
|
||||
public bool DisableCollision = true;
|
||||
@@ -105,16 +107,23 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
protected Transform _previousParent;
|
||||
protected Vector3 _previousScale;
|
||||
protected Bounds _modelBounds;
|
||||
protected bool _appQuitting;
|
||||
protected HVRGrabbable _timeoutGrabbable;
|
||||
protected float _mass;
|
||||
private RigidbodyInterpolation _rbInterpolation;
|
||||
private float _rbDrag;
|
||||
private float _rbAngularDrag;
|
||||
private float _rbMass;
|
||||
private bool _rbGravity;
|
||||
private bool _rbKinematic;
|
||||
private float _socketMass;
|
||||
protected bool _hadRigidBody;
|
||||
protected bool _ignoreGrabSFX;
|
||||
protected Coroutine _fixPositionRoutine;
|
||||
|
||||
|
||||
public HVRGrabbable LinkedGrabbable { get; internal set; }
|
||||
/// <summary>
|
||||
/// If assigned only this grabbable can enter this socket.
|
||||
/// </summary>
|
||||
public HVRGrabbable LinkedGrabbable { get; set; }
|
||||
|
||||
public override bool IsGrabActivated => !IsGrabbing;
|
||||
public override bool IsHoldActive => IsGrabbing;
|
||||
@@ -125,6 +134,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public override bool IsSocket => true;
|
||||
|
||||
public int? PoseHash { get; set; }
|
||||
|
||||
public bool CanAddGrabbable
|
||||
{
|
||||
get
|
||||
@@ -151,6 +162,9 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
Debug.LogWarning($"Sockets with a non kinematic rigidbody should not disable DisableCollision");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(PoseTag))
|
||||
PoseHash = Animator.StringToHash(PoseTag);
|
||||
|
||||
//if (!Rigidbody && HoldType == SocketHoldType.RemoveRigidbody)
|
||||
//{
|
||||
// HoldType = SocketHoldType.Kinematic;
|
||||
@@ -166,7 +180,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
SetupParentDisablesGrab();
|
||||
|
||||
SocketFilters = GetComponents<HVRSocketFilter>();
|
||||
if (SocketFilters == null || SocketFilters.Length == 0)
|
||||
SocketFilters = GetComponents<HVRSocketFilter>();
|
||||
if (HoverActions == null || HoverActions.Length == 0)
|
||||
HoverActions = GetComponents<HVRSocketHoverAction>();
|
||||
|
||||
@@ -201,7 +216,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
var cloneGrabbable = clone.GetComponent<HVRGrabbable>();
|
||||
if (cloneGrabbable)
|
||||
{
|
||||
var t = TryGrab(cloneGrabbable, true, true);
|
||||
TryGrab(cloneGrabbable, true, true);
|
||||
SpawnedPrefab.Invoke(this, clone);
|
||||
}
|
||||
else
|
||||
@@ -270,7 +285,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
if (GrabbableMustBeHeld && grabbable.GrabberCount != 1)
|
||||
return false;
|
||||
var handGrabber = grabbable.PrimaryGrabber as HVRHandGrabber;
|
||||
if (handGrabber == null)
|
||||
if (!handGrabber)
|
||||
return false;
|
||||
if (_timeoutGrabbable && _timeoutGrabbable == grabbable)
|
||||
return false;
|
||||
@@ -282,6 +297,7 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return base.CanHover(grabbable);
|
||||
}
|
||||
|
||||
@@ -309,7 +325,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
grabbable.Released.AddListener(OnHoverGrabbableReleased);
|
||||
|
||||
|
||||
|
||||
base.OnHoverEnter(grabbable);
|
||||
if (HoverActions != null)
|
||||
{
|
||||
@@ -359,7 +374,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
if (CanAddGrabbable && TryGrab(grabbable))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,6 +443,11 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
|
||||
public virtual bool IsValid(HVRGrabbable grabbable)
|
||||
{
|
||||
if (LinkedGrabbable)
|
||||
{
|
||||
return LinkedGrabbable == grabbable;
|
||||
}
|
||||
|
||||
if (grabbable.IsStabbing && !CanGrabStabbingGrabbable || grabbable.IsStabbed || !grabbable.Socketable)
|
||||
return false;
|
||||
|
||||
@@ -476,30 +495,8 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
_previousParent = grabbable.transform.parent;
|
||||
_previousScale = grabbable.transform.localScale;
|
||||
|
||||
if (grabbable.Socketable && grabbable.Socketable.ScaleOverride)
|
||||
{
|
||||
var scaleBox = grabbable.Socketable.ScaleOverride;
|
||||
|
||||
var temp = scaleBox.enabled;
|
||||
|
||||
if (!scaleBox.enabled)
|
||||
{
|
||||
scaleBox.enabled = true;
|
||||
}
|
||||
|
||||
_modelBounds = scaleBox.bounds;
|
||||
|
||||
if (!temp)
|
||||
{
|
||||
scaleBox.enabled = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_modelBounds = grabbable.ModelBounds;
|
||||
}
|
||||
|
||||
grabbable.transform.parent = transform;
|
||||
AttachGrabbable(grabbable);
|
||||
OnGrabbableParented(grabbable);
|
||||
HandleRigidBodyGrab(grabbable);
|
||||
PlaySocketedSFX(grabbable.Socketable);
|
||||
@@ -510,44 +507,51 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetPositionOffset(HVRGrabbable grabbable)
|
||||
protected virtual void AttachGrabbable(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!grabbable || !grabbable.Socketable || !grabbable.Socketable.SocketOrientation)
|
||||
return Vector3.zero;
|
||||
return grabbable.Socketable.SocketOrientation.localPosition;
|
||||
grabbable.transform.parent = transform;
|
||||
}
|
||||
|
||||
protected virtual Quaternion GetRotationOffset(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!grabbable || !grabbable.Socketable || !grabbable.Socketable.SocketOrientation)
|
||||
return Quaternion.identity;
|
||||
return grabbable.Socketable.SocketOrientation.localRotation;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetTargetPosition(HVRGrabbable grabbable)
|
||||
{
|
||||
var offSet = -GetPositionOffset(grabbable);
|
||||
var delta = Quaternion.Inverse(GetRotationOffset(grabbable));
|
||||
offSet = delta * offSet;
|
||||
|
||||
offSet.x *= grabbable.transform.localScale.x;
|
||||
offSet.y *= grabbable.transform.localScale.y;
|
||||
offSet.z *= grabbable.transform.localScale.z;
|
||||
|
||||
return offSet;
|
||||
}
|
||||
|
||||
protected virtual Quaternion GetTargetRotation(HVRGrabbable grabbable)
|
||||
/// <summary>
|
||||
/// Returns the socketed local position
|
||||
/// </summary>
|
||||
public virtual Vector3 GetTargetPosition(HVRGrabbable grabbable)
|
||||
{
|
||||
var socketable = grabbable.Socketable;
|
||||
if (!grabbable || !socketable)
|
||||
return Vector3.zero;
|
||||
|
||||
if (socketable.SocketOrientation)
|
||||
{
|
||||
var rotationOffset = GetRotationOffset(grabbable);
|
||||
return Quaternion.Inverse(rotationOffset);
|
||||
var offSet = -socketable.SocketOrientation.localPosition;
|
||||
var delta = Quaternion.Inverse(socketable.SocketOrientation.localRotation);
|
||||
offSet = delta * offSet;
|
||||
|
||||
offSet.x *= grabbable.transform.localScale.x;
|
||||
offSet.y *= grabbable.transform.localScale.y;
|
||||
offSet.z *= grabbable.transform.localScale.z;
|
||||
|
||||
return offSet;
|
||||
}
|
||||
|
||||
return Quaternion.identity;
|
||||
return socketable.GetPositionOffset(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the socketed local rotation;
|
||||
/// </summary>
|
||||
public virtual Quaternion GetTargetRotation(HVRGrabbable grabbable)
|
||||
{
|
||||
var socketable = grabbable.Socketable;
|
||||
if (!socketable)
|
||||
return Quaternion.identity;
|
||||
|
||||
if (socketable.SocketOrientation)
|
||||
{
|
||||
return Quaternion.Inverse(socketable.SocketOrientation.localRotation);
|
||||
}
|
||||
|
||||
return socketable.GetRotationOffset(this);
|
||||
}
|
||||
|
||||
protected virtual void OnGrabbableParented(HVRGrabbable grabbable)
|
||||
@@ -572,55 +576,71 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
if (!grabbable.Rigidbody)
|
||||
return;
|
||||
|
||||
_rbKinematic = grabbable.Rigidbody.isKinematic;
|
||||
_rbInterpolation = grabbable.Rigidbody.interpolation;
|
||||
|
||||
|
||||
switch (HoldType)
|
||||
{
|
||||
case SocketHoldType.Kinematic:
|
||||
{
|
||||
grabbable.Rigidbody.useGravity = false;
|
||||
grabbable.Rigidbody.velocity = Vector3.zero;
|
||||
grabbable.Rigidbody.angularVelocity = Vector3.zero;
|
||||
grabbable.Rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||
grabbable.Rigidbody.isKinematic = true;
|
||||
grabbable.Rigidbody.interpolation = RigidbodyInterpolation.None;
|
||||
if (DisableCollision) grabbable.SetAllToTrigger();
|
||||
}
|
||||
{
|
||||
grabbable.Rigidbody.velocity = Vector3.zero;
|
||||
grabbable.Rigidbody.angularVelocity = Vector3.zero;
|
||||
grabbable.Rigidbody.collisionDetectionMode = CollisionDetectionMode.ContinuousSpeculative;
|
||||
grabbable.Rigidbody.isKinematic = true;
|
||||
grabbable.Rigidbody.interpolation = RigidbodyInterpolation.None;
|
||||
if (DisableCollision) grabbable.SetAllToTrigger();
|
||||
}
|
||||
break;
|
||||
case SocketHoldType.RemoveRigidbody:
|
||||
{
|
||||
_hadRigidBody = true;
|
||||
_rbMass = grabbable.Rigidbody.mass;
|
||||
_rbGravity = grabbable.Rigidbody.useGravity;
|
||||
_rbDrag = grabbable.Rigidbody.drag;
|
||||
_rbAngularDrag = grabbable.Rigidbody.angularDrag;
|
||||
|
||||
if (Rigidbody)
|
||||
{
|
||||
_hadRigidBody = true;
|
||||
|
||||
if (Rigidbody)
|
||||
{
|
||||
_mass = Rigidbody.mass;
|
||||
Rigidbody.mass += grabbable.Rigidbody.mass;
|
||||
}
|
||||
|
||||
Destroy(grabbable.Rigidbody);
|
||||
if (_fixPositionRoutine != null)
|
||||
{
|
||||
StopCoroutine(_fixPositionRoutine);
|
||||
}
|
||||
_fixPositionRoutine = StartCoroutine(SetPositionNextFrame(grabbable));
|
||||
_socketMass = Rigidbody.mass;
|
||||
Rigidbody.mass += _rbMass;
|
||||
}
|
||||
|
||||
Destroy(grabbable.Rigidbody);
|
||||
if (_fixPositionRoutine != null)
|
||||
{
|
||||
StopCoroutine(_fixPositionRoutine);
|
||||
}
|
||||
|
||||
_fixPositionRoutine = StartCoroutine(SetPositionNextFrame(grabbable));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected virtual void CleanupRigidBody(HVRGrabbable grabbable)
|
||||
{
|
||||
var rb = grabbable.Rigidbody;
|
||||
if (HoldType == SocketHoldType.RemoveRigidbody && _hadRigidBody)
|
||||
{
|
||||
grabbable.Rigidbody = grabbable.gameObject.AddComponent<Rigidbody>();
|
||||
rb = grabbable.Rigidbody = grabbable.gameObject.AddComponent<Rigidbody>();
|
||||
if (Rigidbody)
|
||||
{
|
||||
Rigidbody.mass = _mass;
|
||||
Rigidbody.mass = _socketMass;
|
||||
}
|
||||
|
||||
rb.useGravity = _rbGravity;
|
||||
rb.mass = _rbMass;
|
||||
rb.drag = _rbDrag;
|
||||
rb.angularDrag = _rbAngularDrag;
|
||||
}
|
||||
|
||||
grabbable.ResetRigidBody();
|
||||
if (rb)
|
||||
{
|
||||
rb.collisionDetectionMode = grabbable.OriginalCollisionMode;
|
||||
rb.isKinematic = _rbKinematic;
|
||||
rb.interpolation = _rbInterpolation;
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator SetPositionNextFrame(HVRGrabbable grabbable)
|
||||
@@ -677,21 +697,27 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
if (SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(clip, transform.position);
|
||||
}
|
||||
|
||||
|
||||
protected virtual float GetSocketableScaleSize(HVRSocketable socketable)
|
||||
{
|
||||
return socketable.GetSocketScaleSize(this);
|
||||
}
|
||||
|
||||
protected virtual void UpdateScale(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!grabbable || !ScaleGrabbable)
|
||||
return;
|
||||
var extents = _modelBounds.extents;
|
||||
var axis = extents.x;
|
||||
if (extents.y > axis) axis = extents.y;
|
||||
if (extents.z > axis) axis = extents.z;
|
||||
axis *= 2;
|
||||
|
||||
var finalScale = ComputeScale(grabbable.Socketable);
|
||||
grabbable.transform.localScale = finalScale;
|
||||
}
|
||||
|
||||
public virtual Vector3 ComputeScale(HVRSocketable socketable)
|
||||
{
|
||||
var axis = GetSocketableScaleSize(socketable);
|
||||
var ratio = Size / axis;
|
||||
ratio *= grabbable.Socketable.SocketScale;
|
||||
var counterScale = grabbable.Socketable.CounterScale;
|
||||
grabbable.transform.localScale = new Vector3(ratio * counterScale.x, ratio * counterScale.y, ratio * counterScale.z);
|
||||
ratio *= socketable.SocketScale;
|
||||
var counterScale = socketable.CounterScale;
|
||||
return new Vector3(ratio * counterScale.x, ratio * counterScale.y, ratio * counterScale.z);
|
||||
}
|
||||
|
||||
protected override void OnReleased(HVRGrabbable grabbable)
|
||||
@@ -744,8 +770,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected virtual IEnumerator GrabTimeoutRoutine(HVRGrabbable grabbable)
|
||||
{
|
||||
_timeoutGrabbable = grabbable;
|
||||
@@ -790,7 +814,6 @@ namespace HurricaneVR.Framework.Core.Grabbers
|
||||
[Serializable]
|
||||
public class SocketSpawnEvent : UnityEvent<HVRSocket, GameObject>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public enum SocketCondition
|
||||
|
||||
+4
@@ -6,6 +6,10 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Grabbers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Grabber that uses a HVRSocketContainer as a target of the grab. Main uses are over the shoulder or chest collection type inventories
|
||||
/// </summary>
|
||||
public class HVRSocketContainerGrabber : HVRGrabberBase
|
||||
{
|
||||
public HVRSocketContainer SocketContainer;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
|
||||
/// <summary>
|
||||
/// Filters the incoming grabbing hand by left or right hand only
|
||||
/// </summary>
|
||||
public class HVRGrabHandFilter : HVRHandGrabFilter
|
||||
{
|
||||
|
||||
public HandOptions AllowedHands;
|
||||
|
||||
public override bool CanBeGrabbed(HVRHandGrabber hand)
|
||||
{
|
||||
if (AllowedHands == HandOptions.Both)
|
||||
return true;
|
||||
|
||||
if (AllowedHands == HandOptions.Left && hand.IsLeftHand)
|
||||
return true;
|
||||
|
||||
if (AllowedHands == HandOptions.Right && hand.IsRightHand)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//[Flags]
|
||||
public enum HandOptions
|
||||
{
|
||||
Left = 0, Right = 1, Both = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9cf9028b057d4b7db0423f5d0a26074b
|
||||
timeCreated: 1674090737
|
||||
@@ -17,8 +17,6 @@ using UnityEngine.Serialization;
|
||||
|
||||
namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
|
||||
|
||||
public class HVRGrabbable : MonoBehaviour
|
||||
{
|
||||
#region Fields
|
||||
@@ -26,32 +24,36 @@ namespace HurricaneVR.Framework.Core
|
||||
internal const int TrackedVelocityCount = 10;
|
||||
|
||||
[Header("Grab Settings")]
|
||||
|
||||
[Tooltip("Define grab behaviour, HandGrabber Default, Pull object to hand, Hand goes to the object.")]
|
||||
public GrabBehaviour GrabBehaviour = GrabBehaviour.Default;
|
||||
|
||||
[FormerlySerializedAs("GrabType")]
|
||||
[FormerlySerializedAs("GrabType")]
|
||||
public PoseType PoseType;
|
||||
|
||||
|
||||
[Tooltip("Whether or not the grab uses physics joints with the hand")]
|
||||
public HVRGrabTracking TrackingType;
|
||||
|
||||
|
||||
[Tooltip("One Hand, Swap hand Allowed, or two hand hold allowed")]
|
||||
public HVRHoldType HoldType = HVRHoldType.Swap;
|
||||
|
||||
|
||||
[Tooltip("Control whether grip, trigger, or grip and trigger can grab this")]
|
||||
public HVRGrabControls GrabControl = HVRGrabControls.GripOrTrigger;
|
||||
|
||||
|
||||
[Tooltip("By default input to continue holding will use whatever the Hand Grabber is set to, enable this to allow overriding that behaviour.")]
|
||||
public bool OverrideGrabTrigger;
|
||||
|
||||
|
||||
[DrawIf("OverrideGrabTrigger", true)]
|
||||
[Tooltip("Decide if the grip must be released to drop, toggled off to drop, or manually released in code to drop.")]
|
||||
public HVRGrabTrigger GrabTrigger = HVRGrabTrigger.Active;
|
||||
|
||||
[Tooltip("Does this grabbable require line of sight to the hand grabber to be grabbed?")]
|
||||
public bool RequireLineOfSight = true;
|
||||
|
||||
[FormerlySerializedAs("ParentHandModelImmediately")]
|
||||
[Tooltip("Should the hand model pose immediately to this upon grabbing.")]
|
||||
[Tooltip("Should the hand model pose immediately to this upon grabbing. Useful for non physics based grabbing.")]
|
||||
public bool PoseImmediately;
|
||||
|
||||
[Tooltip("Should the hand model parent to the grabbable once close enough? Required for posing.")]
|
||||
[Tooltip("Should the hand model parent to the grabbable once close enough?")]
|
||||
public bool ParentHandModel;
|
||||
|
||||
[Tooltip("Released if the grabbable exceeds this distance from the grabber.")]
|
||||
@@ -60,9 +62,6 @@ namespace HurricaneVR.Framework.Core
|
||||
[Tooltip("The grabbed object will compare it's distance to this when checking BreakDistance release.")]
|
||||
public BreakDistanceSource BreakDistanceSource = BreakDistanceSource.NoDistanceCheck;
|
||||
|
||||
[Tooltip("If true the object remains kinematic")]
|
||||
public bool RemainsKinematic = true;
|
||||
|
||||
[Tooltip("If true the object is static or attached to something else and shouldn't be pulled and rotated to the hand")]
|
||||
public bool Stationary;
|
||||
|
||||
@@ -78,6 +77,7 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
[Header("Grab Indicators")]
|
||||
public HVRGrabbableHoverBase GrabIndicator;
|
||||
|
||||
public HVRGrabbableHoverBase ForceGrabIndicator;
|
||||
public bool ShowGrabIndicator = true;
|
||||
public bool ShowTriggerGrabIndicator = true;
|
||||
@@ -94,47 +94,30 @@ namespace HurricaneVR.Framework.Core
|
||||
#region Joint
|
||||
|
||||
[Header("Configurable Joint Override")]
|
||||
|
||||
[Tooltip("If set it will override the default joint settings.")]
|
||||
public HVRJointSettings JointOverride;
|
||||
|
||||
[Header("Hand Joint Overrides")]
|
||||
[Header("Physics")]
|
||||
[Embedded]
|
||||
[Tooltip("Overrides the hand strength when one hand is holding this.")]
|
||||
public PDStrength OneHandStrength;
|
||||
|
||||
[Tooltip("Applies the joint settings to the hand joint with one hand hold.")]
|
||||
public HVRJointSettings OneHandJointSettings;
|
||||
|
||||
[Tooltip("Applies the joint settings to the hand joint with two hand hold.")]
|
||||
public HVRJointSettings TwoHandJointSettings;
|
||||
[Embedded]
|
||||
[Tooltip("Overrides the hand strength when two hands are holding this.")]
|
||||
public PDStrength TwoHandStrength;
|
||||
|
||||
[Tooltip("Uses this to pull the object to the hand, overrides default settings")]
|
||||
public HVRJointSettings PullingSettingsOverride;
|
||||
|
||||
|
||||
[Header("Physics")]
|
||||
|
||||
[Tooltip("If true the hand palm will become the center of mass on grab, midpoint for 2 handed grabs")]
|
||||
public bool PalmCenterOfMass;
|
||||
|
||||
#endregion
|
||||
|
||||
[Header("SFX")]
|
||||
[Header("Misc")]
|
||||
[Tooltip("SFX played when grabbed by a hand.")]
|
||||
public AudioClip HandGrabbedClip;
|
||||
|
||||
|
||||
[Header("Sockets")]
|
||||
|
||||
[Tooltip("Socket that this grabbable will start in.")]
|
||||
public HVRSocket StartingSocket;
|
||||
|
||||
[Tooltip("If true this grabbable will be auto grabbed by the StartingSocket whenever it's dropped.")]
|
||||
public bool LinkStartingSocket;
|
||||
|
||||
[Tooltip("If provided only these grab points will be considered when an object is removed from a socket, otherwise the closest grab point will be used.")]
|
||||
public HVRPosableGrabPoint[] SocketGrabPoints;
|
||||
|
||||
[Header("Misc")]
|
||||
|
||||
[Tooltip("RB for hand jointing, majority of grabbables should be on the rigidbody, only assign this for compound objects with secondary grabbables")]
|
||||
public Rigidbody Rigidbody;
|
||||
|
||||
@@ -193,11 +176,22 @@ namespace HurricaneVR.Framework.Core
|
||||
[DrawIf("OverrideMaxDistanceBehaviour", true)]
|
||||
public MaxDistanceBehaviour MaxDistanceBehaviour;
|
||||
|
||||
|
||||
[Header("Deprecated")]
|
||||
[Tooltip("Applies the joint settings to the hand joint with one hand hold.")]
|
||||
public HVRJointSettings OneHandJointSettings;
|
||||
|
||||
[Tooltip("Applies the joint settings to the hand joint with two hand hold.")]
|
||||
public HVRJointSettings TwoHandJointSettings;
|
||||
|
||||
[Tooltip("Socket that this grabbable will start in.")]
|
||||
public HVRSocket StartingSocket;
|
||||
|
||||
[Tooltip("If true this grabbable will be auto grabbed by the StartingSocket whenever it's dropped.")]
|
||||
public bool LinkStartingSocket;
|
||||
|
||||
[Header("Debug")]
|
||||
public bool ShowBoundingBox;
|
||||
|
||||
public bool DrawCenterOfMass;
|
||||
|
||||
public List<Transform> GrabPoints = new List<Transform>();
|
||||
@@ -223,7 +217,6 @@ namespace HurricaneVR.Framework.Core
|
||||
public VRSocketEvent Socketed = new VRSocketEvent();
|
||||
public VRSocketEvent UnSocketed = new VRSocketEvent();
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
@@ -254,20 +247,19 @@ namespace HurricaneVR.Framework.Core
|
||||
/// </summary>
|
||||
public List<Collider> Triggers { get; private set; } = new List<Collider>();
|
||||
|
||||
/// <summary>
|
||||
/// Saved on awake and used by framework to reset after the object is released as the rb has CCD enabled after it's
|
||||
/// released to help with collisions.
|
||||
/// </summary>
|
||||
public CollisionDetectionMode OriginalCollisionMode { get; set; }
|
||||
|
||||
public bool WasGravity { get; set; }
|
||||
|
||||
public bool WasKinematic { get; set; }
|
||||
|
||||
public List<HVRPosableGrabPoint> GrabPointsMeta = new List<HVRPosableGrabPoint>();
|
||||
|
||||
public HVRGrabberBase PrimaryGrabber { get; private set; }
|
||||
public HVRSocket SocketHoverer { get; internal set; }
|
||||
|
||||
|
||||
|
||||
public HVRSocketable Socketable { get; private set; }
|
||||
public HVRSocketable Socketable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The socket this grabbable will return to when it's released.
|
||||
@@ -284,11 +276,33 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
public bool IsHandGrabbed => HandGrabbers.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Transform of the Rigidbody if attached. If MasterGrabbable is assigned, the transform of it's rigidbody.
|
||||
/// Otherwise the transform of the grabbable or MasterGrabbable.
|
||||
/// </summary>
|
||||
public Transform MainTransform
|
||||
{
|
||||
get
|
||||
{
|
||||
if (MasterGrabbable)
|
||||
{
|
||||
if (MasterGrabbable.Rigidbody)
|
||||
return MasterGrabbable.Rigidbody.transform;
|
||||
return MasterGrabbable.transform;
|
||||
}
|
||||
|
||||
if (Rigidbody)
|
||||
return Rigidbody.transform;
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsJointGrab => TrackingType == HVRGrabTracking.ConfigurableJoint || TrackingType == HVRGrabTracking.FixedJoint;
|
||||
|
||||
public bool HasConcaveColliders { get; private set; }
|
||||
|
||||
public bool HasWheelCollider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true will force use the two hand settings regardless of the number of hand grabbers holding
|
||||
/// </summary>
|
||||
@@ -328,6 +342,8 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
public bool BeingDestroyed { get; set; }
|
||||
|
||||
public bool CollidedThisFrame { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private
|
||||
@@ -341,12 +357,10 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
private bool _forceTwoHandSettings;
|
||||
|
||||
private Vector3 _centerOfMass;
|
||||
private RigidbodyInterpolation _rbInterpolation;
|
||||
private float _mass;
|
||||
private bool _waitingForColDetectionReset;
|
||||
|
||||
private Coroutine _resetCollisionDetectionRoutine;
|
||||
private readonly HashSet<Collider> _ignoredColliders = new HashSet<Collider>();
|
||||
private readonly List<HVRHandGrabFilter> _filters = new List<HVRHandGrabFilter>();
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -354,7 +368,13 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
if (!Rigidbody) TryGetComponent(out Rigidbody);
|
||||
if (!Rigidbody)
|
||||
TryGetComponent(out Rigidbody);
|
||||
|
||||
if (Rigidbody)
|
||||
{
|
||||
OriginalCollisionMode = Rigidbody.collisionDetectionMode;
|
||||
}
|
||||
|
||||
SetupColliders();
|
||||
|
||||
@@ -362,17 +382,9 @@ namespace HurricaneVR.Framework.Core
|
||||
PopulateGrabPoints();
|
||||
|
||||
LoadGrabPoints();
|
||||
LoadFilters();
|
||||
|
||||
Socketable = GetComponent<HVRSocketable>();
|
||||
if (Socketable && !Socketable.SocketOrientation)
|
||||
{
|
||||
var orientation = new GameObject("SocketOrientation");
|
||||
orientation.transform.SetParent(this.transform);
|
||||
orientation.transform.localPosition = Vector3.zero;
|
||||
orientation.transform.localRotation = Quaternion.identity;
|
||||
orientation.transform.localScale = Vector3.zero;
|
||||
Socketable.SocketOrientation = orientation.transform;
|
||||
}
|
||||
|
||||
ResetTrackedVelocities();
|
||||
|
||||
@@ -389,7 +401,7 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
//if (Stationary) Debug.LogWarning($"stationary {name}");
|
||||
|
||||
if (IsJointGrab && (!Rigidbody || RemainsKinematic && Rigidbody.isKinematic))
|
||||
if (IsJointGrab && (!Rigidbody || Rigidbody.isKinematic))
|
||||
{
|
||||
Stationary = true;
|
||||
}
|
||||
@@ -400,13 +412,7 @@ namespace HurricaneVR.Framework.Core
|
||||
MaxDistanceBehaviour = MaxDistanceBehaviour.GrabbableDrops;
|
||||
}
|
||||
|
||||
if (GrabColliders != null)
|
||||
{
|
||||
GrabCollidersSet = new HashSet<Collider>(GrabColliders);
|
||||
FilterGrabColliders = GrabColliders.Length > 0;
|
||||
}
|
||||
|
||||
|
||||
SetupGrabColliders();
|
||||
}
|
||||
|
||||
|
||||
@@ -421,6 +427,7 @@ namespace HurricaneVR.Framework.Core
|
||||
LinkedSocket = StartingSocket;
|
||||
LinkedSocket.LinkedGrabbable = this;
|
||||
}
|
||||
|
||||
//let all Starts() go off first
|
||||
StartCoroutine(AttachToStartingSocket());
|
||||
}
|
||||
@@ -437,6 +444,7 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
DrawBoundingBox();
|
||||
}
|
||||
|
||||
if (!IsBeingHeld)
|
||||
ElapsedSinceReleased += Time.deltaTime;
|
||||
|
||||
@@ -445,7 +453,7 @@ namespace HurricaneVR.Framework.Core
|
||||
ProcessUpdate();
|
||||
}
|
||||
|
||||
private void CheckIfStabbing()
|
||||
public void CheckIfStabbing()
|
||||
{
|
||||
IsStabbing = false;
|
||||
|
||||
@@ -465,10 +473,10 @@ namespace HurricaneVR.Framework.Core
|
||||
if (HandGrabbers.Count > 0)
|
||||
{
|
||||
TrackVelocities();
|
||||
|
||||
}
|
||||
|
||||
ProcessFixedUpdate();
|
||||
CollidedThisFrame = false;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
@@ -486,6 +494,9 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
protected virtual void OnCollisionEnter(Collision other)
|
||||
{
|
||||
if (CollidedThisFrame)
|
||||
return;
|
||||
CollidedThisFrame = true;
|
||||
Collided.Invoke(this);
|
||||
}
|
||||
|
||||
@@ -515,7 +526,6 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
@@ -553,8 +563,6 @@ namespace HurricaneVR.Framework.Core
|
||||
if (grabPoint.PoserIndex != hand.PoserIndex)
|
||||
return false;
|
||||
|
||||
if(!grabPoint) return false;
|
||||
|
||||
if (!grabPoint.gameObject.activeInHierarchy || !grabPoint.enabled)
|
||||
{
|
||||
return false;
|
||||
@@ -612,7 +620,7 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
}
|
||||
|
||||
if (closest == null)
|
||||
if (!closest)
|
||||
return null;
|
||||
|
||||
var currentAngle = Quaternion.Angle(hand.HandWorldRotation, closest.GetPoseWorldRotation(hand.HandSide));
|
||||
@@ -641,7 +649,7 @@ namespace HurricaneVR.Framework.Core
|
||||
internal Transform GetGrabPointTransform(HVRHandGrabber hand, GrabpointFilter forceGrab)
|
||||
{
|
||||
var gp = GetGrabPoint(hand, forceGrab);
|
||||
return gp == null ? null : gp.transform;
|
||||
return !gp ? null : gp.transform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -890,11 +898,21 @@ namespace HurricaneVR.Framework.Core
|
||||
if (LinkedGrabbables == null) return false;
|
||||
|
||||
for (int i = 0; i < LinkedGrabbables.Count; i++)
|
||||
if (LinkedGrabbables[i].IsHandGrabbed) return true;
|
||||
if (LinkedGrabbables[i].IsHandGrabbed)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool CanHandGrab(HVRHandGrabber hand)
|
||||
{
|
||||
foreach(var filter in _filters)
|
||||
if (!filter.CanBeGrabbed(hand))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Methods
|
||||
@@ -904,7 +922,6 @@ namespace HurricaneVR.Framework.Core
|
||||
/// </summary>
|
||||
protected virtual void ProcessUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -912,7 +929,6 @@ namespace HurricaneVR.Framework.Core
|
||||
/// </summary>
|
||||
protected virtual void ProcessFixedUpdate()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -926,6 +942,8 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
foreach (var c in parent.GetComponents<Collider>())
|
||||
{
|
||||
if (!c) continue;
|
||||
|
||||
if (c.isTrigger)
|
||||
{
|
||||
triggers.Add(c);
|
||||
@@ -968,10 +986,6 @@ namespace HurricaneVR.Framework.Core
|
||||
Debug.Log($"{name}:OnBeforeGrabbed");
|
||||
}
|
||||
|
||||
if (GrabberCount == 0)
|
||||
{
|
||||
SaveRigidBodyState();
|
||||
}
|
||||
AddGrabber(grabber);
|
||||
}
|
||||
|
||||
@@ -984,6 +998,7 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
Debug.Log($"{name}:OnGrabCanceled");
|
||||
}
|
||||
|
||||
//ResetRigidBody();
|
||||
RemoveGrabber(grabber);
|
||||
}
|
||||
@@ -1008,6 +1023,10 @@ namespace HurricaneVR.Framework.Core
|
||||
if (grabber.IsHandGrabber)
|
||||
{
|
||||
HandGrabbed.Invoke(grabber as HVRHandGrabber, this);
|
||||
if (Rigidbody && !Rigidbody.isKinematic)
|
||||
{
|
||||
Rigidbody.collisionDetectionMode = CollisionDetection;
|
||||
}
|
||||
}
|
||||
|
||||
if (grabber.IsSocket)
|
||||
@@ -1021,6 +1040,7 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
/// <summary>
|
||||
/// Fired after the grabber released this
|
||||
/// </summary>
|
||||
@@ -1038,8 +1058,9 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
RemoveGrabber(grabber);
|
||||
|
||||
|
||||
Socket = null;
|
||||
IsBeingForcedGrabbed = false;
|
||||
IsSocketed = false;
|
||||
|
||||
RemoveJoint(grabber);
|
||||
|
||||
@@ -1048,10 +1069,7 @@ namespace HurricaneVR.Framework.Core
|
||||
ElapsedSinceReleased = 0f;
|
||||
if (Rigidbody)
|
||||
{
|
||||
if (PalmCenterOfMass) Rigidbody.centerOfMass = _centerOfMass;
|
||||
|
||||
Rigidbody.collisionDetectionMode = CollisionDetectionMode.Discrete; //preventing warnings
|
||||
Rigidbody.isKinematic = WasKinematic;
|
||||
|
||||
if (!Rigidbody.isKinematic)
|
||||
{
|
||||
@@ -1060,6 +1078,7 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
StopCoroutine(_resetCollisionDetectionRoutine);
|
||||
}
|
||||
|
||||
_resetCollisionDetectionRoutine = StartCoroutine(ResetCollisionMode());
|
||||
}
|
||||
else
|
||||
@@ -1069,13 +1088,8 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
}
|
||||
|
||||
IsSocketed = _distinctGrabbers.Any(e => e.IsSocket); //really should only be one if socketed...
|
||||
if (!IsSocketed)
|
||||
{
|
||||
Socket = null;
|
||||
}
|
||||
|
||||
if (!PrimaryGrabber && LinkedSocket)
|
||||
if (!PrimaryGrabber && LinkedSocket && gameObject.activeInHierarchy)
|
||||
{
|
||||
StartCoroutine(CheckLinkedSocket());
|
||||
}
|
||||
@@ -1100,7 +1114,6 @@ namespace HurricaneVR.Framework.Core
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeHandGrabberRemoved(HVRHandGrabber handGrabber)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnAfterHandGrabberRemoved(HVRHandGrabber handGrabber)
|
||||
@@ -1115,8 +1128,9 @@ namespace HurricaneVR.Framework.Core
|
||||
IsRightHandGrabbed = false;
|
||||
RightHandGrabber = null;
|
||||
}
|
||||
handGrabber.OverrideHandSettings(null);
|
||||
handGrabber.UpdateGrabbableCOM(this);
|
||||
|
||||
if(handGrabber.StrengthHandler)
|
||||
handGrabber.StrengthHandler.ResetHandOverride();
|
||||
UpdateHandSettings();
|
||||
}
|
||||
|
||||
@@ -1135,30 +1149,53 @@ namespace HurricaneVR.Framework.Core
|
||||
IsRightHandGrabbed = true;
|
||||
RightHandGrabber = handGrabber;
|
||||
}
|
||||
|
||||
UpdateHandSettings();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If provided, will update the hand joint settings depending on one or two handed grabs
|
||||
/// </summary>
|
||||
protected virtual void UpdateHandSettings()
|
||||
public virtual void UpdateHandSettings()
|
||||
{
|
||||
if ((HandGrabbers.Count >= 2 || ForceTwoHandSettings) && TwoHandJointSettings)
|
||||
if (HandGrabbers.Count >= 2 || ForceTwoHandSettings)
|
||||
{
|
||||
//Debug.Log($"{name} Update two hand : {TwoHandJointSettings?.name} [{ForceTwoHandSettings}]");
|
||||
for (int i = 0; i < HandGrabbers.Count; i++)
|
||||
{
|
||||
HandGrabbers[i].OverrideHandSettings(TwoHandJointSettings);
|
||||
if (!HandGrabbers[i].StrengthHandler)
|
||||
continue;
|
||||
|
||||
if (TwoHandStrength)
|
||||
{
|
||||
HandGrabbers[i].StrengthHandler.OverrideHandSettings(TwoHandStrength);
|
||||
}
|
||||
else if (TwoHandJointSettings)
|
||||
{
|
||||
HandGrabbers[i].StrengthHandler.OverrideHandSettings(TwoHandJointSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandGrabbers[i].StrengthHandler.ResetHandOverride();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HandGrabbers.Count > 0)
|
||||
else if (HandGrabbers.Count == 1 && HandGrabbers[0].StrengthHandler)
|
||||
{
|
||||
//Debug.Log($"{name} Update one hand : {OneHandJointSettings?.name}");
|
||||
HandGrabbers[0].OverrideHandSettings(OneHandJointSettings);
|
||||
if (OneHandStrength)
|
||||
{
|
||||
HandGrabbers[0].StrengthHandler.OverrideHandSettings(OneHandStrength);
|
||||
}
|
||||
else if (OneHandJointSettings)
|
||||
{
|
||||
HandGrabbers[0].StrengthHandler.OverrideHandSettings(OneHandJointSettings);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandGrabbers[0].StrengthHandler.ResetHandOverride();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
@@ -1173,7 +1210,12 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void LoadFilters()
|
||||
{
|
||||
_filters.Clear();
|
||||
_filters.AddRange(GetComponents<HVRHandGrabFilter>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locates colliders that are used for line of sight checking and for collision disabling with the grabbing hand when held.
|
||||
/// </summary>
|
||||
@@ -1189,8 +1231,8 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
if (collisionParent)
|
||||
{
|
||||
Colliders.AddRange(collisionParent.gameObject.GetComponentsInChildren<Collider>().Where(c => !c.isTrigger));
|
||||
Triggers.AddRange(collisionParent.gameObject.GetComponentsInChildren<Collider>().Where(c => c.isTrigger));
|
||||
Colliders.AddRange(collisionParent.gameObject.GetComponentsInChildren<Collider>().Where(c => c && !c.isTrigger));
|
||||
Triggers.AddRange(collisionParent.gameObject.GetComponentsInChildren<Collider>().Where(c => c && c.isTrigger));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1205,14 +1247,35 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
if (collisionParent)
|
||||
{
|
||||
AdditionalIgnoreColliders.AddRange(collisionParent.gameObject.GetComponentsInChildren<Collider>().Where(c => !c.isTrigger));
|
||||
AdditionalIgnoreColliders.AddRange(collisionParent.gameObject.GetComponentsInChildren<Collider>().Where(c => c && !c.isTrigger));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateIgnoreColliders();
|
||||
HasConcaveColliders = Triggers.Any(e => { var mesh = e as MeshCollider; return mesh != null && !mesh.convex; });
|
||||
HasConcaveColliders = HasConcaveColliders || Colliders.Any(e => { var mesh = e as MeshCollider; return mesh && !mesh.convex; });
|
||||
HasConcaveColliders = Triggers.Any(e =>
|
||||
{
|
||||
var mesh = e as MeshCollider;
|
||||
return mesh != null && !mesh.convex;
|
||||
});
|
||||
HasConcaveColliders = HasConcaveColliders || Colliders.Any(e =>
|
||||
{
|
||||
var mesh = e as MeshCollider;
|
||||
return mesh && !mesh.convex;
|
||||
});
|
||||
HasWheelCollider = Colliders.Any(e => e is WheelCollider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Caches GrabColliders array into a hashset for lookup for grab detection
|
||||
/// </summary>
|
||||
public void SetupGrabColliders()
|
||||
{
|
||||
if (GrabColliders != null)
|
||||
{
|
||||
GrabCollidersSet = new HashSet<Collider>(GrabColliders);
|
||||
FilterGrabColliders = GrabColliders.Length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateIgnoreColliders()
|
||||
@@ -1254,6 +1317,7 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
_recentVelocities.Enqueue(Rigidbody.velocity);
|
||||
}
|
||||
|
||||
_recentAngularVelocities.Enqueue(angularVelocity);
|
||||
|
||||
_previousRotation = transform.rotation;
|
||||
@@ -1287,31 +1351,6 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveRigidBodyState()
|
||||
{
|
||||
if (!Rigidbody)
|
||||
return;
|
||||
|
||||
WasGravity = Rigidbody.useGravity;
|
||||
WasKinematic = Rigidbody.isKinematic;
|
||||
if (!_waitingForColDetectionReset)
|
||||
{
|
||||
OriginalCollisionMode = Rigidbody.collisionDetectionMode;
|
||||
}
|
||||
|
||||
_centerOfMass = Rigidbody.centerOfMass;
|
||||
_mass = Rigidbody.mass;
|
||||
_rbInterpolation = Rigidbody.interpolation;
|
||||
}
|
||||
|
||||
public virtual void ResetRigidBody()
|
||||
{
|
||||
Rigidbody.useGravity = WasGravity;
|
||||
Rigidbody.mass = _mass;
|
||||
Rigidbody.collisionDetectionMode = OriginalCollisionMode;
|
||||
Rigidbody.interpolation = _rbInterpolation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys and cleanups reference to the configurable joint attached to this grabber
|
||||
/// </summary>
|
||||
@@ -1331,11 +1370,10 @@ namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
if (!Rigidbody)
|
||||
yield break;
|
||||
_waitingForColDetectionReset = true;
|
||||
|
||||
yield return new WaitForSeconds(10f);
|
||||
_waitingForColDetectionReset = false;
|
||||
|
||||
if (!IsBeingHeld)
|
||||
if (!IsBeingHeld && Rigidbody)
|
||||
{
|
||||
Rigidbody.collisionDetectionMode = OriginalCollisionMode;
|
||||
}
|
||||
@@ -1358,8 +1396,6 @@ namespace HurricaneVR.Framework.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
@@ -1486,7 +1522,6 @@ namespace HurricaneVR.Framework.Core
|
||||
private Vector3 v3BackBottomRight;
|
||||
|
||||
|
||||
|
||||
void DrawBoundingBox()
|
||||
{
|
||||
Bounds bounds = transform.GetRendererBounds(gameObject);
|
||||
@@ -1494,14 +1529,14 @@ namespace HurricaneVR.Framework.Core
|
||||
Vector3 v3Center = bounds.center;
|
||||
Vector3 v3Extents = bounds.extents;
|
||||
|
||||
v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top left corner
|
||||
v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top right corner
|
||||
v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom left corner
|
||||
v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom right corner
|
||||
v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top left corner
|
||||
v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top right corner
|
||||
v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom left corner
|
||||
v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom right corner
|
||||
v3FrontTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top left corner
|
||||
v3FrontTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z - v3Extents.z); // Front top right corner
|
||||
v3FrontBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom left corner
|
||||
v3FrontBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z - v3Extents.z); // Front bottom right corner
|
||||
v3BackTopLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top left corner
|
||||
v3BackTopRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y + v3Extents.y, v3Center.z + v3Extents.z); // Back top right corner
|
||||
v3BackBottomLeft = new Vector3(v3Center.x - v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom left corner
|
||||
v3BackBottomRight = new Vector3(v3Center.x + v3Extents.x, v3Center.y - v3Extents.y, v3Center.z + v3Extents.z); // Back bottom right corner
|
||||
|
||||
|
||||
var color = Color.magenta;
|
||||
@@ -1526,12 +1561,16 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
public enum GrabpointFilter
|
||||
{
|
||||
Normal, ForceGrab, Socket
|
||||
Normal,
|
||||
ForceGrab,
|
||||
Socket
|
||||
}
|
||||
|
||||
public enum GrabBehaviour
|
||||
{
|
||||
Default, PullToHand, HandRetrieves
|
||||
Default,
|
||||
PullToHand,
|
||||
HandRetrieves
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using HurricaneVR.Framework.Core;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Optional filter applied to HVRGrabbable object to decide if the potential hand can grab this object
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(HVRGrabbable))]
|
||||
public abstract class HVRHandGrabFilter : MonoBehaviour
|
||||
{
|
||||
public HVRGrabbable Grabbable { get; set; }
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
if (TryGetComponent(out HVRGrabbable g))
|
||||
Grabbable = g;
|
||||
}
|
||||
|
||||
public abstract bool CanBeGrabbed(HVRHandGrabber hand);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bef30b910ae46c4acd561544cc1e389
|
||||
timeCreated: 1674090329
|
||||
@@ -18,7 +18,7 @@ namespace HurricaneVR.Framework.Core
|
||||
|
||||
public void SetupColliders()
|
||||
{
|
||||
HandColliders = GetComponentsInChildren<Collider>().Where(e => !e.isTrigger).ToArray();
|
||||
HandColliders = GetComponentsInChildren<Collider>().Where(e => !e.isTrigger && e.enabled).ToArray();
|
||||
}
|
||||
|
||||
public void DisableCollision()
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
using HurricaneVR.Framework.Core.Sockets;
|
||||
|
||||
namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Dummy socketable added while linking in case one isn't provided so the socket code will not break.
|
||||
/// </summary>
|
||||
public class HVRLinkedSocketable : HVRSocketable
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e342e34c74884f399b6b418e8b6b9273
|
||||
timeCreated: 1666497596
|
||||
@@ -10,7 +10,7 @@ namespace HurricaneVR.Framework.Core
|
||||
[Tooltip("If the required grabbable is dropped, should we release?")]
|
||||
public bool DropIfReleased;
|
||||
|
||||
[Tooltip("If the required grabbable is dropped, let's try and grab it.")]
|
||||
[Tooltip("If the required grabbable is dropped, let's try and grab it.")]
|
||||
public bool GrabRequiredIfReleased;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,6 @@ namespace HurricaneVR.Framework.Core
|
||||
public string LocalEditorRootDirectory;
|
||||
public string LocalRootDirectory;
|
||||
public string LocalResourcesDirectory;
|
||||
public string LocalReferencePoseDirectory;
|
||||
public string LocalRuntimePosesDirectory;
|
||||
public string LocalPosesDirectory;
|
||||
|
||||
@@ -69,7 +68,6 @@ namespace HurricaneVR.Framework.Core
|
||||
public const string DefaultLeftHand = "HVR_left_hand";
|
||||
public const string DefaultRightHand = "HVR_right_hand";
|
||||
|
||||
public const string ReferencePoses = "ReferencePoses";
|
||||
public const string RuntimePoses = "RuntimePoses";
|
||||
|
||||
[Header("Misc Settings")]
|
||||
@@ -151,7 +149,6 @@ namespace HurricaneVR.Framework.Core
|
||||
Debug.LogException(e);
|
||||
}
|
||||
|
||||
//TryCreateReferencePoseFolder();
|
||||
TryCreateRuntimePoseFolder();
|
||||
|
||||
SetupDefaultHands(settings);
|
||||
@@ -216,10 +213,6 @@ namespace HurricaneVR.Framework.Core
|
||||
return path;
|
||||
}
|
||||
|
||||
private string GetDefaultReferencePoseDirectory()
|
||||
{
|
||||
return Path.Combine(GetResourcesDirectory(), ReferencePoses);
|
||||
}
|
||||
|
||||
private string GetDefaultRuntimePosesDirectory()
|
||||
{
|
||||
@@ -281,26 +274,7 @@ namespace HurricaneVR.Framework.Core
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void TryCreateReferencePoseFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(LocalResourcesDirectory)) return;
|
||||
|
||||
if (string.IsNullOrEmpty(LocalReferencePoseDirectory))
|
||||
{
|
||||
LocalReferencePoseDirectory = LocalResourcesDirectory + "ReferencePoses" + Path.DirectorySeparatorChar;
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(GetDefaultReferencePoseDirectory());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void TryCreateRuntimePoseFolder()
|
||||
{
|
||||
@@ -324,9 +298,6 @@ namespace HurricaneVR.Framework.Core
|
||||
[InspectorButton("ShowPosesFolderChooser")]
|
||||
public string ChosePosesDirectory = "Choose Pose Directory";
|
||||
|
||||
//[InspectorButton("ShowReferencePosesFolderChooser", 300)]
|
||||
//public string ChoseReferencePosesDirectory = "Choose Reference Poses Directory";
|
||||
|
||||
[InspectorButton("ShowRuntimePosesFolderChooser", 300)]
|
||||
public string ChoseRunTimePosesDirectory = "Choose RunTime Poses Directory";
|
||||
|
||||
@@ -347,15 +318,7 @@ namespace HurricaneVR.Framework.Core
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
public void ShowReferencePosesFolderChooser()
|
||||
{
|
||||
var ReferencePoseDirectory = EditorUtility.OpenFolderPanel("Choose Pose Directory", null, null);
|
||||
LocalReferencePoseDirectory = ReferencePoseDirectory.Substring(Application.dataPath.IndexOf("Assets"));
|
||||
EditorUtility.SetDirty(this);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
|
||||
[InspectorButton("ReloadGlobalsMethod")]
|
||||
public string ReloadGlobals = "Reload Globals";
|
||||
@@ -458,25 +421,6 @@ namespace HurricaneVR.Framework.Core
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SaveReferencePose(HVRHandPose pose, string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!name.EndsWith(".asset"))
|
||||
{
|
||||
name += ".asset";
|
||||
}
|
||||
|
||||
var path = Path.Combine(LocalReferencePoseDirectory, name);
|
||||
AssetUtils.CreateOrReplaceAsset(pose, path);
|
||||
Debug.Log($"Saved {name} to {LocalReferencePoseDirectory}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddAssetToResource<T>(T asset, string name) where T : Object
|
||||
{
|
||||
try
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using Assets.HurricaneVR.Framework.Shared.Utilities;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core
|
||||
{
|
||||
[RequireComponent(typeof(HVRGrabbable))]
|
||||
public class HVRSocketLink : MonoBehaviour
|
||||
{
|
||||
public HVRSocket Socket;
|
||||
public float ReturnTime = 0f;
|
||||
public bool PlaySocketedSFX = true;
|
||||
|
||||
public HVRGrabbable Grabbable { get; private set; }
|
||||
|
||||
private bool _returning;
|
||||
private float _time;
|
||||
private float _elapsed;
|
||||
private Vector3 _startPos;
|
||||
private Quaternion _startRot;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
Grabbable = GetComponent<HVRGrabbable>();
|
||||
Grabbable.HandFullReleased.AddListener(OnGrabbableReleased);
|
||||
if (!Grabbable.Socketable)
|
||||
{
|
||||
//Socket code expects this, add dummy if not found.
|
||||
Grabbable.Socketable = Grabbable.gameObject.AddComponent<HVRLinkedSocketable>();
|
||||
}
|
||||
if (Socket)
|
||||
{
|
||||
Socket.LinkedGrabbable = Grabbable;
|
||||
this.ExecuteNextUpdate(() => Socket.TryGrab(Grabbable, true, true));
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (_returning)
|
||||
{
|
||||
var pos = Socket.transform.TransformPoint(Socket.GetTargetPosition(Grabbable));
|
||||
var rot = Socket.transform.rotation * Socket.GetTargetRotation(Grabbable);
|
||||
var lerp = _elapsed / _time;
|
||||
_elapsed += Time.deltaTime;
|
||||
Grabbable.transform.position = Vector3.Lerp(_startPos, pos, lerp);
|
||||
Grabbable.transform.rotation = Quaternion.Lerp(_startRot, rot, lerp);
|
||||
|
||||
if (lerp >= 1f)
|
||||
{
|
||||
Grabbable.CanBeGrabbed = true;
|
||||
_returning = false;
|
||||
Grabbable.ResetToNonTrigger();
|
||||
Socket.TryGrab(Grabbable, true, PlaySocketedSFX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGrabbableReleased(HVRGrabberBase arg0, HVRGrabbable arg1)
|
||||
{
|
||||
if (!Socket)
|
||||
return;
|
||||
|
||||
if (ReturnTime > 0f)
|
||||
{
|
||||
_returning = true;
|
||||
var pos = Socket.transform.TransformPoint(Socket.GetTargetPosition(Grabbable));
|
||||
_time = ReturnTime;
|
||||
_elapsed = 0f;
|
||||
Grabbable.SetAllToTrigger();
|
||||
_startPos = Grabbable.transform.position;
|
||||
_startRot = Grabbable.transform.rotation;
|
||||
Grabbable.CanBeGrabbed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Socket.TryGrab(Grabbable, true, PlaySocketedSFX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96785e435f4a7a04d84021e497eeb783
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+112
-44
@@ -11,11 +11,8 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
{
|
||||
[FormerlySerializedAs("PosePosAndRot")]
|
||||
[Header("Settings")]
|
||||
[Tooltip("True for floaty hands, false for FinalIK hands")]
|
||||
public bool PoseHand = true;
|
||||
|
||||
[Tooltip("If true the default poser will pause the hand")]
|
||||
public bool DefaultPoseHand = true;
|
||||
[Tooltip("If true the default poser will pose the hand's local position and rotation")]
|
||||
public bool DefaultPoseHand = true; //fyi - false is best, only left true for older users and their projects
|
||||
|
||||
[Tooltip("Finger bend speed when dynamic pose is active")]
|
||||
public float DynamicPoseSpeed = 16f;
|
||||
@@ -24,11 +21,16 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
public HVRPhysicsPoser PhysicsPoser;
|
||||
public HVRPosableHand Hand;
|
||||
public HVRHandPoser DefaultPoser;
|
||||
|
||||
[Tooltip("Used if the HVRPosableHand component is not on the transform that needs to be posed. IKTarget for VRIK is one example.")]
|
||||
public Transform HandOverride;
|
||||
|
||||
|
||||
[Header("Debug View")]
|
||||
public HVRHandPoser CurrentPoser;
|
||||
|
||||
public HVRHandPoser OverridePoser;
|
||||
|
||||
/// <summary>
|
||||
/// Current hand pose, moves towards BlendedPose based on the speed defined on the Primary Pose
|
||||
/// </summary>
|
||||
@@ -74,7 +76,13 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
|
||||
public bool DynamicPose { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the CurrentPoser is a pose from a held object
|
||||
/// </summary>
|
||||
public bool HandHeldPose { get; internal set; }
|
||||
|
||||
private bool _poseHand = true;
|
||||
private bool _poseHandOverride;
|
||||
private float[] _fingerCurls;
|
||||
|
||||
protected virtual void Start()
|
||||
@@ -170,31 +178,53 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentPoser == null)
|
||||
var poseHand = _poseHand;
|
||||
var poser = CurrentPoser;
|
||||
if (OverridePoser && !HandHeldPose)
|
||||
{
|
||||
return;
|
||||
poser = OverridePoser;
|
||||
poseHand = _poseHandOverride;
|
||||
}
|
||||
|
||||
UpdateBlends();
|
||||
ApplyBlending();
|
||||
Hand.Pose(CurrentPose, _poseHand);
|
||||
if (!poser)
|
||||
return;
|
||||
|
||||
UpdateBlends(poser);
|
||||
ApplyBlending(poser);
|
||||
|
||||
if (poseHand)
|
||||
{
|
||||
if (HandOverride)
|
||||
{
|
||||
HandOverride.localPosition = CurrentPose.Position;
|
||||
HandOverride.localRotation = CurrentPose.Rotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
Hand.Pose(CurrentPose, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Hand.Pose(CurrentPose, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateBlends()
|
||||
private void UpdateBlends(HVRHandPoser poser)
|
||||
{
|
||||
if (!IsMine)
|
||||
return;
|
||||
|
||||
UpdateBlendValue(CurrentPoser.PrimaryPose);
|
||||
UpdateBlendValue(poser.PrimaryPose);
|
||||
|
||||
if (CurrentPoser.Blends == null)
|
||||
if (poser.Blends == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CurrentPoser.Blends.Count; i++)
|
||||
for (int i = 0; i < poser.Blends.Count; i++)
|
||||
{
|
||||
UpdateBlendValue(CurrentPoser.Blends[i]);
|
||||
UpdateBlendValue(poser.Blends[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,16 +272,16 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
}
|
||||
|
||||
|
||||
private void ApplyBlending()
|
||||
private void ApplyBlending(HVRHandPoser poser)
|
||||
{
|
||||
PrimaryPose.CopyTo(BlendedPose);
|
||||
ApplyFingerCurls(DefaultPose, PrimaryPose, BlendedPose, CurrentPoser.PrimaryPose);
|
||||
ApplyFingerCurls(DefaultPose, PrimaryPose, BlendedPose, poser.PrimaryPose);
|
||||
|
||||
if (CurrentPoser.Blends != null)
|
||||
if (poser.Blends != null)
|
||||
{
|
||||
for (int i = 0; i < CurrentPoser.Blends.Count; i++)
|
||||
for (int i = 0; i < poser.Blends.Count; i++)
|
||||
{
|
||||
var blend = CurrentPoser.Blends[i];
|
||||
var blend = poser.Blends[i];
|
||||
|
||||
if (blend.Disabled || !blend.Pose)
|
||||
{
|
||||
@@ -275,7 +305,7 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
}
|
||||
}
|
||||
|
||||
ApplyBlend(CurrentPose, BlendedPose, CurrentPoser.PrimaryPose, CurrentPoser.PrimaryPose.Speed);
|
||||
ApplyBlend(CurrentPose, BlendedPose, poser.PrimaryPose, poser.PrimaryPose.Speed);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -432,24 +462,18 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ResetIfNotDefault()
|
||||
{
|
||||
if (CurrentPoser != DefaultPoser)
|
||||
ResetToDefault();
|
||||
}
|
||||
|
||||
public void ResetToDefault()
|
||||
{
|
||||
DynamicPose = false;
|
||||
if (DefaultPoser != null)
|
||||
_poseHand = DefaultPoseHand;
|
||||
CurrentPoser = DefaultPoser;
|
||||
if (HandHeldPose || !OverridePoser)
|
||||
{
|
||||
SetCurrentPoser(DefaultPoser, DefaultPoseHand);
|
||||
SetupPoser(CurrentPoser);
|
||||
}
|
||||
else
|
||||
else if (OverridePoser)
|
||||
{
|
||||
Debug.Log("Default poser not set.");
|
||||
SetupPoser(OverridePoser);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,17 +484,61 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
PrimaryPose = pose;
|
||||
_poseHand = false;
|
||||
}
|
||||
public void SetCurrentPoser(HVRHandPoser poser, bool poseHand = true)
|
||||
|
||||
/// <summary>
|
||||
/// Sets or reset (pass null) a poser that will take precedence over framework hover posers, but won't take precedence over held object poses.
|
||||
/// </summary>
|
||||
public virtual void SetOverridePoser(HVRHandPoser poser, bool poseHand = false)
|
||||
{
|
||||
_poseHandOverride = poseHand;
|
||||
OverridePoser = poser;
|
||||
|
||||
if (!poser)
|
||||
{
|
||||
SetupPoser(CurrentPoser);
|
||||
}
|
||||
else if (!HandHeldPose)
|
||||
{
|
||||
SetupPoser(poser);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetHeldPoser(HVRHandPoser poser, bool poseHand = false)
|
||||
{
|
||||
HandHeldPose = true;
|
||||
_poseHand = poseHand;
|
||||
CurrentPoser = poser;
|
||||
SetupPoser(poser);
|
||||
}
|
||||
|
||||
public void OnHeldObjectReleased()
|
||||
{
|
||||
HandHeldPose = false;
|
||||
DynamicPose = false;
|
||||
CurrentPoser = DefaultPoser;
|
||||
_poseHand = DefaultPoseHand;
|
||||
if (OverridePoser)
|
||||
{
|
||||
SetupPoser(OverridePoser);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetupPoser(CurrentPoser);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual void SetCurrentPoser(HVRHandPoser poser, bool poseHand = false)
|
||||
{
|
||||
_poseHand = poseHand;
|
||||
if (!PoseHand)
|
||||
{
|
||||
//hand grabber handles posing the IKTarget since the posable hand component is placed on the avatar itself
|
||||
_poseHand = false;
|
||||
}
|
||||
|
||||
CurrentPoser = poser;
|
||||
if (poser == null || poser.PrimaryPose == null) return;
|
||||
if (!OverridePoser || HandHeldPose)
|
||||
SetupPoser(poser);
|
||||
}
|
||||
|
||||
protected virtual void SetupPoser(HVRHandPoser poser)
|
||||
{
|
||||
if (!poser || poser.PrimaryPose == null) return;
|
||||
|
||||
PrimaryPose = poser.PrimaryPose.Pose.GetPose(Hand.IsLeft);
|
||||
|
||||
@@ -487,12 +555,12 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (var i = 0; i < poser.Blends.Count; i++)
|
||||
{
|
||||
poser.Blends[i].Value = 0f; //reset blend weight
|
||||
poser.Blends[i].Value = 0f; //reset blend weight
|
||||
PrimaryPose.CopyTo(Blends[i]); //copy primary pose to the blend pose as a base
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
None = 0, Hand = 1, Thumb = 2, Index = 4, Middle = 8, Ring = 16, Pinky = 32
|
||||
}
|
||||
|
||||
[HelpURL("https://cloudwalker2020.github.io/HurricaneVR-Docs/manual/hand_posing.html")]
|
||||
public class HVRHandPoser : MonoBehaviour
|
||||
{
|
||||
#region EditorState
|
||||
@@ -47,7 +48,6 @@ namespace HurricaneVR.Framework.Core.HandPoser
|
||||
public HVRHandPoseBlend PrimaryPose;
|
||||
public List<HVRHandPoseBlend> Blends = new List<HVRHandPoseBlend>();
|
||||
|
||||
public HVRHandPose ReferencePose;
|
||||
public MirrorAxis MirrorAxis = MirrorAxis.X;
|
||||
|
||||
private void Awake()
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.HandPoser
|
||||
{
|
||||
public class HVRHandTrigger : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 364f55a0f60644beb4e906f6db185d28
|
||||
timeCreated: 1661135657
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using HurricaneVR.Framework.Core.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.HandPoser
|
||||
{
|
||||
public class HVRPoseZone : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Decide to ignore non trigger colliders or not on the hand for stable detection of non moving colliders.")]
|
||||
public bool UseHandTriggersOnly = true;
|
||||
|
||||
[Tooltip("Uses box overlap or sphere overlap")]
|
||||
public bool UseBox = true;
|
||||
|
||||
public Vector3 OverlapBox = new Vector3(.15f, .15f, .15f);
|
||||
public float OverlapRadius = .15f;
|
||||
|
||||
[Tooltip("Layer mask of the hand collider for performant detection")]
|
||||
public LayerMask HandMask;
|
||||
|
||||
[Tooltip("Poser that defines the pose to animate to, captured on awake from same object if not supplied.")]
|
||||
public HVRHandPoser Poser;
|
||||
|
||||
private readonly List<HVRHandGrabber> overlappedHands = new List<HVRHandGrabber>(2);
|
||||
private readonly List<HVRHandGrabber> hands = new List<HVRHandGrabber>(2);
|
||||
private readonly Collider[] _colliders = new Collider[100];
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (!Poser)
|
||||
{
|
||||
TryGetComponent(out Poser);
|
||||
}
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
{
|
||||
hands.Clear();
|
||||
int count;
|
||||
if (UseBox)
|
||||
{
|
||||
count = Physics.OverlapBoxNonAlloc(transform.position, OverlapBox * .5f, _colliders, transform.rotation, HandMask, QueryTriggerInteraction.Collide);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = Physics.OverlapSphereNonAlloc(transform.position, OverlapRadius, _colliders, HandMask, QueryTriggerInteraction.Collide);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var c = _colliders[i];
|
||||
var hand = c.FindComponent<HVRHandGrabber>();
|
||||
if (!hand) continue;
|
||||
|
||||
if (c.isTrigger)
|
||||
{
|
||||
if (!c.TryGetComponent(out HVRHandTrigger _))
|
||||
{
|
||||
//ignore triggers that aren't marked with HVRHandTrigger or a child of the hand model so that other triggers on the hand rigidbody
|
||||
//that are used for other purposes like the distance grabber are aren't considered
|
||||
if (hand.HandAnimator && (!c.transform.IsChildOf(hand.HandAnimator.Hand.transform)) && c.transform != hand.HandAnimator.Hand.transform)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (UseHandTriggersOnly)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
hands.Add(hand);
|
||||
}
|
||||
|
||||
|
||||
foreach (var hand in hands)
|
||||
{
|
||||
if (!overlappedHands.Contains(hand))
|
||||
{
|
||||
hand.SetAnimatorOverridePose(Poser);
|
||||
overlappedHands.Add(hand);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = overlappedHands.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var hand = overlappedHands[i];
|
||||
if (!hand || !hands.Contains(hand))
|
||||
{
|
||||
hand.SetAnimatorOverridePose(null);
|
||||
overlappedHands.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
Gizmos.color = Color.green;
|
||||
if (UseBox)
|
||||
{
|
||||
Gizmos.matrix = transform.localToWorldMatrix;
|
||||
Gizmos.DrawWireCube(Vector3.zero, OverlapBox);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gizmos.DrawWireSphere(transform.position, OverlapRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81ed24babdf5471dbf0b20a8d9f02ba1
|
||||
timeCreated: 1661109513
|
||||
@@ -16,8 +16,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// <summary>
|
||||
/// HMD transform used to detect HMD movement at start
|
||||
/// </summary>
|
||||
[Header("Required Transforms")]
|
||||
public Transform Camera;
|
||||
[Header("Required Transforms")] public Transform Camera;
|
||||
|
||||
/// <summary>
|
||||
/// Camera rig child used to offset the Y height of the HMD.
|
||||
@@ -32,15 +31,13 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// <summary>
|
||||
/// Manually setting this will raise / lower the HMD
|
||||
/// </summary>
|
||||
[Header("Manual Camera Offsetting")]
|
||||
[Tooltip("Manually modify the camera height if needed")]
|
||||
[Header("Manual Camera Offsetting")] [Tooltip("Manually modify the camera height if needed")]
|
||||
public float CameraYOffset;
|
||||
|
||||
/// <summary>
|
||||
/// Used with height calibration to define the virtual player's HMD sight line.
|
||||
/// </summary>
|
||||
[FormerlySerializedAs("PlayerHeight")]
|
||||
[Tooltip("Height of the virtual player")]
|
||||
[FormerlySerializedAs("PlayerHeight")] [Tooltip("Height of the virtual player")]
|
||||
public float EyeHeight = 1.66f;
|
||||
|
||||
/// <summary>
|
||||
@@ -48,19 +45,14 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// Standing - CameraScale is scaled based on the ratio of EyeHeight / HMD height.
|
||||
/// PlayerHeight - No offsetting or scaling performed.
|
||||
/// </summary>
|
||||
[Tooltip("Sitting or standing mode")]
|
||||
public HVRSitStand SitStanding = HVRSitStand.PlayerHeight;
|
||||
[Tooltip("Sitting or standing mode")] public HVRSitStand SitStanding = HVRSitStand.PlayerHeight;
|
||||
|
||||
[Header("Debug Height Offsets")]
|
||||
|
||||
[Tooltip("If true, use up and down arrow to change YOffset to help with testing.")]
|
||||
[Header("Debug Height Offsets")] [Tooltip("If true, use up and down arrow to change YOffset to help with testing.")]
|
||||
public bool DebugKeyboardOffset;
|
||||
|
||||
public float DebugKeyboardIncrement = .25f;
|
||||
|
||||
[Header("Debug Height Calibration")]
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Calibration height is saved to player prefs when height is calibrated.
|
||||
/// </summary>
|
||||
@@ -90,7 +82,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public KeyCode RecalibrateKey = KeyCode.R;
|
||||
|
||||
#elif ENABLE_INPUT_SYSTEM
|
||||
|
||||
public Key HeightCalibrateKey = Key.R;
|
||||
|
||||
#endif
|
||||
@@ -98,8 +89,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// <summary>
|
||||
/// Set by the player controller to raise / lower the camera rig when performing a input driven crouch.
|
||||
/// </summary>
|
||||
[Header("For Debugging Display only")]
|
||||
public float PlayerControllerYOffset = 0f;
|
||||
[Header("For Debugging Display only")] public float PlayerControllerYOffset = 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Floor offset height adjusted by the Standing camera scale (if any).
|
||||
@@ -202,16 +192,18 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
if (IsMine)
|
||||
{
|
||||
if (DebugKeyboardOffset)
|
||||
{
|
||||
#if ENABLE_LEGACY_INPUT_MANAGER
|
||||
|
||||
if (DebugKeyboardOffset && UnityEngine.Input.GetKeyDown(KeyCode.DownArrow))
|
||||
{
|
||||
CameraYOffset += -DebugKeyboardIncrement;
|
||||
}
|
||||
else if (DebugKeyboardOffset && UnityEngine.Input.GetKeyDown(KeyCode.UpArrow))
|
||||
{
|
||||
CameraYOffset += DebugKeyboardIncrement;
|
||||
}
|
||||
if (UnityEngine.Input.GetKeyDown(KeyCode.DownArrow))
|
||||
{
|
||||
CameraYOffset += -DebugKeyboardIncrement;
|
||||
}
|
||||
else if (UnityEngine.Input.GetKeyDown(KeyCode.UpArrow))
|
||||
{
|
||||
CameraYOffset += DebugKeyboardIncrement;
|
||||
}
|
||||
#elif ENABLE_INPUT_SYSTEM
|
||||
if (Keyboard.current[Key.UpArrow].wasPressedThisFrame)
|
||||
{
|
||||
@@ -222,6 +214,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
CameraYOffset += -DebugKeyboardIncrement;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (DebugKeyboardRecalibrate)
|
||||
{
|
||||
@@ -314,6 +307,8 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
public enum HVRDebugCalibrate
|
||||
{
|
||||
None, HMDMoved, Immediately
|
||||
None,
|
||||
HMDMoved,
|
||||
Immediately
|
||||
}
|
||||
}
|
||||
+97
-7
@@ -1,4 +1,6 @@
|
||||
using HurricaneVR.Framework.Core.ScriptableObjects;
|
||||
using System;
|
||||
using HurricaneVR.Framework.Core.ScriptableObjects;
|
||||
using HurricaneVR.Framework.Core.Utils;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Player
|
||||
@@ -6,11 +8,18 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public class HVRHandStrengthHandler : MonoBehaviour
|
||||
{
|
||||
[Header("Debug")]
|
||||
public HVRJointSettings CurrentSettings;
|
||||
public bool LogStrengthChanges;
|
||||
|
||||
|
||||
[Tooltip("If true will update the joint every update - useful for tweaking HVRJointSettings in play mode.")]
|
||||
public bool AlwaysUpdateJoint;
|
||||
|
||||
[Tooltip("Active strength profile")]
|
||||
public PDStrength CurrentStrength;
|
||||
|
||||
[Tooltip("Deprecated active strength profile")]
|
||||
public HVRJointSettings CurrentSettings;
|
||||
|
||||
[Tooltip("Enable to print to console when the strength profile changes")]
|
||||
public bool LogStrengthChanges;
|
||||
|
||||
public HVRJointSettings JointSettings { get; private set; }
|
||||
|
||||
@@ -18,6 +27,12 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
public HVRJointSettings HandGrabberOverride { get; private set; }
|
||||
|
||||
public PDStrength DefaultStrength { get; private set; }
|
||||
|
||||
public PDStrength StrengthOverride { get; private set; }
|
||||
|
||||
public PDStrength HandGrabOverride { get; private set; }
|
||||
|
||||
public ConfigurableJoint Joint { get; set; }
|
||||
|
||||
public bool Stopped { get; private set; }
|
||||
@@ -42,6 +57,12 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
JointSettings = defaultSettings;
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
public void Initialize(PDStrength defaultSettings)
|
||||
{
|
||||
DefaultStrength = defaultSettings;
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
protected virtual void FixedUpdate()
|
||||
{
|
||||
@@ -51,12 +72,20 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateJoint()
|
||||
public virtual void UpdateJoint()
|
||||
{
|
||||
if (Stopped)
|
||||
return;
|
||||
|
||||
if (HandGrabberOverride)
|
||||
if (StrengthOverride)
|
||||
{
|
||||
UpdateStrength(StrengthOverride);
|
||||
}
|
||||
else if (HandGrabOverride)
|
||||
{
|
||||
UpdateStrength(HandGrabOverride);
|
||||
}
|
||||
else if (HandGrabberOverride)
|
||||
{
|
||||
UpdateStrength(HandGrabberOverride);
|
||||
}
|
||||
@@ -68,8 +97,30 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
UpdateStrength(JointSettings);
|
||||
}
|
||||
else if (DefaultStrength)
|
||||
{
|
||||
UpdateStrength(DefaultStrength);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected virtual void UpdateStrength(PDStrength settings)
|
||||
{
|
||||
if (!settings) return;
|
||||
|
||||
CurrentStrength = settings;
|
||||
if(settings.Mode != JointApply.Rotation)
|
||||
Joint.SetLinearDrive(settings.Spring, settings.Damper, settings.MaxForce);
|
||||
if(settings.Mode != JointApply.Position)
|
||||
Joint.SetSlerpDrive(settings.TorqueSpring, settings.TorqueDamper, settings.MaxTorque);
|
||||
|
||||
if (LogStrengthChanges)
|
||||
{
|
||||
Debug.Log($"{settings.name} applied.");
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable Unity.PerformanceAnalysis
|
||||
protected virtual void UpdateStrength(HVRJointSettings settings)
|
||||
{
|
||||
if (settings)
|
||||
@@ -90,7 +141,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
public virtual void OverrideHandSettings(HVRJointSettings settings)
|
||||
internal virtual void OverrideHandSettings(HVRJointSettings settings)
|
||||
{
|
||||
HandGrabberOverride = settings;
|
||||
UpdateJoint();
|
||||
@@ -99,6 +150,32 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public virtual void StopOverride()
|
||||
{
|
||||
JointOverride = null;
|
||||
StrengthOverride = null;
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
public virtual void ResetHandOverride()
|
||||
{
|
||||
var needsReset = HandGrabberOverride || HandGrabOverride;
|
||||
HandGrabberOverride = null;
|
||||
HandGrabOverride = null;
|
||||
if(needsReset)
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override the strength profile. Takes precedence over grabbable strength overrides.
|
||||
/// Call StopOverride to revert to default strength.
|
||||
/// </summary>
|
||||
public virtual void OverrideSettings(PDStrength settings)
|
||||
{
|
||||
StrengthOverride = settings;
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
public virtual void OverrideHandSettings(PDStrength settings)
|
||||
{
|
||||
HandGrabOverride = settings;
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
@@ -113,5 +190,18 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
Stopped = false;
|
||||
UpdateJoint();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class HandStrength
|
||||
{
|
||||
public bool UseOneHandStrength;
|
||||
public bool UseTwoHandStrength;
|
||||
public PDStrength OneHandStrength;
|
||||
public PDStrength TwoHandStrength;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -17,14 +17,20 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// Default hand strength settings.
|
||||
/// </summary>
|
||||
[Header("Settings")]
|
||||
[Tooltip("Default hand strength settings.")]
|
||||
public HVRJointSettings JointSettings;
|
||||
|
||||
[Embedded]
|
||||
[Tooltip("Default hand strength settings.")]
|
||||
public PDStrength Strength;
|
||||
|
||||
[Tooltip("Physx constraint iterations")]
|
||||
public int SolverIterations = 10;
|
||||
|
||||
[Tooltip("Physx constraint iterations")]
|
||||
public int SolverVelocityIterations = 10;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The speed at which the hand returns to the controller when the MaxDistanceBehaviour is not set to HandSweep
|
||||
@@ -66,6 +72,10 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
[Tooltip("Target transform for position and rotation tracking")]
|
||||
public Transform Target;
|
||||
|
||||
[Header("Deprecated")]
|
||||
[Tooltip("Default hand strength settings.")]
|
||||
public HVRJointSettings JointSettings;
|
||||
|
||||
/// <summary>
|
||||
/// Kinematic rigidbody that will hold the joint for stability.
|
||||
/// </summary>
|
||||
@@ -103,10 +113,9 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public HVRHandGrabber Grabber { get; private set; }
|
||||
|
||||
|
||||
private Vector3 _previousControllerPosition;
|
||||
public Vector3 PreviousControllerPosition { get; set; }
|
||||
private Quaternion _previousRotation;
|
||||
private float _timer = 0f;
|
||||
private bool _hasTeleporter;
|
||||
private float _teleportTimer = 0f;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
@@ -126,10 +135,15 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
Teleporter = transform.root.GetComponentInChildren<HVRTeleporter>();
|
||||
}
|
||||
|
||||
_hasTeleporter = Teleporter;
|
||||
if (Teleporter)
|
||||
{
|
||||
Teleporter.PositionUpdate.AddListener(OnPlayerTeleported);
|
||||
Teleporter.BeforeDashTeleport.AddListener(OnBeforeDashTeleport);
|
||||
Teleporter.AfterDashTeleport.AddListener(OnAfterDashTeleport);
|
||||
}
|
||||
|
||||
if (!JointSettings)
|
||||
Debug.LogError("JointSettings field is empty, must be populated with HVRJointSettings scriptable object.");
|
||||
if (!Strength)
|
||||
Debug.LogError("Strength field is empty, must be populated with PDStrength scriptable object.");
|
||||
|
||||
if (!StrengthHandler)
|
||||
{
|
||||
@@ -143,12 +157,23 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
ReturnSpeed = 5f;
|
||||
|
||||
StrengthHandler.Joint = Joint;
|
||||
StrengthHandler.Initialize(JointSettings);
|
||||
if(JointSettings) StrengthHandler.Initialize(JointSettings);
|
||||
else StrengthHandler.Initialize(Strength);
|
||||
}
|
||||
|
||||
private void OnAfterDashTeleport(Vector3 arg0)
|
||||
{
|
||||
Enable();
|
||||
}
|
||||
|
||||
private void OnBeforeDashTeleport(Vector3 arg0)
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
_previousControllerPosition = Target.position;
|
||||
PreviousControllerPosition = Target.position;
|
||||
_previousRotation = Target.rotation;
|
||||
//fixing the issue where the hand goes to world 0,0,0 at start
|
||||
StartCoroutine(StopHandsRoutine());
|
||||
@@ -224,17 +249,16 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
|
||||
|
||||
public virtual void OnPlayerTeleported(Vector3 position)
|
||||
{
|
||||
_teleportTimer = Time.time;
|
||||
SaveTargetState(); //updating state after teleport
|
||||
}
|
||||
|
||||
protected virtual void UpdateDistanceCheck()
|
||||
{
|
||||
if (_hasTeleporter)
|
||||
{
|
||||
if (Teleporter.TeleportState == TeleportState.None) _timer += Time.deltaTime;
|
||||
else _timer = 0f;
|
||||
|
||||
if (_timer < .5f)
|
||||
return;
|
||||
}
|
||||
if (Time.time - _teleportTimer < .5f)
|
||||
return;
|
||||
|
||||
if (!IsReturningToController)
|
||||
{
|
||||
@@ -298,22 +322,26 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
RigidBody.detectCollisions = false;
|
||||
}
|
||||
|
||||
|
||||
public virtual void UpdateTargetVelocity()
|
||||
{
|
||||
var worldVelocity = (Target.position - _previousControllerPosition) / Time.fixedDeltaTime;
|
||||
_previousControllerPosition = Target.position;
|
||||
Joint.targetVelocity = ParentRigidBody.transform.InverseTransformDirection(worldVelocity);
|
||||
|
||||
var angularVelocity = Target.rotation.AngularVelocity(_previousRotation);
|
||||
|
||||
Joint.targetAngularVelocity = Quaternion.Inverse(ParentRigidBody.transform.rotation) * angularVelocity;
|
||||
|
||||
if (Joint.rotationDriveMode == RotationDriveMode.XYAndZ)
|
||||
if (!(Vector3.SqrMagnitude(Target.position - PreviousControllerPosition) > 1f))
|
||||
{
|
||||
Joint.targetAngularVelocity *= -1;
|
||||
var worldVelocity = (Target.position - PreviousControllerPosition) / Time.fixedDeltaTime;
|
||||
Joint.targetVelocity = ParentRigidBody.transform.InverseTransformDirection(worldVelocity);
|
||||
}
|
||||
|
||||
var angularVelocity = Target.rotation.AngularVelocity(_previousRotation);
|
||||
Joint.targetAngularVelocity = Quaternion.Inverse(ParentRigidBody.transform.rotation) * angularVelocity;
|
||||
|
||||
SaveTargetState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the controller position and rotation, call this if you manually move the player outside of the framework teleporter code.
|
||||
/// </summary>
|
||||
public void SaveTargetState()
|
||||
{
|
||||
PreviousControllerPosition = Target.position;
|
||||
_previousRotation = Target.rotation;
|
||||
}
|
||||
|
||||
@@ -333,4 +361,4 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
GrabbableDrops,
|
||||
HandSweep
|
||||
}
|
||||
}
|
||||
}
|
||||
+99
-43
@@ -17,6 +17,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
[Header("Settings")]
|
||||
public bool CanJump = false;
|
||||
|
||||
public bool CanSteerWhileJumping = true;
|
||||
public bool CanSprint = true;
|
||||
public bool CanCrouch = true;
|
||||
@@ -29,27 +30,36 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public LayerMask GroundedLayerMask;
|
||||
public float GroundedDistance = .02f;
|
||||
|
||||
[Tooltip("Grounded sphere case radius factor multiplied by the capsules radius for ground checking.")]
|
||||
public float GroundedRadiusFactor = .5f;
|
||||
|
||||
[Tooltip("Minimum Player Capsule Height.")]
|
||||
public float MinHeight = .3f;
|
||||
|
||||
[Header("Locomotion")]
|
||||
public bool InstantAcceleration = true;
|
||||
|
||||
[Tooltip("Walking speed in m/s.")]
|
||||
public float Acceleration = 15;
|
||||
|
||||
public float Deacceleration = 15f;
|
||||
public float MoveSpeed = 1.5f;
|
||||
public float SprintAcceleration = 20f;
|
||||
|
||||
[Tooltip("Sprinting speed in m/s.")]
|
||||
public float RunSpeed = 3.5f;
|
||||
|
||||
public float Gravity = 9.81f;
|
||||
public float MaxFallSpeed = 2f;
|
||||
public float JumpVelocity = 5f;
|
||||
|
||||
[Tooltip("Double click timeout for sprinting.")]
|
||||
public float DoubleClickThreshold = .25f;
|
||||
|
||||
|
||||
[Header("Turning")]
|
||||
public RotationType RotationType;
|
||||
|
||||
public float SmoothTurnSpeed = 90f;
|
||||
public float SmoothTurnThreshold = .1f;
|
||||
public float SnapAmount = 45f;
|
||||
@@ -61,18 +71,18 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public bool RotateWhileTeleportAiming;
|
||||
|
||||
[Header("Crouching")]
|
||||
|
||||
[Tooltip("Player height must be above this to toggle crouch.")]
|
||||
public float CrouchMinHeight = 1.2f;
|
||||
|
||||
|
||||
[Tooltip("Player height after toggling a crouch via controller.")]
|
||||
public float CrouchHeight = 0.7f;
|
||||
|
||||
|
||||
[Tooltip("Speed at which toggle crouch moves the player up and down.")]
|
||||
public float CrouchSpeed = 1.5f;
|
||||
|
||||
[Header("Transforms")]
|
||||
public Transform Camera;
|
||||
|
||||
public Transform NeckPivot;
|
||||
public Transform Root;
|
||||
public Transform FloorOffset;
|
||||
@@ -81,6 +91,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
[Header("Components")]
|
||||
public HVRCameraRig CameraRig;
|
||||
|
||||
public HVRHandGrabber LeftHand;
|
||||
public HVRHandGrabber RightHand;
|
||||
public HVRJointHand LeftJointHand;
|
||||
@@ -89,23 +100,26 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
[Header("Head Collision")]
|
||||
public HVRHeadCollision HeadCollision;
|
||||
|
||||
public float HeadCollisionFadeSpeed = 1f;
|
||||
|
||||
[Tooltip("If true, when your head collides it returns your head to the body's position")]
|
||||
public bool HeadCollisionPushesBack = true;
|
||||
|
||||
[Tooltip("If true, limits the head distance from the body by MaxLean amount.")]
|
||||
public bool LimitHeadDistance = true;
|
||||
|
||||
[Tooltip("If LimitHeadDistance is true, the max distance your head can be from your body.")]
|
||||
public float MaxLean = .5f;
|
||||
|
||||
[Tooltip("Screen fades when leaning to far into something.")]
|
||||
public bool FadeFromLean = true;
|
||||
|
||||
|
||||
|
||||
|
||||
[Header("Debugging")]
|
||||
public bool MouseTurning;
|
||||
public float MouseSensitivityX = 1f;
|
||||
|
||||
public float MouseSensitivityX = 1f;
|
||||
|
||||
|
||||
public Rigidbody RigidBody { get; private set; }
|
||||
@@ -114,10 +128,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
public virtual float CameraHeight
|
||||
{
|
||||
get
|
||||
{
|
||||
return CameraRig.AdjustedCameraHeight;
|
||||
}
|
||||
get { return CameraRig.AdjustedCameraHeight; }
|
||||
}
|
||||
|
||||
public bool IsCrouching => CameraHeight < CrouchMinHeight;
|
||||
@@ -126,7 +137,9 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
public bool Sprinting { get; set; }
|
||||
|
||||
public bool IsGrounded;// { get; set; }
|
||||
public bool IsGrounded; // { get; set; }
|
||||
|
||||
public Vector3 GroundNormal { get; set; }
|
||||
|
||||
public bool MovementEnabled { get; set; } = true;
|
||||
public bool RotationEnabled { get; set; } = true;
|
||||
@@ -135,8 +148,8 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
public HVRPlayerInputs Inputs { get; private set; }
|
||||
|
||||
public Vector3 PreviousPosition { get; protected set; }
|
||||
|
||||
public Vector3 PreviousPosition { get; set; }
|
||||
|
||||
private Vector3 _previousLeftControllerPosition;
|
||||
private Vector3 _previousRightControllerPosition;
|
||||
|
||||
@@ -158,8 +171,10 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
private Vector3 _previousVelocity;
|
||||
private float yVelocity;
|
||||
private Vector3 xzVelocity;
|
||||
private Quaternion _preTeleportRotation;
|
||||
|
||||
[SerializeField] private float _actualVelocity;
|
||||
[SerializeField]
|
||||
private float _actualVelocity;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
@@ -169,6 +184,8 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
if (Teleporter)
|
||||
{
|
||||
_hasTeleporter = true;
|
||||
Teleporter.BeforeTeleport.AddListener(OnBeforeTeleport);
|
||||
Teleporter.PositionUpdate.AddListener(OnTeleported);
|
||||
}
|
||||
|
||||
if (NeckPivot)
|
||||
@@ -188,6 +205,21 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
ScreenFader = finder.gameObject.GetComponent<HVRScreenFade>();
|
||||
}
|
||||
}
|
||||
|
||||
PreviousPosition = transform.position;
|
||||
}
|
||||
|
||||
private void OnTeleported(Vector3 arg0)
|
||||
{
|
||||
//prevent teleporting from impulsing the hand calcs in AdjustHandAcceleration
|
||||
PreviousPosition = transform.position;
|
||||
var rot = transform.rotation * Quaternion.Inverse(_preTeleportRotation);
|
||||
_previousVelocity = rot * _previousVelocity;
|
||||
}
|
||||
|
||||
private void OnBeforeTeleport(Vector3 arg0)
|
||||
{
|
||||
_preTeleportRotation = transform.rotation;
|
||||
}
|
||||
|
||||
|
||||
@@ -240,6 +272,10 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
// if (Input.GetKeyDown(KeyCode.Q))
|
||||
// {
|
||||
// Teleporter.Teleport(transform.position, Quaternion.AngleAxis(90f, Vector3.up) * transform.forward);
|
||||
// }
|
||||
CheckCameraCorrection();
|
||||
CheckSprinting();
|
||||
UpdateHeight();
|
||||
@@ -262,7 +298,8 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
if (CharacterController.enabled)
|
||||
{
|
||||
HandleMovement();
|
||||
|
||||
HandleMovement();
|
||||
|
||||
if (CanRotate())
|
||||
{
|
||||
@@ -274,7 +311,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
CheckGrounded();
|
||||
|
||||
|
||||
|
||||
_actualVelocity = ((transform.position - PreviousPosition) / Time.deltaTime).magnitude;
|
||||
|
||||
_previousLeftControllerPosition = LeftControllerTransform.position;
|
||||
@@ -307,18 +343,22 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
delta.y = 0f;
|
||||
CameraRig.transform.position -= delta;
|
||||
_waitingForCameraMovement = false;
|
||||
PreviousPosition = transform.position;
|
||||
}
|
||||
|
||||
protected virtual void CheckGrounded()
|
||||
{
|
||||
var origin = CharacterController.center - Vector3.up * (.5f * CharacterController.height - CharacterController.radius);
|
||||
var radius = CharacterController.radius * GroundedRadiusFactor;
|
||||
var origin = CharacterController.center - Vector3.up * (.5f * CharacterController.height - radius);
|
||||
IsGrounded = Physics.SphereCast(
|
||||
transform.TransformPoint(origin) + Vector3.up * CharacterController.contactOffset,
|
||||
CharacterController.radius,
|
||||
transform.TransformPoint(origin) + Vector3.up * CharacterController.contactOffset,
|
||||
radius,
|
||||
Vector3.down,
|
||||
out var hit,
|
||||
GroundedDistance + CharacterController.contactOffset,
|
||||
GroundedLayerMask, QueryTriggerInteraction.Ignore);
|
||||
|
||||
GroundNormal = hit.normal;
|
||||
}
|
||||
|
||||
protected virtual void CheckLean()
|
||||
@@ -330,7 +370,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
delta.y = 0;
|
||||
|
||||
if (delta.sqrMagnitude < .01f || delta.magnitude < MaxLean) return;
|
||||
|
||||
|
||||
if (FadeFromLean)
|
||||
{
|
||||
StartCoroutine(CorrectCamera());
|
||||
@@ -358,6 +398,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
delta.y = 0f;
|
||||
if (delta.magnitude > 0.0f && CharacterController.enabled)
|
||||
{
|
||||
delta = Vector3.ProjectOnPlane(delta, GroundNormal);
|
||||
CharacterController.Move(delta);
|
||||
}
|
||||
|
||||
@@ -438,6 +479,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
HandleHMDMovement();
|
||||
}
|
||||
|
||||
HandleHorizontalMovement();
|
||||
HandleVerticalMovement();
|
||||
AdjustHandAcceleration();
|
||||
@@ -494,7 +536,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
yVelocity = Mathf.Clamp(yVelocity, -MaxFallSpeed, yVelocity);
|
||||
}
|
||||
|
||||
velocity.y = yVelocity;
|
||||
velocity.y += yVelocity;
|
||||
|
||||
CharacterController.Move(velocity * Time.deltaTime);
|
||||
}
|
||||
@@ -519,6 +561,11 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
if (IsGrounded || CanSteerWhileJumping)
|
||||
{
|
||||
if (IsGrounded)
|
||||
{
|
||||
direction = Vector3.ProjectOnPlane(direction, GroundNormal);
|
||||
}
|
||||
|
||||
if (InstantAcceleration)
|
||||
{
|
||||
xzVelocity = speed * direction;
|
||||
@@ -549,22 +596,35 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accounts for the instantaneous acceleration of the player, without this the hands would lag behind
|
||||
/// </summary>
|
||||
protected virtual void AdjustHandAcceleration()
|
||||
{
|
||||
var v = (transform.position - PreviousPosition) / Time.deltaTime;
|
||||
var acceler = (v - _previousVelocity) / Time.deltaTime;
|
||||
_previousVelocity = v;
|
||||
|
||||
|
||||
LeftJointHand.RigidBody.AddForce(acceler * LeftJointHand.RigidBody.mass, ForceMode.Force);
|
||||
RightJointHand.RigidBody.AddForce(acceler * RightJointHand.RigidBody.mass, ForceMode.Force);
|
||||
|
||||
var leftRB = LeftHand.GrabbedTarget?.Rigidbody;
|
||||
var rightRb = RightHand.GrabbedTarget?.Rigidbody;
|
||||
Rigidbody leftRB = null;
|
||||
Rigidbody rightRb = null;
|
||||
|
||||
if (LeftHand.GrabbedTarget && LeftHand.GrabbedTarget.Rigidbody)
|
||||
{
|
||||
leftRB = LeftHand.GrabbedTarget.Rigidbody;
|
||||
}
|
||||
|
||||
if (RightHand.GrabbedTarget && RightHand.GrabbedTarget.Rigidbody)
|
||||
{
|
||||
rightRb = RightHand.GrabbedTarget.Rigidbody;
|
||||
}
|
||||
|
||||
if (leftRB && rightRb && leftRB == rightRb)
|
||||
{
|
||||
LeftJointHand.RigidBody.AddForce(acceler * .5f * leftRB.mass, ForceMode.Force);
|
||||
RightJointHand.RigidBody.AddForce(acceler * .5f * rightRb.mass, ForceMode.Force);
|
||||
LeftJointHand.RigidBody.AddForce(acceler * (.5f * leftRB.mass), ForceMode.Force);
|
||||
RightJointHand.RigidBody.AddForce(acceler * (.5f * rightRb.mass), ForceMode.Force);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -642,7 +702,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (Sprinting && Inputs.IsSprintingActivated)
|
||||
Sprinting = false;
|
||||
else if (!Sprinting && Inputs.IsSprintingActivated)
|
||||
@@ -687,7 +746,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
_cameraBelowCrouchHeight = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected virtual void Crouch()
|
||||
@@ -761,23 +819,23 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// </summary>
|
||||
public void RemoveMultiplayerComponents()
|
||||
{
|
||||
foreach (var t in new[]{
|
||||
typeof(HVRCamera),
|
||||
typeof(Camera),
|
||||
typeof(AudioListener),
|
||||
//typeof(TrackedPoseDriver),
|
||||
typeof(HVRScreenFade),
|
||||
typeof(HVRHeadCollision),
|
||||
typeof(HVRThrowingCenterOfMass),
|
||||
typeof(HVRControllerOffset), typeof(HVRJointHand)
|
||||
})
|
||||
foreach (var t in new[]
|
||||
{
|
||||
typeof(HVRCamera),
|
||||
typeof(Camera),
|
||||
typeof(AudioListener),
|
||||
//typeof(TrackedPoseDriver),
|
||||
typeof(HVRScreenFade),
|
||||
typeof(HVRHeadCollision),
|
||||
typeof(HVRThrowingCenterOfMass),
|
||||
typeof(HVRControllerOffset), typeof(HVRJointHand)
|
||||
})
|
||||
{
|
||||
foreach (var component in GetComponentsInChildren(t))
|
||||
{
|
||||
Destroy(component);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetTurnType(RotationType rotationType)
|
||||
@@ -800,7 +858,8 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
var f = Camera.forward;
|
||||
f.y = 0f;
|
||||
forward.y = 0f;
|
||||
transform.rotation = Quaternion.FromToRotation(f, forward) * transform.rotation;
|
||||
var rotation = Quaternion.AngleAxis(Vector3.SignedAngle(f, forward, Vector3.up), Vector3.up);
|
||||
transform.rotation = rotation * transform.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -816,7 +875,4 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
Smooth,
|
||||
Snap
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
+29
-85
@@ -208,19 +208,14 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
if (LeftJointHand)
|
||||
{
|
||||
LeftJointHand.Disable();
|
||||
LeftJointHand.RigidBody.detectCollisions = false;
|
||||
}
|
||||
|
||||
if (RightJointHand)
|
||||
{
|
||||
RightJointHand.Disable();
|
||||
RightJointHand.RigidBody.detectCollisions = false;
|
||||
}
|
||||
|
||||
LeftHand.Rigidbody.velocity = Vector3.zero;
|
||||
RightHand.Rigidbody.velocity = Vector3.zero;
|
||||
|
||||
_previousPosition = position;
|
||||
}
|
||||
|
||||
@@ -257,9 +252,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
RightJointHand.RigidBody.position = RightJointHand.RigidBody.position;
|
||||
}
|
||||
|
||||
//SweepHand(LeftHand, leftGrabbable);
|
||||
//SweepHand(RightHand, rightGrabbable);
|
||||
|
||||
_previousPosition = position;
|
||||
}
|
||||
|
||||
@@ -323,9 +315,29 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
|
||||
|
||||
Physics.SyncTransforms();
|
||||
|
||||
StartCoroutine(AfterFixedUpdate());
|
||||
var direction = (_teleportStart - _teleportEnd).normalized;
|
||||
direction.y = 0f;
|
||||
|
||||
var offset = Vector3.zero;
|
||||
if (leftGrabbable) offset = leftGrabbable.transform.InverseTransformPoint(RightHand.transform.position);
|
||||
|
||||
PostTeleportSweep(LeftHand, leftGrabbable, direction);
|
||||
|
||||
if (leftGrabbable && leftGrabbable == rightGrabbable)
|
||||
{
|
||||
RightHand.transform.position = leftGrabbable.transform.TransformPoint(offset);
|
||||
RightHand.Rigidbody.position = RightHand.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
PostTeleportSweep(RightHand, rightGrabbable, direction);
|
||||
}
|
||||
|
||||
|
||||
leftGrabbable = null;
|
||||
rightGrabbable = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -346,8 +358,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
SweepHand(hand, hand.GrabbedTarget, target);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
@@ -382,7 +393,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
hand.Rigidbody.position = origin.position;
|
||||
|
||||
var bounds = hand.Rigidbody.GetColliderBounds();
|
||||
var bounds = hand.HandPhysics.HandColliders.GetColliderBounds();
|
||||
var maxSide = Mathf.Max(bounds.size.x, bounds.size.y, bounds.size.z);
|
||||
var start = bounds.center;
|
||||
var length = Vector3.Distance(target, start);
|
||||
@@ -437,7 +448,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
hand.transform.position = hand.Rigidbody.position = target;
|
||||
}
|
||||
|
||||
bounds = hand.Rigidbody.GetColliderBounds();
|
||||
bounds = hand.HandPhysics.HandColliders.GetColliderBounds();
|
||||
|
||||
if (VerboseDebug) DrawSweepLines(hand, start, direction, length);
|
||||
if (VerboseDebug) CastEnd(hand, bounds, start, direction, length);
|
||||
@@ -448,7 +459,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
//backout after forward sweep
|
||||
|
||||
|
||||
|
||||
var offset = Vector3.zero;
|
||||
|
||||
for (var d = 0f; d < backoutDistance; d += .05f)
|
||||
@@ -467,71 +477,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
hand.transform.position = hand.Rigidbody.position;
|
||||
}
|
||||
|
||||
protected virtual IEnumerator AfterFixedUpdate()
|
||||
{
|
||||
yield return new WaitForFixedUpdate();
|
||||
|
||||
var lgPos = Vector3.zero;
|
||||
var rgPos = Vector3.zero;
|
||||
var lgRot = Quaternion.identity;
|
||||
var rgRot = Quaternion.identity;
|
||||
|
||||
if (leftGrabbable) LeftJointHand.transform.GetRelativeValues(leftGrabbable.transform, out lgPos, out lgRot);
|
||||
if (rightGrabbable) RightJointHand.transform.GetRelativeValues(rightGrabbable.transform, out rgPos, out rgRot);
|
||||
|
||||
LeftJointHand.RigidBody.position = LeftJointHand.Target.position;
|
||||
RightJointHand.RigidBody.position = RightJointHand.Target.position;
|
||||
|
||||
if (leftGrabbable)
|
||||
{
|
||||
leftGrabbable.transform.SetPositionAndRotation(
|
||||
LeftJointHand.transform.TransformPoint(lgPos),
|
||||
LeftJointHand.transform.rotation * lgRot);
|
||||
if (leftGrabbable.Rigidbody) leftGrabbable.Rigidbody.velocity = Vector3.zero;
|
||||
}
|
||||
|
||||
if (rightGrabbable)
|
||||
{
|
||||
rightGrabbable.transform.SetPositionAndRotation(
|
||||
RightJointHand.transform.TransformPoint(rgPos),
|
||||
RightJointHand.transform.rotation * rgRot);
|
||||
if (rightGrabbable.Rigidbody) rightGrabbable.Rigidbody.velocity = Vector3.zero;
|
||||
}
|
||||
|
||||
Physics.SyncTransforms();
|
||||
|
||||
LeftHand.Rigidbody.velocity = Vector3.zero;
|
||||
RightHand.Rigidbody.velocity = Vector3.zero;
|
||||
|
||||
LeftJointHand.Enable();
|
||||
RightJointHand.Enable();
|
||||
|
||||
var direction = (_teleportStart - _teleportEnd).normalized;
|
||||
direction.y = 0f;
|
||||
|
||||
var pos = LeftHand.transform.position;
|
||||
|
||||
var offset = Vector3.zero;
|
||||
if (leftGrabbable) offset = leftGrabbable.transform.InverseTransformPoint(RightHand.transform.position);
|
||||
|
||||
PostTeleportSweep(LeftHand, leftGrabbable, direction);
|
||||
|
||||
if (leftGrabbable && leftGrabbable == rightGrabbable)
|
||||
{
|
||||
RightHand.transform.position = leftGrabbable.transform.TransformPoint(offset);
|
||||
RightHand.Rigidbody.position = RightHand.transform.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
PostTeleportSweep(RightHand, rightGrabbable, direction);
|
||||
}
|
||||
|
||||
|
||||
leftGrabbable = null;
|
||||
rightGrabbable = null;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles sweeping the hand and grabbable after a teleport sequence.
|
||||
/// </summary>
|
||||
@@ -574,7 +519,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
return other && other.GrabbedTarget && other.GrabbedTarget.HasCollider(c);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Private
|
||||
|
||||
@@ -676,7 +621,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
private void Backout(HVRHandGrabber hand, HVRGrabbable g, Vector3 direction, HVRTeleportOptions options)
|
||||
{
|
||||
var bounds = hand.Rigidbody.GetColliderBounds();
|
||||
var bounds = hand.HandPhysics.HandColliders.GetColliderBounds();
|
||||
|
||||
if (options && options.CustomBoundingBox)
|
||||
{
|
||||
@@ -709,7 +654,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
if (VerboseDebug)
|
||||
{
|
||||
bounds = hand.Rigidbody.GetColliderBounds();
|
||||
bounds = hand.HandPhysics.HandColliders.GetColliderBounds();
|
||||
|
||||
if (options && options.CustomBoundingBox)
|
||||
{
|
||||
@@ -757,7 +702,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Debugging
|
||||
|
||||
@@ -792,7 +737,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
[Serializable]
|
||||
public class GrabbableStuck : UnityEvent<HVRGrabbable>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public class GrabbableCollisionTracker
|
||||
@@ -816,4 +760,4 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
StartTime = Time.time;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
[Header("Transforms / Components")]
|
||||
public Transform Camera;
|
||||
|
||||
public Transform TeleportLineSourceLeft;
|
||||
public Transform TeleportLineSourceRight;
|
||||
public HVRHandGrabber LeftHand;
|
||||
@@ -20,7 +21,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public HVRPlayerController Player;
|
||||
|
||||
[Header("Teleport Disable Checks")]
|
||||
|
||||
[Tooltip("Should player rotation disable teleport aiming?")]
|
||||
public bool PlayerRotateCheck = true;
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
[Header("Visuals")]
|
||||
public Color ValidColor = new Color(2, 212, 186);
|
||||
|
||||
public Color InvalidColor = new Color(221, 37, 37);
|
||||
public LineRenderer LineRenderer;
|
||||
public LineRenderer DownRenderer;
|
||||
@@ -64,16 +65,17 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
[Header("Ballistic Settings")]
|
||||
public float Speed = 7.5f;
|
||||
|
||||
public float TimeStep = .01f;
|
||||
|
||||
[Header("Bezier Settings")]
|
||||
public float BezierAngleOffset = .3f;
|
||||
|
||||
public AnimationCurve BezierAngleOffsetCurve;
|
||||
public float TeleportDistance = 5f;
|
||||
|
||||
|
||||
[Header("Downward Ray cast")]
|
||||
|
||||
[Tooltip("Max length of the downwards ray cast")]
|
||||
public float DownRayLength = 5f;
|
||||
|
||||
@@ -83,10 +85,10 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
[Header("Dash Teleport")]
|
||||
public bool Dash;
|
||||
|
||||
public float DashSpeed = 15f;
|
||||
|
||||
[Header("Origin Line Of Sight")]
|
||||
|
||||
[Tooltip("If true line of sight from the camera to the origin of the teleport line is required")]
|
||||
public bool RequireOriginLineOfSight;
|
||||
|
||||
@@ -95,8 +97,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
|
||||
[Header("Destination Line Of Sight")]
|
||||
|
||||
|
||||
[Tooltip("If true line of sight from the camera to the teleport destination is required")]
|
||||
public bool RequireDestinationLineOfSight;
|
||||
|
||||
@@ -110,7 +110,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
|
||||
[Header("Destination Validation")]
|
||||
|
||||
[Tooltip("If true the fall distance from the bottom of the capsule cannot exceed MaxDropDistance")]
|
||||
public bool CheckDropDistance;
|
||||
|
||||
@@ -135,15 +134,16 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
public CapsuleCollider Capsule;
|
||||
|
||||
|
||||
public TeleportPositionUpdate BeforeDashTeleport = new TeleportPositionUpdate();
|
||||
public TeleportPositionUpdate AfterDashTeleport = new TeleportPositionUpdate();
|
||||
public TeleportPositionUpdate BeforeTeleport = new TeleportPositionUpdate();
|
||||
public UnityEvent AfterTeleport = new UnityEvent();
|
||||
public TeleportPositionUpdate PositionUpdate = new TeleportPositionUpdate();
|
||||
|
||||
|
||||
[Header("Debugging")]
|
||||
|
||||
|
||||
public Vector3 DownHitNormal;
|
||||
|
||||
public float SurfaceAngle;
|
||||
public bool IsDropDistanceValid;
|
||||
public bool IsSurfaceAngleValid;
|
||||
@@ -214,7 +214,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
/// </summary>
|
||||
public int LastIndex { get; protected set; }
|
||||
|
||||
public Transform TeleportLineSource => TeleportHand == HVRHandSide.Left ? TeleportLineSourceLeft : TeleportLineSourceRight;
|
||||
public virtual Transform TeleportLineSource => TeleportHand == HVRHandSide.Left ? TeleportLineSourceLeft : TeleportLineSourceRight;
|
||||
|
||||
/// <summary>
|
||||
/// Did the forward raycast find a valid teleportable location
|
||||
@@ -253,6 +253,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
protected float _timeSinceLastRotation;
|
||||
protected Quaternion _previousPlayerRotation;
|
||||
private Vector3 _leftVel, _rightVel, _leftHeldVel, _rightHeldVel;
|
||||
|
||||
|
||||
protected virtual void Awake()
|
||||
@@ -305,8 +306,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public virtual void Enable()
|
||||
{
|
||||
CanTeleport = true;
|
||||
@@ -334,6 +333,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
IsTeleportValid = false;
|
||||
}
|
||||
|
||||
SurfaceAngle = Vector3.Angle(Vector3.up, SurfaceNormal);
|
||||
CheckValidTeleportChanged(IsTeleportPreviouslyValid);
|
||||
HandleValidStatus(IsTeleportValid);
|
||||
@@ -391,14 +391,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
else if (TeleportState == TeleportState.Teleporting)
|
||||
{
|
||||
UpdateTeleport();
|
||||
}
|
||||
else if (TeleportState == TeleportState.AwaitingNextFrame)
|
||||
{
|
||||
OnAfterTeleport();
|
||||
if (Dash)
|
||||
{
|
||||
OnAfterDashTeleport();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,7 +402,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsTeleportActivated())
|
||||
if (!IsAiming && IsTeleportActivated())
|
||||
{
|
||||
OnTeleportActivated();
|
||||
}
|
||||
@@ -450,7 +443,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
HitPosition = forwardHit.point - direction.normalized * CollisionBuffer;
|
||||
HitCollider = forwardHit.collider;
|
||||
|
||||
destination = forwardHit.point;// + VerticalBuffer;
|
||||
destination = forwardHit.point; // + VerticalBuffer;
|
||||
|
||||
if (CheckValidDestination(HitCollider.gameObject, destination, forwardHit.normal))
|
||||
{
|
||||
@@ -476,7 +469,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
LastDownwardPoint = downwardHit.point;
|
||||
DownHitNormal = downwardHit.normal;
|
||||
|
||||
destination = downwardHit.point;// + VerticalBuffer;
|
||||
destination = downwardHit.point; // + VerticalBuffer;
|
||||
|
||||
if (!CheckValidDestination(downwardHit.collider.gameObject, destination, downwardHit.normal))
|
||||
{
|
||||
@@ -530,7 +523,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
protected virtual void HandleValidStatus(bool valid)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnTeleportActivated()
|
||||
@@ -797,7 +789,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
length = hit.distance;
|
||||
}
|
||||
|
||||
var point = ray.GetPoint(length);// - CollisionBuffer);
|
||||
var point = ray.GetPoint(length); // - CollisionBuffer);
|
||||
|
||||
return point;
|
||||
}
|
||||
@@ -811,6 +803,7 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
angle = MaxAngle;
|
||||
return Vector3.RotateTowards(Vector3.down, Forward, Mathf.Deg2Rad * MaxAngle, 0f);
|
||||
}
|
||||
|
||||
return Forward;
|
||||
}
|
||||
|
||||
@@ -995,10 +988,42 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
protected virtual void OnBeforeDashTeleport()
|
||||
{
|
||||
var leftGrabbable = LeftHand.GrabbedTarget;
|
||||
var rightGrabbable = RightHand.GrabbedTarget;
|
||||
|
||||
_leftVel = LeftHand.Rigidbody.velocity;
|
||||
_rightVel = RightHand.Rigidbody.velocity;
|
||||
|
||||
_leftHeldVel = Vector3.zero;
|
||||
_rightHeldVel = Vector3.zero;
|
||||
|
||||
var lrb = leftGrabbable ? leftGrabbable.Rigidbody : null;
|
||||
var rrb = rightGrabbable ? rightGrabbable.Rigidbody : null;
|
||||
|
||||
if (lrb) _leftHeldVel = lrb.velocity;
|
||||
if (rrb) _rightHeldVel = rrb.velocity;
|
||||
|
||||
//execute last, hand will disable itself in it's event handler
|
||||
BeforeDashTeleport.Invoke(FeetPosition);
|
||||
}
|
||||
|
||||
protected virtual void OnAfterDashTeleport()
|
||||
{
|
||||
//execute first, hand will enable itself in it's event handler
|
||||
AfterDashTeleport.Invoke(FeetPosition);
|
||||
|
||||
|
||||
//restore velocity from before dash
|
||||
var leftGrabbable = LeftHand.GrabbedTarget;
|
||||
var rightGrabbable = RightHand.GrabbedTarget;
|
||||
|
||||
var lrb = leftGrabbable ? leftGrabbable.Rigidbody : null;
|
||||
var rrb = rightGrabbable ? rightGrabbable.Rigidbody : null;
|
||||
|
||||
LeftHand.Rigidbody.velocity = _leftVel;
|
||||
RightHand.Rigidbody.velocity = _rightVel;
|
||||
if (lrb) lrb.velocity = _leftHeldVel;
|
||||
if (rrb && rrb != lrb) rrb.velocity = _rightHeldVel;
|
||||
}
|
||||
|
||||
protected virtual void OnBeforeTeleport()
|
||||
@@ -1021,20 +1046,24 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
if (RightHand) RightHand.BreakDistanceCooldown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantly teleports the player to the desired position
|
||||
/// </summary>
|
||||
public virtual bool Teleport(Vector3 position)
|
||||
{
|
||||
if (IsTeleporting)
|
||||
return false;
|
||||
|
||||
OnBeforeTeleport();
|
||||
TeleportState = TeleportState.Teleporting;
|
||||
TeleportDestination = position;
|
||||
Teleport(position, Vector3.zero, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Teleport(Vector3 position, Vector3 direction)
|
||||
/// <summary>
|
||||
/// Optionally rotate the player to the desired direction, and then instantly teleports the player to the desired position
|
||||
/// </summary>
|
||||
public virtual void Teleport(Vector3 position, Vector3 direction, bool faceDirection = true)
|
||||
{
|
||||
if (!Teleport(position))
|
||||
if (IsTeleporting)
|
||||
return;
|
||||
|
||||
if (!Player) return;
|
||||
@@ -1050,40 +1079,80 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
//snapshot relative values and then reapply after rotating the player
|
||||
|
||||
var leftGrabbable = LeftHand.GrabbedTarget;
|
||||
var rightGrabbable = RightHand.GrabbedTarget;
|
||||
|
||||
if (LeftHand)
|
||||
{
|
||||
Player.GetRelativeValues(LeftHand, out leftPos, out leftRot);
|
||||
if (LeftHand.GrabbedTarget)
|
||||
LeftHand.GetRelativesTo(Player, out leftPos, out leftRot);
|
||||
if (leftGrabbable)
|
||||
{
|
||||
LeftHand.GetRelativeValues(LeftHand.GrabbedTarget, out leftGrabPos, out leftGrabRot);
|
||||
leftGrabbable.MainTransform.GetRelativesTo(LeftHand, out leftGrabPos, out leftGrabRot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (RightHand)
|
||||
{
|
||||
Player.GetRelativeValues(RightHand, out rightPos, out rightRot);
|
||||
if (RightHand.GrabbedTarget) RightHand.GetRelativeValues(RightHand.GrabbedTarget, out rightGrabPos, out rightGrabRot);
|
||||
RightHand.GetRelativesTo(Player, out rightPos, out rightRot);
|
||||
if (rightGrabbable)
|
||||
{
|
||||
rightGrabbable.MainTransform.GetRelativesTo(RightHand, out rightGrabPos, out rightGrabRot);
|
||||
}
|
||||
}
|
||||
|
||||
Player.FaceDirection(direction);
|
||||
var lv = LeftHand.Rigidbody.velocity;
|
||||
var rv = RightHand.Rigidbody.velocity;
|
||||
|
||||
var leftObjV = Vector3.zero;
|
||||
var rightObjV = Vector3.zero;
|
||||
|
||||
var lrb = leftGrabbable ? leftGrabbable.Rigidbody : null;
|
||||
var rrb = rightGrabbable ? rightGrabbable.Rigidbody : null;
|
||||
|
||||
if (lrb) leftObjV = lrb.velocity;
|
||||
if (rrb) rightObjV = rrb.velocity;
|
||||
|
||||
BeforeTeleport.Invoke(FeetPosition);
|
||||
|
||||
var before = Player.transform.rotation;
|
||||
if (faceDirection)
|
||||
Player.FaceDirection(direction);
|
||||
var rot = Player.transform.rotation * Quaternion.Inverse(before);
|
||||
|
||||
lv = rot * lv;
|
||||
rv = rot * rv;
|
||||
|
||||
leftObjV = rot * leftObjV;
|
||||
rightObjV = rot * rightObjV;
|
||||
|
||||
if (LeftHand)
|
||||
{
|
||||
LeftHand.transform.SetPositionAndRotation(Player.transform.TransformPoint(leftPos), Player.transform.rotation * leftRot);
|
||||
if (LeftHand.GrabbedTarget)
|
||||
if (leftGrabbable)
|
||||
{
|
||||
LeftHand.GrabbedTarget.transform.SetPositionAndRotation(LeftHand.transform.TransformPoint(leftGrabPos), LeftHand.transform.rotation * leftGrabRot);
|
||||
leftGrabbable.MainTransform.SetPositionAndRotation(LeftHand.transform.TransformPoint(leftGrabPos), LeftHand.transform.rotation * leftGrabRot);
|
||||
}
|
||||
}
|
||||
|
||||
if (RightHand)
|
||||
{
|
||||
RightHand.transform.SetPositionAndRotation(Player.transform.TransformPoint(rightPos), Player.transform.rotation * rightRot);
|
||||
if (RightHand.GrabbedTarget)
|
||||
if (rightGrabbable)
|
||||
{
|
||||
RightHand.GrabbedTarget.transform.SetPositionAndRotation(RightHand.transform.TransformPoint(rightGrabPos), RightHand.transform.rotation * rightGrabRot);
|
||||
rightGrabbable.MainTransform.SetPositionAndRotation(RightHand.transform.TransformPoint(rightGrabPos), RightHand.transform.rotation * rightGrabRot);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UpdatePlayerPosition(position);
|
||||
PositionUpdate.Invoke(FeetPosition);
|
||||
AfterTeleport.Invoke();
|
||||
|
||||
LeftHand.Rigidbody.velocity = lv;
|
||||
RightHand.Rigidbody.velocity = rv;
|
||||
if (lrb) lrb.velocity = leftObjV;
|
||||
if (rrb && rrb != lrb) rrb.velocity = rightObjV;
|
||||
}
|
||||
|
||||
protected virtual Vector3 FeetPosition => CharacterController.transform.position;
|
||||
@@ -1099,7 +1168,8 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
UpdatePlayerPosition(TeleportDestination);
|
||||
PositionUpdate.Invoke(FeetPosition);
|
||||
TeleportState = TeleportState.AwaitingNextFrame;
|
||||
OnAfterTeleport();
|
||||
OnAfterDashTeleport();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1107,7 +1177,6 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
{
|
||||
UpdatePlayerPosition(TeleportDestination);
|
||||
PositionUpdate.Invoke(FeetPosition);
|
||||
TeleportState = TeleportState.AwaitingNextFrame;
|
||||
}
|
||||
|
||||
protected virtual void RightHandReleased(HVRGrabberBase arg0, HVRGrabbable grabbable)
|
||||
@@ -1145,20 +1214,19 @@ namespace HurricaneVR.Framework.Core.Player
|
||||
|
||||
public enum HVRTeleportCurve
|
||||
{
|
||||
Ballistic, Bezier
|
||||
Ballistic,
|
||||
Bezier
|
||||
}
|
||||
|
||||
public enum TeleportState
|
||||
{
|
||||
None,
|
||||
Teleporting,
|
||||
Dashing,
|
||||
AwaitingNextFrame
|
||||
Dashing
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TeleportPositionUpdate : UnityEvent<Vector3>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -100,9 +100,9 @@ namespace HurricaneVR.Framework.Core.ScriptableObjects
|
||||
{
|
||||
mass = joint.connectedBody.mass;
|
||||
}
|
||||
else
|
||||
else if(joint.gameObject.TryGetComponent(out Rigidbody rb))
|
||||
{
|
||||
mass = joint.gameObject.GetComponent<Rigidbody>().mass;
|
||||
mass = rb.mass;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.ScriptableObjects
|
||||
{
|
||||
[CreateAssetMenu(menuName = "HurricaneVR/Hand Strength", fileName = "HandStrength")]
|
||||
public class PDStrength : ScriptableObject
|
||||
{
|
||||
public JointApply Mode = JointApply.PositionAndRotation;
|
||||
|
||||
//[Header("Force")]
|
||||
public float Spring = 3000f;
|
||||
public float Damper = 300f;
|
||||
public float MaxForce = 300f;
|
||||
|
||||
//[Header("Torque")]
|
||||
public float TorqueSpring = 500f;
|
||||
public float TorqueDamper = 50f;
|
||||
public float MaxTorque = 75f;
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 595f9e32dd154ba28dcd9b9fb86e85eb
|
||||
timeCreated: 1666138458
|
||||
+22
-5
@@ -5,6 +5,9 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
/// <summary>
|
||||
/// Groups sockets together for inventory like querying
|
||||
/// </summary>
|
||||
public class HVRSocketContainer : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Adds all sockets found on or below this object.")]
|
||||
@@ -19,11 +22,9 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
Sockets = GetComponentsInChildren<HVRSocket>().ToList();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any socket in the container is not currently holding an object
|
||||
/// </summary>
|
||||
public virtual bool HasAvailableSocket()
|
||||
{
|
||||
for (var i = 0; i < Sockets.Count; i++)
|
||||
@@ -35,11 +36,22 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any socket in the container is free and is able to socket this grabbable based on the socket filter applied
|
||||
/// </summary>
|
||||
/// <param name="grabbable"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool HasAvailableSocket(HVRGrabbable grabbable)
|
||||
{
|
||||
return TryFindAvailableSocket(grabbable, out var socket);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if any socket in the container is free and able to socket the provided grabbable based on the filter applied.
|
||||
/// </summary>
|
||||
/// <param name="grabbable">Grabbable to check the filter for</param>
|
||||
/// <param name="socket">Resulting free socket, null if none found</param>
|
||||
/// <returns></returns>
|
||||
public virtual bool TryFindAvailableSocket(HVRGrabbable grabbable, out HVRSocket socket)
|
||||
{
|
||||
socket = Sockets.FirstOrDefault(e => !e.IsGrabbing && e.IsValid(grabbable));
|
||||
@@ -48,6 +60,11 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sockets the grabbable to the first found free socket if any are available, returns true if it succeeded
|
||||
/// </summary>
|
||||
/// <param name="grabbable"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool TryAddGrabbable(HVRGrabbable grabbable)
|
||||
{
|
||||
if (TryFindAvailableSocket(grabbable, out var socket))
|
||||
|
||||
@@ -11,5 +11,10 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
/// Return true if the HVRSocketable is allowed in the socket this filter is attached to.
|
||||
/// </summary>
|
||||
public abstract bool IsValid(HVRSocketable socketable);
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,46 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using HurricaneVR.Framework.Shared;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
[RequireComponent(typeof(HVRGrabbable))]
|
||||
public class HVRSocketable : MonoBehaviour
|
||||
{
|
||||
public HVRGrabbable Grabbable { get; private set; }
|
||||
public Transform SocketOrientation;
|
||||
public float SocketScale = 1f;
|
||||
|
||||
[Tooltip("Stores relative position and rotation information for any socket type.")]
|
||||
public List<SocketPose> Poses = new List<SocketPose>();
|
||||
|
||||
[Tooltip("If your grabbable model is not at 1,1,1 scale. ")]
|
||||
public Vector3 CounterScale = Vector3.one;
|
||||
|
||||
[Header("Scaling")] [Tooltip("If true the the renderer bounds at the time of socketing will be used to scale the object in a socket that has scaling enabled.")]
|
||||
public bool UseRendererBounds = true;
|
||||
|
||||
[Tooltip("If greater than 0 and UseRendererBounds is disabled, the size used when computing socket scale when socketing into a socket with scale enabled.")]
|
||||
public float ScaleSize = 0f;
|
||||
|
||||
[Tooltip("Socket scale factor applied after socketing.")]
|
||||
public float SocketScale = 1f;
|
||||
|
||||
[Tooltip("Override renderer bounds when socket is scaling")]
|
||||
public BoxCollider ScaleOverride;
|
||||
|
||||
public AudioClip SocketedClip;
|
||||
|
||||
[Header("SFX")] public AudioClip SocketedClip;
|
||||
public AudioClip UnsocketedClip;
|
||||
|
||||
[Tooltip("If populated this object cannot be socketed if any of these objects are held.")]
|
||||
public HVRGrabbable[] LinkedGrabbables;
|
||||
|
||||
|
||||
[Header("Deprecated")]
|
||||
public Transform SocketOrientation;
|
||||
|
||||
public bool AnyLinkedGrabbablesHeld
|
||||
{
|
||||
get
|
||||
@@ -40,9 +61,115 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
private Dictionary<int, SocketPose> _poseCache = new Dictionary<int, SocketPose>();
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
Grabbable = GetComponent<HVRGrabbable>();
|
||||
|
||||
InitializePoses();
|
||||
}
|
||||
|
||||
public void InitializePoses()
|
||||
{
|
||||
foreach (var pose in Poses)
|
||||
{
|
||||
pose.Init();
|
||||
}
|
||||
|
||||
_poseCache = Poses.Where(e => !string.IsNullOrWhiteSpace(e.SocketTag))
|
||||
.GroupBy(e=>e.Hash)
|
||||
.ToDictionary(e => e.Key, e => e.First());
|
||||
}
|
||||
|
||||
public virtual float GetSocketScaleSize(HVRSocket socket)
|
||||
{
|
||||
Vector3 size;
|
||||
|
||||
if (ScaleOverride)
|
||||
{
|
||||
size = ScaleOverride.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!UseRendererBounds && ScaleSize > 0f)
|
||||
{
|
||||
return ScaleSize;
|
||||
}
|
||||
|
||||
//making sure the AABB is aligned the same every time before pulling the renderer bounds
|
||||
|
||||
var rot = transform.rotation;
|
||||
|
||||
transform.rotation = Quaternion.identity;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Grabbable)
|
||||
{
|
||||
Grabbable = GetComponent<HVRGrabbable>();
|
||||
}
|
||||
#endif
|
||||
|
||||
size = Grabbable.ModelBounds.size;
|
||||
|
||||
transform.rotation = rot;
|
||||
}
|
||||
|
||||
var axis = size.x;
|
||||
|
||||
if (size.y > axis) axis = size.y;
|
||||
if (size.z > axis) axis = size.z;
|
||||
|
||||
return axis;
|
||||
}
|
||||
|
||||
public virtual Vector3 GetPositionOffset(HVRSocket socket)
|
||||
{
|
||||
if (socket.PoseHash.HasValue && _poseCache.TryGetValue(socket.PoseHash.Value, out var pose))
|
||||
{
|
||||
return pose.Position;
|
||||
}
|
||||
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
public virtual Quaternion GetRotationOffset(HVRSocket socket)
|
||||
{
|
||||
if (socket.PoseHash.HasValue && _poseCache.TryGetValue(socket.PoseHash.Value, out var pose))
|
||||
{
|
||||
return pose.Rotation;
|
||||
}
|
||||
|
||||
return Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class SocketPose
|
||||
{
|
||||
public string SocketTag;
|
||||
public Vector3 Position;
|
||||
public Vector3 EulerAngles;
|
||||
|
||||
private Quaternion? _rotation;
|
||||
|
||||
public Quaternion Rotation
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_rotation.HasValue)
|
||||
_rotation = Quaternion.Euler(EulerAngles);
|
||||
return _rotation.Value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int Hash { get; private set; }
|
||||
|
||||
public void Init()
|
||||
{
|
||||
if (SocketTag != null)
|
||||
Hash = Animator.StringToHash(SocketTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,27 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
[SerializeField] private string[] _socketables = new string[32];
|
||||
|
||||
[Tooltip("Needed to identify this tag file when using addressables. Will populate with the SO name if not provided.")]
|
||||
public string Identifier;
|
||||
|
||||
public int Hash { get; set; }
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Identifier))
|
||||
{
|
||||
Identifier = name;
|
||||
}
|
||||
|
||||
Hash = Animator.StringToHash(Identifier);
|
||||
}
|
||||
|
||||
public virtual bool MatchesTags(HVRSocketableTags other)
|
||||
{
|
||||
return other.Hash == Hash;
|
||||
}
|
||||
|
||||
|
||||
public string this[int index]
|
||||
{
|
||||
get { return _socketables[index]; }
|
||||
|
||||
+27
-7
@@ -1,17 +1,37 @@
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
public class HVRStringSocketFilter : HVRSocketFilter
|
||||
{
|
||||
[Tooltip("Lower cased and trimmed prior to hashing.")]
|
||||
public string SocketType;
|
||||
|
||||
public int? Hash { get; private set; }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
ResetHash();
|
||||
}
|
||||
|
||||
public void ResetHash()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(SocketType))
|
||||
{
|
||||
SocketType = SocketType.Trim();
|
||||
Hash = Animator.StringToHash(SocketType.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsValid(HVRSocketable socketable)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(SocketType)) return false;
|
||||
if (!socketable) return false;
|
||||
var stringFilter = socketable as HVRStringSocketable;
|
||||
if (stringFilter == null) return false;
|
||||
if (string.IsNullOrWhiteSpace(stringFilter.SocketType)) return false;
|
||||
return SocketType.ToLowerInvariant().Equals(stringFilter.SocketType.ToLowerInvariant());
|
||||
if (!Hash.HasValue || !socketable)
|
||||
return false;
|
||||
var stringSocketable = socketable as HVRStringSocketable;
|
||||
if (!stringSocketable || !stringSocketable.Hash.HasValue)
|
||||
return false;
|
||||
return Hash.Value == stringSocketable.Hash.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-1
@@ -1,7 +1,27 @@
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
public class HVRStringSocketable : HVRSocketable
|
||||
{
|
||||
[Tooltip("Lower cased and trimmed prior to hashing.")]
|
||||
public string SocketType;
|
||||
|
||||
public int? Hash { get; private set; }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
ResetHash();
|
||||
}
|
||||
|
||||
public void ResetHash()
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(SocketType))
|
||||
{
|
||||
SocketType = SocketType.Trim();
|
||||
Hash = Animator.StringToHash(SocketType.ToLowerInvariant());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -7,10 +7,10 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
public HVRSocketableTag Tags;
|
||||
|
||||
|
||||
[Tooltip("If true, the socketable is valid as long as a there is a single match, otherwise all selected tags must be assigned on the socketable.")]
|
||||
public bool Any = true;
|
||||
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (Tags == null)
|
||||
@@ -31,12 +31,12 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
var tagSocketable = socketable as HVRTagSocketable;
|
||||
|
||||
if (tagSocketable == null || tagSocketable.Tags == null)
|
||||
if (!tagSocketable || tagSocketable.Tags == null)
|
||||
return false;
|
||||
|
||||
var socketableTags = tagSocketable.Tags;
|
||||
|
||||
if (socketableTags.Tags != Tags.Tags)
|
||||
if (!socketableTags.Tags.MatchesTags(Tags.Tags))
|
||||
return false;
|
||||
|
||||
var anyHit = false;
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using HurricaneVR.Framework.Shared;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Sockets
|
||||
{
|
||||
public class HVRTagSocketable : HVRSocketable
|
||||
{
|
||||
[Header("Socketable Tags")]
|
||||
public HVRSocketableTag Tags;
|
||||
|
||||
|
||||
@@ -18,9 +20,8 @@ namespace HurricaneVR.Framework.Core.Sockets
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
|
||||
#endif
|
||||
Tags.Tags = HVRSettings.Instance.DefaultSocketableTags;
|
||||
}
|
||||
|
||||
Tags.Tags = HVRSettings.Instance.DefaultSocketableTags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,45 +15,28 @@ namespace HurricaneVR.Framework.Core.UI
|
||||
public Camera Camera { get; private set; }
|
||||
public LineRenderer Pointer { get; private set; }
|
||||
|
||||
public float offsetPointerHit;
|
||||
public GameObject PointerHit;
|
||||
|
||||
public PointerEventData PointerEventData { get; internal set; }
|
||||
|
||||
public HVRController Controller => HVRInputManager.Instance.GetController(HandSide);
|
||||
public GameObject CurrentUIElement;// { get; internal set; }
|
||||
|
||||
private void Start()
|
||||
protected virtual void Start()
|
||||
{
|
||||
Camera = GetComponent<Camera>();
|
||||
Pointer = GetComponent<LineRenderer>();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
protected virtual void Update()
|
||||
{
|
||||
Pointer.enabled = CurrentUIElement;
|
||||
if (Pointer.enabled)
|
||||
{
|
||||
Pointer.SetPosition(0, transform.position);
|
||||
Pointer.SetPosition(1, PointerEventData.pointerCurrentRaycast.worldPosition);
|
||||
if(PointerHit)
|
||||
{
|
||||
var forward = PointerEventData.pointerCurrentRaycast.worldNormal;
|
||||
forward *= offsetPointerHit;
|
||||
|
||||
PointerHit.transform.position = PointerEventData.pointerCurrentRaycast.worldPosition + forward;
|
||||
PointerHit.transform.rotation = PointerEventData.pointerCurrentRaycast.gameObject.transform.rotation;
|
||||
Debug.DrawRay(PointerHit.transform.position, PointerEventData.pointerCurrentRaycast.worldNormal, Color.red);
|
||||
Debug.DrawRay(PointerHit.transform.position, CurrentUIElement.transform.forward, Color.yellow);
|
||||
}
|
||||
}
|
||||
if(PointerHit)
|
||||
{
|
||||
PointerHit.SetActive(Pointer.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Process()
|
||||
public virtual void Process()
|
||||
{
|
||||
PointerEventData.Reset();
|
||||
PointerEventData.position = new Vector2(Camera.pixelWidth / 2, Camera.pixelHeight / 2);
|
||||
|
||||
@@ -40,11 +40,6 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnCollisionEnter(Collision other)
|
||||
{
|
||||
//Debug.Log($"Impulse: {other.impulse}. Velocity: {other.relativeVelocity}");
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Utils
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
|
||||
public class EmbeddedAttribute : PropertyAttribute
|
||||
{
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 39fe36781abf42198e0f3c98afb72795
|
||||
timeCreated: 1666155343
|
||||
@@ -84,6 +84,19 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
yield return new WaitForSeconds(timeout);
|
||||
transform.SetLayerRecursive(layer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locates a component by checking the collider first, then the collider's rigidbody, then finally uses GetComponentInParent.
|
||||
/// </summary>
|
||||
public static T FindComponent<T>(this Collider collider, bool tryParent = true) where T : Component
|
||||
{
|
||||
if (collider.TryGetComponent(out T c) || collider.attachedRigidbody && collider.attachedRigidbody.TryGetComponent(out c))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
return tryParent ? collider.GetComponentInParent<T>() : default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,24 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
joint.highAngularXLimit = ll;
|
||||
}
|
||||
|
||||
public static void SetAngularYLimit(this ConfigurableJoint joint, float limit, float bounciness = 0f, float contactDistance = 0f)
|
||||
{
|
||||
joint.angularYLimit = new SoftJointLimit() { bounciness = bounciness, contactDistance = contactDistance, limit = limit };
|
||||
}
|
||||
|
||||
public static void SetAngularZLimit(this ConfigurableJoint joint, float limit, float bounciness = 0f, float contactDistance = 0f)
|
||||
{
|
||||
joint.angularZLimit = new SoftJointLimit() { bounciness = bounciness, contactDistance = contactDistance, limit = limit };
|
||||
}
|
||||
|
||||
public static void SetAngularLimits(this ConfigurableJoint joint, float xLow, float xHigh, float y, float z)
|
||||
{
|
||||
joint.SetAngularXLowLimit(xLow);
|
||||
joint.SetAngularXHighLimit(xHigh);
|
||||
joint.SetAngularYLimit(y);
|
||||
joint.SetAngularZLimit(z);
|
||||
}
|
||||
|
||||
public static void LimitXMotion(this ConfigurableJoint joint)
|
||||
{
|
||||
joint.xMotion = ConfigurableJointMotion.Limited;
|
||||
@@ -63,6 +81,18 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
joint.zMotion = ConfigurableJointMotion.Limited;
|
||||
}
|
||||
|
||||
public static void FreeLinearMotion(this ConfigurableJoint joint)
|
||||
{
|
||||
joint.xMotion = joint.yMotion = joint.zMotion = ConfigurableJointMotion.Free;
|
||||
}
|
||||
|
||||
public static void LimitLinearMotion(this ConfigurableJoint joint)
|
||||
{
|
||||
joint.LimitXMotion();
|
||||
joint.LimitYMotion();
|
||||
joint.LimitZMotion();
|
||||
}
|
||||
|
||||
public static void LockLinearMotion(this ConfigurableJoint joint)
|
||||
{
|
||||
joint.LockXMotion();
|
||||
@@ -70,6 +100,13 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
joint.LockZMotion();
|
||||
}
|
||||
|
||||
public static void LimitAngularMotion(this ConfigurableJoint joint)
|
||||
{
|
||||
joint.LimitAngularXMotion();
|
||||
joint.LimitAngularYMotion();
|
||||
joint.LimitAngularZMotion();
|
||||
}
|
||||
|
||||
public static void LimitAngularXMotion(this ConfigurableJoint joint)
|
||||
{
|
||||
joint.angularXMotion = ConfigurableJointMotion.Limited;
|
||||
|
||||
+13
-3
@@ -3,23 +3,33 @@ using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Utils
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Specialized shoulder inventory collector that will check the hand's velocity to prevent grabbing when we feel like the player is throwing something
|
||||
/// </summary>
|
||||
public class HVRShoulderGrabber : HVRSocketContainerGrabber
|
||||
{
|
||||
public float VelocityCutoff = 2f;
|
||||
|
||||
public override bool CanHover(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!base.CanHover(grabbable))
|
||||
return false;
|
||||
|
||||
var handGrabber = grabbable.PrimaryGrabber as HVRHandGrabber;
|
||||
if (handGrabber == null)
|
||||
if (!handGrabber)
|
||||
return false;
|
||||
|
||||
//if a forward throw is happening don't grab it
|
||||
var velocity = handGrabber.ComputeThrowVelocity(grabbable, out var dummy);
|
||||
var velocity = handGrabber.ComputeThrowVelocity(grabbable, out var dummy, true);
|
||||
velocity.y = transform.position.y;
|
||||
if (Vector3.Dot(velocity.normalized, transform.forward) > 0f)
|
||||
var dot = Vector3.Dot(transform.forward, velocity);
|
||||
if (dot > VelocityCutoff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,20 +5,25 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
{
|
||||
public class HVRShoulderSocket : HVRSocket
|
||||
{
|
||||
public float VelocityCutoff = 2f;
|
||||
|
||||
public override bool CanHover(HVRGrabbable grabbable)
|
||||
{
|
||||
if (!base.CanHover(grabbable))
|
||||
return false;
|
||||
|
||||
var handGrabber = grabbable.PrimaryGrabber as HVRHandGrabber;
|
||||
if (handGrabber == null)
|
||||
if (!handGrabber)
|
||||
return false;
|
||||
|
||||
//if a forward throw is happening don't grab it
|
||||
var velocity = handGrabber.ComputeThrowVelocity(grabbable, out var dummy);
|
||||
var velocity = handGrabber.ComputeThrowVelocity(grabbable, out var dummy, true);
|
||||
velocity.y = transform.position.y;
|
||||
if (Vector3.Dot(velocity.normalized, transform.forward) > 0f)
|
||||
var dot = Vector3.Dot(transform.forward, velocity);
|
||||
if (dot > VelocityCutoff)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -228,14 +228,17 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
var elapsed = 0f;
|
||||
while (elapsed < TimeToSlow)
|
||||
{
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
Time.timeScale = Mathf.Lerp(1f, scale, elapsed / TimeToSlow);
|
||||
Time.fixedDeltaTime = 1f / RefreshRate * Time.timeScale;
|
||||
if (SmoothFixedTimeStep)
|
||||
ResetBuffer();
|
||||
yield return null;
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
}
|
||||
|
||||
Time.timeScale = scale;
|
||||
Time.fixedDeltaTime = 1f / RefreshRate * Time.timeScale;
|
||||
|
||||
_slowRoutine = null;
|
||||
}
|
||||
|
||||
@@ -245,14 +248,16 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
var start = Time.timeScale;
|
||||
while (elapsed < TimeToSlow)
|
||||
{
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
Time.timeScale = Mathf.Lerp(start, 1f, elapsed / TimeToResume);
|
||||
Time.fixedDeltaTime = 1f / RefreshRate * Time.timeScale;
|
||||
if (SmoothFixedTimeStep)
|
||||
ResetBuffer();
|
||||
yield return null;
|
||||
elapsed += Time.unscaledDeltaTime;
|
||||
}
|
||||
|
||||
Time.timeScale = 1f;
|
||||
Time.fixedDeltaTime = 1f / RefreshRate;
|
||||
_resetRoutine = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HurricaneVR.Framework.Shared;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace HurricaneVR.Framework.Core.Utils
|
||||
{
|
||||
@@ -142,11 +144,16 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
public static Bounds GetColliderBounds(this Collider[] colliders)
|
||||
{
|
||||
var bounds = new Bounds();
|
||||
var first = true;
|
||||
for (var i = 0; i < colliders.Length; i++)
|
||||
{
|
||||
var collider = colliders[i];
|
||||
if (i == 0)
|
||||
|
||||
if (!collider.enabled) continue;
|
||||
|
||||
if (first)
|
||||
{
|
||||
first = false;
|
||||
bounds = collider.bounds;
|
||||
}
|
||||
else
|
||||
@@ -256,11 +263,12 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
|
||||
public static T EnsureComponent<T>(this GameObject obj) where T : UnityEngine.Component
|
||||
{
|
||||
var temp = obj.GetComponent<T>();
|
||||
if (temp)
|
||||
return temp;
|
||||
if (!obj.TryGetComponent(out T component))
|
||||
{
|
||||
component = obj.AddComponent<T>();
|
||||
}
|
||||
|
||||
return obj.AddComponent<T>();
|
||||
return component;
|
||||
}
|
||||
|
||||
public static T EnsureComponent<T>(this Transform t) where T : UnityEngine.Component
|
||||
@@ -338,7 +346,7 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
/// <summary>
|
||||
/// return the position and rotation of target relative to relativeTo
|
||||
/// </summary>
|
||||
public static void GetRelativeValues(this Transform relativeTo, Transform target, out Vector3 pos, out Quaternion rot)
|
||||
public static void GetRelativesTo(this Transform target, Transform relativeTo, out Vector3 pos, out Quaternion rot)
|
||||
{
|
||||
pos = relativeTo.InverseTransformPoint(target.position);
|
||||
rot = Quaternion.Inverse(relativeTo.rotation) * target.rotation;
|
||||
@@ -347,20 +355,20 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
/// <summary>
|
||||
/// return the position and rotation of target relative to relativeTo
|
||||
/// </summary>
|
||||
public static void GetRelativeValues(this Component relativeTo, Transform target, out Vector3 pos, out Quaternion rot)
|
||||
public static void GetRelativesTo(this Component target, Transform relativeTo, out Vector3 pos, out Quaternion rot)
|
||||
{
|
||||
pos = Vector3.zero;
|
||||
rot = Quaternion.identity;
|
||||
if (!relativeTo || !target) return;
|
||||
|
||||
pos = relativeTo.transform.InverseTransformPoint(target.position);
|
||||
pos = relativeTo.transform.InverseTransformPoint(target.transform.position);
|
||||
rot = Quaternion.Inverse(relativeTo.transform.rotation) * target.transform.rotation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return the position and rotation of target relative to relativeTo
|
||||
/// </summary>
|
||||
public static void GetRelativeValues(this Component relativeTo, Component target, out Vector3 pos, out Quaternion rot)
|
||||
public static void GetRelativesTo(this Component target, Component relativeTo, out Vector3 pos, out Quaternion rot)
|
||||
{
|
||||
pos = Vector3.zero;
|
||||
rot = Quaternion.identity;
|
||||
@@ -398,5 +406,12 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
{
|
||||
return float.IsNaN(v.x) || float.IsNaN(v.y) || float.IsNaN(v.z) || float.IsInfinity(v.x) || float.IsInfinity(v.y) || float.IsInfinity(v.z);
|
||||
}
|
||||
|
||||
public static List<string> SplitClean(this string s, char separator)
|
||||
{
|
||||
return s.Split(new[] {separator}, StringSplitOptions.RemoveEmptyEntries).Select(e => e.Trim()).Where(e => !e.IsNullOrWhiteSpace()).ToList();
|
||||
}
|
||||
|
||||
public static bool IsNullOrWhiteSpace(this string s) => string.IsNullOrWhiteSpace(s);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using FMODUnity;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
@@ -15,7 +14,21 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
|
||||
static SFXPlayer s_Instance;
|
||||
public static SFXPlayer Instance => s_Instance;
|
||||
|
||||
static int id;
|
||||
public AudioSource SFXReferenceSource;
|
||||
public int SFXSourceCount;
|
||||
|
||||
[Tooltip("Changes object name to the clip. This will create garbage.")]
|
||||
public bool SetClipName;
|
||||
|
||||
Dictionary<Guid, PlayEvent> m_PlayEvents = new Dictionary<Guid, PlayEvent>();
|
||||
List<int> m_PlayingSources = new List<int>();
|
||||
|
||||
AudioSource[] m_SFXSourcePool;
|
||||
|
||||
int m_UsedSource = 0;
|
||||
private List<Guid> IDToRemove = new List<Guid>();
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (s_Instance != null)
|
||||
@@ -25,26 +38,103 @@ namespace HurricaneVR.Framework.Core.Utils
|
||||
}
|
||||
|
||||
s_Instance = this;
|
||||
|
||||
m_SFXSourcePool = new AudioSource[SFXSourceCount];
|
||||
|
||||
for (int i = 0; i < SFXSourceCount; ++i)
|
||||
{
|
||||
m_SFXSourcePool[i] = Instantiate(SFXReferenceSource, transform);
|
||||
m_SFXSourcePool[i].gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
foreach (var playEvent in m_PlayEvents)
|
||||
{
|
||||
playEvent.Value.Time -= Time.deltaTime;
|
||||
|
||||
if (playEvent.Value.Time <= 0.0f)
|
||||
IDToRemove.Add(playEvent.Key);
|
||||
}
|
||||
|
||||
foreach (var id in IDToRemove)
|
||||
{
|
||||
m_PlayEvents.Remove(id);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_PlayingSources.Count; ++i)
|
||||
{
|
||||
int id = m_PlayingSources[i];
|
||||
|
||||
if (!m_SFXSourcePool[id].isPlaying)
|
||||
{
|
||||
m_SFXSourcePool[id].gameObject.SetActive(false);
|
||||
m_PlayingSources.RemoveAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
IDToRemove.Clear();
|
||||
}
|
||||
|
||||
public AudioSource GetNewSource()
|
||||
{
|
||||
return Instantiate(SFXReferenceSource);
|
||||
}
|
||||
|
||||
public void PlaySFXRandomPitch(AudioClip clip, Vector3 position, float min, float max)
|
||||
{
|
||||
PlaySFX(clip, position, Random.Range(min, max), 1f);
|
||||
}
|
||||
|
||||
|
||||
public void PlaySFXCooldown(AudioClip clip, Vector3 position, Guid sourceId, float pitch = 1f, float volume = 1f, float cooldownTime = 0.5f)
|
||||
{
|
||||
if (clip == null)
|
||||
return;
|
||||
|
||||
//can't play this sound again as the previous one with the same source was too early
|
||||
if (m_PlayEvents.ContainsKey(sourceId))
|
||||
return;
|
||||
|
||||
PlaySFX(clip, position, pitch, volume);
|
||||
|
||||
m_PlayEvents.Add(sourceId, new PlayEvent() { Time = cooldownTime });
|
||||
}
|
||||
|
||||
public void PlaySFX(AudioClip clip, Vector3 position)
|
||||
{
|
||||
|
||||
PlaySFX(clip, position, 1f, 1f);
|
||||
}
|
||||
|
||||
public void PlaySFX(AudioClip clip, Vector3 position, float pitch, float volume)
|
||||
{
|
||||
if (clip == null)
|
||||
return;
|
||||
|
||||
}
|
||||
var audioSource = m_SFXSourcePool[m_UsedSource];
|
||||
|
||||
public void PlaySFX(EventReference refClip, Vector3 position)
|
||||
{
|
||||
RuntimeManager.PlayOneShot(refClip.Guid, position);
|
||||
if (!audioSource)
|
||||
return;
|
||||
|
||||
m_PlayingSources.Add(m_UsedSource);
|
||||
|
||||
m_UsedSource = m_UsedSource + 1;
|
||||
if (m_UsedSource >= m_SFXSourcePool.Length) m_UsedSource = 0;
|
||||
|
||||
if (SetClipName && Application.isEditor)
|
||||
{
|
||||
audioSource.name = clip.name;
|
||||
}
|
||||
|
||||
audioSource.gameObject.SetActive(true);
|
||||
audioSource.transform.position = position;
|
||||
audioSource.clip = clip;
|
||||
|
||||
audioSource.volume = volume;
|
||||
audioSource.pitch = pitch;
|
||||
audioSource.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"name": "HurricaneVR.Framework",
|
||||
"rootNamespace": "Zero",
|
||||
"references": [
|
||||
"Hurricane.Shared",
|
||||
"UnityEngine.SpatialTracking",
|
||||
@@ -10,8 +9,7 @@
|
||||
"Unity.XR.OpenVR",
|
||||
"Unity.XR.OpenXR",
|
||||
"Oculus.VR",
|
||||
"SteamVR_Actions",
|
||||
"FMODUnity"
|
||||
"SteamVR_Actions"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using HurricaneVR.Framework.ControllerInput;
|
||||
using HurricaneVR.Framework.Core;
|
||||
using HurricaneVR.Framework.Shared.Utilities;
|
||||
using UnityEngine;
|
||||
@@ -199,7 +200,8 @@ namespace HurricaneVR.Framework.Shared
|
||||
SecondaryTouchButtonState.Active,
|
||||
TrackPadTouchState.Active,
|
||||
JoystickTouchState.Active,
|
||||
Knuckles);
|
||||
Knuckles,
|
||||
HVRInputManager.Instance.IsOpenXR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,6 +499,7 @@ namespace HurricaneVR.Framework.Shared
|
||||
Vive,
|
||||
Knuckles,
|
||||
Cosmos,
|
||||
ReverbG2
|
||||
ReverbG2,
|
||||
Pico
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using HurricaneVR.Framework.ControllerInput;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Shared
|
||||
@@ -59,7 +60,7 @@ namespace HurricaneVR.Framework.Shared
|
||||
public float PinkyTotal => JoystickTouchWeight.Pinky + TrackpadTouchWeight.Pinky + PrimaryTouchWeight.Pinky + SecondaryTouchWeight.Pinky +
|
||||
TriggerTouchWeight.Pinky + GripWeight.Pinky + TriggerWeight.Pinky;
|
||||
|
||||
public void Evaluate(float[] curls, float grip, float trigger, bool triggerTouch, bool primaryTouch, bool secondaryTouch, bool trackpadTouch, bool joystickTouch, bool knuckles)
|
||||
public void Evaluate(float[] curls, float grip, float trigger, bool triggerTouch, bool primaryTouch, bool secondaryTouch, bool trackpadTouch, bool joystickTouch, bool knuckles, bool isOpenXR)
|
||||
{
|
||||
var joystick = joystickTouch ? 1f : 0f;
|
||||
var trackPad = trackpadTouch ? 1f : 0f;
|
||||
@@ -83,7 +84,8 @@ namespace HurricaneVR.Framework.Shared
|
||||
GripWeight.Index * grip +
|
||||
TriggerWeight.Index * trigger;
|
||||
|
||||
if (!knuckles || KnucklesOverrideGripFingers)
|
||||
//until openxr has index finger curls supplied (if ever..)
|
||||
if (!knuckles || (KnucklesOverrideGripFingers || isOpenXR))
|
||||
{
|
||||
curls[2] = JoystickTouchWeight.Middle * joystick +
|
||||
TrackpadTouchWeight.Middle * trackPad +
|
||||
|
||||
@@ -22,13 +22,14 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
}
|
||||
}
|
||||
|
||||
private void OnStringGrabbed(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
private void OnStringGrabbed(HVRHandGrabber hand, HVRGrabbable arg1)
|
||||
{
|
||||
if (!bow.ArrowNocked && ArrowPrefab)
|
||||
{
|
||||
var go = Instantiate(ArrowPrefab);
|
||||
var arrow = go.GetComponent<HVRArrow>();
|
||||
bow.NockArrow(arrow);
|
||||
hand.DisableHandCollision(arrow.Grabbable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,13 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
{
|
||||
[Header("Bow String")]
|
||||
public HVRGrabbable NockGrabbable;
|
||||
|
||||
public float StringLimit = .5f;
|
||||
public float StringDropLimit = .6f;
|
||||
|
||||
[Header("Settings")]
|
||||
public HVRBowLimitStyle StringLimitStyle = HVRBowLimitStyle.Limit;
|
||||
|
||||
public float ShootThreshold = .2f;
|
||||
public float Speed = 50f;
|
||||
public AnimationCurve SpeedCurve;
|
||||
@@ -27,7 +29,6 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
|
||||
[Header("Transforms")]
|
||||
|
||||
[Tooltip("Arrow Rest When the bow is held with the left hand.")]
|
||||
public Transform LeftRest;
|
||||
|
||||
@@ -39,6 +40,7 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
[Header("Haptics")]
|
||||
public bool StringHaptics = true;
|
||||
|
||||
public bool BowHandHaptics = true;
|
||||
|
||||
[Tooltip("Number of haptic ticks by percent traveled.")]
|
||||
@@ -61,6 +63,7 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
[Header("SFX")]
|
||||
public AudioClip StringClip;
|
||||
|
||||
public float StringMinPitch = 1f;
|
||||
public float StringMaxPitch = 1.25f;
|
||||
|
||||
@@ -137,8 +140,6 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
@@ -147,7 +148,6 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
protected virtual void UpdateBow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void FixedUpdate()
|
||||
@@ -159,12 +159,10 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
protected virtual void BeforeFixedUpdateBow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void AfterFixedUpdateBow()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void FixedUpdateBow()
|
||||
@@ -272,22 +270,20 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
protected virtual void PlayStringSFX(float nockDistance)
|
||||
{
|
||||
var pitch = nockDistance.Remap(0, StringLimit, StringMinPitch, StringMaxPitch);
|
||||
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(StringClip, NockGrabbable.transform.position, pitch, 1f);
|
||||
if (SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(StringClip, NockGrabbable.transform.position, pitch, 1f);
|
||||
}
|
||||
|
||||
protected virtual void PlayReleasedSFX()
|
||||
{
|
||||
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(ReleasedSFX.GetRandom(), NockGrabbable.transform.position);
|
||||
if (SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(ReleasedSFX.GetRandom(), NockGrabbable.transform.position);
|
||||
}
|
||||
|
||||
protected virtual void OnGrabbed(HVRGrabberBase arg0, HVRGrabbable arg1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnReleased(HVRGrabberBase arg0, HVRGrabbable arg1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void BeforeNockHovered(HVRGrabberBase grabber, HVRGrabbable grabbable)
|
||||
@@ -318,7 +314,7 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
|
||||
var grabbable = arrow.Grabbable;
|
||||
grabbable.ForceRelease();
|
||||
//grabbable.ForceRelease();
|
||||
grabbable.CanBeGrabbed = false;
|
||||
grabbable.Rigidbody.sleepThreshold = 0f;
|
||||
grabbable.Grabbed.AddListener(OnNockedArrowGrabbed);
|
||||
@@ -332,6 +328,7 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
if (NockHand)
|
||||
{
|
||||
NockHand.DisableHandCollision(Arrow.Grabbable);
|
||||
NockHand.TryGrab(NockGrabbable, true);
|
||||
NockHand = null;
|
||||
}
|
||||
@@ -369,17 +366,16 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
{
|
||||
StartCoroutine(EnableBowHandCollisionRoutine(arg0, Arrow.Grabbable));
|
||||
}
|
||||
|
||||
BowHand = null;
|
||||
}
|
||||
|
||||
protected virtual void OnStringReleased(HVRHandGrabber arg0, HVRGrabbable arg1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnStringGrabbed(HVRHandGrabber hand, HVRGrabbable nock)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnBowSocketed(HVRSocket arg0, HVRGrabbable arg1)
|
||||
@@ -392,7 +388,6 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
protected virtual void OnBowUnsocketed(HVRSocket arg0, HVRGrabbable arg1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnArrowDropped()
|
||||
@@ -403,7 +398,6 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
Arrow.Grabbable.CanBeGrabbed = true;
|
||||
|
||||
Arrow = null;
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnArrowRemoved(HVRArrow arrow)
|
||||
@@ -429,10 +423,11 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
{
|
||||
if (!hand || !arrow)
|
||||
yield break;
|
||||
yield return new WaitForSeconds(.25f);
|
||||
yield return new WaitForSeconds(1f);
|
||||
if (BowHand && BowHand == hand || !arrow)
|
||||
yield break;
|
||||
UpdateBowHandCollision(hand, arrow, true);
|
||||
Grabbable.IgnoreCollision(arrow, false);
|
||||
}
|
||||
|
||||
public void OnDrawGizmosSelected()
|
||||
@@ -457,6 +452,5 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
public class HVRBowEvent : UnityEvent<HVRPhysicsBow>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using HurricaneVR.Framework.Core;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Weapons.Bow
|
||||
@@ -18,10 +19,21 @@ namespace HurricaneVR.Framework.Weapons.Bow
|
||||
|
||||
protected override void OnGrabbed(HVRGrabArgs args)
|
||||
{
|
||||
Debug.Log($"nocked");
|
||||
//Debug.Log($"nocked");
|
||||
args.Cancel = true;
|
||||
Grabbed.Invoke(this, args.Grabbable);
|
||||
ForceRelease();
|
||||
//ForceRelease();
|
||||
}
|
||||
|
||||
protected override void OnReleased(HVRGrabbable grabbable)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnHoverEnter(HVRGrabbable grabbable)
|
||||
{
|
||||
if (grabbable.LeftHandGrabber) grabbable.LeftHandGrabber.IgnoreNextCollisionCheck = true;
|
||||
if (grabbable.RightHandGrabber) grabbable.RightHandGrabber.IgnoreNextCollisionCheck = true;
|
||||
base.OnHoverEnter(grabbable);
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
-16
@@ -62,6 +62,10 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
private Transform _grabbedPositionTracker;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The offset of the cocking handle when it's grabbed
|
||||
/// </summary>
|
||||
protected float GrabOffset { get; set; }
|
||||
|
||||
public bool EmptyOpen { get; protected set; }
|
||||
|
||||
@@ -160,27 +164,27 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
return;
|
||||
}
|
||||
|
||||
var pullDirection = (Grabbable.HandGrabbers[0].TrackedController.position - _grabbedPositionTracker.transform.position);
|
||||
var pullDirection = (Grabbable.HandGrabbers[0].TrackedController.position - _grabbedPositionTracker.position);
|
||||
var backDirection = (MaxPositionWorld - ForwardPositionWorld).normalized * 10;
|
||||
var amount = Vector3.Dot(pullDirection, backDirection);
|
||||
var amount = Vector3.Dot(pullDirection, backDirection) * Difficulty;
|
||||
|
||||
if (amount > 0)
|
||||
if (amount + GrabOffset > 0)
|
||||
{
|
||||
UpdatePosition(amount);
|
||||
|
||||
var distance = Vector3.Distance(transform.position, ForwardPositionWorld);
|
||||
|
||||
CheckEject(distance);
|
||||
CheckChamberDistance(distance);
|
||||
ClampPullBack(distance, BackDirectionWorld);
|
||||
MoveBolt();
|
||||
AnimateParts();
|
||||
CheckLock(distance);
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.localPosition = ForwardPosition;
|
||||
}
|
||||
|
||||
var distance = Vector3.Distance(transform.position, ForwardPositionWorld);
|
||||
|
||||
CheckEject(distance);
|
||||
CheckChamberDistance(distance);
|
||||
ClampPullBack(distance, BackDirectionWorld);
|
||||
MoveBolt();
|
||||
AnimateParts();
|
||||
CheckLock(distance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,8 +206,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
|
||||
private void UpdatePosition(float amount)
|
||||
{
|
||||
|
||||
transform.position = ForwardPositionWorld + BackDirectionWorld * (amount * Difficulty);
|
||||
transform.position = ForwardPositionWorld + BackDirectionWorld * (amount + GrabOffset);
|
||||
}
|
||||
|
||||
|
||||
@@ -337,6 +340,8 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
|
||||
protected virtual void OnGrabbed(HVRHandGrabber grabber, HVRGrabbable slide)
|
||||
{
|
||||
GrabOffset = 0f;
|
||||
|
||||
if (ImmediateReleaseWhenOpen && EmptyOpen && LocksBack)
|
||||
{
|
||||
if (Bolt)
|
||||
@@ -350,14 +355,17 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
_previousVelocity = Vector3.zero;
|
||||
if (Type == HVRCockingHandleType.Pump)
|
||||
{
|
||||
_grabbedPositionTracker.transform.position = grabber.GrabPoint.position;
|
||||
_grabbedPositionTracker.position = grabber.GrabPoint.position;
|
||||
}
|
||||
else
|
||||
{
|
||||
_grabbedPositionTracker.transform.localPosition = transform.parent.InverseTransformPoint(_previousHandPosition);
|
||||
_grabbedPositionTracker.localPosition = transform.parent.InverseTransformPoint(_previousHandPosition);
|
||||
GrabOffset = Vector3.Distance(ForwardPositionWorld, transform.position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected virtual void OnReleased(HVRHandGrabber grabber, HVRGrabbable slide)
|
||||
{
|
||||
EmptyOpen = false;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HurricaneVR.Framework.Components;
|
||||
@@ -36,7 +37,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
|
||||
[Tooltip("Is chambering required to shoot")]
|
||||
public bool RequiresChamberedBullet = true;
|
||||
public FireType FireType = FireType.Single;
|
||||
public GunFireType FireType = GunFireType.Single;
|
||||
|
||||
[Tooltip("Speed of the bullet prefab")]
|
||||
public float BulletSpeed = 40f;
|
||||
@@ -126,7 +127,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
private Coroutine _animationRoutine;
|
||||
|
||||
public UnityEvent Fired = new UnityEvent();
|
||||
public GunHitEvent Hit = new GunHitEvent();
|
||||
public HVRGunHitEvent Hit = new HVRGunHitEvent();
|
||||
|
||||
protected float TimeOfLastShot { get; set; }
|
||||
|
||||
@@ -554,7 +555,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
return;
|
||||
}
|
||||
|
||||
if (FireType == FireType.Single)
|
||||
if (FireType == GunFireType.Single)
|
||||
{
|
||||
if (Time.time - TimeOfLastShot < Cooldown)
|
||||
return;
|
||||
@@ -565,7 +566,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsFiring && FireType == FireType.ThreeRoundBurst)
|
||||
if (IsFiring && FireType == GunFireType.ThreeRoundBurst)
|
||||
return;
|
||||
|
||||
IsFiring = true;
|
||||
@@ -574,7 +575,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
|
||||
public virtual void TriggerReleased()
|
||||
{
|
||||
if (FireType == FireType.Automatic)
|
||||
if (FireType == GunFireType.Automatic)
|
||||
{
|
||||
IsFiring = false;
|
||||
}
|
||||
@@ -602,7 +603,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
PlayHaptics(Grabbable, Haptics.DryFire);
|
||||
}
|
||||
|
||||
public virtual void UpdateTrackedBullets()
|
||||
private void UpdateTrackedBullets()
|
||||
{
|
||||
for (int i = 0; i < _objects.Count; i++)
|
||||
{
|
||||
@@ -615,7 +616,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
|
||||
if (Physics.Raycast(bullet.transform.position, tracker.Direction, out var hit, distance, HitLayerMask, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
OnHit(bullet, hit, tracker.Direction);
|
||||
OnHit(hit, tracker.Direction);
|
||||
bullet.SetActive(false);
|
||||
_objects[i].SetRenderersActive(false);
|
||||
}
|
||||
@@ -708,7 +709,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
TimeOfLastShot = Time.time;
|
||||
RoundsFired++;
|
||||
|
||||
if (FireType == FireType.ThreeRoundBurst && RoundsFired == 3)
|
||||
if (FireType == GunFireType.ThreeRoundBurst && RoundsFired == 3)
|
||||
{
|
||||
IsFiring = false;
|
||||
}
|
||||
@@ -1005,7 +1006,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
}
|
||||
|
||||
|
||||
protected virtual void OnHit(GameObject bullet, RaycastHit hit, Vector3 direction)
|
||||
protected virtual void OnHit(RaycastHit hit, Vector3 direction)
|
||||
{
|
||||
var damageHandler = hit.collider.GetComponent<HVRDamageHandlerBase>();
|
||||
if (damageHandler)
|
||||
@@ -1020,7 +1021,7 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
hit.collider.attachedRigidbody.AddForceAtPosition(direction.normalized * Force, hit.point, ForceMode.Impulse);
|
||||
}
|
||||
|
||||
Hit.Invoke(damageHandler);
|
||||
Hit.Invoke(new GunHitArgs(this, direction, hit));
|
||||
}
|
||||
|
||||
public virtual void EjectBullet()
|
||||
@@ -1126,4 +1127,39 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class HVRGunHitEvent : UnityEvent<GunHitArgs>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public struct GunHitArgs
|
||||
{
|
||||
public HVRGunBase Gun;
|
||||
public Vector3 HitPoint;
|
||||
public Vector3 Normal;
|
||||
public Vector3 Direction;
|
||||
public Collider Collider;
|
||||
public Rigidbody Rb;
|
||||
public float Distance;
|
||||
|
||||
public GunHitArgs(HVRGunBase gun, Vector3 direction, RaycastHit hit)
|
||||
{
|
||||
Gun = gun;
|
||||
HitPoint = hit.point;
|
||||
Normal = hit.normal;
|
||||
Direction = direction;
|
||||
Collider = hit.collider;
|
||||
Rb = hit.collider.attachedRigidbody;
|
||||
Distance = hit.distance;
|
||||
}
|
||||
}
|
||||
|
||||
public enum GunFireType
|
||||
{
|
||||
Single,
|
||||
ThreeRoundBurst,
|
||||
Automatic
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using UnityEngine;
|
||||
using HurricaneVR.Framework.Core;
|
||||
using HurricaneVR.Framework.Core.Grabbers;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HurricaneVR.Framework.Weapons.Guns
|
||||
{
|
||||
@@ -32,5 +34,15 @@ namespace HurricaneVR.Framework.Weapons.Guns
|
||||
EjectCasing();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAmmoSocketed(HVRGrabberBase grabber, HVRGrabbable grabbable)
|
||||
{
|
||||
AmmoSocketedHaptics();
|
||||
}
|
||||
|
||||
protected override void OnAmmoSocketReleased(HVRGrabberBase arg0, HVRGrabbable arg1)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,12 @@ namespace HurricaneVR.Framework.Weapons
|
||||
|
||||
public class HVRAmmoReleaseAction : HVRInputAction
|
||||
{
|
||||
public HVRRayCastGun HVRRayCastGun { get; private set; }
|
||||
public HVRGunBase Gun { get; private set; }
|
||||
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
HVRRayCastGun = GetComponent<HVRRayCastGun>();
|
||||
Gun = GetComponent<HVRGunBase>();
|
||||
}
|
||||
|
||||
@@ -41,10 +39,9 @@ namespace HurricaneVR.Framework.Weapons
|
||||
release = controller.PrimaryButtonState.JustActivated;
|
||||
}
|
||||
|
||||
if (release)
|
||||
if (release && Gun)
|
||||
{
|
||||
HVRRayCastGun?.ReleaseAmmo();
|
||||
Gun?.ReleaseAmmo();
|
||||
Gun.ReleaseAmmo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,92 @@
|
||||
using FMODUnity;
|
||||
using System.Collections.Generic;
|
||||
using HurricaneVR.Framework.Core.Utils;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace HurricaneVR.Framework.Weapons
|
||||
{
|
||||
public class HVRGunSounds : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private EventReference fired;
|
||||
[SerializeField] private EventReference outOfAmmo;
|
||||
[SerializeField] private EventReference slideBack;
|
||||
[SerializeField] private EventReference slideForward;
|
||||
[SerializeField] private EventReference loadMagazine;
|
||||
[SerializeField] private EventReference unloadMagazine;
|
||||
|
||||
public AudioClip Fired;
|
||||
public AudioClip OutOfAmmo;
|
||||
|
||||
//public AudioClip AmmoInserted;
|
||||
//public AudioClip AmmoReleased;
|
||||
|
||||
public AudioClip SlideBack;
|
||||
public AudioClip SlideForward;
|
||||
|
||||
public List<AudioClip> FiredVariations = new List<AudioClip>();
|
||||
//public List<AudioClip> AmmoInsertedVariations = new List<AudioClip>();
|
||||
//public List<AudioClip> AmmoReleasedVariations = new List<AudioClip>();
|
||||
|
||||
public List<AudioClip> SlideBackVariations = new List<AudioClip>();
|
||||
public List<AudioClip> SlideForwardVariations = new List<AudioClip>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
AddVariation(Fired, FiredVariations);
|
||||
//AddVariation(AmmoInserted, AmmoInsertedVariations);
|
||||
//AddVariation(AmmoReleased, AmmoReleasedVariations);
|
||||
AddVariation(SlideBack, SlideBackVariations);
|
||||
AddVariation(SlideForward, SlideForwardVariations);
|
||||
}
|
||||
|
||||
public virtual void PlayGunFire()
|
||||
{
|
||||
PlayClip(fired);
|
||||
PlayVariation(FiredVariations);
|
||||
}
|
||||
|
||||
|
||||
//public virtual void PlayAmmoInserted()
|
||||
//{
|
||||
// PlayVariation(AmmoInsertedVariations);
|
||||
//}
|
||||
|
||||
//public virtual void PlayAmmoReleased()
|
||||
//{
|
||||
// PlayVariation(AmmoReleasedVariations);
|
||||
//}
|
||||
|
||||
public virtual void PlayOutOfAmmo()
|
||||
{
|
||||
PlayClip(outOfAmmo);
|
||||
PlayClip(OutOfAmmo);
|
||||
}
|
||||
|
||||
public virtual void PlaySlideForward()
|
||||
{
|
||||
PlayClip(slideForward);
|
||||
PlayVariation(SlideForwardVariations);
|
||||
}
|
||||
|
||||
public virtual void PlaySlideBack()
|
||||
{
|
||||
PlayClip(slideBack);
|
||||
PlayVariation(SlideBackVariations);
|
||||
}
|
||||
|
||||
public virtual void PlayLoadMagazine()
|
||||
protected virtual void PlayVariation(List<AudioClip> variations)
|
||||
{
|
||||
PlayClip(loadMagazine);
|
||||
if (variations.Count == 0)
|
||||
return;
|
||||
|
||||
var index = Random.Range(0, variations.Count);
|
||||
var sfx = variations[index];
|
||||
|
||||
PlayClip(sfx);
|
||||
}
|
||||
|
||||
public virtual void PlayUnloadMagazine()
|
||||
protected virtual void PlayClip(AudioClip clip)
|
||||
{
|
||||
PlayClip(unloadMagazine);
|
||||
if (!clip)
|
||||
return;
|
||||
|
||||
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(clip, transform.position);
|
||||
}
|
||||
|
||||
protected virtual void PlayClip(EventReference clip)
|
||||
|
||||
private void AddVariation(AudioClip clip, List<AudioClip> variations)
|
||||
{
|
||||
if (clip.IsNull) return;
|
||||
RuntimeManager.PlayOneShot(clip.Guid, transform.position);
|
||||
if (clip && !variations.Contains(clip))
|
||||
{
|
||||
variations.Add(clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user