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,61 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using HurricaneVR.Framework.Core;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoBackpack : MonoBehaviour
{
[Tooltip("Used to ignore collision with grabbable colliders.")]
public List<Collider> Colliders = new List<Collider>();
void Start()
{
if (Colliders == null || Colliders.Count == 0)
{
Colliders = GetComponentsInChildren<Collider>().Where(e=>!e.isTrigger).ToList();
}
if (Colliders.Count > 0)
StartCoroutine(IgnoreColliders());
}
public IEnumerator IgnoreColliders()
{
yield return null;
//this will only ignore grabbables at the start of the game.
//you would need to ignore the collision yourself if you instantiate grabbables after.
var watch = Stopwatch.StartNew();
var grabbables = FindObjectsOfType<HVRGrabbable>();
foreach (var grabbable in grabbables)
{
IgnoreCollision(grabbable);
}
watch.Stop();
//Debug.Log($"Backpack colliders ignore took : {watch.ElapsedMilliseconds} ms.");
}
public void IgnoreCollision(HVRGrabbable grabbable)
{
for (var i = 0; i < grabbable.Colliders.Count; i++)
{
var c = grabbable.Colliders[i];
if (!c)
continue;
for (var j = 0; j < Colliders.Count; j++)
{
var ourCollider = Colliders[j];
if (ourCollider.isTrigger)
continue;
Physics.IgnoreCollision(c, ourCollider);
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,39 @@
using System.Linq;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using HurricaneVR.Framework.Core.HandPoser;
using HurricaneVR.Framework.Shared;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoCodeGrabbing : MonoBehaviour
{
public HVRHandGrabber Grabber { get; set; }
public HVRGrabbable Grabbable;
public HVRGrabTrigger GrabTrigger;
public HVRPosableGrabPoint GrabPoint;
public void Start()
{
Grabber = GameObject.FindObjectsOfType<HVRHandGrabber>().FirstOrDefault(e => e.gameObject.activeInHierarchy);
}
public void Grab()
{
if (Grabbable && Grabber)
{
if (GrabTrigger == HVRGrabTrigger.ManualRelease && Grabber.GrabbedTarget == Grabbable)
{
Grabber.ForceRelease();
return;
}
//grabber needs to have it's release sequence completed if it's holding something
if(Grabber.IsGrabbing)
Grabber.ForceRelease();
Grabber.Grab(Grabbable, GrabTrigger, GrabPoint);
}
}
}
}

View File

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

View File

@@ -0,0 +1,33 @@
using HurricaneVR.Framework.Core.ScriptableObjects;
using HurricaneVR.Framework.Core.Utils;
using HurricaneVR.Framework.Shared;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
[RequireComponent(typeof(ConfigurableJoint))]
public class DemoDummyArm : MonoBehaviour
{
public Transform Anchor;
public float Length = .5f;
public LineRenderer Rope;
public Transform ArmRopeAnchor;
void Start()
{
var joint = GetComponent<ConfigurableJoint>();
joint.SetLinearLimit(Length);
joint.anchor = ArmRopeAnchor.localPosition;
joint.autoConfigureConnectedAnchor = false;
joint.connectedAnchor = Anchor.position;
Rope.positionCount = 2;
}
// Update is called once per frame
void Update()
{
Rope.SetPosition(0, Anchor.position);
Rope.SetPosition(1, ArmRopeAnchor.position);
}
}
}

View File

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

View File

@@ -0,0 +1,54 @@
using HurricaneVR.Framework.Core.Stabbing;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoFullStabConfetti : MonoBehaviour
{
public HVRStabbable Stabbable;
public ParticleSystem Confetti;
public bool OnFullStab;
private Vector3 point;
private Vector3 normal;
public void Start()
{
Stabbable = GetComponentInParent<HVRStabbable>();
TryGetComponent(out Confetti);
if (Stabbable)
{
Stabbable.Stabbed.AddListener(Stabbed);
Stabbable.UnStabbed.AddListener(Unstabbed);
Stabbable.FullStabbed.AddListener(FullStabbed);
}
}
private void FullStabbed(HVRStabber arg0, HVRStabbable arg1)
{
if (OnFullStab)
PopConfetti(normal);
}
private void PopConfetti(Vector3 dir)
{
Confetti.transform.position = Stabbable.transform.TransformPoint(point);
Confetti.transform.rotation = Quaternion.FromToRotation(Confetti.transform.up, dir) * Confetti.transform.rotation;
Confetti.Stop();
Confetti.Play();
}
private void Unstabbed(HVRStabber arg0, HVRStabbable arg1)
{
}
private void Stabbed(StabArgs stabArgs)
{
normal = stabArgs.Normal;
point = Stabbable.transform.InverseTransformPoint(stabArgs.Point);
if (!OnFullStab)
PopConfetti(normal);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 29ec6e434945470790acce6ca1f4cbbc
timeCreated: 1635220277

View File

@@ -0,0 +1,49 @@
using HurricaneVR.Framework.Core.Utils;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoGlassRotate : MonoBehaviour
{
public float Timer = 5f;
public float Degrees = 135;
public bool Unlocked;
public bool DoneRotating;
public AudioClip SFXOpen;
private float _elapsed;
void Start()
{
}
void Update()
{
if (!Unlocked || DoneRotating)
return;
_elapsed += UnityEngine.Time.deltaTime;
transform.localRotation = transform.localRotation * Quaternion.Euler(new Vector3(-Degrees / Timer * Time.deltaTime, 0f, 0f));
if (_elapsed > Timer)
{
_elapsed = 0f;
DoneRotating = true;
}
}
public void Unlock()
{
if (!Unlocked)
{
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXOpen, transform.position);
}
Unlocked = true;
}
}
}

View File

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

View File

@@ -0,0 +1,42 @@
using HurricaneVR.Framework.Core.Utils;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoHatchDoor : MonoBehaviour
{
public float Timer = 5f;
public float Degrees = 180;
public bool Unlocked;
public bool DoneRotating;
public AudioClip SFXOpen;
private float _elapsed;
void Update()
{
if (!Unlocked || DoneRotating)
return;
_elapsed += UnityEngine.Time.deltaTime;
transform.localRotation = transform.localRotation * Quaternion.Euler(new Vector3(-Degrees / Timer * Time.deltaTime, 0f, 0f));
if (_elapsed > Timer)
{
_elapsed = 0f;
DoneRotating = true;
}
}
public void Unlock()
{
if (!Unlocked)
{
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXOpen, transform.position);
}
Unlocked = true;
}
}
}

