您的位置:首页 > 移动开发 > Unity3D

unity ai car demo

2016-01-23 17:38 621 查看

目的

  此例子的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: