123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- namespace Valve.VR.InteractionSystem
- {
- public class HandCollider : MonoBehaviour
- {
- private new Rigidbody rigidbody;
- [HideInInspector]
- public HandPhysics hand;
- public LayerMask collisionMask;
- Collider[] colliders;
- public FingerColliders fingerColliders;
- [System.Serializable]
- public class FingerColliders
- {
- [Tooltip("Starting at tip and going down. Max 2.")]
- public Transform[] thumbColliders = new Transform[1];
- [Tooltip("Starting at tip and going down. Max 3.")]
- public Transform[] indexColliders = new Transform[2];
- [Tooltip("Starting at tip and going down. Max 3.")]
- public Transform[] middleColliders = new Transform[2];
- [Tooltip("Starting at tip and going down. Max 3.")]
- public Transform[] ringColliders = new Transform[2];
- [Tooltip("Starting at tip and going down. Max 3.")]
- public Transform[] pinkyColliders = new Transform[2];
- public Transform[] this[int finger]
- {
- get
- {
- switch (finger)
- {
- case 0:
- return thumbColliders;
- case 1:
- return indexColliders;
- case 2:
- return middleColliders;
- case 3:
- return ringColliders;
- case 4:
- return pinkyColliders;
- default:
- return null;
- }
- }
- set
- {
- switch (finger)
- {
- case 0:
- thumbColliders = value; break;
- case 1:
- indexColliders = value; break;
- case 2:
- middleColliders = value; break;
- case 3:
- ringColliders = value; break;
- case 4:
- pinkyColliders = value; break;
- }
- }
- }
- }
- private static PhysicMaterial physicMaterial_lowfriction;
- private static PhysicMaterial physicMaterial_highfriction;
- private void Awake()
- {
- rigidbody = GetComponent<Rigidbody>();
- rigidbody.maxAngularVelocity = 50;
- }
- private void Start()
- {
- colliders = GetComponentsInChildren<Collider>();
- if (physicMaterial_lowfriction == null)
- {
- physicMaterial_lowfriction = new PhysicMaterial("hand_lowFriction");
- physicMaterial_lowfriction.dynamicFriction = 0;
- physicMaterial_lowfriction.staticFriction = 0;
- physicMaterial_lowfriction.bounciness = 0;
- physicMaterial_lowfriction.bounceCombine = PhysicMaterialCombine.Minimum;
- physicMaterial_lowfriction.frictionCombine = PhysicMaterialCombine.Minimum;
- }
- if (physicMaterial_highfriction == null)
- {
- physicMaterial_highfriction = new PhysicMaterial("hand_highFriction");
- physicMaterial_highfriction.dynamicFriction = 1f;
- physicMaterial_highfriction.staticFriction = 1f;
- physicMaterial_highfriction.bounciness = 0;
- physicMaterial_highfriction.bounceCombine = PhysicMaterialCombine.Minimum;
- physicMaterial_highfriction.frictionCombine = PhysicMaterialCombine.Average;
- }
- SetPhysicMaterial(physicMaterial_lowfriction);
- scale = SteamVR_Utils.GetLossyScale(hand.transform);
- }
- void SetPhysicMaterial(PhysicMaterial mat)
- {
- if (colliders == null) colliders = GetComponentsInChildren<Collider>();
- for (int i = 0; i < colliders.Length; i++)
- {
- colliders[i].sharedMaterial = mat;
- }
- }
- float scale;
- public void SetCollisionDetectionEnabled(bool value)
- {
- rigidbody.detectCollisions = value;
- }
- public void MoveTo(Vector3 position, Quaternion rotation)
- {
- targetPosition = position;
- targetRotation = rotation;
- //rigidbody.MovePosition(position);
- //rigidbody.MoveRotation(rotation);
- ExecuteFixedUpdate();
- }
- public void TeleportTo(Vector3 position, Quaternion rotation)
- {
- targetPosition = position;
- targetRotation = rotation;
- MoveTo(position, rotation);
- rigidbody.position = position;
- if (rotation.x != 0 || rotation.y != 0 || rotation.z != 0 || rotation.w != 0)
- rigidbody.rotation = rotation;
- //also update transform in case physics is disabled
- transform.position = position;
- transform.rotation = rotation;
- }
- public void Reset()
- {
- TeleportTo(targetPosition, targetRotation);
- }
- public void SetCenterPoint(Vector3 newCenter)
- {
- center = newCenter;
- }
- private Vector3 center;
- private Vector3 targetPosition = Vector3.zero;
- private Quaternion targetRotation = Quaternion.identity;
- protected const float MaxVelocityChange = 10f;
- protected const float VelocityMagic = 6000f;
- protected const float AngularVelocityMagic = 50f;
- protected const float MaxAngularVelocityChange = 20f;
- public bool collidersInRadius;
- protected void ExecuteFixedUpdate()
- {
- collidersInRadius = Physics.CheckSphere(center, 0.2f, collisionMask);
- if (collidersInRadius == false)
- {
- //keep updating velocity, just in case. Otherwise you get jitter
- rigidbody.velocity = Vector3.zero;
- rigidbody.angularVelocity = Vector3.zero;
- /*
- rigidbody.velocity = (targetPosition - rigidbody.position) / Time.fixedDeltaTime;
- float angle; Vector3 axis;
- (targetRotation * Quaternion.Inverse(rigidbody.rotation)).ToAngleAxis(out angle, out axis);
- rigidbody.angularVelocity = axis.normalized * angle / Time.fixedDeltaTime;
- */
- rigidbody.MovePosition(targetPosition);
- rigidbody.MoveRotation(targetRotation);
- }
- else
- {
- Vector3 velocityTarget, angularTarget;
- bool success = GetTargetVelocities(out velocityTarget, out angularTarget);
- if (success)
- {
- float maxAngularVelocityChange = MaxAngularVelocityChange * scale;
- float maxVelocityChange = MaxVelocityChange * scale;
- rigidbody.velocity = Vector3.MoveTowards(rigidbody.velocity, velocityTarget, maxVelocityChange);
- rigidbody.angularVelocity = Vector3.MoveTowards(rigidbody.angularVelocity, angularTarget, maxAngularVelocityChange);
- }
- }
- }
- protected bool GetTargetVelocities(out Vector3 velocityTarget, out Vector3 angularTarget)
- {
- bool realNumbers = false;
- float velocityMagic = VelocityMagic;
- float angularVelocityMagic = AngularVelocityMagic;
- Vector3 positionDelta = (targetPosition - rigidbody.position);
- velocityTarget = (positionDelta * velocityMagic * Time.deltaTime);
- if (float.IsNaN(velocityTarget.x) == false && float.IsInfinity(velocityTarget.x) == false)
- {
- realNumbers = true;
- }
- else
- velocityTarget = Vector3.zero;
- Quaternion rotationDelta = targetRotation * Quaternion.Inverse(rigidbody.rotation);
- float angle;
- Vector3 axis;
- rotationDelta.ToAngleAxis(out angle, out axis);
- if (angle > 180)
- angle -= 360;
- if (angle != 0 && float.IsNaN(axis.x) == false && float.IsInfinity(axis.x) == false)
- {
- angularTarget = angle * axis * angularVelocityMagic * Time.deltaTime;
- realNumbers &= true;
- }
- else
- angularTarget = Vector3.zero;
- return realNumbers;
- }
- const float minCollisionEnergy = 0.1f;
- const float maxCollisionEnergy = 1.0f;
- const float minCollisionHapticsTime = 0.2f;
- private float lastCollisionHapticsTime;
- private void OnCollisionEnter(Collision collision)
- {
- bool touchingDynamic = false;
- if (collision.rigidbody != null)
- {
- if (collision.rigidbody.isKinematic == false) touchingDynamic = true;
- }
- // low friction if touching static object, high friction if touching dynamic
- SetPhysicMaterial(touchingDynamic ? physicMaterial_highfriction : physicMaterial_lowfriction);
- float energy = collision.relativeVelocity.magnitude;
- if(energy > minCollisionEnergy && Time.time - lastCollisionHapticsTime > minCollisionHapticsTime)
- {
- lastCollisionHapticsTime = Time.time;
- float intensity = Util.RemapNumber(energy, minCollisionEnergy, maxCollisionEnergy, 0.3f, 1.0f);
- float length = Util.RemapNumber(energy, minCollisionEnergy, maxCollisionEnergy, 0.0f, 0.06f);
- hand.hand.TriggerHapticPulse(length, 100, intensity);
- }
- }
- }
- }
|