Welcome to Unity Learning,Unity training ,UnityEnterprise TrainingEducation Area, there are manyUnity3d Resources,Unity3d Training Video,Unity3d Tutorials,Unity3d Frequently Asked questions,Unity3d Project Source code, the "Dog Planing Learning Network" Unity's Ultimate Academy, dedicated to building the industry unity3d Training , learning the first brand. Before making a production, 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 reaction force to the tyre, thus producing the RPM.
The power of the engine can be obtained by the RPM formula: RPM = engine power 60/2pi, 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 rear drive vehicle, the front wheel direction rotation big angle, the ground gives a certain centripetal force, at the same time the rear wheel gives more impetus, causes "the drift" the movement.
Based on the above principles, it is easier to understand the following article.
Let me start by stating that there are many ways to develop a car. I racing version after countless different methods, countless times after the final selection of a popular accepted. These methods, let me a 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 on the vehicle can not achieve your intended target, caused, must be in the vehicle tires above the shell collision, the tires need to be strong to support it always remain.
There's a magical thing in Unity3d called Wheelcollider, which specializes in simulating tire support and tire turns, as well as tire transverse forces, forward forces, and suspension shock systems.
This thing is very handy, as long as you put this thing on 4 tires, debug his forwardfriction and sidewaysfriction
Achieve the effect you want, and then assign values to the Motortorque of the drive wheel, and 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, then from high to stable.
This wheelcollider is very useful, once indulged in this. But later found that he had a lot of unreasonable places. Want to get the best result, or abandon him.
In order to support the collision of the vehicle housing does not touch the ground, must write a suspension dynamic support force, in 4 tyre position, support the whole 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.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;
}
}
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.distance = 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;
}
}
}
Then after the suspension support, the design of the vehicle power.
There are also 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 the vehicle drive wheel, such as the rear wheel. With the Rigidbody addforceatposition can be done, the front wheel only need to provide lateral force can realize the trajectory of the turn. But don't look so easy, it also involves a lot of numerical and curve problems. In providing vehicle power, you need a curve so that the vehicle does not equalize, because it is unreal, and in the front wheel transverse force, you must be a curve from 0 to the highest point and then down to the equilibrium point. So your car is more real. These all require a few mathematical knowledge.
The latter is a vehicle trajectory that is modeled by an algorithm. This algorithm has all the forces acting on the center of the vehicle.
Turn trajectory, I use a turning radius to express, so that the vehicle in the turn is quite true, must change the speed of the car turn. Of course, some mathematical knowledge was used. Code of Dedication:
#region Calculate Turn angle
VOID steering (bool cansteer, Vector3 relativevelocity)
{
if (Cansteer this. Onground)
{
if (This.shiftthrottle = = 1)
{
This.transform.RotateAround (This.transform.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);
}
}
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 simulated vehicle trajectory can not achieve drift performance, but I added a sliding scale calculation algorithm, with the vehicle lateral movement speed, and the forward speed, the ratio to determine whether the vehicle is in a drift state, such as in, then start the Drift sliding program. Of course, my car is very natural, do not do. As for tire traces, it is to determine whether the bottom, the point of the formation of tire traces Gameobject, that's all.
Finally, the next introduction, all vehicles need to simulate, when traveling, the tyre rotates with the speed of the vehicle is related to the authenticity of things. It's actually very simple. Not much to say, hair code:
#region Tire rolling and rotating 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);//rotation
fwheelmodels[1].transform.rotation = fwheelmodels[1].transform.parent.rotation * Quaternion.Euler (RotationValue, this.steering, 0);//rotation
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
For more information, please visit the "Dog Planing Learning Network" Unity Ultimate Academy
statement: This document comes from the "Dog Planing Learning Network" Community-unity Extreme College, is a self-published Unity3d study articles, if anything violates your relevant interests, please communicate with the official, we will deal with the real-time.
Unity3d Racing vehicle performance algorithms