csharp SteamVR手交互实例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp SteamVR手交互实例相关的知识,希望对你有一定的参考价值。
[RequireComponent( typeof( Interactable ) )]
public class InteractableSimple : MonoBehaviour
{
private TextMesh textMesh;
private Vector3 oldPosition;
private Quaternion oldRotation;
private float attachTime;
private Hand.AttachmentFlags attachmentFlags =
Hand.defaultAttachmentFlags & // AttachmentFlags.ParentToHand | AttachmentFlags.DetachOthers
// | AttachmentFlags.DetachFromOtherHand | AttachmentFlags.TurnOnKinematic | AttachmentFlags.SnapOnAttach;
( ~Hand.AttachmentFlags.SnapOnAttach ) & // The object should snap to the position of the specified attachment point on the hand.
(~Hand.AttachmentFlags.DetachOthers) & // Other objects attached to this hand will be detached.
(~Hand.AttachmentFlags.VelocityMovement); // The object will attempt to move to match the position and rotation of the hand.
private Interactable interactable;
//-------------------------------------------------
void Awake()
{
textMesh = GetComponentInChildren<TextMesh>();
textMesh.text = "No Hand Hovering";
interactable = this.GetComponent<Interactable>();
}
//-------------------------------------------------
// Called when a Hand starts hovering over this object
//-------------------------------------------------
private void OnHandHoverBegin( Hand hand )
{
textMesh.text = "Hovering hand: " + hand.name;
}
//-------------------------------------------------
// Called when a Hand stops hovering over this object
//-------------------------------------------------
private void OnHandHoverEnd( Hand hand )
{
textMesh.text = "No Hand Hovering";
}
//-------------------------------------------------
// Called every Update() while a Hand is hovering over this object
//-------------------------------------------------
private void HandHoverUpdate( Hand hand )
{
GrabTypes startingGrabType = hand.GetGrabStarting();
bool isGrabEnding = hand.IsGrabEnding(this.gameObject);
if (interactable.attachedToHand == null && startingGrabType != GrabTypes.None)
{
// Save our position/rotation so that we can restore it when we detach
oldPosition = transform.position;
oldRotation = transform.rotation;
// Call this to continue receiving HandHoverUpdate messages,
// and prevent the hand from hovering over anything else
hand.HoverLock(interactable);
// Attach this object to the hand
hand.AttachObject(gameObject, startingGrabType, attachmentFlags);
}
else if (isGrabEnding)
{
// Detach this object from the hand
hand.DetachObject(gameObject);
// Call this to undo HoverLock
hand.HoverUnlock(interactable);
// Restore position/rotation
transform.position = oldPosition;
transform.rotation = oldRotation;
}
}
//-------------------------------------------------
// Called when this GameObject becomes attached to the hand
//-------------------------------------------------
private void OnAttachedToHand( Hand hand )
{
textMesh.text = "Attached to hand: " + hand.name;
attachTime = Time.time;
}
//-------------------------------------------------
// Called when this GameObject is detached from the hand
//-------------------------------------------------
private void OnDetachedFromHand( Hand hand )
{
textMesh.text = "Detached from hand: " + hand.name;
}
//-------------------------------------------------
// Called every Update() while this GameObject is attached to the hand
//-------------------------------------------------
private void HandAttachedUpdate( Hand hand )
{
textMesh.text = "Attached to hand: " + hand.name + "\nAttached time: " + ( Time.time - attachTime ).ToString( "F2" );
}
//-------------------------------------------------
// Called when this attached GameObject becomes the primary attached object
//-------------------------------------------------
private void OnHandFocusAcquired( Hand hand )
{
}
//-------------------------------------------------
// Called when another attached GameObject becomes the primary attached object
//-------------------------------------------------
private void OnHandFocusLost( Hand hand )
{
}
}
//-------------------------------------------------------------------------
[RequireComponent( typeof( Interactable ) )]
[RequireComponent( typeof( Rigidbody ) )]
[RequireComponent( typeof(VelocityEstimator))]
public class Throwable : MonoBehaviour
{
[EnumFlags]
[Tooltip( "The flags used to attach this object to the hand." )]
public Hand.AttachmentFlags attachmentFlags = Hand.AttachmentFlags.ParentToHand | Hand.AttachmentFlags.DetachFromOtherHand | Hand.AttachmentFlags.TurnOnKinematic;
[Tooltip("The local point which acts as a positional and rotational offset to use while held")]
public Transform attachmentOffset;
[Tooltip( "How fast must this object be moving to attach due to a trigger hold instead of a trigger press? (-1 to disable)" )]
public float catchingSpeedThreshold = -1;
public ReleaseStyle releaseVelocityStyle = ReleaseStyle.GetFromHand;
[Tooltip("The time offset used when releasing the object with the RawFromHand option")]
public float releaseVelocityTimeOffset = -0.011f;
public float scaleReleaseVelocity = 1.1f;
[Tooltip( "When detaching the object, should it return to its original parent?" )]
public bool restoreOriginalParent = false;
public bool attachEaseIn = false;
public AnimationCurve snapAttachEaseInCurve = AnimationCurve.EaseInOut( 0.0f, 0.0f, 1.0f, 1.0f );
public float snapAttachEaseInTime = 0.15f;
protected VelocityEstimator velocityEstimator;
protected bool attached = false;
protected float attachTime;
protected Vector3 attachPosition;
protected Quaternion attachRotation;
protected Transform attachEaseInTransform;
public UnityEvent onPickUp;
public UnityEvent onDetachFromHand;
public bool snapAttachEaseInCompleted = false;
protected RigidbodyInterpolation hadInterpolation = RigidbodyInterpolation.None;
protected new Rigidbody rigidbody;
[HideInInspector]
public Interactable interactable;
//-------------------------------------------------
protected virtual void Awake()
{
velocityEstimator = GetComponent<VelocityEstimator>();
interactable = GetComponent<Interactable>();
if ( attachEaseIn )
{
attachmentFlags &= ~Hand.AttachmentFlags.SnapOnAttach;
}
rigidbody = GetComponent<Rigidbody>();
rigidbody.maxAngularVelocity = 50.0f;
if(attachmentOffset != null)
{
interactable.handFollowTransform = attachmentOffset;
}
}
//-------------------------------------------------
protected virtual void OnHandHoverBegin( Hand hand )
{
bool showHint = false;
// "Catch" the throwable by holding down the interaction button instead of pressing it.
// Only do this if the throwable is moving faster than the prescribed threshold speed,
// and if it isn't attached to another hand
if ( !attached && catchingSpeedThreshold != -1)
{
float catchingThreshold = catchingSpeedThreshold * SteamVR_Utils.GetLossyScale(Player.instance.trackingOriginTransform);
GrabTypes bestGrabType = hand.GetBestGrabbingType();
if ( bestGrabType != GrabTypes.None )
{
if (rigidbody.velocity.magnitude >= catchingThreshold)
{
hand.AttachObject( gameObject, bestGrabType, attachmentFlags );
showHint = false;
}
}
}
if ( showHint )
{
hand.ShowGrabHint();
}
}
//-------------------------------------------------
protected virtual void OnHandHoverEnd( Hand hand )
{
hand.HideGrabHint();
}
//-------------------------------------------------
protected virtual void HandHoverUpdate( Hand hand )
{
GrabTypes startingGrabType = hand.GetGrabStarting();
if (startingGrabType != GrabTypes.None)
{
hand.AttachObject( gameObject, startingGrabType, attachmentFlags, attachmentOffset );
hand.HideGrabHint();
}
}
//-------------------------------------------------
protected virtual void OnAttachedToHand( Hand hand )
{
//Debug.Log("Pickup: " + hand.GetGrabStarting().ToString());
hadInterpolation = this.rigidbody.interpolation;
attached = true;
onPickUp.Invoke();
hand.HoverLock( null );
rigidbody.interpolation = RigidbodyInterpolation.None;
velocityEstimator.BeginEstimatingVelocity();
attachTime = Time.time;
attachPosition = transform.position;
attachRotation = transform.rotation;
if ( attachEaseIn )
{
attachEaseInTransform = hand.objectAttachmentPoint;
}
snapAttachEaseInCompleted = false;
}
//-------------------------------------------------
protected virtual void OnDetachedFromHand(Hand hand)
{
attached = false;
onDetachFromHand.Invoke();
hand.HoverUnlock(null);
rigidbody.interpolation = hadInterpolation;
Vector3 velocity;
Vector3 angularVelocity;
GetReleaseVelocities(hand, out velocity, out angularVelocity);
rigidbody.velocity = velocity;
rigidbody.angularVelocity = angularVelocity;
}
public virtual void GetReleaseVelocities(Hand hand, out Vector3 velocity, out Vector3 angularVelocity)
{
switch (releaseVelocityStyle)
{
case ReleaseStyle.ShortEstimation:
velocityEstimator.FinishEstimatingVelocity();
velocity = velocityEstimator.GetVelocityEstimate();
angularVelocity = velocityEstimator.GetAngularVelocityEstimate();
break;
case ReleaseStyle.AdvancedEstimation:
hand.GetEstimatedPeakVelocities(out velocity, out angularVelocity);
break;
case ReleaseStyle.GetFromHand:
velocity = hand.GetTrackedObjectVelocity(releaseVelocityTimeOffset);
angularVelocity = hand.GetTrackedObjectAngularVelocity(releaseVelocityTimeOffset);
break;
default:
case ReleaseStyle.NoChange:
velocity = rigidbody.velocity;
angularVelocity = rigidbody.angularVelocity;
break;
}
if (releaseVelocityStyle != ReleaseStyle.NoChange)
velocity *= scaleReleaseVelocity;
}
//-------------------------------------------------
protected virtual void HandAttachedUpdate(Hand hand)
{
if (attachEaseIn)
{
float t = Util.RemapNumberClamped(Time.time, attachTime, attachTime + snapAttachEaseInTime, 0.0f, 1.0f);
if (t < 1.0f)
{
t = snapAttachEaseInCurve.Evaluate(t);
transform.position = Vector3.Lerp(attachPosition, attachEaseInTransform.position, t);
transform.rotation = Quaternion.Lerp(attachRotation, attachEaseInTransform.rotation, t);
}
else if (!snapAttachEaseInCompleted)
{
gameObject.SendMessage("OnThrowableAttachEaseInCompleted", hand, SendMessageOptions.DontRequireReceiver);
snapAttachEaseInCompleted = true;
}
}
if (hand.IsGrabEnding(this.gameObject))
{
hand.DetachObject(gameObject, restoreOriginalParent);
// Uncomment to detach ourselves late in the frame.
// This is so that any vehicles the player is attached to
// have a chance to finish updating themselves.
// If we detach now, our position could be behind what it
// will be at the end of the frame, and the object may appear
// to teleport behind the hand when the player releases it.
//StartCoroutine( LateDetach( hand ) );
}
}
//-------------------------------------------------
protected virtual IEnumerator LateDetach( Hand hand )
{
yield return new WaitForEndOfFrame();
hand.DetachObject( gameObject, restoreOriginalParent );
}
//-------------------------------------------------
protected virtual void OnHandFocusAcquired( Hand hand )
{
gameObject.SetActive( true );
velocityEstimator.BeginEstimatingVelocity();
}
//-------------------------------------------------
protected virtual void OnHandFocusLost( Hand hand )
{
gameObject.SetActive( false );
velocityEstimator.FinishEstimatingVelocity();
}
}
public enum ReleaseStyle
{
NoChange,
GetFromHand,
ShortEstimation,
AdvancedEstimation,
}
以上是关于csharp SteamVR手交互实例的主要内容,如果未能解决你的问题,请参考以下文章
[AR/VR教程] SteamVR Unity工具包:控制器交互
Unity3D OpenVR SteamVR 获取输入动作按键 交互设备数据方法
Unity3D OpenVR SteamVR 在头盔视觉前面常驻文本