Skip to content

Commit 438af0e

Browse files
committed
feat(Interaction): allow different rotation actions for rotate grab
The Rotate Transform Grab Mechanic now has a new rotation action option which allows the object to be rotated based on not only the angle in difference between the origin of the object and the controller current grab position but can also be based on the rotation of the controller through one of it's axes (roll, pitch, yaw). This can help with simulating other mechanics such as turning a screw by swiveling the controller in the hand instead of grabbing and pulling the object in the direction to move it.
1 parent 797b8fe commit 438af0e

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

Assets/VRTK/Documentation/API.md

+6
Original file line numberDiff line numberDiff line change
@@ -5945,6 +5945,7 @@ Rotates the Transform of the Interactable Object around a specified transform lo
59455945
* **Detach Distance:** The maximum distance the grabbing object is away from the Interactable Object before it is automatically dropped.
59465946
* **Origin Deadzone:** The distance between grabbing object and the centre of Interactable Object that is considered to be non grabbable. If the grabbing object is within the `Origin Deadzone` distance then it will be automatically ungrabbed.
59475947
* **Rotate Around:** The local axis in which to rotate the object around.
5948+
* **Rotation Action:** Determines how the rotation of the object is calculated based on the action of the grabbing object.
59485949
* **Rotation Friction:** The amount of friction to apply when rotating, simulates a tougher rotation.
59495950
* **Release Deceleration Damper:** The damper in which to slow the Interactable Object's rotation down when released to simulate continued momentum. The higher the number, the faster the Interactable Object will come to a complete stop on release.
59505951
* **Reset To Orign On Release Speed:** The speed in which the Interactable Object returns to it's origin rotation when released. If the `Reset To Orign On Release Speed` is `0f` then the rotation will not be reset.
@@ -5958,6 +5959,11 @@ Rotates the Transform of the Interactable Object around a specified transform lo
59585959
* `xAxis` - The local X Axis of the transform.
59595960
* `yAxis` - The local Y Axis of the transform.
59605961
* `zAxis` - The local Z Axis of the transform.
5962+
* `public enum RotationType` - The way in which rotation from the grabbing object is applied.
5963+
* `FollowAttachPoint` - The angle between the Interactable Object origin and the grabbing object attach point.
5964+
* `FollowLongitudinalAxis` - The angular velocity across the grabbing object's longitudinal axis (the roll axis).
5965+
* `FollowLateralAxis` - The angular velocity across the grabbing object's lateral axis (the pitch axis).
5966+
* `FollowPerpendicularAxis` - The angular velocity across the grabbing object's perpendicular axis (the yaw axis).
59615967
* `public Quaternion originRotation` - The default local rotation of the Interactable Object.
59625968

59635969
### Class Events

Assets/VRTK/Source/Scripts/Interactions/GrabAttachMechanics/VRTK_RotateTransformGrabAttach.cs

+60-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,29 @@ public enum RotationAxis
5959
zAxis
6060
}
6161

62+
/// <summary>
63+
/// The way in which rotation from the grabbing object is applied.
64+
/// </summary>
65+
public enum RotationType
66+
{
67+
/// <summary>
68+
/// The angle between the Interactable Object origin and the grabbing object attach point.
69+
/// </summary>
70+
FollowAttachPoint,
71+
/// <summary>
72+
/// The angular velocity across the grabbing object's longitudinal axis (the roll axis).
73+
/// </summary>
74+
FollowLongitudinalAxis,
75+
/// <summary>
76+
/// The angular velocity across the grabbing object's lateral axis (the pitch axis).
77+
/// </summary>
78+
FollowLateralAxis,
79+
/// <summary>
80+
/// The angular velocity across the grabbing object's perpendicular axis (the yaw axis).
81+
/// </summary>
82+
FollowPerpendicularAxis
83+
}
84+
6285
[Header("Detach Settings")]
6386

6487
[Tooltip("The maximum distance the grabbing object is away from the Interactable Object before it is automatically dropped.")]
@@ -70,6 +93,8 @@ public enum RotationAxis
7093

