- Home /
How to Clamp Rotation of a Rigidbody when Using AddTorque
Using Unity 3D 2020.2.0b14.3668
Here's what I'm trying to do:
- Allow the user to drag a 3D object with the mouse, rotating the object, but not moving its location.
The object (box or cube) is in-line with the camera, directly in front of it, on the forward (Z)axis, with one face facing the camera.
The object should rotate 360° around the up (Y) axis when the user drags the mouse left or right.
The object should pitch forward (down) or back (up) around the right (X) axis when the user drags the mouse up or down on the screen.
The object should NOT pitch downward more than 90°, nor upward more than -90° from the starting point.
The object, if at (or near) its extreme rotation on the X, could then be allowed to roll on the Z, but otherwise I don't want it to roll on the Z.
I'm using physics, the object has a rigid body, is NOT affected by gravity, and is NOT kinematic.
Here is how I'm trying to do this:
I'm trying to use Debug.Log statements to find the value of the rotation of the object when it is dragged up or down.
I would then create variables to set the maximum up / down rotation values.
I would then create IF statements that say "If the thing is at or beyond the max value of rotation on that axis, don't move it any more in that direction, even if the user keeps dragging it."
It's not working. Here's what I'm running into:
It doesn't respect the max value - The user can continue dragging the object all the way past the max value, and flip it upside down. I don't want that behavior.
The angles shown in the debug statements are not the same angles I see in the object's Transform in the Inspector, and I'm not sure they are consistent every time I test the thing.
The object still rotates on the Z axis, which I do not want, even though I have the Freeze Rotation Constraint turned on in the Rigid Body in the Inspector. I have no idea why, but I can see some rotation on the Z axis in the inspector.
My Code is Here (Does anybody see what I'm doing wrong?):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class userRotatesObject : MonoBehaviour
{
public float angularSpeed;
public float dampenX = 10f;
public float dampenY = 20f;
public float maxRotationDownward = -0.0003f;
public float maxRotationUpward = 0.0003f;
protected Rigidbody theRigidBody;
public bool rotMaxedDownward = false;
public bool rotMaxedUpward = false;
public int mouseDirX = 0;
public int mouseDirY = 0;
public Vector3 mPrevPos = Vector3.zero;
public Vector3 mPosDelta = Vector3.zero;
// Start is called before the first frame update
void Start()
{
Cursor.SetCursor(cursorPointNormal, Vector2.zero, CursorMode.ForceSoftware);
theRigidBody = GetComponent<Rigidbody>();
Debug.Log("START - X angle is: " + theRigidBody.rotation.eulerAngles.x);
}
void FixedUpdate() //Use FixedUpdate instead of Update when dealing with forces, drag, angularvelocity and stuff
{
//speed = r.velocity.magnitude;
angularSpeed = theRigidBody.angularVelocity.magnitude;
if (mouseDirX == -1 && (!rotMaxedUpward || !rotMaxedDownward))
{
theRigidBody.AddTorque(Vector3.up);
Debug.Log("Mouse Direction is -X and The X angle is: " + theRigidBody.rotation.eulerAngles.x);
}
if (mouseDirX == 1 && (!rotMaxedUpward || !rotMaxedDownward))
{
theRigidBody.AddTorque(Vector3.up * -1.0f);
Debug.Log("Mouse Direction is X and The X angle is: " + theRigidBody.rotation.eulerAngles.x);
}
if (mouseDirY == 1 && !rotMaxedUpward)
{
theRigidBody.AddTorque(Vector3.right);
Debug.Log("Mouse Direction Y and the X angle is: " + theRigidBody.rotation.eulerAngles.x);
}
if (mouseDirY == -1 && !rotMaxedDownward)
{
theRigidBody.AddTorque(Vector3.right * -1.0f);
Debug.Log("Mouse Direction -Y and the X angle is: " + theRigidBody.rotation.eulerAngles.x);
}
}
void OnMouseDrag()
{
//Dragging the object allows the user to see it from all sides.
mPosDelta = Input.mousePosition - mPrevPos;
//These if statements tell me which way the mouse is moving on the screen, which is 2D,
if (mPosDelta.x > 0)
{
mouseDirX = 1;
}
if (mPosDelta.x < 0)
{
mouseDirX = -1;
}
if (mPosDelta.x == 0)
{
mouseDirX = 0;
}
if (mPosDelta.y > 0)
{
mouseDirY = 1;
rotMaxedDownward = false; //If the mouse is moving upward on the screen, then the object should NOT be at its max swing point downward.
}
if (mPosDelta.y < 0)
{
mouseDirY = -1;
rotMaxedUpward = false; //If the mouse is moving downward on the screen, then the object should NOT be at its max swing point upward.
}
if (mPosDelta.y == 0)
{
mouseDirY = 0;
}
mPrevPos = Input.mousePosition;
}
void OnMouseUp()
{
mouseDirX = 0;
mouseDirY = 0;
}
}
Answer by JeffreyBennett · Dec 14, 2020 at 04:29 PM
Why is there rotation on the Z axis when the option Freeze Rotation is selected for the Z axis in the Rigidbody's Constraints?
Ok, freezing rotation on the Z axis in the late update function seems to have fixed this issue.
Now for my rant-style question: (Hands thrown up in the air) Wh? Wh? WHY!?!? What on Earth is the Freeze Rotation setting FOR (in the inspector) if you have to add this line of code to freeze rotation?!?!
Ok, I'm done with that.
Here is where I found this > https://answers.unity.com/questions/1183356/freezing-x-and-y-rotation-not-working-rigidbody.html
I just copied that guy's late update function from the posting at the link and pasted it into my code, just below my fixed update. Now it is working pretty much as I had in $$anonymous$$d.
Your answer
Follow this Question
Related Questions
OnTriggerEnter and OnTriggerStay often not registering 1 Answer
Objects stuck dragging across floor 1 Answer
Player gets stuck into object after collision 2 Answers
Trying To Make Burger Builder 1 Answer
Car collision impact with object 1 Answer