游戏AI-个体AI角色的操控行为(1)

2019-05-28 23:14:28 浏览数 (1)

1.靠近

创建一个类SteeringForSeek继承Steering,将目标物体拖入Target,我们的AI就会自动向Target靠近。

重写其中的Force方法 在Vehicle中会遍历所有的Steering的子类,我们实现的靠近类重写的Force就会被加入Vehicle的力中来实现物体的移动

代码语言:javascript复制
public class SteeringForSeek : Steering {

    public GameObject target;

    Vector3 desiredVelocity;
    //获得被操控的AI角色以便查询最大速度的等信息
    Vehicle m_vehicle;

    float maxSpeed;

    bool isPlanar;

    // Use this for initialization
    void Start () {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
        isPlanar = m_vehicle.isPlanar;
    }

    public override Vector3 Force()
    {
        //预期速度
        desiredVelocity = (target.transform.position - transform.position).normalized
            * maxSpeed;
        //只在平面上运动
        if (isPlanar)
        {
            desiredVelocity.y = 0;
        }
        return (desiredVelocity - m_vehicle.velocity);
    }
}
2.离开

相比于上面的Seek,Flee的desriedVelocity是反方向的。 将追逐此AI的物体拖入Target,在target进入AI的危险感知范围时,AI将进行逃跑

代码语言:javascript复制
public class SteeringForFlee : Steering {
    public GameObject target;
    //AI意识到危险的范围
    public float fearDistance = 20;
    Vector3 desiredVelocity;
    Vehicle m_vehicle;
    float maxSpeed;


    
    void Start () {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
    }
    
    public override Vector3 Force()
    {
        Vector3 tempPos = new Vector3(transform.position.x,
            0, transform.position.z);
        Vector3 tempTargetPos = new Vector3(target.transform.position.x,
            0, target.transform.position.z);
        if (Vector3.Distance(tempPos, tempTargetPos) > fearDistance)
        {
            return new Vector3(0, 0, 0);
        }
        desiredVelocity = (transform.position - target.transform.position)
            .normalized * maxSpeed;
        return desiredVelocity - m_vehicle.velocity;
    }
}

Capsule追随 Sphere逃离

3.抵达

我们希望AI在到达目标的时候减小速度,避免冲过目标,AI进入停止半径后,将逐渐减小预期速度,直到降为0. 如果距离大于减速半径,将预期速度设为最大速度,如果AI进入减速半径,AI将与其速度设置为目标距离减去当前速度,

代码语言:javascript复制
public class SteeringForArrive : Steering {

    public bool isPlanar = true;
    public float arrivalDistance = 0.3f;
    public float characterRadius = 1.2f;
    //与目标小于此距离时开始减速
    public float slowDownDistance;
    public GameObject target;
    private Vector3 desiredVelocity;
    private Vehicle m_vehicle;
    private float maxSpeed;



    // Use this for initialization
    void Start () {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
        isPlanar = m_vehicle.isPlanar;
    }

    public override Vector3 Force()
    {
        Vector3 toTarget = target.transform.position - transform.position;
        Vector3 desiredVelocity;
        Vector3 returnForce;
        if (isPlanar)
        {
            toTarget.y = 0;
        }
        float distance = toTarget.magnitude;
        
        if(distance > slowDownDistance)
        {
            desiredVelocity = toTarget.normalized * maxSpeed;
            returnForce = desiredVelocity - m_vehicle.velocity;
        }
        else
        {
            desiredVelocity = toTarget - m_vehicle.velocity;
            //返回预期速度和当前速度的差值
            returnForce = desiredVelocity - m_vehicle.velocity;
        }
        return returnForce;
    }
}

Arrive.gif

4.追逐

追逐与Arrive很相似,不过目标不再是静止的,而是在移动的,最简单的方法是,让AI直接向目标位置靠近,但我们要让AI预测目标未来的位置,让AI朝着目标未来的位置进行移动,通过一个简单地预测器,来让目标向目标未来位置进行移动.

代码语言:javascript复制
public class SteeringForPursuit : Steering {
    public GameObject target;
    private Vector3 desiredVelocity;
    private Vehicle m_vehicle;
    private float maxSpeed;
    // Use this for initialization
    void Start () {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
    }

    public override Vector3 Force()
    {
        Vector3 toTarget = target.transform.position - transform.position;
        float relativeDirection = Vector3.Dot(target.transform.forward, transform.forward);
        if (Vector3.Dot(toTarget,transform.forward)>0 && 
            (relativeDirection > 0.95f))
        {
            desiredVelocity = (target.transform.position - transform.position)
                .normalized * maxSpeed;
            return desiredVelocity - m_vehicle.velocity;
        }
        //预测时间的长短:正比于到目标位置的距离,反比与目标和AI的速度和
        float lookaheadTime = toTarget.magnitude / (target.GetComponent<Vehicle>().velocity.magnitude
              maxSpeed);
        //预期速度
        desiredVelocity = (target.transform.position  
            target.GetComponent<Vehicle>().velocity * lookaheadTime -
            transform.position).normalized * maxSpeed;
        return desiredVelocity - m_vehicle.velocity;
    }

    // Update is called once per frame
    void Update () {
        
    }
}

普通的接近:

SimpleArrive.gif

预测未来位置后:

Pursuit.gif

延长预测时间:

Pursuit2.gif

0 人点赞