前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >游戏AI-个体AI角色的操控行为(1)

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

作者头像
祝你万事顺利
发布2019-05-28 23:14:28
5250
发布2019-05-28 23:14:28
举报
文章被收录于专栏:Unity游戏开发Unity游戏开发
1.靠近

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

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

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将进行逃跑

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将与其速度设置为目标距离减去当前速度,

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朝着目标未来的位置进行移动,通过一个简单地预测器,来让目标向目标未来位置进行移动.

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.04.16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.靠近
  • 2.离开
  • 3.抵达
  • 4.追逐
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档