shenjianxing 6b341ae2b4 适配VR
2025-04-01 16:16:45 +08:00

132 lines
4.3 KiB
C#

////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2007-2020 , Inc. All Rights Reserved.
//
////////////////////////////////////////////////////////////////////////////////
using UnityEngine;
using UnityEngine.EventSystems;
using GCSeries.Core.EventSystems;
using GCSeries.Core.Input;
namespace GCSeries.Core.Samples
{
public class Draggable :
ZPointerInteractable, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public bool Active = true;
////////////////////////////////////////////////////////////////////////
// Public Methods
////////////////////////////////////////////////////////////////////////
public override ZPointer.DragPolicy GetDragPolicy(ZPointer pointer)
{
if (pointer is ZMouse)
{
return ZPointer.DragPolicy.LockToScreenAlignedPlane;
}
if (pointer is ZStylus)
{
return ZPointer.DragPolicy.LockHitPosition;
}
return base.GetDragPolicy(pointer);
}
public virtual void OnBeginDrag(PointerEventData eventData)
{
if (!this.Active) return;
ZPointerEventData pointerEventData = eventData as ZPointerEventData;
if (pointerEventData == null ||
pointerEventData.button != PointerEventData.InputButton.Left)
{
return;
}
Pose pose = pointerEventData.Pointer.EndPointWorldPose;
// Cache the initial grab state.
this._initialGrabOffset =
Quaternion.Inverse(this.transform.rotation) *
(this.transform.position - pose.position);
this._initialGrabRotation =
Quaternion.Inverse(pose.rotation) *
this.transform.rotation;
// If the grabbable object has a rigidbody component,
// mark it as kinematic during the grab.
var rigidbody = this.GetComponent<Rigidbody>();
if (rigidbody != null)
{
this._isKinematic = rigidbody.isKinematic;
rigidbody.isKinematic = true;
}
// Capture pointer events.
pointerEventData.Pointer.CapturePointer(this.gameObject);
}
public virtual void OnDrag(PointerEventData eventData)
{
if (!this.Active) return;
if (_initialGrabOffset == Vector3.zero) return;
ZPointerEventData pointerEventData = eventData as ZPointerEventData;
if (pointerEventData == null ||
pointerEventData.button != PointerEventData.InputButton.Left)
{
return;
}
Pose pose = pointerEventData.Pointer.EndPointWorldPose;
// Update the grab object's rotation.
this.transform.rotation =
pose.rotation * this._initialGrabRotation;
// Update the grab object's position.
this.transform.position =
pose.position +
(this.transform.rotation * this._initialGrabOffset);
}
public virtual void OnEndDrag(PointerEventData eventData)
{
if (!this.Active) return;
ZPointerEventData pointerEventData = eventData as ZPointerEventData;
if (pointerEventData == null ||
pointerEventData.button != PointerEventData.InputButton.Left)
{
return;
}
// Release the pointer.
pointerEventData.Pointer.CapturePointer(null);
// If the grabbable object has a rigidbody component,
// restore its original isKinematic state.
var rigidbody = this.GetComponent<Rigidbody>();
if (rigidbody != null)
{
rigidbody.isKinematic = this._isKinematic;
}
_initialGrabOffset = Vector3.zero;
}
////////////////////////////////////////////////////////////////////////
// Private Members
////////////////////////////////////////////////////////////////////////
private Vector3 _initialGrabOffset = Vector3.zero;
private Quaternion _initialGrabRotation = Quaternion.identity;
private bool _isKinematic = false;
}
}