Search Unity

How to "rig" a disc brake to the front wheels of a vehicle?

Discussion in 'Scripting' started by John1515, Aug 17, 2017.

  1. John1515

    John1515

    Joined:
    Nov 29, 2012
    Posts:
    248
    Hey

    I'm trying to attach a disc brake to the steering wheels of a vehicle but working with rotations in C# is driving me nuts!
    Consider the green thing: it should follow the front wheels when steering, but they shouldn't spin with the wheels.


    I tried different approaches:
    1) Transform.lookat: Disc brakes "looking at" the wheels. getting wrong orientation but it works. But any attempt to correct the rotation through scripts screws it up completely..

    2) Copying the Y rotation into the disc brake's:

    Code (CSharp):
    1. public Transform Tire;
    2.     float  rotX;
    3.     float  rotY;
    4.     float  rotZ;
    5.  
    6.     Vector3 desiredRotation;
    7.  
    8.  
    9.     void Start () {
    10.         rotX = gameObject.transform.eulerAngles.x;
    11.         rotY = gameObject.transform.eulerAngles.y;
    12.         rotZ = gameObject.transform.eulerAngles.z;
    13.     }
    14.  
    15.  
    16.     void LateUpdate () {
    17.        
    18.         desiredRotation = new Vector3 (rotX,Tire.transform.eulerAngles.y-90,rotZ);
    19.        
    20.     }
    The result is so strange that I can't put words on it. Unity seems to screw up the rotation completely. At least for my brain cell..
     
  2. Scabbage

    Scabbage

    Joined:
    Dec 11, 2014
    Posts:
    268
    Vector3s are vectors with dimension 3, ie. 3 variables.

    For starters, doing rotations with Euler angles are a pain in the ass. They might be easier to understand intuitively, but they pretty much always lead to problems for beginners/people not mathematically inclined. You really should be using quaternions and the methods Unity provides with them. Quaternions are 4 dimensional (x, y, z, and w), and behave differently to Euler rotations. You don't need to know how they work though, Unity handles it for you.

    Are you using WheelColliders for this? If you are you could just use the steerAngle variable to set the brake rotation with Quaternion.Euler(). I know I said not to use euler angles, but for simple stuff like this and with local rotations it's fine.


    Anyway the basic gist of this is you only need one float to encode the rotation, everything else is constrained because of how you want it to behave. In this case we have the cars up vector, which always points up (relative to the car). The brake only ever rotates around that axis:

    Code (CSharp):
    1. float steerAngle = wheel.steerAngle;
    2. brake.transform.localRotation = Quaternion.Euler(0f, steerAngle, 0f);
    Essentially, if you set the local rotation you don't get headaches from the global transforms. I'm assuming the "brake" is a separate GameObject from the wheel and "wheel" is a WheelCollider, but the idea is the same no matter how you're storing the wheel steering.
     
    John1515 likes this.
  3. John1515

    John1515

    Joined:
    Nov 29, 2012
    Posts:
    248
    Thank you so much! With a tiny adaption to get the orientation right ( Quaternion.Euler(90, steerAngle, 90);) it seems to work! :D:D One headache less! ;)

    For those wondering, this is the full script now :p

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class fixRotationBreaks : MonoBehaviour {
    4.     public WheelCollider wheel;
    5.     void Update () {
    6.         float steerAngle = wheel.steerAngle;
    7.         transform.localRotation = Quaternion.Euler(90, steerAngle, 90);
    8.     }
    9. }