天天看點

遊戲AI-個體AI角色的操控行為(2)

5.随機徘徊

我們希望場景中有随機移動的機關,如巡邏的士兵 吃草的牛羊,往往我們在場景中設定幾個點讓機關在幾個點中随機移動,這樣會出現一種情況,機關突然掉頭,Craig Reynolds突出的随機徘徊解決了這個問題

public class SteeringForWander : Steering {
    public float wanderRadius;//Wander半徑
    public float wanderDistance;//Wander距離
    public float wanderJitter;//每秒加到随機位移的最大值
    
    
    private Vector3 desiredVelocity;
    private Vehicle m_vehicle;
    private float maxSpeed;
    private Vector3 circleTarget;
    private Vector3 wanderTarget;
    // Use this for initialization
    void Start () {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
        //選圓上一個點作為初始點
        circleTarget = new Vector3(wanderRadius * 0.5f, 0, wanderRadius * 0.3f);

    }

    public override Vector3 Force()
    {
        //随機位移
        Vector3 randomDisplacement = new Vector3((Random.value - 0.5f) * 2 * wanderJitter, 0, (Random.value - 0.5f) * 2 * wanderJitter);
        //從初始點加上一個随機位移
        circleTarget += randomDisplacement;
        //将得到的新點進行投射到圓弧上
        circleTarget = wanderRadius * circleTarget.normalized;
        wanderTarget = m_vehicle.velocity.normalized * wanderDistance + circleTarget + transform.position;
        desiredVelocity = (wanderTarget - transform.position).normalized * maxSpeed;
        return desiredVelocity - m_vehicle.velocity;
    }
}           

複制

遊戲AI-個體AI角色的操控行為(2)

Wander.gif

6.避開障礙

通過在AI前方發射一條一定長度的射線來檢測AI前方是否有需要躲避的物體,在有障礙時,我們給AI一個向量為向前方的向量加上障礙中心到AHead的向量,來讓AI物體避開障礙.

public class SteeringForCollisionAvoidance : Steering {
    public Vehicle m_vehicle;
    private float maxSpeed;

    Vector3 desiredVelocity;
    float maxForce;
    //避免障礙的力
    public float avoidanceForce;
    public float MAX_SEE_AHEAD = 2.0f;

    GameObject[] allColliders;
    
    
    // Use this for initialization
    void Start () {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
        maxForce = m_vehicle.maxForce;
        if(avoidanceForce > maxForce)
        {
            avoidanceForce = maxForce;
        }
        allColliders = GameObject.FindGameObjectsWithTag("obstacle");
    }

    public override Vector3 Force()
    {
        RaycastHit hit;
        Vector3 force = new Vector3(0, 0, 0);
        Vector3 velocity = m_vehicle.velocity;
        Vector3 normalizedVelocity = velocity.normalized;
        //從AI向前發射一條射線,如果在需要避開障礙的範圍内,進行目前前方加一個原點到前方的向量和來作為新的力
        if (Physics.Raycast(transform.position,normalizedVelocity,out hit, MAX_SEE_AHEAD * velocity.magnitude / maxSpeed))
        {
            Vector3 ahead = transform.position + normalizedVelocity * MAX_SEE_AHEAD * (velocity.magnitude / maxSpeed);
            force = ahead - hit.collider.transform.position;
            force *= avoidanceForce;
        }
        return force;
    }
}           

複制

遊戲AI-個體AI角色的操控行為(2)

CollisionAvoidance.gif