This commit is contained in:
shenjianxing 2025-03-26 14:11:26 +08:00
parent bbcf0f96d9
commit 7002723f5e
9 changed files with 365 additions and 9 deletions

View File

@ -0,0 +1,203 @@
//-----------------------------------------------------------------------
// <copyright file="Draggable.cs" ProjectName="Turing 3D Core">
// Copyright (c) Beijing HiteVision Turing Intelligent Technology Co.,Ltd. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
using Turing.Core.EventSystems;
using Turing.Core.TuringInput;
using Turing.Core.Utility;
using UnityEngine;
using UnityEngine.EventSystems;
namespace Turing.Samples
{
public class Draggable :
TuringPointerInteractable, IBeginDragHandler, IDragHandler, IEndDragHandler
{
[Tooltip("Change Drag Button")]
public PointerEventData.InputButton dragTargetButton = PointerEventData.InputButton.Left;
////////////////////////////////////////////////////////////////////////
// Private Members
////////////////////////////////////////////////////////////////////////
private Vector3 _initialGrabOffset = Vector3.zero;
private Quaternion _initialGrabRotation = Quaternion.identity;
private bool _isKinematic = false;
private Transform originParent;
private Transform grab;
private Transform grabRotate;
private float distance;
////////////////////////////////////////////////////////////////////////
// Public Methods
////////////////////////////////////////////////////////////////////////
public override TuringPointer.DragPolicy GetDragPolicy(TuringPointer pointer)
{
if (pointer is TuringMouse)
{
return TuringPointer.DragPolicy.LockToScreenAlignedPlane;
}
if (pointer is TuringTouch)
{
return TuringPointer.DragPolicy.LockToScreenAlignedPlane;
}
if (pointer is TuringStylus)
{
return TuringPointer.DragPolicy.LockHitPosition;
}
return base.GetDragPolicy(pointer);
}
public virtual void OnBeginDrag(PointerEventData eventData)
{
TuringPointerEventData pointerEventData = eventData as TuringPointerEventData;
if (pointerEventData == null)
{
return;
}
if (pointerEventData.button == dragTargetButton)
{
if (pointerEventData.Pointer is TuringStylus)
{
Pose pose = pointerEventData.Pointer.EndPointWorldPose;
this._initialGrabOffset =
Quaternion.Inverse(this.transform.rotation) *
(this.transform.position - pose.position);
// this._initialGrabRotation = this.transform.localRotation;
grab = new GameObject("Grab").GetComponent<Transform>();
grabRotate = new GameObject("GrabRotate").GetComponent<Transform>();
grabRotate.position = pose.position;
grabRotate.rotation *= TuringProvider.CurrentFrame.DisplayAligner.transform.rotation;
grab.position = pose.position;
originParent = transform.parent;
grab.LookAt(pointerEventData.Pointer.transform);
distance = Vector3.Distance(grab.position, pointerEventData.Pointer.transform.position);
transform.SetParent(grabRotate);
grabRotate.SetParent(grab);
this._initialGrabRotation = grabRotate.localRotation;
}
else
{
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)
{
TuringPointerEventData pointerEventData = eventData as TuringPointerEventData;
if (pointerEventData == null)
{
return;
}
if (pointerEventData.pointerDrag != this.gameObject)
{
return;
}
if (pointerEventData.button == dragTargetButton)
{
if (pointerEventData.Pointer is TuringStylus)
{
TuringStylus stylus = (TuringStylus)pointerEventData.Pointer;
grabRotate.localRotation = _initialGrabRotation * Quaternion.Euler(stylus.StylueEulerAngle);
// Debug.Log("------------"+_initialGrabRotation.eulerAngles+" "+stylus.StylueEulerAngle);
grab.transform.position = pointerEventData.Pointer.transform.position + (stylus._target.Points[0] - stylus._target.Points[1]).normalized * distance;
grab.LookAt(pointerEventData.Pointer.transform);
}
else
{
HandleLeftDrag(pointerEventData);
}
}
}
private void HandleLeftDrag(TuringPointerEventData pointerEventData)
{
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)
{
TuringPointerEventData pointerEventData = eventData as TuringPointerEventData;
if (pointerEventData == null ||
pointerEventData.button != dragTargetButton)
{
return;
}
Debug.Log("EndDrag");
if (pointerEventData.Pointer is TuringStylus)
{
// Pose pose = pointerEventData.Pointer.EndPointWorldPose;
// this._initialGrabOffset =
// Quaternion.Inverse(this.transform.rotation) *
// (this.transform.position - pose.position);
// grab = new GameObject("Grab").GetComponent<Transform>();
// grab.transform.position = pose.position;
// originParent = transform.parent;
// grab.LookAt(pointerEventData.Pointer.transform);
// transform.SetParent(grab);
transform.SetParent(originParent);
Destroy(grab.gameObject);
Destroy(grabRotate.gameObject);
}
// 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;
}
}
}
}

View File

@ -3,6 +3,8 @@ using QFramework.Example;
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Turing.Samples;
using UnityEditor;
using UnityEngine; using UnityEngine;
using XMLTool; using XMLTool;
@ -11,7 +13,7 @@ public class Body3DOjbItem : MonoBehaviour
public Body3D.Body body; public Body3D.Body body;
public ObjectToggle objToggle; public ObjectToggle objToggle;
ObjDrag objDrag; IObjDrag objDrag;
// 记录上一次鼠标按下的时间 // 记录上一次鼠标按下的时间
private float lastClickTime; private float lastClickTime;
// 双击的时间间隔阈值 // 双击的时间间隔阈值
@ -22,6 +24,11 @@ public class Body3DOjbItem : MonoBehaviour
{ {
shader = GetComponent<Renderer>()?.material.shader; shader = GetComponent<Renderer>()?.material.shader;
TypeEventSystem.Global.Register<OnChangeMat>(OnChangeMatEvent).UnRegisterWhenGameObjectDestroyed(this); TypeEventSystem.Global.Register<OnChangeMat>(OnChangeMatEvent).UnRegisterWhenGameObjectDestroyed(this);
#if VR
#if Turing
gameObject.GetOrAddComponent<Draggable>();
#endif
#endif
} }
private void OnChangeMatEvent(OnChangeMat t) private void OnChangeMatEvent(OnChangeMat t)
@ -85,11 +92,20 @@ public class Body3DOjbItem : MonoBehaviour
colorToggle.SetColor(ObjectColorToggle.State.Off); colorToggle.SetColor(ObjectColorToggle.State.Off);
} }
} }
#if VR
#if Turing
objDrag = gameObject.GetOrAddComponent<TuringDraggableEx>();
#endif
#else
objDrag = gameObject.GetOrAddComponent<ObjDrag>(); objDrag = gameObject.GetOrAddComponent<ObjDrag>();
#endif
objDrag.OnDragEnd.AddListener(obj => objDrag.OnDragEnd.AddListener(obj =>
{ {
Body3DController.Instance.AddMoveObj(gameObject); Body3DController.Instance.AddMoveObj(gameObject);
}); });
RefreshDrag(); RefreshDrag();
if (isOn) if (isOn)
{ {
@ -125,7 +141,7 @@ public class Body3DOjbItem : MonoBehaviour
{ {
if (Body3DController.Instance.CheckStatus(Body3DController.Status.Drag)) if (Body3DController.Instance.CheckStatus(Body3DController.Status.Drag))
{ {
var drag = gameObject.GetComponent<ObjDrag>(); var drag = gameObject.GetComponent<IObjDrag>();
if (drag != null) if (drag != null)
{ {
drag.OnDoubleClick(); drag.OnDoubleClick();

View File

@ -4,14 +4,28 @@ using System;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
public class ObjDrag : MonoBehaviour public class ObjDrag : MonoBehaviour, IObjDrag
{ {
private Vector3 offset; private Vector3 offset;
public bool isOn = false; bool isOn = false;
Vector3 startPosition; Vector3 startPosition;
public UnityEvent<GameObject> OnDragEnd = new UnityEvent<GameObject>(); UnityEvent<GameObject> OnDragEnd = new UnityEvent<GameObject>();
bool IObjDrag.isOn { get => isOn; set => isOn = value; }
UnityEvent<GameObject> IObjDrag.OnDragEnd
{
get
{
if (OnDragEnd == null)
{
OnDragEnd = new UnityEvent<GameObject>();
}
return OnDragEnd;
}
}
void Start() void Start()
{ {
startPosition = gameObject.transform.position; startPosition = gameObject.transform.position;

View File

@ -0,0 +1,13 @@
using UnityEngine.Events;
using UnityEngine;
public interface IObjDrag
{
bool isOn { get; set; }
UnityEvent<GameObject> OnDragEnd { get; }
void OnDoubleClick();
}

View File

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

View File

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

View File

@ -0,0 +1,80 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Turing.Samples;
using Turing.Core.EventSystems;
using UnityEngine.EventSystems;
using QFramework;
using UnityEngine.Events;
using DG.Tweening;
public class TuringDraggableEx : Draggable, IObjDrag
{
bool isOn = false;
UnityEvent<GameObject> OnDragEnd;
bool IObjDrag.isOn { get => isOn; set => isOn = value; }
Vector3 beginPos;
UnityEvent<GameObject> IObjDrag.OnDragEnd
{
get
{
if (OnDragEnd == null)
{
OnDragEnd = new UnityEvent<GameObject>();
}
return OnDragEnd;
}
}
Vector3 startPosition;
private void Start()
{
startPosition = gameObject.transform.position;
}
public override void OnBeginDrag(PointerEventData eventData)
{
beginPos = gameObject.Position();
if (isOn == false)
{
gameObject.transform.position = beginPos;
}
else
{
base.OnBeginDrag(eventData);
}
}
public override void OnDrag(PointerEventData eventData)
{
if (isOn)
{
base.OnDrag(eventData);
}
else
{
gameObject.transform.position = beginPos;
}
}
public override void OnEndDrag(PointerEventData eventData)
{
if (isOn)
{
base.OnEndDrag(eventData);
OnDragEnd?.Invoke(gameObject);
}
}
public void OnDoubleClick()
{
transform.DOMove(startPosition, 0.1f);
}
}

View File

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

View File

@ -77,7 +77,7 @@ namespace QFramework.Example
GameObject obj = Body3DController.Instance.PopMoveObj(); GameObject obj = Body3DController.Instance.PopMoveObj();
if (obj != null) if (obj != null)
{ {
obj.GetComponent<ObjDrag>().OnDoubleClick(); obj.GetComponent<IObjDrag>().OnDoubleClick();
} }
}); });
@ -110,7 +110,7 @@ namespace QFramework.Example
GameObject obj = Body3DController.Instance.PopMoveObj(); GameObject obj = Body3DController.Instance.PopMoveObj();
if (obj != null) if (obj != null)
{ {
obj.GetComponent<ObjDrag>().OnDoubleClick(); obj.GetComponent<IObjDrag>().OnDoubleClick();
} }
} }
}); });