7194
[Tooltip("The local axis in which to rotate the object around.")]
7295
public RotationAxis rotateAround = RotationAxis.xAxis;
96+
[Tooltip("Determines how the rotation of the object is calculated based on the action of the grabbing object.")]
97+
public RotationType rotationAction = RotationType.FollowAttachPoint;
7398
[Tooltip("The amount of friction to apply when rotating, simulates a tougher rotation.")]
7499
[Range(1f, 32f)]
75100
public float rotationFriction = 1f;
@@ -122,6 +147,7 @@ public enum RotationAxis
122147
protected Coroutine resetRotationRoutine;
123148
protected Coroutine decelerateRotationRoutine;
124149
protected bool[] limitsReached = new bool[2];
150+
protected VRTK_ControllerReference grabbingObjectReference;
125151

126152
public virtual void OnAngleChanged(RotateTransformGrabAttachEventArgs e)
127153
{
@@ -179,6 +205,7 @@ public override bool StartGrab(GameObject grabbingObject, GameObject givenGrabbe
179205
grabbedObjectBounds = VRTK_SharedMethods.GetBounds(givenGrabbedObject.transform);
180206
limitsReached = new bool[2];
181207
CheckAngleLimits();
208+
grabbingObjectReference = VRTK_ControllerReference.GetControllerReference(grabbingObject);
182209
return grabResult;
183210
}
184211

@@ -210,7 +237,7 @@ public override void ProcessUpdate()
210237
float distance = Vector3.Distance(transform.position, controllerAttachPoint.transform.position);
211238
if (StillTouching() && distance >= originDeadzone)
212239
{
213-
Vector3 newRotation = CalculateAngle(transform.position, previousAttachPointPosition, controllerAttachPoint.transform.position);
240+
Vector3 newRotation = GetNewRotation();
214241
previousAttachPointPosition = controllerAttachPoint.transform.position;
215242
currentRotationSpeed = newRotation;
216243
UpdateRotation(newRotation, true, true);
@@ -292,6 +319,38 @@ protected override void Initialise()
292319
currentRotation = Vector3.zero;
293320
}
294321

322+
protected virtual Vector3 GetNewRotation()
323+
{
324+
Vector3 grabbingObjectAngularVelocity = Vector3.zero;
325+
if (VRTK_ControllerReference.IsValid(grabbingObjectReference))
326+
{
327+
grabbingObjectAngularVelocity = VRTK_DeviceFinder.GetControllerAngularVelocity(grabbingObjectReference) * VRTK_SharedMethods.DividerToMultiplier(rotationFriction);
328+
}
329+
330+
switch (rotationAction)
331+
{
332+
case RotationType.FollowAttachPoint:
333+
return CalculateAngle(transform.position, previousAttachPointPosition, controllerAttachPoint.transform.position);
334+
case RotationType.FollowLongitudinalAxis:
335+
return BuildFollowAxisVector(grabbingObjectAngularVelocity.x);
336+
case RotationType.FollowPerpendicularAxis:
337+
return BuildFollowAxisVector(grabbingObjectAngularVelocity.y);
338+
case RotationType.FollowLateralAxis:
339+
return BuildFollowAxisVector(grabbingObjectAngularVelocity.z);
340+
}
341+
342+
return Vector3.zero;
343+
}
344+
345+
protected virtual Vector3 BuildFollowAxisVector(float givenAngle)
346+
{
347+
float xAngle = (rotateAround == RotationAxis.xAxis ? givenAngle : 0f);
348+
float yAngle = (rotateAround == RotationAxis.yAxis ? givenAngle : 0f);
349+
float zAngle = (rotateAround == RotationAxis.zAxis ? givenAngle : 0f);
350+
351+
return new Vector3(xAngle, yAngle, zAngle);
352+
}
353+
295354
protected virtual Vector3 CalculateAngle(Vector3 originPoint, Vector3 originalGrabPoint, Vector3 currentGrabPoint)
296355
{
297356
float xRotated = (rotateAround == RotationAxis.xAxis ? CalculateAngle(originPoint, originalGrabPoint, currentGrabPoint, transform.right) : 0f);

0 commit comments

Comments
 (0)