Search code examples
unity-game-engineartificial-intelligenceunityscriptraycastingracing

Unity - Car AI Avoiding obstacle


sorry for asking too often. I have a problem on Andrew Gotow's Car AI. The Problem is The AI did not avoid player / car in front of them or they just go ahead and hit the player / car in front of them. When hit a car or any obstacle, They stop accelerating or stop working.

Please help me. I can't figure it out how to make the AI shouldn't hit the obstacle

this is the code i use. Thanks for any help

function GotNewWaypoint(newWay : Vector3, newRot : Quaternion){
    wpObj.transform.position = newWay;
    wpObj.transform.rotation = newRot;// wpObj is a triggered box collider that sets GotNewWaypoint function everytime AI hits the collider
}

function NavigateTowardsWaypoint(){ // Runs in Update function
var relativePosition : Vector3;
var hit : RaycastHit;

if(!alternativeWaypointer){
    relativePosition = transform.InverseTransformPoint(Vector3(wpObj.transform.position.x,transform.position.y,wpObj.transform.position.z));
}else{// turn on alternative position if Spherecast hits object
    relativePosition = transform.InverseTransformPoint(Vector3(raycaster*wpObj.transform.position.x,transform.position.y,wpObj.transform.position.z)); // move wpObj on axis x a bit so the AI shouldn't hit the obstacle
}

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;//used for ai's handling control. usually it's 1 or -1

if(Mathf.Abs(inputSteer) < .5){
    inputTorque = relativePosition.z / relativePosition.magnitude; //corner is not too tight, accelerate
}else{
    inputTorque = 0.0; // corner is too tight, stop accelerating
}

}


Solution

  • From what I can gather, your AI has a test to see if it will collide with something. The result of this test appears to be assigned to the variable alternativeWaypointer allowing for the following if statement:

    if(!alternativeWaypointer){
        relativePosition = computePosition(trajectory);
    }else{
        relativePosition = computePosition(adjustTrajectory(trajectory));
    }
    

    It's possible that your adjust trajectory logic isn't working. Perhaps this can be tested? In lieu of this, a likely problem is that your adjusted trajectory isn't sufficiently adjusted to avoid the collision. We can solve this by creating a series of hypothetical trajectories and then picking the best candidate.

    alternativeWaypointer = isCollisionLikely(trajectory);
    
    if(!alternativeWaypointer) {
        relativePosition = computePosition(trajectory);
    } else {
        /* generate alternative trajectories, adjustments range from minimal to extreme */
        List<Trajectory> alternatives = adjustTrajectoryList(trajectory, MINIMAL, EXTREME);
    
        /* Of these, pick one and run with it */
        Trajectory preferred = leastLikelyCollisionTrajectory(alternatives);
        relativePosition = computePosition(preferred);
    }
    

    You could use your existing logic to pick a preferred trajectory. It won't be the most sophisticated thing in the world, but it would be a starting point:

    Trajectory leastLikelyCollistionTrajectory(List<Trajectory> options) {
    
        /* iterate from minimal adjustment to extreme */
        foreach(Trajectory t in options) {
            if(!isCollisionLikely(t)) {
                return t; /* return the first trajectory that seems ok */
            }
        }
    
        /* otherwise resort to the most extreme and hope */
        return options.last();
    }
    

    I've mixed pseudo code with a bit of java in an attempt to make it clearer. Does this look like it would solve your problem?