Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only. On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live. Read our full announcement for more information and let us know if you have any questions.

Question Car physics - Initial force to rigidbody?

Discussion in 'Physics' started by pviola051, Feb 6, 2024.

  1. pviola051

    pviola051

    Joined:
    Feb 5, 2024
    Posts:
    2
    Hello, I'm very new at Unity and C# and I'm watching some tutorials to develop a small game. In particular I'd like to develop a simple racing game and I found this very nice video (that I've already seen in some threads here):



    In the video, the developers of Very Very Valet break down the physics they implemented, using a single rigidbody for their cars and calculating all the forces (suspension, steering, acceleration/braking) to apply to it at the wheels positions.
    My point is: in the calculations of these forces they use the car's rigidbody velocity but in my tests is always zero. So is it correct to assume that there is another force applied to this rigidbody before these calculations?
    Something like:


    Vector3 forwardForce = (100f * _AccelerationInput) * transform.forward;
    _Rigidbody.AddForce(forwardForce * Time.fixedDeltaTime)

    So for example, the code that calculates the acceleration force in my case becomes:

    Code (CSharp):
    1.  
    2. private void FixedUpdate()
    3. {
    4.     if (_Rigidbody == null)
    5.     {
    6.        return;
    7.     }
    8.  
    9.     Vector3 forwardForce = (100f * _AccelerationInput) * transform.forward;
    10.     _Rigidbody.AddForce(forwardForce * Time.fixedDeltaTime);
    11.  
    12.     for (int i = 0; i < _WheelsTransformsArray.Length; ++i)
    13.     {
    14.         Transform wheelTransform = _WheelsTransformsArray[i];
    15.  
    16.         if (wheelTransform == null)
    17.         {
    18.             return;
    19.         }
    20.  
    21.         RaycastHit hit;
    22.         if (Physics.Raycast(wheelTransform.position, -transform.up, out hit, LayerMask.GetMask("Ground")))
    23.         {
    24.            // Code from the tutorial
    25.             Vector3 accelDirection = wheelTransform.forward;
    26.  
    27.             if (_AccelerationInput > Mathf.Epsilon)
    28.             {
    29.                  // Forward speed of the car.
    30.  
    31.                  float carSpeed = Vector3.Dot(transform.forward, _Rigidbody.velocity);
    32.  
    33.                  // Normalize car speed.
    34.  
    35.                  float normSpeed = Mathf.Clamp01(Mathf.Abs(carSpeed) / _MaxSpeed);
    36.  
    37.                  // Avavilable torque.
    38.  
    39.                  float availableTorque = m_TorqueCurve.Evaluate(normSpeed) * _AccelerationInput;
    40.  
    41.                  _Rigidbody.AddForceAtPosition(accelDirection * availableTorque, wheelTransform.position);
    42.             }
    43.           // End code from the tutorial
    44.       }
    45. }
    It seems working but I'm not sure if I'm doing the right thing or if I'm missing something.
    Thanks in advance for the help!

    (sorry for the code identation or if something is not clear)
     
  2. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    2,063
    You don't need to apply a force for velocity to not be zero: you just need to apply an acceleration, such as gravity. So unless your rigidbody is kinematic, is asleep (or extremely still), or has no gravity applied to it, velocity won't be exactly zero.

    Note that your code doesn't need for velocity to be larger than zero in order to apply an acceleration to the car: it maps normalized velocity (in the 0-1 range) to available torque using a curve, and the available torque when velocity is zero is larger than zero - see video at 20:40.

    So even when the car is absolutely still and its velocity equals zero, you will be able to accelerate it.
     
    Last edited: Feb 7, 2024
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,761
    Note, you should not be scaling the force by the delta-time, that will happen when it is integrated during the simulation step so you're essentially scaling it down twice by this.
     
  4. codebiscuits

    codebiscuits

    Joined:
    Jun 16, 2020
    Posts:
    126
    Unless you've a hankering to learn about car physics, I'd maybe grab something off the asset store (I like Edy Vehicle Physics, which I think is great for "fun" non-stunt driving physics on roads with regular cars (wheels under the bodywork)).
    I haven't tried this specific tutorial myself, but for a really simple way to get a nice driving feeling, I think stuff like this is really good:

    Like, to get you going quickly, where you've a car on the screen and can drive it. Obvs it's not physically accurate *at all*, but maybe you don't care, I think it's cool:) I thiink that tutorial will get everything you need going for free, but if not, Kenney has source & a demo on Patreon you can get for £4.50 (I searched Kenney's Patreon for "Car", looks like it's in the March Update).
     
    Edy likes this.
  5. pviola051

    pviola051

    Joined:
    Feb 5, 2024
    Posts:
    2
    You're absolutely right!
    I was focusing on the wrong thing, that the dot product of the car's forward and rigidbody velocity was zero, forgetting that the available torque curve starts at 0.5.
    The fact that it didn't work at first I think was due to the fact that the mass of my "car" was too large (like 100), and using AddForce with ForceMode = Force (that is depends on the mass) the applied force was too small to have any effect (pls correct me if I'm wrong)
    Now removing the initial force that I had added and having set mass = 1 it works. Of course I'll adjust the values in the tuning phase.

    I think I know what you mean: I'm just applying a force magnitude in Newtons and with that delta time I'm multiplying my force by a constant value (0.02 in this case) which however has nothing to do with the physical meaning itself. My fault, I should think more about what I'm doing and which forces I'm dealing with. Thanks for the insight!

    Thanks for the video and the info about the author! I came across this tutorial but, like you said, is not physically accurate so I decided to go with the tutorial I posted, because I wanted to practice Unity and C# but also some mathematical concepts. But I saved this tutorial because it's quite nice and it's a different way to implement what I need, so for exercise I'll definitely use it! :D
     
    Last edited: Feb 8, 2024
    codebiscuits likes this.
  6. arkano22

    arkano22

    Joined:
    Sep 20, 2012
    Posts:
    2,063
    You're absolutely right :). F = ma, so a = F/m, which means that the change in velocity (acceleration) caused by a force is inversely proportional to the mass of the object: the heavier the object, the less change in velocity caused by the same force.

    So if you have an object with mass = 1 kg, the same force that is able to move it wouldn't be able to if the object weighted 100 kg instead.

    Again absolutely correct :)