【Unity】入门学习笔记180519——人工智能(3)——个体操控(2)

个体AI角色的操控行为de实现


2.4 Pursuit 追逐

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


/*追逐
 * 类似于靠近行为,但目标是移动的,要实现的是可以预测目标未来的位置
 * 使用简单的预测器,计算目标在未来时间T的目标位置,关键是确定预测间隔T
 */


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(transform.forward, target.transform.forward);
        //如果夹角大于0,且追逐者基本面对着逃避者,那么直接向逃避者当前位置移动
        if ((Vector3.Dot(toTarget, transform.forward) > 0) && (relativeDirection < -0.95f))
        {
            desiredVelocity = (target.transform.position - transform.position).normalized * maxSpeed;
            //返回操控向量
            return (desiredVelocity - m_vehicle.velocity);
        }


        //计算预测时间,正比于追逐者与逃避者的距离,反比于追逐者和逃避者的速度和
        float lookaheadTime = toTarget.magnitude / (maxSpeed + target.GetComponent<Vehicle>().velocity.magnitude);
        //计算预期速度
        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 () {
		
	}
}


2.5 Evade 逃避

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/*逃避
 * 逃离预测位置
 * 
 */

public class SteeringForEvade : 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 lookaheadTime = toTarget.magnitude / (maxSpeed + target.GetComponent<Vehicle>().velocity.magnitude);
        //计算预期速度
        desiredVelocity = (transform.position - (target.transform.position + target.GetComponent<Vehicle>().velocity * lookaheadTime))
            .normalized * maxSpeed;
        //返回操控向量
        return (desiredVelocity - m_vehicle.velocity);
    }

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


2.6 Wander 随机徘徊

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

 /*随机徘徊
 * 类似于气缸曲轴传动
 * 利用不同的连杆长度(Wander距离)、角色到圆心的距离(Wander半径)、每帧随机偏移大小,产生不同的随机运动
 * 这个函数的效果与帧率相关
 */

public class SteeringForWander : Steering {

    //徘徊半径,即Wander圈的半径
    public float wanderRadius;
    //徘徊距离,即Wander圈凸出在AI角色前面的距离
    public float wanderDistance;
    //每秒加到目标的随机位移的最大值
    public float wanderJitter;
    public bool isPlanar;
    private Vector3 desiredVelocuty;
    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;
        isPlanar = m_vehicle.isPlanar;
        //选取圆圈上的一个点作为初始点
        circleTarget = new Vector3(wanderRadius * 0.707f, 0, wanderRadius * 0.707f);
	}

    public override Vector3 Force()
    {
        //计算平均位移
        Vector3 randomDisplacement = new Vector3((Random.value - 0.5f) * 2 * wanderJitter, (Random.value - 0.5f) * 2 * wanderJitter, (Random.value - 0.5f)
            * wanderJitter);
        if (isPlanar)
            randomDisplacement.y = 0;
        //将随机位移移加到初始点上,得到新的位置
        circleTarget += randomDisplacement;
        //由于新位置很可能不在圆周上,因此需要投影到圆周上
        circleTarget = wanderRadius * circleTarget.normalized;
        //之前计算出的值是相对AI角色和AI角色的前进方向的需要转换为世界坐标
        wanderTarget = m_vehicle.velocity.normalized * wanderDistance + circleTarget + transform.position;
        //计算预期速度,返回操纵向量
        desiredVelocuty = (wanderTarget - transform.position).normalized * maxSpeed;
        return (desiredVelocuty - m_vehicle.velocity);
    }

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


猜你喜欢

转载自blog.csdn.net/dylan_day/article/details/80374491