码迷,mamicode.com
首页 > 编程语言 > 详细

unity ai car demo

时间:2016-01-23 18:17:57      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:

目的

  此例子的AI效果就是要车子在一条连续的封闭的曲线上面不停的自己循环移动。

其它

  对车子运动控制,请看上一篇http://www.cnblogs.com/zkzk945/p/5146474.html

基本思路

  利用样条曲线(catmull-rom spline)将路径点通过插值形成连续的曲线,根据车子离开路径起始点的距离计算出车子在路径上的目标点,目标点决定了车子的朝向、油门、刹车。

   target.position = circuit.GetRoutePoint(progressDistance + m_lookAheadForTargetOffset +
                                                m_lookAheadForTargetFactor*speed).pos;
        target.rotation = Quaternion.LookRotation(circuit.GetRoutePoint(progressDistance + m_lookAheadForTargetOffset +
                                                m_lookAheadForTargetFactor * speed).dir);

以上代码就是根据和初始点的距离计算目标点,包括了目标点的位置和朝向。

        progressPoint = circuit.GetRoutePoint(progressDistance);
        //Debug.Log(progressDistance);
        Vector3 progressDelta = progressPoint.pos - transform.position;
        if (Vector3.Dot(progressDelta, progressPoint.dir) < 0)
        {
            progressDistance += progressDelta.magnitude*0.5f;
        }

以上代码是为了判断车子是否在目标点的前面,如果是,那么增加progressDistance,可以让target目标点定位到车子的前方去,这样target点就会在样条曲线上面循环移动,那么车子也会尾随其移动。

//遇到转角或者控制节点,减速处理
                float desiredSpeed = m_carController.MaxSpeed;

                Vector3 delta = m_target.position - transform.position;
                float distanceCautiousFactor = Mathf.InverseLerp(m_cautiousMaxDistance, 0, delta.magnitude);

                float spinningAngle = m_rigidbody.angularVelocity.magnitude*m_cautiousMaxDistance;

                float cautiousnessRequired = Mathf.Max(Mathf.InverseLerp(0, m_cautiousMaxAngle, spinningAngle),
                    distanceCautiousFactor);

                desiredSpeed = Mathf.Lerp(m_carController.MaxSpeed, m_carController.MaxSpeed*m_cautiousSpeedFactor,
                    cautiousnessRequired);

以上代码是在转角点时对期望速度的处理,根据车子和目标点的距离、车子本身的角速度,求得一个紧张系数,当车子距离目标点越紧或者角速度越大,紧张系数也就越大,这样车子就需要减慢速度,以防止翻车。

 Vector3 offsetTargetPos = m_target.position;

                offsetTargetPos += m_target.right*
                                   (Mathf.PerlinNoise(Time.time*m_lateralWanderSpeed, m_randomPerlin)*2 - 1)*
                                   m_lateralWanderDistance;

                Vector3 localTarget = transform.InverseTransformPoint(offsetTargetPos);

                float targetAngle = Mathf.Atan2(localTarget.x, localTarget.z) * Mathf.Rad2Deg;

                float steer = Mathf.Clamp(targetAngle * m_steerSensitivity, -1, 1);

                float accelBrakeSensitivity = (desiredSpeed < m_carController.CurrentSpeed)
                    ? m_brakeSensitivity
                    : m_accelSensitivity;

                float accle = Mathf.Clamp((desiredSpeed - m_carController.CurrentSpeed)*accelBrakeSensitivity, -1, 1);

                //Debug.Log(accle);
                //Debug.Log((1 - m_accelWanderAmount) +
                //         (Mathf.PerlinNoise(Time.time*m_accelWanderSpeed, m_randomPerlin)*m_accelWanderAmount));

                accle *= (1 - m_accelWanderAmount) +
                         (Mathf.PerlinNoise(Time.time*m_accelWanderSpeed, m_randomPerlin)*m_accelWanderAmount);
                //Debug.Log(accle);

                m_carController.Move(steer, accle, accle, 0f);

首先对目标点进行柏林噪声随机,然后根据目标点算出方向盘的方向。然后根据期望速度和当前速度计算出油门或者刹车输入,最后手动传给控制汽车移动的函数,实现了汽车的自动化运行。

源码

http://git.oschina.net/zkzk945/CarAIDemo521

unity ai car demo

标签:

原文地址:http://www.cnblogs.com/zkzk945/p/5153688.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!