Unity3d Racing Vehicle Performance Algorithms---summary (turn) __ algorithm

Source: Internet
Author: User

The performance of the car has been a long time algorithm, in determining the final version of the car, do a summary.
The article is still not very detailed, point to refer to, do not want to use too much work time.

Before making, you must first understand the principle of the real vehicle:
The vehicle is divided into front wheel drive, rear wheel drive and four drive. The power is provided by the engine, the force of the reaction is to the tyre, so the RPM is produced.
The power of the engine can be obtained from the RPM formula: RPM = engine power X60/2XPI, these are simulations, just to better serve the following actions. There is also the "drift" of the public concern, the so-called drift is, in the back of the car, the front wheel rotation angle, the ground to a certain centripetal force, while the rear wheels give more power, resulting in "drift" action.

Based on the above principles, it is easier to understand the following article.

Let me start by stating that there are a number of ways to develop a car. My car version after countless different methods, countless times after the revision of the final election of a public acceptance. These methods, let me go all the way.

First of all, you have to understand that the vehicle can not be a whole shell, because in contact with the ground, the force of the vehicle can not achieve your expected target, caused, must be in the vehicle tires above the shell collision, the tyre needs to be strong to support it is always not falling down.

Unity3d has a magical thing called Wheelcollider, which specializes in simulating tyre support forces and tyre turns, as well as lateral force, forward force, and suspension shock system of tyre.
This thing is very handy, so long as you put this thing on 4 tires, debug his forwardfriction and sidewaysfriction
Reach the effect you want, and then assign the motortorque of the drive wheel, your vehicle will move.
Remember how many times you need to debug forward friction and transverse friction. The suspension system can also change its value when you need it. Also, these two frictional forces are a curve from low to high, and then from high to stable.

This wheelcollider is very easy to use, once indulged in this. But later found that he had a lot of unreasonable places. Want to get the best results, or abandon him.

In order to support the vehicle's collision housing without touching the ground, a suspension dynamic support must be written, in 4 tyre positions, to support the entire vehicle suspended above the ground.
About this suspension dynamic support force under this dedication:

