Skip to main content
New Participant
December 9, 2024
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?

MrJigsAnswer
New Participant
January 22, 2025

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

New Participant
January 22, 2025

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.

MrJigsAuthorAnswer
New Participant
January 22, 2025

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.