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

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


2.1    Seek 靠近this

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

/*靠近
 *指定一个目标位置,根据当前的运动速度向量,返回一个操控AI角色到达该目标位置的“操控力”
 * 使AI角色自动向该位置移动
 */

public class SteeringForSeek : Steering {

    //目标物体
    public GameObject target;
    //预期速度
    private Vector3 desiredVelocity;
    //得到被操控AI角色,以便查询这个AI角色的最大速度等信息
    private Vehicle m_vehicle;
    //最大速度
    private float maxSpeed;
    //是否仅在二维平面上运动
    private bool isPlanar;

	// Use this for initialization
	void Start () {
        //获取AI角色,并读取属性
        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);
    }
	// Update is called once per frame
	void Update () {
		
	}
}

2.2    Flee 离开spa

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

/*离开
 *指定一个目标位置,根据当前的运动速度向量,返回一个操控AI角色离开该目标位置的“操控力”
 * 与靠近行为相反,惟一区别是DesiredVelocity具备相反的方向,使AI角色自动向位置相反方向移动
 */

public class SteeringForFlee : Steering {

    public GameObject target;
    //设置使AI角色意识到危险并开始逃跑的范围
    public float fearDistance = 20;
    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 tmpPos = new Vector3(transform.position.x, 0, transform.position.z);
        Vector3 tmpTargetPos = new Vector3(target.transform.position.x, 0, target.transform.position.z);
        //若是AI角色与目标距离大于逃跑距离,那么返回0向量
        if (Vector3.Distance(tmpPos, tmpTargetPos) > fearDistance)
            return new Vector3(0, 0, 0);
        //若是AI角色与目标距离小于逃跑距离,那么计算逃跑所需的操控向量
        desiredVelocity = (transform.position - target.transform.position).normalized * maxSpeed;
        return (desiredVelocity - m_vehicle.velocity);
    }

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

2.3    Arrival 抵达插件

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

/*抵达
 *AI角色可以减速并停到目标位置,避免冲过目标,前段和靠近的行为状态是同样的,经过设置中止半径,开始逐渐减少预期速度,直到减少至0
 * 使利用Itween插件实现的也不错
 */

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()
    {
        //计算AI角色与目标之间的距离
        Vector3 toTarget = target.transform.position - transform.position;
        //预期速度
        Vector3 desiredVelocity;
        //返回的操控向量
        Vector3 returnForce;

        if (isPlanar)
            toTarget.y = 0;
        float distance = toTarget.magnitude;
        //若是与目标之间的距离大于所设置的减速半径
        if (distance > slowDownDistance)
        {
            //预期速度时AI角色与目标点之间的距离
            desiredVelocity = toTarget.normalized * maxSpeed;
            //返回与预期速度与当前速度的差
            returnForce = desiredVelocity - m_vehicle.velocity;
        }
        else
        {
            //计算预期速度,并返回预期速度与当前速度的差
            desiredVelocity = toTarget - m_vehicle.velocity;
            //返回预期速度与当前速度的差
            returnForce = desiredVelocity - m_vehicle.velocity;
        }
        return returnForce;
    }

    private void OnDrawGizmos()
    {
        //在目标周围画白色线框球,显示出减速范围
        Gizmos.DrawWireSphere(target.transform.position, slowDownDistance);
    }
    // Update is called once per frame
    void Update () {
		
	}
}