I. Overview
In Unity3d official resources, standard Assets–>vehicles–>car is a vehicle-related resource, including racing models, racing control scripts, and more. Although it is very convenient to use, but because some scripts are not thoroughly understood, it is not good. In particular, the main control script Carcontroller, this time I have a comprehensive analysis of this script
Two. CarController1. Main function flowchart
The whole Carcontroller script controls the car with a common function move.
2. Code type definition Section
//汽车驱动类型 internalenum CarDriveType { //四驱 FrontWheelDrive, //后驱 RearWheelDrive, //前驱 FourWheelDrive } //速度类型 internalenum SpeedType { //英里每小时 MPH, //千米每小时 KPH }
3. Code Definition Section
[Serializefield]PrivateCardrivetype m_cardrivetype = cardrivetype.fourwheeldrive; [Serializefield]Privatewheelcollider[] M_wheelcolliders =Newwheelcollider[4]; [Serializefield]Privategameobject[] M_wheelmeshes =Newgameobject[4]; [Serializefield]Privatewheeleffects[] M_wheeleffects =Newwheeleffects[4];//center of gravity position[Serializefield]PrivateVector3 M_centreofmassoffset;//maximum turning angle[Serializefield]Private floatM_maximumsteerangle; [Range (0,1)] [Serializefield]Private floatM_steerhelper;//0 is raw physics, 1 the car would grip in the direction it is facing[Range (0,1)] [Serializefield]Private floatM_tractioncontrol;//0 is no traction control, 1 are full interference //torque for all tires[Serializefield]Private floatM_fulltorqueoverallwheels;//Reverse torque[Serializefield]Private floatM_reversetorque;//maximum braking torque[Serializefield]Private floatM_maxhandbraketorque;//MAX under pressure[Serializefield]Private floatM_downforce = -F//Speed unit[Serializefield]PrivateSpeedtype M_speedtype;//maximum speed[Serializefield]Private floatM_topspeed = $;total number of gears//positions[Serializefield]Private Static intNoofgears =5;//[Serializefield]Private floatM_revrangeboundary =1F//maximum sliding distance[Serializefield]Private floatM_sliplimit;//braking torque[Serializefield]Private floatM_braketorque;
4. Function move
//External call for vehicle Movement control function Public void Move(floatSteering,floatAccelfloatFootbrake,floatHandbrake) {Debug.Log ("***************************: "+ Footbrake +" "+ handbrake);//Keep the current tyre mesh following wheelcollider rotation for(inti =0; I <4; i++) {quaternion quat; Vector3 position; M_wheelcolliders[i]. Getworldpose ( outPosition outQuat); M_wheelmeshes[i].transform.position = position; M_wheelmeshes[i].transform.rotation = Quat; }//clamp Input Values //Limit input value rangeSteering = Mathf.clamp (steering,-1,1); Accelinput = Accel = Mathf.clamp (Accel,0,1); Brakeinput = Footbrake =-1*mathf.clamp (Footbrake,-1,0); Handbrake = Mathf.clamp (handbrake,0,1);//set the steer on the front wheels. //Set front wheel corner //assuming that wheels 0 and 1 is the front wheels. //wheels Subscript 0, 1 is the front wheelM_steerangle = Steering*m_maximumsteerangle; m_wheelcolliders[0].steerangle = M_steerangle; m_wheelcolliders[1].steerangle = M_steerangle;//Call Angle Assist Assistant,Steerhelper ();//Set acceleration/brake information to WheelcolliderApplydrive (Accel, Footbrake);//Check speed rangeCapspeed ();//set the handbrake. //Set handbrake //assuming that wheels 2 and 3 is the rear wheels. //wheel subscript is 2, 3 is the rear wheel if(Handbrake >0f) {//Set the handbrake value to the rear wheel to achieve deceleration purpose varHbtorque = Handbrake*m_maxhandbraketorque; m_wheelcolliders[2].braketorque = Hbtorque; m_wheelcolliders[3].braketorque = Hbtorque; }//calculate speed, used for external call speed attribute revs to play engine sound, etc.Calculaterevs ();//Change gear positionGearchanging ();//apply under pressureAdddownforce ();//Check tiresCheckforwheelspin ();//Traction control systemTractioncontrol (); }
5. Function Steerhelper, key attribute: M_steerhelper
Private void Steerhelper() { for(inti =0; I <4; i++) {Wheelhit wheelhit; M_wheelcolliders[i]. Getgroundhit ( outWheelhit);if(Wheelhit.normal = = Vector3.zero)return;//wheels arent on the ground so dont realign the rigidbody velocity //If the wheel is off the ground, you don't have to adjust the car angle.}//This if are needed to avoid gimbal lock problems that would make the car suddenly shift direction //This is to avoid the universal lock problem, the universal lock problem will cause the car to suddenly change direction (I know the universal lock problem, but do not understand how to avoid the problem below, I only know that the use of four yuan is to avoid the universal lock problem) //The effect of this if function is: if the last car body y-direction angle than this time less than 10 degrees, according to the degree of the difference multiplied by the coefficient m_steerhelper, to obtain the degree of rotation required //Based on this degree, calculate the number of four, and then rotate the body speed directly to the degree of this offset, //According to the definition of m_steerhelper at the beginning of the code, this approach is equivalent to doing an angle assist, not entirely with wheelcollider physical effects //and directly control the speed direction, adjust the angle of the car. ///Now, if the smaller the m_steerhelper, the smaller the adjustment angle, and if the M_steerhelper is 0, the angle of the adjustment is 0. if(Mathf.abs (M_OLDROTATION-TRANSFORM.EULERANGLES.Y) <Tenf) {varTurnadjust = (transform.eulerangles.y-m_oldrotation) * m_steerhelper; quaternion velrotation = Quaternion.angleaxis (Turnadjust, vector3.up); m_rigidbody.velocity = velrotation * m_rigidbody.velocity; } m_oldrotation = Transform.eulerangles.y; }
I through the practice, found that the effect is if the M_steerhelper is 0, the car turn angle is very dead, if 1, turning angle is particularly flexible. So this attribute depends on the individual situation to adjust
6. Function Tranctioncontrol, key attribute M_tractioncontrol
//Crude traction control, reduces the power to wheel if the car is wheel spinning too much //If the car tires are excessively slippery, the traction system can control the reduction of tyre power Private void Tractioncontrol() {Wheelhit wheelhit;Switch(M_cardrivetype) {//Four drive CaseCardrivetype.fourwheeldrive://Loop through all wheels for(inti =0; I <4; i++) {M_wheelcolliders[i]. Getgroundhit ( outWheelhit); Adjusttorque (Wheelhit.forwardslip); } Break;//Rear drive Casecardrivetype.rearwheeldrive:m_wheelcolliders[2]. Getgroundhit ( outWheelhit); Adjusttorque (Wheelhit.forwardslip); m_wheelcolliders[3]. Getgroundhit ( outWheelhit); Adjusttorque (Wheelhit.forwardslip); Break;//Precursor Casecardrivetype.frontwheeldrive:m_wheelcolliders[0]. Getgroundhit ( outWheelhit); Adjusttorque (Wheelhit.forwardslip); m_wheelcolliders[1]. Getgroundhit ( outWheelhit); Adjusttorque (Wheelhit.forwardslip); Break; } }Private void Adjusttorque(floatForwardslip) {//When the forward sliding distance exceeds the threshold, it means that the tyre is excessively slippery, reducing traction to reduce the speed. if(Forwardslip >= m_sliplimit && m_currenttorque >=0) {M_currenttorque-=Ten* M_tractioncontrol; }Else{M_currenttorque + =Ten* M_tractioncontrol;if(M_currenttorque > M_fulltorqueoverallwheels) {m_currenttorque = M_fulltorqueoverallwheels; } } }
As can be seen from the above function, the M_tractioncontrol controls the increment size of each increase or decrease in traction.
Let's look at another section of the start code.
//设置当前扭矩,初始化的扭矩值跟m_TractionControl大小有关,m_TractionControl决定是否有牵引力,如果m_TractionControl //值为0,则当前扭矩直接就是最大值,如果该值为1,则初始扭矩为0,然后汽车启动慢慢增加扭矩力。 m_CurrentTorque = m_FullTorqueOverAllWheels - (m_TractionControl*m_FullTorqueOverAllWheels);
that is, if the M_tractioncontrol is 1, then the first car torque force is 0, and then through the above function Tranctioncontrol in the code, each time 10 force to increase.
we will find that every time you start the car will be very slow, and if the hill climb when not rushed up, stopped in the Banpo, and then want to rush up, very difficult, because this time torque is very small, insufficient power;
If we set the M_tractioncontrol to 0, then the car will start off with full power and no more reduction, but the car can start up very fast.
If we set the M_tractioncontrol to 0.5, then the car starts off with half the power, and then the other half of the momentum changes dynamically.
So as long as you hold on to the above points, according to their own needs to set the property is good
7. Function Calculaterevs (), focus attribute revs
//Calculate Speed Private void Calculaterevs() {//Calculate engine revs (for Display/sound) //Calculate engine speed (for display and sound only) //( This is do in Retrospect-revs be used in force/power calculations) //(My personal understanding:) This calculation is the rotational speed of the backtracking and cannot be used for force calculation. In other words, this is based on the speed, the inverse calculation of the speed, just for the effect of display //Calculates the speed factor at the current gear (determines the speed at the current position)Calculategearfactor ();//Position factor: Current position/total number of stalls varGearnumfactor = m_gearnum/(float) Noofgears;//Calculate the minimum speed at the current gear level varRevsrangemin = Ulerp (0F, M_revrangeboundary, Curvefactor (Gearnumfactor));//Calculate the maximum speed at the current gear level varRevsrangemax = Ulerp (M_revrangeboundary,1F, Gearnumfactor);//Based on the current speed factor, calculate the current speedRevs = Ulerp (Revsrangemin, Revsrangemax, m_gearfactor); }
One of the more strange places is the calculation of revsrangemin, the use of the Curvefactor curve function for the gear factor, my understanding is that because the correspondence between gears and rotational speed is not a simple relationship of y = x, Therefore, it is not possible to use gearnumfactor directly as a proportional coefficient of rotational speed, so a conversion is required, that is, the corresponding relationship between the gear position or speed and speed is rotational speed = 1-(1-x) (1-x). Look at the curve I made out of this function,
As to why the maximum rotational speed is calculated, and the function is not used, I haven't figured it out yet.
8. Function Calculategearfactor
//Calculate the file position factor Private void Calculategearfactor() {floatF = (1/(float) noofgears);//Gear factor is a normalised representation of the current speed within the current gear ' s range of speeds. //We smooth towards the ' target ' gear factor, so this revs don ' t instantly snap up or down when changing gear. //We want the values to move in a smooth way, to ensure that the speed does not suddenly get higher or lower at the shift. //Reverse difference, through the current speed of the proportional value, find the current speed at the current position of the proportional location, the resulting value will be a 0~1 range of values. varTargetgearfactor = Mathf.inverselerp (F*m_gearnum, f* (M_gearnum +1), Mathf.abs (Currentspeed/maxspeed));//Smoothing difference from the current position factor to the target profile factorM_gearfactor = Mathf.lerp (M_gearfactor, Targetgearfactor, time.deltatime*5f); }
From the above we can see that at least the corresponding relationship between gear speed, is generally linear, not curve. Otherwise the inverse interpolation function above may have to use the curve transformation function.
Three. Other
Other functions have some interesting functions, and I'm not going to list them here. I uploaded my annotated version of the Carcontroller, hoping to give useful friends some inspiration. I have a lot of understanding may be wrong, just to justify, I will later study the results can be updated again
My upload comment version link:
http://download.csdn.net/detail/narutojzm1/9516648
Unity3d Official Resources Car Master Script Carcontroller translation and explanation