View File

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

View File

@@ -0,0 +1,45 @@
using HurricaneVR.Framework.Components;
using HurricaneVR.Framework.Core.Utils;
using HurricaneVR.Framework.Shared;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoHeavyDoor : MonoBehaviour
{
public Rigidbody DoorRigidbody;
public HVRRotationTracker ValveTracker;
public HVRRotationLimiter Limiter;
public float MaxAngle = 130f;
public AudioClip[] SFX;
public float SFXAngle = 10f;
public float Angle;
private Quaternion _startRotation;
void Start()
{
_startRotation = DoorRigidbody.transform.rotation;
}
void FixedUpdate()
{
var angle = HVRUtilities.Remap(ValveTracker.Angle, Limiter.MinAngle, Limiter.MaxAngle, 0f, MaxAngle);
DoorRigidbody.MoveRotation(_startRotation * Quaternion.Euler(0f, angle, 0f));
if (SFX != null && SFX.Length > 0)
{
if (ValveTracker.Angle > Angle + SFXAngle || ValveTracker.Angle < Angle - SFXAngle)
{
var index = Random.Range(0, SFX.Length);
var sfx = SFX[index];
Angle = ValveTracker.Angle;
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(sfx, transform.position);
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,124 @@
using System.Collections.Generic;
using System.Linq;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoHelper : MonoBehaviour
{
class ResetState
{
public HVRGrabbable Grabbable;
public HVRGrabbable Clone;
public Vector3 Position;
public Quaternion Rotation;
public Vector3 Scale { get; set; }
public Transform Parent;
}
public List<Transform> Parents = new List<Transform>();
public List<HVRGrabbable> Grabbables = new List<HVRGrabbable>();
[Header("Debug")] public bool ForceReset;
private readonly List<ResetState> _grabbableState = new List<ResetState>();
void Start()
{
foreach (var parent in Parents)
{
if (parent)
AddResetGrabbable(parent);
}
foreach (var grabbable in Grabbables)
{
SaveResetGrabbable(grabbable.transform.parent, grabbable);
}
}
private void AddResetGrabbable(Transform parent)
{
foreach (var grabbable in parent.GetComponentsInChildren<HVRGrabbable>().Where(e => e.transform.parent == parent))
{
SaveResetGrabbable(parent, grabbable);
}
}
private void SaveResetGrabbable(Transform parent, HVRGrabbable grabbable)
{
var clone = Instantiate(grabbable);
clone.gameObject.SetActive(false);
clone.gameObject.hideFlags = HideFlags.HideInHierarchy;
var state = new ResetState()
{
Grabbable = grabbable,
Clone = clone,
Position = grabbable.transform.position,
Rotation = grabbable.transform.rotation,
Scale = grabbable.transform.localScale,
Parent = parent
};
_grabbableState.Add(state);
}
void Update()
{
if (ForceReset)
{
ResetGrabbables();
ForceReset = false;
}
}
private List<HVRGrabbable> _balls = new List<HVRGrabbable>();
public void BallSpawned(HVRSocket socket, GameObject ball)
{
var grabbable = ball.GetComponent<HVRGrabbable>();
_balls.Add(grabbable);
}
public void ResetGrabbables()
{
foreach (var state in _grabbableState)
{
if (!state.Grabbable)
{
state.Grabbable = state.Clone;
state.Grabbable.gameObject.SetActive(true);
state.Clone = Instantiate(state.Clone);
state.Clone.gameObject.SetActive(false);
state.Clone.gameObject.hideFlags = HideFlags.HideInHierarchy;
state.Grabbable.transform.parent = state.Parent;
}
if (!state.Grabbable.IsBeingHeld)
{
state.Grabbable.transform.parent = state.Parent;
state.Grabbable.transform.position = state.Position;
state.Grabbable.transform.rotation = state.Rotation;
state.Grabbable.transform.localScale = state.Scale;
state.Grabbable.Rigidbody.velocity = Vector3.zero;
state.Grabbable.Rigidbody.angularVelocity = Vector3.zero;
}
}
var remove = new List<HVRGrabbable>();
foreach (var ball in _balls)
{
if (ball.IsBeingHeld)
continue;
Destroy(ball.gameObject);
remove.Add(ball);
}
remove.ForEach(grabbable => _balls.Remove(grabbable));
}
}
}

View File

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

View File

@@ -0,0 +1,37 @@
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoHolster : HVRSocket
{
public override Vector3 GetTargetPosition(HVRGrabbable grabbable)
{
if (grabbable.TryGetComponent(out DemoHolsterOrientation orientation))
{
var offSet = -orientation.Orientation.localPosition;
var delta = Quaternion.Inverse(orientation.Orientation.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 base.GetTargetPosition(grabbable);
}
public override Quaternion GetTargetRotation(HVRGrabbable grabbable)
{
if (grabbable.TryGetComponent(out DemoHolsterOrientation orientation))
{
return Quaternion.Inverse(orientation.Orientation.localRotation);
}
return base.GetTargetRotation(grabbable);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d924166925eb40e2be6e7d5a2f425dcf
timeCreated: 1602796165

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoHolsterOrientation : MonoBehaviour
{
public Transform Orientation;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9acbeaf1abf945cebc6d902c79e4c30c
timeCreated: 1602796491

View File

@@ -0,0 +1,46 @@
using System.Collections.Generic;
using HurricaneVR.Framework.Shared;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoKeyHologram : MonoBehaviour
{
public float Interval = .2f;
public float LastMove;
public List<Vector3> Positions = new List<Vector3>();
public int Index;
#if UNITY_EDITOR
[InspectorButton("AddPositionMethod")] public string AddPosition;
public void AddPositionMethod()
{
Positions.Add(transform.localPosition);
}
#endif
void Start()
{
}
void Update()
{
if (Time.time > LastMove && Time.time - LastMove > Interval && Positions.Count > 0)
{
if (Index >= Positions.Count)
Index = 0;
transform.localPosition = Positions[Index];
Index++;
LastMove = Time.time;
}
}
public void Destroy()
{
Destroy(gameObject);
}
}
}

View File

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

View File

@@ -0,0 +1,117 @@
using HurricaneVR.Framework.Components;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoKeypad : MonoBehaviour
{
public UnityEvent Unlocked = new UnityEvent();
public string Code;
public TextMeshPro Display;
public string Entry = "";
public bool ForceUnlock;
public int Index => Entry?.Length ?? 0;
public int MaxLength => Code?.Length ?? 0;
private bool _unlocked;
protected virtual void Start()
{
var buttons = GetComponentsInChildren<DemoKeypadButton>();
var colliders = GetComponentsInChildren<Collider>();
foreach (var keyCollider in colliders)
{
foreach (var ourCollider in GetComponents<Collider>())
{
Physics.IgnoreCollision(ourCollider, keyCollider);
}
}
for (int i = 0; i < buttons.Length; i++)
{
var button = buttons[i];
button.ButtonDown.AddListener(OnButtonDown);
if (i >= 0 && i <= 9)
{
button.Key = i.ToString()[0];
}
else if (i == 10)
{
button.Key = '<';
}
else if (i == 11)
{
button.Key = '+';
}
if (button.TextMeshPro)
{
button.TextMeshPro.text = button.Key.ToString();
}
}
Entry = "";
if (Display)
{
Display.text = Entry.PadLeft(MaxLength, '*');
}
}
public virtual void Update()
{
if (ForceUnlock)
{
ForceUnlock = false;
Unlock();
}
}
protected virtual void OnButtonDown(HVRPhysicsButton button)
{
var keyPadButton = button as DemoKeypadButton;
if (keyPadButton.Key == '<')
{
if (Entry.Length > 0)
{
Entry = Entry.Substring(0, Entry.Length - 1);
}
else
{
return;
}
}
else if (keyPadButton.Key == '+')
{
if (Code == Entry)
{
Unlock();
}
}
else if (Index >= 0 && Index < MaxLength)
{
Entry += keyPadButton.Key;
}
if (Display)
{
Display.text = Entry.PadLeft(MaxLength, '*');
}
}
protected virtual void Unlock()
{
if (!_unlocked)
Unlocked.Invoke();
_unlocked = true;
Debug.Log($"unlocked!");
}
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using HurricaneVR.Framework.Components;
using TMPro;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoKeypadButton : HVRPhysicsButton
{
public char Key;
public TextMeshPro TextMeshPro;
protected override void Awake()
{
ConnectedBody = transform.parent.GetComponentInParent<Rigidbody>();
base.Awake();
}
}
}

View File

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

View File

@@ -0,0 +1,29 @@
using TMPro;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoLeverDisplay : MonoBehaviour
{
private int _step;
private float _angle;
private TextMeshPro _tm;
private void Awake()
{
_tm = GetComponent<TextMeshPro>();
}
public void OnStepChanged(int step)
{
_step = step;
_tm.text = $"{_step}/{_angle:f0}";
}
public void OnAngleChanged(float angle, float delta)
{
_angle = angle;
_tm.text = $"{_step}/{_angle:f0}";
}
}
}

View File

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

View File

@@ -0,0 +1,74 @@
using System.Collections;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using HurricaneVR.Framework.Core.Utils;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.TechDemo.Scripts
{
[RequireComponent(typeof(DemoPassthroughSocket))]
public class DemoLock : MonoBehaviour
{
public DemoPassthroughSocket Socket;
public HVRGrabbable FaceGrabbable;
public GameObject Face;
public Transform Key;
public float AnimationTime = 1f;
public AudioClip SFXUnlocked;
public AudioClip SFXKeyInserted;
public float LockThreshold = 89f;
public UnityEvent Unlocked = new UnityEvent();
private bool _unlocked;
public void Start()
{
Socket = GetComponent<DemoPassthroughSocket>();
Socket.Grabbed.AddListener(OnKeyGrabbed);
}
public void Update()
{
if (!_unlocked && FaceGrabbable.transform.localRotation.eulerAngles.x > LockThreshold)
{
_unlocked = true;
Unlocked.Invoke();
Debug.Log($"lock unlocked!");
FaceGrabbable.ForceRelease();
FaceGrabbable.Rigidbody.constraints = RigidbodyConstraints.FreezeAll;
FaceGrabbable.CanBeGrabbed = false;
FaceGrabbable.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXUnlocked, FaceGrabbable.transform.position);
}
}
private void OnKeyGrabbed(HVRGrabberBase grabber, HVRGrabbable key)
{
StartCoroutine(MoveKey(key));
}
private IEnumerator MoveKey(HVRGrabbable key)
{
var start = key.transform.position;
var startRot = key.transform.rotation;
var elapsed = 0f;
while (elapsed < AnimationTime)
{
key.transform.position = Vector3.Lerp(start, Key.position, elapsed / AnimationTime);
key.transform.rotation = Quaternion.Lerp(startRot, Key.rotation, elapsed / AnimationTime);
elapsed += Time.deltaTime;
yield return null;
}
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXKeyInserted, FaceGrabbable.transform.position);
FaceGrabbable.gameObject.SetActive(true);
Face.SetActive(false);
Destroy(key.gameObject);
}
}
}

View File

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

View File

@@ -0,0 +1,46 @@
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(HingeJoint))]
public class DemoLockedDoor : MonoBehaviour
{
private HingeJoint _hinge;
private Rigidbody _rigidbody;
public float MinAngle;
public float MaxAngle;
public bool LockOnStart = true;
void Start()
{
_hinge = GetComponent<HingeJoint>();
_rigidbody = GetComponent<Rigidbody>();
if (LockOnStart)
Lock();
}
private void Lock()
{
var limit = _hinge.limits;
limit.min = 0f;
limit.max = 0f;
_hinge.limits = limit;
_rigidbody.constraints = RigidbodyConstraints.FreezeAll;
}
public void Unlock()
{
var limits = _hinge.limits;
limits.min = MinAngle;
limits.max = MaxAngle;
_hinge.limits = limits;
_rigidbody.constraints = RigidbodyConstraints.None;
}
}
}

View File

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

View File

@@ -0,0 +1,34 @@
using System.Linq;
using HurricaneVR.Framework.Core.Player;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoManualTeleport : MonoBehaviour
{
public Transform PositionOne;
public Transform PositionTwo;
public HVRTeleporter Teleporter { get; set; }
public void Start()
{
Teleporter = GameObject.FindObjectsOfType<HVRTeleporter>().FirstOrDefault(e => e.gameObject.activeInHierarchy);
}
public void GoToOne()
{
if (Teleporter && PositionOne)
{
Teleporter.Teleport(PositionOne.position, PositionOne.forward);
}
}
public void GoToTwo()
{
if (Teleporter && PositionTwo)
{
Teleporter.Teleport(PositionTwo.position, PositionTwo.forward);
}
}
}
}

