查看: 1509|回复: 1
打印 上一主题 下一主题

unity3d 动力学 汽车脚本_代码

[复制链接]

2508

主题

2

听众

3万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
32806
精华
12

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-6-29 14:31:57 |只看该作者 |倒序浏览

   
        
            这是从官网论坛上收集的一个汽车脚本,经过验证可以使用。由于skidmarks这个配套的脚本没有找到,所以把skidmarks相关的语句都屏蔽了,所以很遗憾没有刹车印的效果,其他的没有改。

            

                拿出来共享,感兴趣的一起研究下。

            

                汽车脚本代码看起来都比较复杂,主要是老外的编程底子牛,什么都写到代码里自动生成了。其实有些东西可以在编辑器里完成,这样就省不少代码了。还有制动和变速箱部分用了不少代码,这个可能要点汽车发动机知识,反正我是一点都没看懂。

            

                不想研究的可以直接拿来用。

            

                使用方法如下:

            

                1、把脚本直接连到汽车车身网格上,车身要有Rigidbody Component,要有四个轮子网格做子物体。 要想有声音的话还要有AudioSource Component。

            

                2、打开Inspector,选择汽车脚本,把四个轮子连接到相对应的Transform参数上。设置wheelRadius参数为你轮子网格的大小。WheelCollider是自动生成的,所以无需手动添加。这样就能保证运行了,其他的声音和灰尘可以再添加。

            

                脚本源代码如下:
            
            
            
                #pragma strict

                 
               

                 
                //maximal corner and braking acceleration capabilities

                 
                var maxCornerAccel=10.0;

                 
                var maxBrakeAccel=10.0;

                 
               

                 
                //center of gravity height - effects tilting in corners

                 
                var cogY = 0.0;

                 
               

                 
                //engine powerband

                 
                var minRPM = 700;

                 
                var maxRPM = 6000;

                 
               

                 
                //maximum Engine Torque

                 
                var maxTorque = 400;

                 
               

                 
                //automatic transmission shift points

                 
                var shiftDownRPM = 2500;

                 
                var shiftUpRPM = 5500;

                 
               

                 
                //gear ratios

                 
                var gearRatios = [-2.66, 2.66, 1.78, 1.30, 1.00];

                 
                var finalDriveRatio = 3.4;

                 
               

                 
                //a basic handling modifier:

                 
                //1.0 understeer

                 
                //0.0 oversteer

                 
                var handlingTendency = 0.7;

                 
               

                 
                //graphical wheel objects

                 
                var wheelFR : Transform;

                 
                var wheelFL : Transform;

                 
                var wheelBR : Transform;

                 
                var wheelBL : Transform;

                 
               

                 
                //suspension setup

                 
                var suspensionDistance = 0.3;

                 
                var springs = 1000;

                 
                var dampers = 200;

                 
                var wheelRadius = 0.45;

                 
               

                 
                //particle effect for ground dust

                 
                var groundDustEffect : Transform;

                 
               

                 
                private var queryUserInput = ***e;

                 
                private var engineRPM : float;

                 
                private var steerVelo = 0.0;

                 
                private var brake = 0.0;

                 
                private var handbrake = 0.0;

                 
                private var steer = 0.0;

                 
                private var motor = 0.0;

                 
                //private var skidTime = 0.0;

                 
                private var onGround = false;

                 
                private var cornerSlip = 0.0;

                 
                private var driveSlip = 0.0;

                 
                private var wheelRPM : float;

                 
                private var gear = 1;

                 
                //private var skidmarks : Skidmarks;

                 
                private var wheels : WheelData[];

                 
                private var wheelY = 0.0;

                 
                private var rev = 0.0;

                 
               

                 
                //Functions to be used by external scripts

                 
                //controlling the car if required

                 
                //===================================================================

                 
               

                 
                //return a status string for the vehicle

                 
                function GetStatus(gui : GUIText) {

                 
                   gui.text="v="+(rigidbody.velocity.magnitude * 3.6).ToString("f1") + " km/h
gear= "+gear+"
rpm= "+engineRPM.ToString("f0");

                 
                }

                 
               

                 
                //return an information string for the vehicle

                 
                function GetControlString(gui : GUIText) {

                 
                   gui.text="Use arrow keys to control the jeep,
space for handbrake.";

                 
                }

                 
               

                 
                //Enable or disable user controls

                 
                function SetEnableUserInput(enableInput)

                 
                {

                 
                   queryUserInput=enableInput;

                 
                }

                 
               

                 
                //Car physics

                 
                //===================================================================

                 
               

                 
                //some whee calculation data

                 
                class WheelData{

                 
                   var rotation = 0.0;

                 
                   var coll : WheelCollider;

                 
                   var graphic : Transform;

                 
                   var maxSteerAngle = 0.0;

                 
                   var lastSkidMark = -1;

                 
                   var powered = false;

                 
                   var handbraked = false;

                 
                   var originalRotation : Quaternion;

                 
                };

                 
               

                 
                function Start () {

                 
                   //setup wheels

                 
                   wheels=new WheelData[4];

                 
                   for(i=0;i<4;i++)

                 
                      wheels = new WheelData();

                 
                       

                 
                   wheels[0].graphic = wheelFL;

                 
                   wheels[1].graphic = wheelFR;

                 
                   wheels[2].graphic = wheelBL;

                 
                   wheels[3].graphic = wheelBR;

                 
               

                 
                   wheels[0].maxSteerAngle=30.0;

                 
                   wheels[1].maxSteerAngle=30.0;

                 
                   wheels[2].powered=***e;

                 
                   wheels[3].powered=***e;

                 
                   wheels[2].handbraked=***e;

                 
                   wheels[3].handbraked=***e;

                 
               

                 
                   for(w in wheels)

                 
                   {

                 
                      if(w.graphic==null)

                 
                         Debug.Log("You need to assign all four wheels for the car script!");

                 
                      if(!w.graphic.transform.IsChildOf(transform))   

                 
                         Debug.Log("Wheels need to be children of the Object with the car script");

                 
                          

                 
                      w.originalRotation = w.graphic.localRotation;

                 
               

                 
                      //create collider

                 
                      colliderObject = new GameObject("WheelCollider");

                 
                      colliderObject.transform.parent = transform;

                 
                      colliderObject.transform.position = w.graphic.position;

                 
                      w.coll = colliderObject.AddComponent(WheelCollider);

                 
                      w.coll.suspensionDistance = suspensionDistance;

                 
                      w.coll.suspensionSpring.spring = springs;

                 
                      w.coll.suspensionSpring.damper = dampers;

                 
                      //no grip, as we simulate handling ourselves

                 
                      w.coll.forwardFriction.stiffness = 0;

                 
                      w.coll.sidewaysFriction.stiffness = 0;

                 
                      w.coll.radius = wheelRadius;

                 
                   }   

                 
               

                 
                   //get wheel height (height forces are applied on)

                 
                   wheelY=wheels[0].graphic.localPosition.y;

                 
                    

                 
                   //setup center of gravity

                 
                   rigidbody.centerOfMass.y = cogY;

                 
                    

                 
                   //find skidmark object

                 
                //   skidmarks = FindObjectOfType(typeof(Skidmarks));

                 
                    

                 
                   //shift to first

                 
                   gear=1;

                 
                }

                 
               

                 
                //update wheel status

                 
                function UpdateWheels()

                 
                {

                 
                   //calculate handbrake slip for traction gfx

                 
                    handbrakeSlip=handbrake*rigidbody.velocity.magnitude*0.1;

                 
                   if(handbrakeSlip>1)

                 
                      handbrakeSlip=1;

                 
                       

                 
                   totalSlip=0.0;

                 
                   onGround=false;

                 
                   for(w in wheels)

                 
                   {      

                 
                      //rotate wheel

                 
                      w.rotation += wheelRPM / 60.0 * -rev * 360.0 * Time.fixedDeltaTime;

                 
                      w.rotation = Mathf.Repeat(w.rotation, 360.0);      

                 
                      w.graphic.localRotation= Quaternion.Euler( w.rotation, w.maxSteerAngle*steer, 0.0 ) * w.originalRotation;

                 
               

                 
                      //check if wheel is on ground

                 
                      if(w.coll.isGrounded)

                 
                         onGround=***e;

                 
                          

                 
                      slip = cornerSlip+(w.powered?driveSlip:0.0)+(w.handbraked?handbrakeSlip:0.0);

                 
                      totalSlip += slip;

                 
                       

                 
                      var hit : WheelHit;

                 
                      var c : WheelCollider;

                 
                      c = w.coll;

                 
                      if(c.GetGroundHit(hit))

                 
                      {

                 
                         //if the wheel touches the ground, adjust graphical wheel position to reflect springs

                 
                         w.graphic.localPosition.y-=Vector3.Dot(w.graphic.position-hit.point,transform.up)-w.coll.radius;

                 
                          

                 
                         //create dust on ground if appropiate

                 
                         if(slip>0.5 && hit.collider.tag=="Dusty")

                 
                         {

                 
                            groundDustEffect.position=hit.point;

                 
                            groundDustEffect.particleEmitter.worldVelocity=rigidbody.velocity*0.5;

                 
                            groundDustEffect.particleEmitter.minEmission=(slip-0.5)*3;

                 
                            groundDustEffect.particleEmitter.maxEmission=(slip-0.5)*3;

                 
                            groundDustEffect.particleEmitter.Emit();                        

                 
                         }

                 
                          

                 
                         //and skid marks            

                 
                         /*if(slip>0.75 && skidmarks != null)

                 
                            w.lastSkidMark=skidmarks.AddSkidMark(hit.point,hit.normal,(slip-0.75)*2,w.lastSkidMark);

                 
                         else

                 
                            w.lastSkidMark=-1; */

                 
                      }

                 
                     // else w.lastSkidMark=-1;

                 
                   }

                 
                   totalSlip/=wheels.length;

                 
                }

                 
               

                 
                //Automatically shift gears

                 
                function AutomaticTransmission()

                 
                {

                 
                   if(gear>0)

                 
                   {

                 
                      if(engineRPM>shiftUpRPM&&gear<gearRatios.length-1)

                 
                         gear++;

                 
                      if(engineRPM<shiftDownRPM&&gear>1)

                 
                         gear--;

                 
                   }

                 
               

                 
                }

                 
               

                 
                //Calculate engine acceleration force for current RPM and trottle

                 
                function CalcEngine() : float

                 
                {

                 
                   //no engine when braking

                 
                   if(brake+handbrake>0.1)

                 
                      motor=0.0;

                 
                    

                 
                   //if car is airborne, just rev engine

                 
                   if(!onGround)

                 
                   {

                 
                      engineRPM += (motor-0.3)*25000.0*Time.deltaTime;

                 
                      engineRPM = Mathf.Clamp(engineRPM,minRPM,maxRPM);

                 
                      return 0.0;

                 
                   }

                 
                   else

                 
                   {

                 
                      AutomaticTransmission();

                 
                      engineRPM=wheelRPM*gearRatios[gear]*finalDriveRatio;

                 
                      if(engineRPM<minRPM)

                 
                         engineRPM=minRPM;

                 
                      if(engineRPM<maxRPM)

                 
                      {

                 
                         //fake a basic torque curve

                 
                         x = (2*(engineRPM/maxRPM)-1);

                 
                         torqueCurve = 0.5*(-x*x+2);

                 
                         torqueToForceRatio = gearRatios[gear]*finalDriveRatio/wheelRadius;

                 
                         return motor*maxTorque*torqueCurve*torqueToForceRatio;

                 
                      }

                 
                      else

                 
                         //rpm delimiter

                 
                         return 0.0;

                 
                   }

                 
                }

                 
               

                 
                //Car physics

                 
                //The physics of this car are really a trial-and-error based extension of

                 
                //basic "Asteriods" physics -- so you will get a pretty arcade-like feel.

                 
                //This may or may not be what you want, for a more physical approach research

                 
                //the wheel colliders

                 
                function HandlePhysics () {

                 
                   var velo=rigidbody.velocity;

                 
                   wheelRPM=velo.magnitude*60.0*0.5;

                 
               

                 
                   rigidbody.angularVelocity=new Vector3(rigidbody.angularVelocity.x,0.0,rigidbody.angularVelocity.z);

                 
                   dir=transform.TransformDirection(Vector3.forward);

                 
                   flatDir=Vector3.Normalize(new Vector3(dir.x,0,dir.z));

                 
                   flatVelo=new Vector3(velo.x,0,velo.z);

                 
                   rev=Mathf.Sign(Vector3.Dot(flatVelo,flatDir));

                 
                   //when moving backwards or standing and brake is pressed, switch to reverse

                 
                   if((rev<0||flatVelo.sqrMagnitude<0.5)&&brake>0.1)

                 
                      gear=0;

                 
                   if(gear==0)

                 
                   {   

                 
                      //when in reverse, flip brake and gas

                 
                      tmp=brake;

                 
                      brake=motor;

                 
                      motor=tmp;

                 
                       

                 
                      //when moving forward or standing and gas is pressed, switch to drive

                 
                      if((rev>0||flatVelo.sqrMagnitude<0.5)&&brake>0.1)

                 
                         gear=1;

                 
                   }

                 
                   engineForce=flatDir*CalcEngine();

                 
                   totalbrake=brake+handbrake*0.5;

                 
                   if(totalbrake>1.0)totalbrake=1.0;

                 
                   brakeForce=-flatVelo.normalized*totalbrake*rigidbody.mass*maxBrakeAccel;

                 
               

                 
                   flatDir*=flatVelo.magnitude;

                 
                   flatDir=Quaternion.AngleAxis(steer*30.0,Vector3.up)*flatDir;

                 
                   flatDir*=rev;

                 
                   diff=(flatVelo-flatDir).magnitude;

                 
                   cornerAccel=maxCornerAccel;

                 
                   if(cornerAccel>diff)cornerAccel=diff;

                 
                   cornerForce=-(flatVelo-flatDir).normalized*cornerAccel*rigidbody.mass;

                 
                   cornerSlip=Mathf.Pow(cornerAccel/maxCornerAccel,3);

                 
                    

                 
                   rigidbody.AddForceAtPosition(brakeForce+engineForce+cornerForce,transform.position+transform.up*wheelY);

                 
                    

                 
                   handbrakeFactor=1+handbrake*4;

                 
                   if(rev<0)

                 
                      handbrakeFactor=1;

                 
                   veloSteer=((15/(2*velo.magnitude+1))+1)*handbrakeFactor;

                 
                   steerGrip=(1-handlingTendency*cornerSlip);

                 
                   if(rev*steer*steerVelo<0)

                 
                      steerGrip=1;

                 
                   maxRotSteer=2*Time.fixedDeltaTime*handbrakeFactor*steerGrip;

                 
                   fVelo=velo.magnitude;

                 
                   veloFactor=fVelo<1.0?fVelo:Mathf.Pow(velo.magnitude,0.3);

                 
                   steerVeloInput=rev*steer*veloFactor*0.5*Time.fixedDeltaTime*handbrakeFactor;

                 
                   if(velo.magnitude<0.1)

                 
                      steerVeloInput=0;

                 
                   if(steerVeloInput>steerVelo)

                 
                   {

                 
                      steerVelo+=0.02*Time.fixedDeltaTime*veloSteer;

                 
                      if(steerVeloInput<steerVelo)

                 
                         steerVelo=steerVeloInput;

                 
                   }

                 
                   else

                 
                   {

                 
                      steerVelo-=0.02*Time.fixedDeltaTime*veloSteer;

                 
                      if(steerVeloInput>steerVelo)

                 
                         steerVelo=steerVeloInput;

                 
                   }

                 
                   steerVelo=Mathf.Clamp(steerVelo,-maxRotSteer,maxRotSteer);   

                 
                   transform.Rotate(Vector3.up*steerVelo*57.295788);

                 
                }

                 
               

                 
                function FixedUpdate () {

                 
                   //query input axes if necessarry

                 
                   if(queryUserInput)

                 
                   {

                 
                      brake = Mathf.Clamp01(-Input.GetAxis("Vertical"));

                 
                      handbrake = Input.GetButton("Jump")?1.0:0.0;

                 
                      steer = Input.GetAxis("Horizontal");

                 
                       motor = Mathf.Clamp01(Input.GetAxis("Vertical"));

                 
                    }

                 
                   else

                 
                   {

                 
                      motor = 0;

                 
                      steer = 0;

                 
                      brake = 0;

                 
                      handbrake = 0;

                 
                   }

                 
               

                 
               

                 
                   //if car is on ground calculate handling, otherwise just rev the engine

                 
                    if(onGround)

                 
                      HandlePhysics();

                 
                   else

                 
                      CalcEngine();   

                 
                       

                 
                   //wheel GFX

                 
                   UpdateWheels();

                 
               

                 
                   //engine sounds

                 
                   audio.pitch=0.5+0.2*motor+0.8*engineRPM/maxRPM;

                 
                   audio.volume=0.5+0.8*motor+0.2*engineRPM/maxRPM;

                 
                }

                 
               

                 
                //Called by DamageReceiver if boat destroyed

                 
                function Detonate()

                 
                {

                 
                   //destroy wheels

                 
                   for( w in wheels )

                 
                      w.coll.gameObject.active=false;

                 
               

                 
                   //no more car physics

                 
                   enabled=false;

                 
                }

                 
               

                 
                @script RequireComponent (Rigidbody)

                 
                @script RequireComponent (AudioSource)
            
            
            复制代码
            
        
   
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

1274

主题

1

听众

4万

积分

禁止发言

纳金币
43676
精华
4
沙发
发表于 2012-6-29 14:46:11 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-5-6 09:29 , Processed in 0.112242 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部