void Suspensionholdforce () {Float Fullcompressionspringforce = this.rigidbody.mass * 0.25f * 2.0f *-physics.gravity
     . Y; This.

     Onground = true;
         foreach (Gameobject item in fwheelmodels) {Raycasthit hit; BOOL Onground = Physics.raycast (Item.transform.parent.position,-item.transform.parent.inversetransformdirection (

         Vector3.up), out hit, This.suspensiontravel + This.radius);
            if (Onground && hit.collider.isTrigger) {onground = false;
            Float dist = this.suspensiontravel + This.radius; Raycasthit[] hits = Physics.raycastall (Item.transform.parent.position,-
            Item.transform.parent.InverseTransformDirection (vector3.up), This.suspensiontravel + This.radius); foreach (Raycasthit test in hits) {if (!test.collider.istrigger && test.distance <=
                     DIST) {hit = test;
        Onground = true;             dist = test.distance; }} if (Onground) {Vector3 Wheelvelo = this.rigidbody.GetPointVelocit
             Y (item.transform.parent.position); Vector3 Localvelo = transform.
             Inversetransformdirection (Wheelvelo); Vector3 Groundnormal = transform.
             Inversetransformdirection (Hit.normal);
             float Damperforce = Vector3.dot (Localvelo, groundnormal) * 5000F;
             float compression = 1.0f-((Hit.distance-radius)/suspensiontravel); Vector3 Springforce = (fullcompressionspringforce*compression-damperforce) *

             Item.transform.parent.InverseTransformDirection (vector3.up);

             Springforce.z = springforce.x = 0f;

         This.rigidbody.AddForceAtPosition (Springforce, item.transform.parent.position); } else {this.
        Onground = false; } foreach (Gameobject item in bwheelmodels) {RaycastHit Hit; BOOL Onground = Physics.raycast (Item.transform.parent.position,-item.transform.parent.inversetransformdirection (

         Vector3.up), out hit, This.suspensiontravel + This.radius);
               if (Onground && hit.collider.isTrigger) {onground = false;
               Float dist = this.suspensiontravel + This.radius; Raycasthit[] hits = Physics.raycastall (Item.transform.parent.position,-
               Item.transform.parent.InverseTransformDirection (vector3.up), This.suspensiontravel + This.radius); foreach (Raycasthit test in hits) {if!test.collider.istrigger && Test.distan
                           CE <= dist) {hit = test;
                           Onground = true;
                      dist = test.distance; }} if (Onground) {Vector3 Wheelvelo = This.rigidbody.
                Getpointvelocity (item.transform.parent.position); Vector3 Localvelo = transform.
                Inversetransformdirection (Wheelvelo); Vector3 Groundnormal = transform.
                Inversetransformdirection (Hit.normal);
                float Damperforce = Vector3.dot (Localvelo, groundnormal) * 5000F;
                float compression = 1.0f-((Hit.distance-radius)/suspensiontravel); Vector3 Springforce = (fullcompressionspringforce*compression-damperforce) *
                Item.transform.parent.InverseTransformDirection (vector3.up);
                Springforce.z = springforce.x = 0f;
          This.rigidbody.AddForceAtPosition (Springforce, item.transform.parent.position); } else {this.
          Onground = false;
 }
     }
}
So after the suspension support, it is time to design the vehicle power.
There are 2 ways to do this: One Direction is the real vehicle trajectory and the other is the analog vehicle trajectory.
The former method is to place the power point on a vehicle driving wheel, such as a rear wheel. With the Rigidbody addforceatposition can be done, the front wheels only need to provide lateral force can achieve the turn of the track. But don't say it's so easy, it involves a lot of numerical and curve problems. In providing the vehicle power, you need a curve so that the vehicle will not be evenly accelerated, because it is very unreal, and in the front wheel transverse force, you must be 0 to the highest point, and then down to the equilibrium point of the curve. So your car will look more real. These all require a few mathematical knowledge.
The latter is an algorithm used to simulate a vehicle trajectory. This algorithm has all the forces acting on the center point of the vehicle.
Turning path, I use the turning radius, so that the vehicle in the turn is quite authentic, must change the speed of the car turn. Of course, I used some knowledge of maths. Code dedication:

#region calculates the turn angle void steering (bool cansteer, Vector3 relativevelocity) {if Cansteer && this. Onground) {if (This.shiftthrottle = = 1) {This.transform.RotateAround (this.transf Orm. Transformpoint (this. Fwheelmodels[0].transform.localposition + this. fwheelmodels[1].transform.localposition) * 0.5f), this.transform.up, This.rigidbody.velocity.magnitude *2f*
              This.steeringinput * time.deltatime * 2f); ~ this.rigidbody.AddForceAtPosition (this. Fwheelmodels[0].transform. Transformdirection (vector3.right*this.steeringinput) * 3f * this.rigidbody.mass, this.
             Fwheelmodels[0].transform.position); ~ this.rigidbody.AddForceAtPosition (this. Fwheelmodels[1].transform. Transformdirection (vector3.right*this.steeringinput) * 3f * this.rigidbody.mass, this.
             Fwheelmodels[1].transform.position);
         return; } if (This.throttle * this.transform.InverseTransformDirection (this.rigidbody.velocity). z < 0) return;
       float Turnradius = 3.0f/mathf.sin ((90f-this.steering) * Mathf.deg2rad);
       float Minmaxturn = Evaluatespeedtoturn (this.rigidbody.velocity.magnitude);
       float turnspeed = Mathf.clamp (Relativevelocity.z/turnradius,-MINMAXTURN/10, MINMAXTURN/10); This.transform.RotateAround (this.transform.position + this.transform.right * Turnradius * this.steeringinput,

       Transform.up, Turnspeed * mathf.rad2deg * time.deltatime * this.steeringinput);
       ~ Vector3 Debugstartpoint = transform.position + transform.right * Turnradius * this.steeringinput;

       ~ Vector3 Debugendpoint = debugstartpoint + vector3.up * 5f;
    ~ Debug.drawline (Debugstartpoint, Debugendpoint, color.red);
     The float Evaluatespeedtoturn (float speed) {if (Speed > This.topspeed/2) return minimumturn;
     float Speedindex = 1-(Speed/(THIS.TOPSPEED/2)); return Minimumturn + Speedindex * (Maximumturn-miniMumturn);
 } #endregion

This simulation of the vehicle trajectory, can not achieve drift performance, but I added a sliding ratio calculation algorithm, with the vehicle lateral movement speed, and the rate of forward speed, to determine whether the vehicle is in the drift state, if in, then start Drift slide program. Of course, my car is very natural, do not do. As for tire traces, is to determine whether to touch the bottom, at that point to generate tire traces Gameobject, that's all.

Finally, all vehicles need to simulate, when driving, the tires with the speed of rotation this is related to the vehicle appears to be authentic things. actually very simple. Not much to say, send code:

#region tyre rolling and rotation simulation void Wheelroll () {Float Averageangularvelo = (this.rigidbody.GetPointVelocity) (this. bwheelmodels[0].transform.parent.position). Magnitude + this.rigidbody.GetPointVelocity (this.
      bwheelmodels[0].transform.parent.position). magnitude)/2f;

      float Engineangularvelo = Averageangularvelo * 3f; float rpm = Engineangularvelo * (60.0f/(2*MATHF.PI)) * (This.transform.InverseTransformDirection ( this.rigidbody.velocity). z > 0f?

      1f: -1f);

      ~ Debug.Log (This.transform.InverseTransformDirection (this.rigidbody.velocity). z); fwheelmodels[0].transform.rotation = fwheelmodels[0].transform.parent.rotation * Quaternion.Euler (RotationValue, this.steering, 0)//Rotate fwheelmodels[1].transform.rotation = fwheelmodels[1].transform.parent.rotation * Quaternion. Euler (Rotationvalue, this.steering, 0);/rotate bwheelmodels[0].transform.rotation = bwheelmodels[0].transform.parent . Rotation * Quaternion.euler (rotationvalue, 0, 0);/rotate Bwheelmodels[1].transform.rotation = bwheelmodels[1].transform.parent.rotation * Quaternion.euler (RotationValue, 0, 0);/rotate
Rotationvalue + = RPM * (360f/60f) * time.deltatime;
 }

#endregion

Http://www.cnblogs.com/lm3515/archive/2010/09/21/1832324.html

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.