View File

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

View File

@@ -0,0 +1,28 @@
using HurricaneVR.Framework.Core.Grabbers;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoPassthroughSocket : HVRSocket
{
protected override void Start()
{
base.Start();
ScaleGrabbable = false;
GrabbableMustBeHeld = true;
GrabsFromHand = true;
CanRemoveGrabbable = false;
ParentDisablesGrab = true;
}
protected override void OnGrabbed(HVRGrabArgs args)
{
AllowGrabbing = false;
AllowHovering = false;
args.Cancel = true;
Grabbed.Invoke(this, args.Grabbable);
ForceRelease();
PlaySocketedSFX(args.Grabbable.Socketable);
}
}
}

View File

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

View File

@@ -0,0 +1,66 @@
using HurricaneVR.Framework.Components;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using HurricaneVR.Framework.Core.Utils;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoPowerUnit : MonoBehaviour
{
public UnityEvent PoweredUp = new UnityEvent();
public HVRSocket LeftSocket;
public HVRSocket RightSocket;
public MeshRenderer LeftLight;
public MeshRenderer RightLight;
public HVRRotationTracker LeverRotation;
public float RequiredAngle = 175f;
public AudioClip SFXPoweredOn;
public int RequiredCells = 2;
public int SocketedCellCount;
public bool Engaged;
public Material OnMaterial;
public bool IsPoweredUp => SocketedCellCount == RequiredCells;
void Start()
{
LeftSocket.Grabbed.AddListener(OnLeftSocketGrabbed);
RightSocket.Grabbed.AddListener(OnRightSocketGrabbed);
}
private void OnRightSocketGrabbed(HVRGrabberBase arg0, HVRGrabbable arg1)
{
SocketedCellCount++;
var mats = RightLight.materials;
mats[0] = OnMaterial;
RightLight.materials = mats;
}
private void OnLeftSocketGrabbed(HVRGrabberBase arg0, HVRGrabbable arg1)
{
SocketedCellCount++;
var mats = LeftLight.materials;
mats[0] = OnMaterial;
LeftLight.materials = mats;
}
void Update()
{
if (LeverRotation.Angle > RequiredAngle && IsPoweredUp && !Engaged)
{
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(SFXPoweredOn, LeftSocket.transform.position);
Engaged = true;
PoweredUp.Invoke();
Debug.Log($"poweredup!");
}
}
}
}

