26 [Tooltip(
"Transform that will be dragged. Defaults to the object of the component.")]
29 [Tooltip(
"Scale by which hand movement in z is multiplied to move the dragged object.")]
30 public float DistanceScale = 2f;
37 OrientTowardUserAndKeepUpright
42 [Tooltip(
"Controls the speed at which the object will interpolate toward the desired position")]
44 public float PositionLerpSpeed = 0.2f;
46 [Tooltip(
"Controls the speed at which the object will interpolate toward the desired rotation")]
48 public float RotationLerpSpeed = 0.2f;
50 public bool IsDraggingEnabled =
true;
52 private bool isDragging;
54 private Vector3 objRefForward;
55 private Vector3 objRefUp;
56 private float objRefDistance;
57 private Quaternion gazeAngularOffset;
58 private float handRefDistance;
59 private Vector3 objRefGrabPoint;
61 private Vector3 draggingPosition;
62 private Quaternion draggingRotation;
65 private uint currentInputSourceId;
66 private Rigidbody hostRigidbody;
67 private bool hostRigidbodyWasKinematic;
71 if (HostTransform == null)
73 HostTransform = transform;
76 hostRigidbody = HostTransform.GetComponent<Rigidbody>();
79 private void OnDestroy()
94 if (IsDraggingEnabled && isDragging)
105 if (!IsDraggingEnabled)
122 if (hostRigidbody != null)
124 hostRigidbodyWasKinematic = hostRigidbody.isKinematic;
125 hostRigidbody.isKinematic =
true;
130 Vector3 inputPosition = Vector3.zero;
131 #if UNITY_2017_2_OR_NEWER 147 Vector3 pivotPosition = GetHandPivotPosition(cameraTransform);
148 handRefDistance = Vector3.Magnitude(inputPosition - pivotPosition);
149 objRefDistance = Vector3.Magnitude(initialDraggingPosition - pivotPosition);
151 Vector3 objForward = HostTransform.forward;
152 Vector3 objUp = HostTransform.up;
154 objRefGrabPoint = cameraTransform.transform.InverseTransformDirection(HostTransform.position - initialDraggingPosition);
156 Vector3 objDirection = Vector3.Normalize(initialDraggingPosition - pivotPosition);
157 Vector3 handDirection = Vector3.Normalize(inputPosition - pivotPosition);
159 objForward = cameraTransform.InverseTransformDirection(objForward);
160 objUp = cameraTransform.InverseTransformDirection(objUp);
161 objDirection = cameraTransform.InverseTransformDirection(objDirection);
162 handDirection = cameraTransform.InverseTransformDirection(handDirection);
164 objRefForward = objForward;
168 gazeAngularOffset = Quaternion.FromToRotation(handDirection, objDirection);
169 draggingPosition = initialDraggingPosition;
171 StartedDragging.RaiseEvent();
178 private Vector3 GetHandPivotPosition(Transform cameraTransform)
180 return cameraTransform.position +
new Vector3(0, -0.2f, 0) - cameraTransform.forward * 0.2f;
189 if (IsDraggingEnabled == isEnabled)
194 IsDraggingEnabled = isEnabled;
205 private void UpdateDragging()
209 Vector3 inputPosition = Vector3.zero;
210 #if UNITY_2017_2_OR_NEWER 226 Vector3 pivotPosition = GetHandPivotPosition(cameraTransform);
228 Vector3 newHandDirection = Vector3.Normalize(inputPosition - pivotPosition);
230 newHandDirection = cameraTransform.InverseTransformDirection(newHandDirection);
231 Vector3 targetDirection = Vector3.Normalize(gazeAngularOffset * newHandDirection);
232 targetDirection = cameraTransform.TransformDirection(targetDirection);
234 float currentHandDistance = Vector3.Magnitude(inputPosition - pivotPosition);
236 float distanceRatio = currentHandDistance / handRefDistance;
237 float distanceOffset = distanceRatio > 0 ? (distanceRatio - 1f) * DistanceScale : 0;
238 float targetDistance = objRefDistance + distanceOffset;
240 draggingPosition = pivotPosition + (targetDirection * targetDistance);
244 draggingRotation = Quaternion.LookRotation(HostTransform.position - pivotPosition);
248 draggingRotation = HostTransform.rotation;
252 Vector3 objForward = cameraTransform.TransformDirection(objRefForward);
253 Vector3 objUp = cameraTransform.TransformDirection(objRefUp);
254 draggingRotation = Quaternion.LookRotation(objForward, objUp);
257 Vector3 newPosition = Vector3.Lerp(HostTransform.position, draggingPosition + cameraTransform.TransformDirection(objRefGrabPoint), PositionLerpSpeed);
259 if (hostRigidbody == null)
261 HostTransform.position = newPosition;
265 hostRigidbody.MovePosition(newPosition);
269 Quaternion newRotation = Quaternion.Lerp(HostTransform.rotation, draggingRotation, RotationLerpSpeed);
270 if (hostRigidbody == null)
272 HostTransform.rotation = newRotation;
276 hostRigidbody.MoveRotation(newRotation);
281 Quaternion upRotation = Quaternion.FromToRotation(HostTransform.up, Vector3.up);
282 HostTransform.rotation = upRotation * HostTransform.rotation;
300 currentInputSource = null;
301 currentInputSourceId = 0;
302 if (hostRigidbody != null)
304 hostRigidbody.isKinematic = hostRigidbodyWasKinematic;
306 StoppedDragging.RaiseEvent();
311 if (!IsDraggingEnabled)
326 if (!IsDraggingEnabled)
341 if (currentInputSource != null &&
342 eventData.
SourceId == currentInputSourceId)
358 #if UNITY_2017_2_OR_NEWER 375 #endif // UNITY_2017_2_OR_NEWER 380 currentInputSourceId = eventData.
SourceId;
384 Vector3 initialDraggingPosition = (details == null)
385 ? HostTransform.position
386 : details.Value.
Point;
388 StartDragging(initialDraggingPosition);
398 if (currentInputSource != null && eventData.
SourceId == currentInputSourceId)