很抱歉频繁提问。我在使用Andrew Gotow的汽车AI时遇到了问题。问题是AI没有避开前方的玩家/车辆,或者它们只是继续前进并撞上前方的玩家/车辆。一旦撞到车辆或任何障碍物,它们就会停止加速或停止工作。
请帮帮我。我不知道如何让AI不撞到障碍物。
这是我使用的代码。感谢任何帮助
function GotNewWaypoint(newWay : Vector3, newRot : Quaternion){ wpObj.transform.position = newWay; wpObj.transform.rotation = newRot;// wpObj是触发盒碰撞器,每次AI碰到碰撞器时都会设置GotNewWaypoint函数}function NavigateTowardsWaypoint(){ // 在Update函数中运行var relativePosition : Vector3;var hit : RaycastHit;if(!alternativeWaypointer){ relativePosition = transform.InverseTransformPoint(Vector3(wpObj.transform.position.x,transform.position.y,wpObj.transform.position.z));}else{// 如果Spherecast检测到物体,则开启替代位置 relativePosition = transform.InverseTransformPoint(Vector3(raycaster*wpObj.transform.position.x,transform.position.y,wpObj.transform.position.z)); // 在x轴上稍微移动wpObj以便AI不撞到障碍物}if(Physics.SphereCast(transform.position,40,transform.forward,hit,30)){ if(hit.transform != this.transform){ if(hit.collider.tag == "Player" || hit.collider.tag == "Opponent" || hit.collider.tag == "Environtment"){ alternativeWaypointer = true; raycaster = -Vector3.Normalize(hit.point).x * 5; }else alternativeWaypointer = false; }}inputSteer = relativePosition.x / relativePosition.magnitude;//用于AI的操控控制。通常为1或-1if(Mathf.Abs(inputSteer) < .5){ inputTorque = relativePosition.z / relativePosition.magnitude; //转角不太紧,可以加速}else{ inputTorque = 0.0; //转角太紧,停止加速}
}
回答:
据我所知,您的AI有一个测试来检查它是否会与某物碰撞。这个测试的结果似乎被分配给了变量alternativeWaypointer
,允许下面的if语句执行:
if(!alternativeWaypointer){ relativePosition = computePosition(trajectory);}else{ relativePosition = computePosition(adjustTrajectory(trajectory));}
可能您的调整轨迹逻辑没有起作用。或许可以测试一下?如果不是这样,一个可能的问题是您的调整轨迹没有足够调整以避免碰撞。我们可以通过创建一系列假设的轨迹,然后选择最佳候选来解决这个问题。
alternativeWaypointer = isCollisionLikely(trajectory);if(!alternativeWaypointer) { relativePosition = computePosition(trajectory);} else { /* 生成替代轨迹,调整范围从最小到最大 */ List<Trajectory> alternatives = adjustTrajectoryList(trajectory, MINIMAL, EXTREME); /* 从中选择一个并执行 */ Trajectory preferred = leastLikelyCollisionTrajectory(alternatives); relativePosition = computePosition(preferred);}
您可以使用现有的逻辑来选择首选轨迹。这可能不是世界上最复杂的东西,但它是一个起点:
Trajectory leastLikelyCollistionTrajectory(List<Trajectory> options) { /* 从最小调整到最大调整进行迭代 */ foreach(Trajectory t in options) { if(!isCollisionLikely(t)) { return t; /* 返回第一个看起来没问题的轨迹 */ } } /* 否则使用最极端的调整并希望它有效 */ return options.last();}
我混合了伪代码和一些Java代码,试图使其更清晰。这看起来能解决您的问题吗?