View File

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

View File

@@ -0,0 +1,176 @@
using HurricaneVR.Framework.Components;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
namespace HurricaneVR.TechDemo.Scripts
{
public enum SafeDialState
{
CamOne,
CamTwo,
CamThree,
Unlocked
}
public class DemoSafeDial : HVRRotationTracker
{
public TextMeshPro NumberLabel;
public TextMeshPro DebugLabel;
public bool DisplayDebug;
public int First = 30;
public int Second = 15;
public int Third = 01;
public int CurrentNumber;
public float CamDistance;
public float PreviousDistance;
public float Tolerance = 40f;
public float LowerBound = 0f;
public float UpperBound = 0f;
public int AccuracyAllowance = 1;
public UnityEvent Unlocked = new UnityEvent();
private SafeDialState _state;
public SafeDialState State
{
get { return _state; }
set
{
_state = value;
ComputeBounds();
}
}
public int NumberOfRotations
{
get
{
return ((int)Mathf.Abs(CamDistance)) / 355;
}
}
protected override void Start()
{
base.Start();
ResetLockState(SafeDialState.CamOne);
if (DebugLabel)
{
DebugLabel.text = $"Code:{First},{Second},{Third}\r\n Dist: {CamDistance:f0}\r\nState: {State}\r\nTolerance: {Tolerance:f0}\r\nL_Bound: {LowerBound:f0}\r\nU_Bound: {UpperBound:f0}";
}
}
private void ComputeBounds()
{
switch (State)
{
case SafeDialState.CamOne:
LowerBound = 0f;
UpperBound = 1080f;
break;
case SafeDialState.CamTwo:
LowerBound = -360f - (360 - Second * StepSize);
UpperBound = 0f + Tolerance;
break;
case SafeDialState.CamThree:
if (Third < Second)
{
UpperBound = (Steps - Second + Third) * StepSize;
}
else
{
UpperBound = (Third - Second) * StepSize;
}
LowerBound = 0f;
break;
case SafeDialState.Unlocked:
break;
}
LowerBound -= Tolerance;
UpperBound += Tolerance;
}
protected override void Update()
{
base.Update();
}
public bool IsFirstInRange => CurrentNumber >= First - AccuracyAllowance && CurrentNumber <= First + AccuracyAllowance;
public bool IsSecondInRange => CurrentNumber >= Second - AccuracyAllowance && CurrentNumber <= Second + AccuracyAllowance;
public bool IsThirdInRange => CurrentNumber >= Third - AccuracyAllowance && CurrentNumber <= Third + AccuracyAllowance;
public void ResetLockState(SafeDialState state)
{
State = state;
CamDistance = 0f;
PreviousDistance = 0f;
}
protected override void OnStepChanged(int step, bool raiseEvents)
{
base.OnStepChanged(step, raiseEvents);
CurrentNumber = step;
if (NumberLabel)
{
NumberLabel.text = CurrentNumber.ToString("n0");
}
if (DebugLabel)
{
DebugLabel.text = $"Code:{First},{Second},{Third}\r\n Dist: {CamDistance:f0}\r\nState: {State}\r\nTolerance: {Tolerance:f0}\r\nL_Bound: {LowerBound:f0}\r\nU_Bound: {UpperBound:f0}";
}
}
protected override void OnAngleChanged(float angle, float delta)
{
CamDistance += delta;
if (CamDistance < LowerBound)
{
ResetLockState(SafeDialState.CamOne);
}
else if (CamDistance > UpperBound && State != SafeDialState.CamOne)
{
if (State == SafeDialState.CamTwo)
{
CamDistance = 1080f;
State = SafeDialState.CamOne;
}
else
{
ResetLockState(SafeDialState.CamOne);
}
}
if (State == SafeDialState.CamOne && NumberOfRotations >= 3 && IsFirstInRange)
{
ResetLockState(SafeDialState.CamTwo);
}
else if (State == SafeDialState.CamTwo && NumberOfRotations == 1 && IsSecondInRange)
{
ResetLockState(SafeDialState.CamThree);
}
else if (State == SafeDialState.CamThree && IsThirdInRange)
{
State = SafeDialState.Unlocked;
Unlocked.Invoke();
}
}
}
}

