Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Rotating rigidbody around its LOCAL axis

Discussion in 'Physics' started by wantondalliance, Oct 8, 2019.

  1. wantondalliance

    wantondalliance

    Joined:
    Aug 22, 2018
    Posts:
    28
    I've been searching how to do this for a while, and a few other people have asked the same thing but the answers are either very vague or aren't a solution.

    It has to be the rigidbody because other objects will interact with it. Imagine it's a seesaw that a ball can roll back and forth along:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SetRotation : MonoBehaviour
    4. {
    5.     public InputSource InputSource; //Value of 0 - 1
    6.  
    7.     public Vector3 AxisOfRotation;
    8.     public float AngleOfRotation;
    9.  
    10.     public Vector3 _initialRotation;
    11.     public Vector3 _targetRotation;
    12.     public Vector3 _localRotAxis;
    13.     public Vector3 _targetRot;
    14.    
    15.     protected Rigidbody _rb;
    16.  
    17.     void Awake()
    18.     {
    19.         _rb = GetComponent<Rigidbody>();
    20.  
    21.         _initialRotation = _rb.rotation.eulerAngles;
    22.  
    23.     }
    24.  
    25.     void FixedUpdate()
    26.     {
    27.         Vector3 offsetRot = AxisOfRotation * AngleOfRotation * InputSource.Output;
    28.         _targetRot = _initialRotation + offsetRot;
    29.         Quaternion targetRotQuat = Quaternion.Euler(_targetRot);
    30.  
    31.         _rb.MoveRotation(targetRotQuat);
    32.     }
    33. }
    Weirdly this script works but only if AxisOfRotation is between a certain range, so (0, 0, 1) does work as intended, but (0, 1, 0) doesn't. I imagine this is to do with gimbal problems?

    Some people suggested using transform.InverseTransformDirection but I'm not really sure which vector exactly needs converting to local space...

    Any help would be much appreciated.
     
  2. Maeslezo

    Maeslezo

    Joined:
    Jun 16, 2015
    Posts:
    106
    To be honest, I don't understand what you are doing in your code.

    Something like this should work

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SetRotation : MonoBehaviour
    4. {
    5.     [Range(0.0f, 1.0f)]
    6.     public float input; //Value of 0 - 1
    7.  
    8.     public Vector3 axisOfRotation;
    9.     public float angleOfRotation;
    10.  
    11.     public Quaternion initialRotation;
    12.     public Quaternion targetRot;
    13.  
    14.     protected Rigidbody rb;
    15.  
    16.     void Awake()
    17.     {
    18.         rb = GetComponent<Rigidbody>();
    19.         initialRotation = rb.rotation;
    20.     }
    21.  
    22.     void FixedUpdate()
    23.     {
    24.         float angle = angleOfRotation * input;
    25.         Quaternion q = Quaternion.AngleAxis(angle, axisOfRotation);
    26.         targetRot = initialRotation * q;
    27.         rb.MoveRotation(targetRot);
    28.     }
    29. }
    30.  
    rotation.gif
     
  3. wantondalliance

    wantondalliance

    Joined:
    Aug 22, 2018
    Posts:
    28
    Despite you not understanding my code, your script works perfectly, thank you - and thanks for the demonstration too! :)
     
  4. Maeslezo

    Maeslezo

    Joined:
    Jun 16, 2015
    Posts:
    106
    glad it helped!