Search Unity

setting transform.eulerangles cause rigid body to spin out of control when x eulerangle is at 270

Discussion in 'Scripting' started by samshosho, Aug 15, 2018.

  1. samshosho

    samshosho

    Joined:
    Apr 12, 2010
    Posts:
    370
    I have been struggling with this for days now, a rigid body set on a car.
    doing this,

    Code (CSharp):
    1. rigid.MoveRotation (Quaternion.Euler(rigid.rotation.eulerAngles.x, CurCarRotation, rigid.rotation.eulerAngles.z));
    or this,

    Code (CSharp):
    1. MyTransform.eulerAngles = new Vector3(MyTransform.eulerAngles.x, CurCarRotation, MyTransform.eulerAngles.z);
    cause the car to spin out of control for 2 seconds, then stops when the car is vertical, so x euler is at 270.

    Any explanation?? and idea?
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    You should avoid in this case, using directly eulers, to control rotation.
    Is just how quaternion works. It can "flip" rotation axis in certain orientations.
    in very simplistic way, if you want to add safely vertical local rotation of rigid body

    Code (CSharp):
    1. rigid.rotation *= Quaternion.Euler ( 0, deltaRotation, 0 ) ;
    Personally I use normally forces, or torques, but in your #1 case,

    Code (CSharp):
    1. rigid.MoveRotation ( rigid.rotation * Quaternion.Euler (0, deltaCarRotation, 0) );
    Notice delta rotation, rather current rotation, as you adding rotation, along rigid body its own local Y axis.
     
  3. samshosho

    samshosho

    Joined:
    Apr 12, 2010
    Posts:
    370
    I think both lines will set the eulerangles of x and z to zero, that's not wanted, as i want the car to keep it's x eulerangle and z eulerangle since it's constantly moving.
    Multiplying will diffenately set those two to zero.

    The problem that i am facing is not setting the eulerangle of the y, but rather setting the eulerangle of the x to it's own,

    so even doing this, will cause the rigid body of the car to spin out of control when x hits 270 or 70, so upside down, or downside up, vertically.

    Code (CSharp):
    1. Vector3 myEuler = MyTransform.localEulerAngles;
    2. MyTransform.localEulerAngles = myEuler;
    Using MyTransform or rigid, result in the same behaviour. notice, that i am not changing anything here, just setting the same figures back into the same transform or rigid, still cause the same problem. So really it's not a matter of what i am feeding in to the y eulerangle.
    It's a problem with setting the eulerangles directly. and of course i can't just change the y.

    Also, if i use the delta, which is the change in rotation, it fails, because the y eularangle goes from positive figures to negative figures, which are feed from virtual joystick.
     
  4. samshosho

    samshosho

    Joined:
    Apr 12, 2010
    Posts:
    370
    doing this

    Code (CSharp):
    1. rigid.rotation = Quaternion.Euler(rigid.rotation.x, CurCarRotation, rigid.rotation.z);
    Keeps the x and z rotation at zero, no matter what!
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Multiplying quaternion works like rotation addition, in local frame reference, not like SET. So please try it first.

    Assuming you have GameObject configured as x = pitch, y = yaw, z = roll.

    Delta y indeed should take values +-, if you want turn left, or right. So where is the issue?
    If you keep feeding -1, it will keep turning left. if is +1, then right. and in fact can be any float value.
     
  6. samshosho

    samshosho

    Joined:
    Apr 12, 2010
    Posts:
    370
    using this

    Code (CSharp):
    1. deltaRotation = CurCarRotation - deltaRotation;
    2.                         rigid.rotation *= Quaternion.Euler(0, deltaRotation, 0);
    3.                         deltaRotation = CurCarRotation;
    Does prevent the problem from happening, but the problem is, deltaRotation is not correct, so now the joystick doesn't rotate the car correctly, it gives different direction and changes over time. So facing the joystick say to the right, might face the car to the left and that changes with time, so the result is not reliable.

    Bare in mind that the joystick CurCarRotation value is the actual angle of the joystick, which is the angle the car should face to match with the joystick with none rotating camera.
     
  7. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Glad Quaternions works
    Regarding inputs, this is different problem.
    First, you should have system reliably working and decoupled from any inputs.
    Then you do correct mapping of inputs. Don't try fit system to inputs as you did initially.
    This shouldn't be the problem, since you know what is on input and what to expect on output.
    You can evaluate mapping, ratio, scale, or whatever needs to be.
    Mind, not all joysticks are the same. So you need take this into consideration.
     
  8. samshosho

    samshosho

    Joined:
    Apr 12, 2010
    Posts:
    370
    this worked, not sure why when other stuff didn't!

    Code (CSharp):
    1. Vector3 CarRot = CarTransform.eulerAngles;
    2.                                 CarTransform.rotation = Quaternion.Euler (CarRot.x, CurRotation, CarRot.z);
     
  9. samshosho

    samshosho

    Joined:
    Apr 12, 2010
    Posts:
    370
    spoke too soon. After testing a bit farther, i got exact same problem, if not even more severe!
    will go back to trying and implement what you mentioned, and change the joystick input and see how that goes.

    Thanks for you help