View File

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

View File

@@ -0,0 +1,9 @@
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoSafeDoor : MonoBehaviour
{
}
}

View File

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

View File

@@ -0,0 +1,66 @@
using System.Collections;
using HurricaneVR.Framework.Core.Utils;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoSlidingDoor : MonoBehaviour
{
public Rigidbody LeftDoor;
public Rigidbody RightDoor;
public Transform Lock;
public float LockRotateTime = 1;
public float LockRotateAngles = 360;
public float OpenOffset = .5f;
public float Speed = 1f;
public AudioClip OpenedClip;
private bool _opened;
public void Start()
{
//this.ExecuteAfterSeconds(OpenDoors, 1);
}
public void OpenDoors()
{
if (_opened)
return;
_opened = true;
if(SFXPlayer.Instance) SFXPlayer.Instance.PlaySFX(OpenedClip, transform.position);
StartCoroutine(OpenDoorRoutine());
}
private IEnumerator OpenDoorRoutine()
{
var elapsed = 0f;
var LockRotateSpeed = LockRotateAngles / LockRotateTime * Time.deltaTime;
while (elapsed < LockRotateTime)
{
Lock.localRotation *= Quaternion.Euler(0f, 0f, LockRotateSpeed);
yield return null;
elapsed += Time.deltaTime;
}
elapsed = 0f;
var time = OpenOffset / Speed + (2 * Time.fixedDeltaTime);
while (elapsed < time)
{
yield return new WaitForFixedUpdate();
var next = Vector3.MoveTowards(LeftDoor.transform.position, LeftDoor.transform.parent.TransformPoint(new Vector3(-OpenOffset, 0f, 0f)), Speed * Time.fixedDeltaTime);
LeftDoor.MovePosition(next);
next = Vector3.MoveTowards(RightDoor.transform.position, RightDoor.transform.parent.TransformPoint(new Vector3(OpenOffset, 0f, 0f)), Speed * Time.fixedDeltaTime);
RightDoor.MovePosition(next);
elapsed += Time.fixedDeltaTime;
}
}
}
}

View File

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

View File

@@ -0,0 +1,9 @@
using HurricaneVR.Framework.Core.Sockets;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoSocketFilter : HVREnumFlagsSocketFilter<DemoSocketableItems>
{
}
}

View File

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

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections;
using System.Collections.Generic;
using HurricaneVR.Framework.Core.Sockets;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoSocketables : HVREnumFlagsSocketable<DemoSocketableItems>
{
}
[Flags]
public enum DemoSocketableItems
{
None = 0,
Pistol = 1 << 0,
PistolMagazine = 1 << 1,
SMG = 1 << 2,
SMGMagazine = 1 << 3,
PowerCell = 1 << 4,
SmallObject = 1 << 5,
LargeObject = 1 << 6,
DoorKey = 1 << 7,
ShotgunShell = 1 << 8,
Valve = 1 << 9,
Key = 1 << 10,
All = ~0
}
}

View File

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

View File

@@ -0,0 +1,223 @@
using System.Linq;
using HurricaneVR.Framework.ControllerInput;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using HurricaneVR.Framework.Core.Player;
using HurricaneVR.Framework.Shared;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoUIManager : MonoBehaviour
{
public HVRPlayerController Player;
public HVRCameraRig CameraRig;
public HVRPlayerInputs Inputs;
public TextMeshProUGUI SitStandText;
public TextMeshProUGUI PauseText;
public TextMeshProUGUI ForceGrabText;
public TextMeshProUGUI LeftForceText;
public TextMeshProUGUI RightForceText;
public Slider TurnRateSlider;
public Slider SnapTurnSlider;
public TextMeshProUGUI TurnRateText;
public TextMeshProUGUI SnapRateText;
public Toggle SmoothTurnToggle;
public Toggle LineGrabTrigger;
public HVRForceGrabber LeftForce;
public HVRForceGrabber RightForce;
public HVRJointHand LeftHand;
public HVRJointHand RightHand;
private Transform leftparent;
private Transform rightParent;
private bool Paused;
void Start()
{
if (!Player)
{
Player = GameObject.FindObjectsOfType<HVRPlayerController>().FirstOrDefault(e => e.gameObject.activeInHierarchy);
}
if (Player)
{
if (!CameraRig)
{
CameraRig = Player.GetComponentInChildren<HVRCameraRig>();
}
if (!Inputs)
{
Inputs = Player.GetComponentInChildren<HVRPlayerInputs>();
}
if (!LeftHand) LeftHand = Player.Root.GetComponentsInChildren<HVRHandGrabber>().FirstOrDefault(e => e.HandSide == HVRHandSide.Left)?.GetComponent<HVRJointHand>();
if (!RightHand) RightHand = Player.Root.GetComponentsInChildren<HVRHandGrabber>().FirstOrDefault(e => e.HandSide == HVRHandSide.Right)?.GetComponent<HVRJointHand>();
}
if(LeftHand) leftparent = LeftHand.transform.parent;
if(RightHand)rightParent = RightHand.transform.parent;
UpdateSitStandButton();
UpdateForceGrabButton();
TurnRateSlider.value = Player.SmoothTurnSpeed;
SnapTurnSlider.value = Player.SnapAmount;
TurnRateText.text = Player.SmoothTurnSpeed.ToString();
SnapRateText.text = Player.SnapAmount.ToString();
SmoothTurnToggle.isOn = Player.RotationType == RotationType.Smooth;
LineGrabTrigger.isOn = HVRSettings.Instance.LineGrabTriggerLoose;
TurnRateSlider.onValueChanged.AddListener(OnTurnRateChanged);
SnapTurnSlider.onValueChanged.AddListener(OnSnapTurnRateChanged);
SmoothTurnToggle.onValueChanged.AddListener(OnSmoothTurnChanged);
LineGrabTrigger.onValueChanged.AddListener(OnLineGrabTriggerChanged);
LeftForce = Player.transform.root.GetComponentsInChildren<HVRForceGrabber>().FirstOrDefault(e => e.HandSide == HVRHandSide.Left);
RightForce = Player.transform.root.GetComponentsInChildren<HVRForceGrabber>().FirstOrDefault(e => e.HandSide == HVRHandSide.Right);
UpdateLeftForceButton();
UpdateRightForceButton();
}
private void OnLineGrabTriggerChanged(bool arg0)
{
HVRSettings.Instance.LineGrabTriggerLoose = arg0;
}
public void CalibrateHeight()
{
if (CameraRig)
CameraRig.Calibrate();
}
public void OnSitStandClicked()
{
var index = (int)CameraRig.SitStanding;
index++;
if (index > 2)
{
index = 0;
}
CameraRig.SetSitStandMode((HVRSitStand)index);
UpdateSitStandButton();
}
public void OnForceGrabClicked()
{
var index = (int)Inputs.ForceGrabActivation;
index++;
if (index > (int)HVRForceGrabActivation.GripOrTrigger)
{
index = 0;
}
Inputs.ForceGrabActivation = (HVRForceGrabActivation)index;
UpdateForceGrabButton();
}
private void UpdateForceGrabButton()
{
ForceGrabText.text = Inputs.ForceGrabActivation.ToString();
}
private void UpdateSitStandButton()
{
SitStandText.text = CameraRig.SitStanding.ToString();
}
public void OnTurnRateChanged(float rate)
{
Player.SmoothTurnSpeed = rate;
TurnRateText.text = Player.SmoothTurnSpeed.ToString();
}
public void OnSnapTurnRateChanged(float rate)
{
Player.SnapAmount = rate;
SnapRateText.text = Player.SnapAmount.ToString();
}
public void OnSmoothTurnChanged(bool smooth)
{
Player.RotationType = smooth ? RotationType.Smooth : RotationType.Snap;
}
public void OnLeftForceGrabModeClicked()
{
if (LeftForce)
{
if (LeftForce.GrabStyle == HVRForceGrabMode.ForcePull)
{
LeftForce.GrabStyle = HVRForceGrabMode.GravityGloves;
}
else
{
LeftForce.GrabStyle = HVRForceGrabMode.ForcePull;
}
UpdateLeftForceButton();
}
}
public void OnRightForceGrabModeClicked()
{
if (RightForce)
{
if (RightForce.GrabStyle == HVRForceGrabMode.ForcePull)
{
RightForce.GrabStyle = HVRForceGrabMode.GravityGloves;
}
else
{
RightForce.GrabStyle = HVRForceGrabMode.ForcePull;
}
UpdateRightForceButton();
}
}
private void UpdateLeftForceButton()
{
LeftForceText.text = LeftForce.GrabStyle.ToString();
}
private void UpdateRightForceButton()
{
RightForceText.text = RightForce.GrabStyle.ToString();
}
public void TogglePause()
{
if (LeftHand && RightHand)
{
if (Paused)
{
PauseText.text = "Pause";
Time.timeScale = 1f;
LeftHand.transform.parent = leftparent;
RightHand.transform.parent = rightParent;
}
else
{
PauseText.text = "Unpause";
Time.timeScale = .00000001f;
LeftHand.transform.parent = LeftHand.Target;
RightHand.transform.parent = RightHand.Target;
}
Paused = !Paused;
}
}
}
}

