Replace UltimateXR with HurricaneVR

This commit is contained in:
2024-08-08 17:01:07 +02:00
parent e8658374d6
commit fb21dbbb73
5932 changed files with 358362 additions and 2174150 deletions

View File

@@ -0,0 +1,36 @@
using Assets.HurricaneVR.Framework.Shared.Utilities;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRAutoDropMagazine : HVRSocket
{
public HVRSocket MagazineSocket;
protected override void OnHoverEnter(HVRGrabbable grabbable)
{
ForceRelease();
if (MagazineSocket && IsValid(grabbable) && grabbable.HandGrabbers.Count > 0)
{
Debug.Log($"drop");
MagazineSocket.ForceRelease();
}
}
public override bool IsValid(HVRGrabbable grabbable)
{
if (!MagazineSocket || !MagazineSocket.IsGrabbing)
return false;
return MagazineSocket.IsValid(grabbable);
}
public override bool CanGrab(HVRGrabbable grabbable)
{
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9329b61191544954aadf4fa05841e222
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System.Collections;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRAutomaticGun : HVRGunBase
{
protected override void Awake()
{
base.Awake();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f9db1f9e84328a44ae9e19e161049a2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
using HurricaneVR.Framework.Components;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRBullet : MonoBehaviour
{
public float Speed;
public float Gravity;
public float TimeToLive;
public float Elapsed;
public LayerMask LayerMask;
public bool Hit;
public HVRGunBase Gun { get; set; }
//public UnityEvent
public void Reset()
{
Elapsed = 0f;
Hit = false;
}
public void Update()
{
//d = vt;
Elapsed += Time.deltaTime;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: babd6ea8b8aeb3d4aa046f31d4b6cce8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using HurricaneVR.Framework.Core.Utils;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRBulletEmitter : HVRGunEmitterBase
{
public override void Emit()
{
var clone = Instantiate(Prefab);
var rb = clone.GetRigidbody();
if (!rb)
return;
Launch(rb);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c2ba0ca1bfc7cc54891c0fd0342b7489
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,467 @@
using System.Collections;
using System.Collections.Generic;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRCockingHandle : HVRGunPart
{
[Header("Settings")]
[Tooltip("Forward speed of the slide when released")]
public float ForwardSpeed = 10f;
[Tooltip("Faux difficulty for pulling back the handle")]
public float Difficulty = .05f;
[Tooltip("If the handle was popped open due to out of ammo, it will release immediately upon being grabbed")]
public bool ImmediateReleaseWhenOpen = true;
[Tooltip("If true, locks back even if the handle isn't reciprocating")]
public bool LockBackOverride;
public HVRCockingHandleType Type;
[Header("Lock Options")]
public bool LocksForward;
public bool TriggerUnlocks;
public float TriggerThreshold = .7f;
[Tooltip("Hand must move this fast to unlock the handle")]
public float AccelerationThreshold = 2f;
[Header("Components")]
public HVRGrabbable Grabbable;
[Tooltip("Bolt that moves with the charging handle, pump")]
public HVRGunBolt Bolt;
[Header("Editor Positions")]
[Tooltip("Position to reach to eject the chambered round")]
public Vector3 EjectPosition;
[Tooltip("Position to reach that will chamber a round.")]
public Vector3 ChamberRoundPosition;
public List<HVRGunPart> AnimatedParts = new List<HVRGunPart>();
[Header("Slide Events")]
public UnityEvent Released = new UnityEvent();
public UnityEvent EjectReached = new UnityEvent();
public UnityEvent ChamberRound = new UnityEvent();
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; }
public Vector3 ForwardPositionWorld => transform.parent.TransformPoint(ForwardPosition);
public Vector3 MaxPositionWorld => transform.parent.TransformPoint(BackwardPosition);
public Vector3 BackDirectionWorld => (MaxPositionWorld - ForwardPositionWorld).normalized;
private float _chamberedRequiredDistance;
private bool _chamberDistanceReached;
private float _maximumDistance;
private float _ejectDistance;
private bool _ejectDistanceReached;
private float _lockDistance;
private bool _lockDistanceReached;
private Vector3 _previousHandPosition;
private Vector3 _previousVelocity;
private Vector3 _handAcceleration;
private bool _locked = true;
private Coroutine _forwardRoutine;
public virtual bool LocksBack
{
get
{
if (Type == HVRCockingHandleType.Reciprocating)
{
return true;
}
return LockBackOverride;
}
}
protected virtual void Awake()
{
if (!Grabbable)
{
Grabbable = GetComponent<HVRGrabbable>();
}
if (Grabbable)
{
Grabbable.HandGrabbed.AddListener(OnGrabbed);
Grabbable.HandReleased.AddListener(OnReleased);
}
else
{
Debug.LogError($"{name} is missing it's grabbable component.");
}
var go = new GameObject("GrabTracker");
go.transform.parent = transform.parent;
_grabbedPositionTracker = go.transform;
_chamberedRequiredDistance = Vector3.Distance(ChamberRoundPosition, ForwardPosition);
_maximumDistance = Vector3.Distance(BackwardPosition, ForwardPosition);
_ejectDistance = Vector3.Distance(EjectPosition, ForwardPosition);
_lockDistance = _maximumDistance * .05f;
}
public void Enable()
{
Grabbable.CanBeGrabbed = true;
}
public void Disable()
{
Grabbable.CanBeGrabbed = false;
}
protected virtual void Update()
{
if (Grabbable.HandGrabbers.Count > 0)
{
UpdateHandTracking();
if (_locked)
{
if (CheckUnlock())
{
Unlock();
}
}
if (_locked && LocksForward)
{
return;
}
var pullDirection = (Grabbable.HandGrabbers[0].TrackedController.position - _grabbedPositionTracker.position);
var backDirection = (MaxPositionWorld - ForwardPositionWorld).normalized * 10;
var amount = Vector3.Dot(pullDirection, backDirection) * Difficulty;
if (amount + GrabOffset > 0)
{
UpdatePosition(amount);
}
else
{
transform.localPosition = ForwardPosition;
}
var distance = Vector3.Distance(transform.position, ForwardPositionWorld);
CheckEject(distance);
CheckChamberDistance(distance);
ClampPullBack(distance, BackDirectionWorld);
MoveBolt();
AnimateParts();
CheckLock(distance);
}
}
protected virtual void CheckLock(float distance)
{
if (!LocksForward)
return;
if (distance > _lockDistance && !_lockDistanceReached)
{
_lockDistanceReached = true;
}
else if (distance < _lockDistance && _lockDistanceReached)
{
Close();
_lockDistanceReached = false;
}
}
private void UpdatePosition(float amount)
{
transform.position = ForwardPositionWorld + BackDirectionWorld * (amount + GrabOffset);
}
public void Lock()
{
_locked = true;
//Debug.Log($"lock");
}
public void Unlock()
{
_locked = false;
//Debug.Log($"unlock");
}
protected virtual bool CheckUnlock()
{
if (!LocksForward)
return true;
if (TriggerUnlocks)
{
if (Grabbable.HandGrabbers.Count > 0)
{
if (Grabbable.HandGrabbers[0].Controller.Trigger > TriggerThreshold)
{
return true;
}
}
}
else
{
if (_handAcceleration.magnitude > AccelerationThreshold)
{
return true;
}
}
return false;
}
protected virtual void CheckEject(float distance)
{
if (distance > _ejectDistance && !_ejectDistanceReached)
{
EjectReached.Invoke();
_ejectDistanceReached = true;
}
else if (distance < _ejectDistance && _ejectDistanceReached)
{
_ejectDistanceReached = false;
}
}
protected virtual void CheckChamberDistance(float distance)
{
if (distance > _chamberedRequiredDistance)
{
if (!_chamberDistanceReached)
{
_chamberDistanceReached = true;
}
}
else if (distance < _chamberedRequiredDistance && _chamberDistanceReached)
{
_chamberDistanceReached = false;
ChamberRound.Invoke();
}
}
protected virtual void ClampPullBack(float distance, Vector3 backDirection)
{
if (distance > _maximumDistance)
{
transform.localPosition = BackwardPosition;
}
}
protected virtual void UpdateHandTracking()
{
if (!Grabbable.IsBeingHeld)
return;
if (Grabbable.PrimaryGrabber.IsHandGrabber)
{
var hand = Grabbable.HandGrabbers[0];
var velocity = hand.TrackedController.position - _previousHandPosition;
_handAcceleration = (velocity - _previousVelocity) / Time.deltaTime;
_previousVelocity = velocity;
_previousHandPosition = hand.TrackedController.position;
}
}
protected virtual void MoveBolt()
{
if (Bolt)
{
if (_ejectDistance == 0f)
{
return;
}
var percent = Vector3.Distance(transform.localPosition, ForwardPosition) / _maximumDistance;
if (percent > .90)
{
Bolt.IsPushedBack = false;
}
if (Bolt.IsPushedBack && percent < .90)
return;
Bolt.Move(percent);
}
}
protected virtual void AnimateParts()
{
var percent = Vector3.Distance(transform.localPosition, ForwardPosition) / _maximumDistance;
foreach (var part in AnimatedParts)
{
part.Animate(percent, CycleDirection.Backward);
}
}
public void Move(float percent)
{
transform.localPosition = Vector3.Lerp(ForwardPosition, BackwardPosition, percent);
}
protected virtual void OnGrabbed(HVRHandGrabber grabber, HVRGrabbable slide)
{
GrabOffset = 0f;
if (ImmediateReleaseWhenOpen && EmptyOpen && LocksBack)
{
if (Bolt)
{
Bolt.IsPushedBack = false;
}
Grabbable.ForceRelease();
}
_previousHandPosition = grabber.TrackedController.position;
_previousVelocity = Vector3.zero;
if (Type == HVRCockingHandleType.Pump)
{
_grabbedPositionTracker.position = grabber.GrabPoint.position;
}
else
{
_grabbedPositionTracker.localPosition = transform.parent.InverseTransformPoint(_previousHandPosition);
GrabOffset = Vector3.Distance(ForwardPositionWorld, transform.position);
}
}
protected virtual void OnReleased(HVRHandGrabber grabber, HVRGrabbable slide)
{
EmptyOpen = false;
if (Type != HVRCockingHandleType.Pump)
{
Close();
}
}
public void Close()
{
if (_forwardRoutine != null)
return;
StartCoroutine(ForwardRoutine());
}
protected virtual IEnumerator ForwardRoutine()
{
Grabbable.CanBeGrabbed = false;
while (true)
{
var distance = Vector3.Distance(transform.localPosition, ForwardPosition);
var travel = ForwardSpeed * Time.deltaTime;
if (distance < travel)
{
transform.localPosition = ForwardPosition;
MoveBolt();
AnimateParts();
break;
}
transform.localPosition = Vector3.MoveTowards(transform.localPosition, ForwardPosition, travel);
AnimateParts();
MoveBolt();
yield return null;
}
_forwardRoutine = null;
Grabbable.CanBeGrabbed = true;
if (_chamberDistanceReached)
{
ChamberRound.Invoke();
}
Released.Invoke();
_chamberDistanceReached = false;
_ejectDistanceReached = false;
EmptyOpen = false;
if (LocksForward)
{
Lock();
}
}
public virtual void PushBack()
{
if (LocksBack)
{
transform.localPosition = EjectPosition;
EmptyOpen = true;
_chamberDistanceReached = true;
if (Bolt)
{
Bolt.Move(1f);
}
}
}
public override void Animate(float percent, CycleDirection direction)
{
if (Type == HVRCockingHandleType.Reciprocating)
{
Move(percent);
}
}
//public void OnDrawGizmosSelected()
//{
// Gizmos.color = Color.green;
// Gizmos.DrawCube(ForwardPositionWorld, new Vector3(.025f, .025f, .025f));
// Gizmos.color = Color.red;
// Gizmos.DrawCube(MaxPositionWorld, new Vector3(.025f, .025f, .025f));
// Gizmos.color = Color.yellow;
// Gizmos.DrawCube(transform.parent.TransformPoint(EjectPosition), new Vector3(.025f, .025f, .025f));
// Gizmos.color = Color.cyan;
// Gizmos.DrawCube(transform.parent.TransformPoint(ChamberRoundPosition), new Vector3(.025f, .025f, .025f));
//}
}
public enum HVRCockingHandleType
{
Reciprocating, NonReciprocating, Pump
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a5b6a3a6b34cc6743b0fff4f3ee25c54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRGrabMagazine : HVRHandGrabEvent
{
public float GrabDelay = .05f;
public HVRSocket MagSocket;
protected WaitForSeconds Timeout;
protected override void Awake()
{
base.Awake();
Timeout = new WaitForSeconds(GrabDelay);
}
protected override bool CheckEnableGrab()
{
return MagSocket && MagSocket.IsGrabbing;
}
protected override void OnHandGrabbed(HVRHandGrabber hand, HVRGrabbable arg1)
{
base.OnHandGrabbed(hand, arg1);
if (MagSocket && MagSocket.GrabbedTarget)
{
var ammo = MagSocket.GrabbedTarget;
MagSocket.ForceRelease();
StartCoroutine(GrabRoutine(ammo, hand));
}
}
protected IEnumerator GrabRoutine(HVRGrabbable ammo, HVRHandGrabber hand)
{
//yield return Timeout;
yield return new WaitForSeconds(GrabDelay);
if (ammo && !ammo.IsBeingHeld && !hand.GrabbedTarget)
{
hand.TryGrab(ammo, true);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4ead9473e10324d4684477e2ecd88999
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1dddf24d500dae7489529737f2333e93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRGunBolt : HVRGunPart
{
public bool IsPushedBack { get; set; }
private void Awake()
{
}
public void Move(float percent)
{
if (float.IsNaN(percent))
return;
transform.localPosition = Vector3.Lerp(ForwardPosition, BackwardPosition, percent);
}
public virtual void PushBack()
{
transform.localPosition = BackwardPosition;
IsPushedBack = true;
}
public override void Animate(float percent, CycleDirection direction)
{
Move(percent);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da604da12e078d7458bac76897f36d1b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using HurricaneVR.Framework.Core.Utils;
using HurricaneVR.Framework.Shared.Utilities;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public abstract class HVRGunEmitterBase : MonoBehaviour
{
public float LaunchRadius = .05f;
public float MinVelocity = 4f;
public float MaxVelocity = 6f;
public Vector3 MinAngularVelocity = new Vector3(0f, 8f, 0f);
public Vector3 MaxAngularVelocity = new Vector3(0f, 10f, 0f);
public HVRGunBase Gun;
public GameObject Prefab;
protected virtual void Awake()
{
}
public virtual void Emit()
{
}
public virtual void Launch(Rigidbody rb)
{
if (!rb)
return;
rb.velocity = Vector3.zero;
rb.angularVelocity = Vector3.zero;
rb.transform.position = transform.position;
rb.transform.rotation = transform.rotation;
var xy = Random.insideUnitCircle * LaunchRadius;
var launchDirection = transform.right + new Vector3(0f, xy.x, xy.y);
rb.velocity = launchDirection * Random.Range(MinVelocity, MaxVelocity);
rb.AddRelativeTorque(
Random.Range(MinAngularVelocity.x, MaxAngularVelocity.x),
Random.Range(MinAngularVelocity.y, MaxAngularVelocity.y),
Random.Range(MinAngularVelocity.z, MaxAngularVelocity.z),
ForceMode.VelocityChange
);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b0c4c4c9f5c075a4ba3413652b9cd352
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,39 @@
using System;
using HurricaneVR.Framework.Shared;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
[CreateAssetMenu(menuName = "HurricaneVR/GunHaptics", fileName = "GunHaptics")]
public class HVRGunHaptics : ScriptableObject
{
public void Reset()
{
Fire = new HapticData(.20f, .70f, 150f);
DryFire = new HapticData(.04f, .5f, 50f);
TriggerSqueezed = new HapticData(.1f, .01f, 60f);
TriggeredReleased = new HapticData(.025f, .2f, 45f);
CockingHandleEject = new HapticData(.05f, 200f, .22f);
CockingHandleChamberedRound = new HapticData(.05f, 200f, .22f);
CockingHandleReleased = new HapticData(.05f, 200f, .22f);
AmmoSocketed = new HapticData(.05f, 200f, .22f);
AmmoSocketReleased = new HapticData(.05f, 200f, .22f);
}
public HapticData DryFire;
public HapticData Fire;
public HapticData TriggeredReleased;
public HapticData TriggerSqueezed;
public HapticData CockingHandleEject;
public HapticData CockingHandleChamberedRound;
public HapticData CockingHandleReleased;
public HapticData AmmoSocketed;
public HapticData AmmoSocketReleased;
public float TriggerSqueezeStop = .7f;
public float TriggerSqueezeStart = .1f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 226cce0b7ab93444c9da83b531f6aa9a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRGunPart : MonoBehaviour
{
[Header("Gun Part Positions (Base Class)")]
public Vector3 ForwardPosition;
public Vector3 BackwardPosition;
public virtual void Animate(float percent, CycleDirection direction)
{
if (float.IsNaN(percent))
return;
transform.localPosition = Vector3.Lerp(ForwardPosition, BackwardPosition, percent);
}
}
public enum CycleDirection
{
Backward,
Forward
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ed770b5ca1394bd46a54e22aedf55187
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
using System.Collections;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRMagazineSocket : HVRSocket
{
[Header("Magazine Socket Fields")]
public bool Animate = true;
public float AnimationTime = .2f;
public float MagazineTravel = .1f;
public bool AnimateEject;
public float EjectTime = .2f;
public Transform MagazineAxis;
protected Vector3 MagazineDirection => MagazineAxis ? MagazineAxis.forward : -transform.up;
protected override void OnGrabbableParented(HVRGrabbable grabbable)
{
if (Animate)
{
StartCoroutine(LoadAnimationRoutine(grabbable));
}
else
{
base.OnGrabbableParented(grabbable);
}
}
protected virtual IEnumerator LoadAnimationRoutine(HVRGrabbable grabbable)
{
CanRemoveGrabbable = false;
var elapsed = 0f;
var targetPosition = GetTargetPosition(grabbable);
var targetRotation = GetTargetRotation(grabbable);
var direction = targetPosition - grabbable.transform.localPosition;
var speed = direction.magnitude / AnimationTime;
grabbable.transform.position = transform.position + MagazineDirection * MagazineTravel;
grabbable.transform.localRotation = targetRotation;
while (elapsed < AnimationTime)
{
grabbable.transform.localPosition = Vector3.MoveTowards(grabbable.transform.localPosition, targetPosition, speed * Time.deltaTime);
elapsed += Time.deltaTime;
yield return null;
}
grabbable.transform.localPosition = targetPosition;
CanRemoveGrabbable = true;
}
protected virtual IEnumerator EjectAnimationRoutine(HVRGrabbable grabbable)
{
grabbable.CanBeGrabbed = false;
grabbable.Rigidbody.useGravity = false;
var elapsed = 0f;
var direction = MagazineDirection;
var speed = MagazineTravel / EjectTime;
var target = grabbable.transform.position + direction.normalized * MagazineTravel;
while (elapsed < EjectTime && grabbable)
{
grabbable.transform.position = Vector3.MoveTowards(grabbable.transform.position, target, speed * Time.deltaTime);
grabbable.Rigidbody.velocity = Vector3.zero;
grabbable.Rigidbody.angularVelocity = Vector3.zero;
elapsed += Time.deltaTime;
yield return null;
}
//magazine might be destroyed if it's empty
if (grabbable)
{
grabbable.Rigidbody.useGravity = true;
grabbable.CanBeGrabbed = true;
}
}
protected override void OnReleased(HVRGrabbable grabbable)
{
base.OnReleased(grabbable);
if (AnimateEject && gameObject.activeInHierarchy)
{
StartCoroutine(EjectAnimationRoutine(grabbable));
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a13d52c8343fece4a9e5696716c06f69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System.Collections;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRPistol : HVRGunBase
{
protected override void Awake()
{
base.Awake();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bbd328f6ceb25be44b7a7b2cdd971854
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections;
using System.Collections.Generic;
using HurricaneVR.Framework.Core.Utils;
using HurricaneVR.Framework.Shared.Utilities;
using UnityEngine;
using Random = UnityEngine.Random;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRPooledEmitter : HVRGunEmitterBase
{
public int MinLife = 5;
public int MaxLife = 10;
public int MaxObjects = 30;
public HideFlags HideFlags = HideFlags.HideInHierarchy;
private readonly List<HVRPooledObjectTracker> _objects = new List<HVRPooledObjectTracker>();
protected override void Awake()
{
base.Awake();
for (int i = 0; i < MaxObjects; i++)
{
if (Prefab)
{
_objects.Add(new HVRPooledObjectTracker());
_objects[i].Object = Instantiate(Prefab);
_objects[i].Object.SetActive(false);
_objects[i].Rigidbody = _objects[i].Object.GetRigidbody();
_objects[i].Object.hideFlags = HideFlags;
_objects[i].Colliders = _objects[i].Object.GetComponentsInChildren<Collider>();
}
}
}
public virtual void Update()
{
for (int i = 0; i < _objects.Count; i++)
{
if (_objects[i].Object.activeSelf)
{
_objects[i].Elapsed += Time.deltaTime;
if (_objects[i].Elapsed > _objects[i].TimeToLive)
{
_objects[i].Object.SetActive(false);
}
}
}
}
public override void Emit()
{
HVRPooledObjectTracker tracker = null;
var time = -1f;
for (int i = 0; i < _objects.Count; i++)
{
if (!_objects[i].Object.activeSelf)
{
tracker = _objects[i];
break;
}
if (_objects[i].Elapsed > time)
{
tracker = _objects[i];
time = _objects[i].Elapsed;
}
}
if (tracker != null)
{
tracker.Elapsed = 0f;
tracker.TimeToLive = Random.Range(MinLife, MaxLife);
tracker.Object.SetActive(true);
var rb = tracker.Rigidbody;
if (rb)
{
Launch(rb);
if (Gun)
{
Gun.IgnoreCollision(tracker.Colliders, 1f);
}
}
}
}
private class HVRPooledObjectTracker
{
public GameObject Object;
public Rigidbody Rigidbody;
public float Elapsed;
public float TimeToLive;
public Collider[] Colliders;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 615314fd4a55b7e42af9ee3b76badb4f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRShotgun : HVRGunBase
{
[Header("Shotgun Settings")]
public int NumberOfPellets = 5;
public float ShotRadius = 0.05f;
protected override void Awake()
{
base.Awake();
Ammo = GetComponent<HVRShotgunMagazine>();
}
protected override void OnFire(Vector3 direction)
{
for (int i = 0; i < NumberOfPellets; i++)
{
var xy = Random.insideUnitCircle * ShotRadius;
var newDirection = direction + transform.TransformDirection(xy);
FireBullet(newDirection);
}
}
protected override void OnCockingHandleEjected()
{
base.OnCockingHandleEjected();
if (ChamberedCasing && ChamberedCasing.activeSelf)
{
EjectCasing();
}
}
protected override void OnAmmoSocketed(HVRGrabberBase grabber, HVRGrabbable grabbable)
{
AmmoSocketedHaptics();
}
protected override void OnAmmoSocketReleased(HVRGrabberBase arg0, HVRGrabbable arg1)
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3d4f312e756ab8b44bed084477f9ba1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns
{
public class HVRTriggerAnimator : MonoBehaviour
{
public bool Rotate = true;
public Quaternion StartRotation;
public Quaternion EndRotation;
public bool Move = false;
public Vector3 ForwardPosition;
public Vector3 BackwardPosition;
protected virtual void Awake()
{
if (StartRotation.w == 0f)
{
StartRotation = transform.localRotation;
}
if (EndRotation.w == 0f)
{
EndRotation = transform.localRotation;
}
}
public virtual void Animate(float trigger)
{
if (Rotate)
{
transform.localRotation = Quaternion.Lerp(StartRotation, EndRotation, trigger);
}
if (Move)
{
transform.localPosition = Vector3.Lerp(ForwardPosition, BackwardPosition, trigger);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bb7bbd5fbb64d0646a11fe1ab1882b15
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9c2df5b3fe73cc54791749a805e37687
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns.PartFinders
{
public class HVRChamberedCasingFinder : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ada3d5a28435ca42ab5cbc53dc7c2a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns.PartFinders
{
public class HVRChamberedRoundFinder : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b67ef4552bd2b1f49894e6ff773d67da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace HurricaneVR.Framework.Weapons.Guns.PartFinders
{
public class HVRMagazineFinder : MonoBehaviour
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ac97456e56d5c543861420a61ed719b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: