Forum Discussion

MrJigs's avatar
MrJigs
Honored Guest
2 years ago
Solved

Reset a "One grab rotate transformer"

I've got a lever that I'm manipulating with a "grabbable" a "hand grab interactable" and a "One grab rotate transformer" the last one with constraints. This is working fine. But when released the lever stays in the transformed position. I would like the lever to return to its original position when released.

If I add a method to return the "target transform" to its original rotation and call it from the unity event wrapper on "when unselect" it seems to work until one tries to manipulate the lever again it then appears that the constraints have rotated by half the difference between min and max. The lever will rotate correctly between these "new" min and max values but of course is visually in the wrong place. i.e if the min max values were originally from -20 to 20. After the "reset" they appear to be from -40 to 0.

Any suggestions on how to properly return the lever to its original position?

  • I did get a working solution in the end. I created a copy of the OneGrabRotateTransformer script and added the following to the EndTransform() method.

            public void EndTransform()
            {
    
                Debug.Log("EndTransform");
    
                var targetTransform = _grabbable.Transform;
    
                Vector3 localAxis = Vector3.zero;
                localAxis[(int)_rotationAxis] = 1f;
                _worldPivotPose = ComputeWorldPivotPose();
                Vector3 rotationAxis = _worldPivotPose.rotation * localAxis;
    
                // update previous
                _previousVectorInPivotSpace = new Vector3(0f, 0f, 1f);
    
                //Quaternion deltaRotation = Quaternion.AngleAxis(_constrainedRelativeAngle - _startAngle, rotationAxis);
                Quaternion deltaRotation = Quaternion.AngleAxis(0f, rotationAxis);
    
                float parentScale = 1f;
                Pose transformDeltaInWorldSpace =
                    new Pose(
                        _worldPivotPose.rotation * (parentScale * _transformPoseInPivotSpace.position),
                        _worldPivotPose.rotation * _transformPoseInPivotSpace.rotation);
    
                Pose transformDeltaRotated = new Pose(
                    deltaRotation * transformDeltaInWorldSpace.position,
                    deltaRotation * transformDeltaInWorldSpace.rotation);
    
                targetTransform.position = _worldPivotPose.position + transformDeltaRotated.position;
                targetTransform.rotation = transformDeltaRotated.rotation;
                _relativeAngle = 0.0f;
                _constrainedRelativeAngle = 0.0f;
                direction = Direction.None;
            }

    Although I haven't tested it I'm pretty sure the last three lines are sufficient ๐Ÿ˜€. Adding it to this method will reset the stick when the grab ends.

2 Replies

  • Did you ever find a solution? I also have this issue with a grabbable, which I want to reset to a position when it was released. But as soon as it's grabbed again it jumps to the position where it was last grabbed.

    • MrJigs's avatar
      MrJigs
      Honored Guest

      I did get a working solution in the end. I created a copy of the OneGrabRotateTransformer script and added the following to the EndTransform() method.

              public void EndTransform()
              {
      
                  Debug.Log("EndTransform");
      
                  var targetTransform = _grabbable.Transform;
      
                  Vector3 localAxis = Vector3.zero;
                  localAxis[(int)_rotationAxis] = 1f;
                  _worldPivotPose = ComputeWorldPivotPose();
                  Vector3 rotationAxis = _worldPivotPose.rotation * localAxis;
      
                  // update previous
                  _previousVectorInPivotSpace = new Vector3(0f, 0f, 1f);
      
                  //Quaternion deltaRotation = Quaternion.AngleAxis(_constrainedRelativeAngle - _startAngle, rotationAxis);
                  Quaternion deltaRotation = Quaternion.AngleAxis(0f, rotationAxis);
      
                  float parentScale = 1f;
                  Pose transformDeltaInWorldSpace =
                      new Pose(
                          _worldPivotPose.rotation * (parentScale * _transformPoseInPivotSpace.position),
                          _worldPivotPose.rotation * _transformPoseInPivotSpace.rotation);
      
                  Pose transformDeltaRotated = new Pose(
                      deltaRotation * transformDeltaInWorldSpace.position,
                      deltaRotation * transformDeltaInWorldSpace.rotation);
      
                  targetTransform.position = _worldPivotPose.position + transformDeltaRotated.position;
                  targetTransform.rotation = transformDeltaRotated.rotation;
                  _relativeAngle = 0.0f;
                  _constrainedRelativeAngle = 0.0f;
                  direction = Direction.None;
              }

      Although I haven't tested it I'm pretty sure the last three lines are sufficient ๐Ÿ˜€. Adding it to this method will reset the stick when the grab ends.

โ†’ Find helpful resources to begin your development journey in Getting Started

โ†’ Get the latest information about HorizonOS development in News & Announcements.

โ†’ Access Start program mentor videos and share knowledge, tutorials, and videos in Community Resources.

โ†’ Get support or provide help in Questions & Discussions.

โ†’ Show off your work in What Iโ€™m Building to get feedback and find playtesters.

โ†’ Looking for documentation?  Developer Docs

โ†’ Looking for account support?  Support Center

โ†’ Looking for the previous forum?  Forum Archive

โ†’ Looking to join the Start program? Apply here.

 

Recent Discussions