View File

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

View File

@@ -0,0 +1,59 @@
using HurricaneVR.Framework.Shared;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
public class DemoValveHologram : MonoBehaviour
{
public float Interval = .2f;
public Quaternion StartRotation;
public Quaternion EndRotation;
private Quaternion _current;
private Quaternion _next;
private float _elapsed;
#if UNITY_EDITOR
[InspectorButton("SaveStartRotationMethod")]
public string SaveStartRotation;
[InspectorButton("SaveEndRotationMethod")]
public string SaveEndRotation;
public void SaveStartRotationMethod()
{
StartRotation = transform.localRotation;
}
public void SaveEndRotationMethod()
{
EndRotation = transform.localRotation;
}
#endif
void Start()
{
_current = StartRotation;
_next = EndRotation;
}
void Update()
{
_elapsed += Time.deltaTime;
if (_elapsed > Interval)
{
var temp = _current;
_current = _next;
_next = temp;
_elapsed = 0f;
}
transform.localRotation = Quaternion.Lerp(_current, _next, _elapsed / Interval);
}
public void Destroy()
{
Destroy(gameObject);
}
}
}

View File

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

View File

@@ -0,0 +1,51 @@
using System.Collections;
using HurricaneVR.Framework.Core;
using HurricaneVR.Framework.Core.Grabbers;
using UnityEngine;
namespace HurricaneVR.TechDemo.Scripts
{
[RequireComponent(typeof(DemoPassthroughSocket))]
public class DemoValveLock : MonoBehaviour
{
public DemoPassthroughSocket Socket;
public HVRGrabbable FaceGrabbable;
public float AnimationTime = 1f;
public void Start()
{
Socket = GetComponent<DemoPassthroughSocket>();
Socket.Grabbed.AddListener(OnValveGrabbed);
}
public void Update()
{
}
private void OnValveGrabbed(HVRGrabberBase grabber, HVRGrabbable key)
{
StartCoroutine(MoveKey(key));
}
private IEnumerator MoveKey(HVRGrabbable key)
{
var start = key.transform.position;
var startRot = key.transform.rotation;
var elapsed = 0f;
while (elapsed < AnimationTime)
{
key.transform.position = Vector3.Lerp(start, FaceGrabbable.transform.position, elapsed / AnimationTime);
key.transform.rotation = Quaternion.Lerp(startRot, FaceGrabbable.transform.rotation, elapsed / AnimationTime);
elapsed += Time.deltaTime;
yield return null;
}
FaceGrabbable.gameObject.SetActive(true);
Destroy(key.gameObject);
}
}
}

View File

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