目的

  对unity的car demo进行解析,看下wheelcollider的运行原理。

结果

  下图就是我用unity的基础模型搭建起来的车子,实现了前进、后退、转弯、刹车等功能,当然就是抄的官方的代码。

搭建模型

  摄像机、灯光使用创建场景时默认的。

  创建一个plane当道路使用,一个cube用来检测碰撞。

  cube有三种用来测试碰撞的状态。一是可以不添加rigidbody,此时cube为静态刚体,碰撞时不会动。而是添加rigidbody但是使用is kinematic选项,此时cube为动态运动学刚体,碰撞效果和静态刚体一样,不会动。三是使用rigidbody,但是不勾选is kinematic,对刚体的mass大小进行修改,我们的车子默认是1000kg,可以看到不同障碍物的碰撞反应。

  主体car,也就是车子就比较复杂了。如上图所示,主要分为模型和碰撞体两部分,碰撞体又分为车身碰撞体和车轮碰撞体。

  

车身碰撞体

  车身碰撞体用的是简单的unity中自带的boxcollider,分别用了三个表示车身、车底座、车头,当然你还可以增加你需要的collider。

车轮碰撞体 wheelcollider

  车轮碰撞体用的是unity中自带的wheelcollider,分别有前左轮、前右轮、后左轮、后右轮,参数暂时使用默认的参数。

模型

  车身模型都是使用的unity中自带的cube,车轮使用的是unity中自带的sphere。注意,需要把他们自带的collider都删除掉,因为我们在前两步已经添加了对应的collider了。

关键代码解释

方向控制

m_steerAngle = steering*m_maxSteerAngle;
            //Debug.Log(m_steerAngle);
            m_wheelColliders[0].steerAngle = m_steerAngle;
            m_wheelColliders[1].steerAngle = m_steerAngle;

wheelcollider有个参数为steerAngle,通过调节这个参数就可以控制车子的转向,这个地方需要注意车子的转向角度有个最大值,例子中给的是25°。

油门控制

 private void ApplyDrive(float accel, float footbrake)
        {
            float thrustTorque;
            switch (m_carDriveType)
            {
                case CarDriveType.FourWheelDrive:
                {
                    thrustTorque = accel*(m_currentTorque/4f);
                    for (int i = 0; i < 4; i++)
                    {
                        m_wheelColliders[i].motorTorque = thrustTorque;
                    }
                    break;

                }
                case CarDriveType.FrontWheelDrive:
                {
                    thrustTorque = accel * (m_currentTorque / 2f);
                    m_wheelColliders[0].motorTorque = m_wheelColliders[1].motorTorque = thrustTorque;
                    break;
                }
                case CarDriveType.RearWheelDrive:
                {
                    thrustTorque = accel * (m_currentTorque / 2f);

                    m_wheelColliders[2].motorTorque = m_wheelColliders[3].motorTorque = thrustTorque;
                    break;
                }
            }

            for (int i = 0; i < 4; i++)
            {
                if (CurrentSpeed > 5 && Vector3.Angle(transform.forward, m_rigidbody.velocity) < 50f)
                {
                    m_wheelColliders[i].brakeTorque = m_brakeTorque*footbrake;
                }
                else if (footbrake > 0)
                {
                    m_wheelColliders[i].brakeTorque = 0f;
                    m_wheelColliders[i].motorTorque = -m_reversTorque*footbrake;
                }
            }
        }

case语句将车子分为四驱、前驱、后驱,本例按四驱来解释。当车子为四驱时,向前的牵引力需要分配给四个轮子,所以需要除以4。accel为油门系数,当我们按”w“键时,这个值就会慢慢变为1,这时我们通过修改motorTorque参数的值就可以控制车子前进起来了。
footbrake为刹车系数,当我们按”s“键的时候,这个值会慢慢变为1,这时我们通过修改brakeTorque的值就可以给车子增加刹车力矩。当然刹车力矩时在车速比较高的条件下才需要修改的,这里我们当速度大于5km/h时就添加刹车力矩。

当汽车速度较小,footbrake参数将会用来当倒车系数,这个和油门系数一样,乘以倒车力矩的最大值,即可获得实时的倒车力矩,用来实现倒车的效果。

 

源码放在了git上 http://git.oschina.net/zkzk945/CarDemo