Unity人工智能学习—确定性AI算法之追踪算法二
转自:http://blog.csdn.net/zhangxiao13627093203/article/details/47658673
上一篇讲到了追踪算法的比较简单的形式,看上去比较假,因为AI控制的对象过于精确地跟踪目标。一种更自然的追踪方式可以这样做,使得跟踪者的方向矢量与从跟踪目标的中心到跟踪者的中心所定义的方向矢量靠拢。如图所示:
这个算法的基本思路是这样的:假设AI控制的对象即追踪者有如下属性
1、Position:(tracker.x,tracker.y)
2、Velocity:(tracker.vx,tracker.vy)
追踪目标有如下属性:
1、Postion:(target.x,target.y)
2、Velocity:(target.vx,target.vy)
接下来就是调整追踪者的速度向量的常用逻辑:
1、计算从跟踪者到跟踪目标的向量:TV=(target.x-tracker.x,target.y-tracker.y)=(tvx,tvy),归一化TV,这样就可以得到一个单位向量,从而方便计算它与坐标轴的角度。归一化也即是sqrt(x^2+y^2).
2、调整追踪者当前的速度向量,加上一个按rate比例缩放过的TV*
tracker.x+=rate*tvx;
traker.y+=rate*tvy;
注意这一步才是关键,它使得导弹的追踪不在是从前的直接紧密追踪而是会有一个变轨迹的过程,另外当rate等于1的时候,跟踪向量会合的更快,跟踪算法对目标跟踪的根据紧密,并更快地的修正目标的运动。
3、跟踪者的速度向量修改过后,有可能向量的速度会溢出最大值。换言之,跟踪者一旦锁定了目标的方向就会继续沿着该方向加速。所以需要设置一个上限,让追踪者的速度从某处慢下来
在Unity5.1.1实现的效果图如图所示:在这里我还调整了导弹的追踪方向rotation的变化,其实如果是3D空间就可以直接使用lookAt方法来使得导弹的运动方向始终朝向目标,但是在2D平面上就没有这么好的方法供我们调用了,所以我自己写了一个算法。如果不加这个方向修正算法的结果如图所示:
导弹的运行是不是显得非常的生硬,运动的轨迹和导弹头的朝向并不一致,这一段的修正导弹头的方向的代码如下:
void LookAtTarget()
{
float zAngles;
if(moveVy==0)
{
zAngles = moveVx >= 0 ? -90 : 90;
}
zAngles = Mathf.Atan(moveVx / moveVy) * (-180 / Mathf.PI);
if(moveVy<0)
{
zAngles = zAngles - 180;
}
Vector3 tempAngles = new Vector3(0, 0, zAngles);
Quaternion tempQua = this.transform.rotation;
tempQua.eulerAngles = tempAngles;
this.transform.rotation = tempQua;
}
算法的计算思路是:
注意:这个平面上的角度主要是Z轴的角度变化,而Z轴的角度是导弹头方向直线与y轴的夹角,这点比较蛋疼。另外坐标的顶点是位于屏幕的左上角。
1、根据导弹的运动速度矢量来调整导弹头的方向
2、导弹的速度矢量为x和y方向的矢量和,根据反三角函数来计算出导弹与屏幕坐标y轴的夹角
3、要特别注意当moveVy为0的情况,不考虑这个会导致计算反三角的时候分母为零而因溢出而报错,以及moveVy小于0的情况,不考虑这个会使得方向刚好会想法。
最终的代码为:
sing UnityEngine;
using System.Collections;
using UnityEngine.UI; public class AITrackAdvanced : MonoBehaviour {
public Image target;
public float target_moveSpeed;
public float MIN_trackingRate;//最小的追踪向量改变率
public float MIN_TrackingDis;
public float MAX_trackingVel;
public float moveVx;//x方向的速度
public float moveVy;//y方向的速度
// Use this for initialization
void Start () { } // Update is called once per frame
void Update () {
Debug.Log((Mathf.Atan(moveVx / moveVy) * (-180 / Mathf.PI))); // LookAtTarget();
// this.transform.position += new Vector3(moveVx * Time.deltaTime, moveVy * Time.deltaTime, 0);
MoveTarget();
Track_AIAdvanced();
CheckMoveBoundary();
}
void LookAtTarget()
{
float zAngles;
if(moveVy==0)
{
zAngles = moveVx >= 0 ? -90 : 90;
}
zAngles = Mathf.Atan(moveVx / moveVy) * (-180 / Mathf.PI);
if(moveVy<0)
{
zAngles = zAngles - 180;
}
Vector3 tempAngles = new Vector3(0, 0, zAngles);
Quaternion tempQua = this.transform.rotation;
tempQua.eulerAngles = tempAngles;
this.transform.rotation = tempQua;
}
/// <summary>
/// 通过键盘来控制移动目标
/// </summary>
void MoveTarget()
{
float x = Input.GetAxis("Horizontal") * 100;
float y = Input.GetAxis("Vertical") * 100;
//如果超出屏幕范围则让它出现在另一面
target.transform.Translate(x * Time.deltaTime * target_moveSpeed, y * Time.deltaTime * target_moveSpeed, 0);
if (target.transform.position.x >= Screen.width)
{
//使用了Image的target.rectTransform.lossyScale.x来表示显示的图片宽度
target.transform.position = new Vector3(-target.rectTransform.lossyScale.x, target.transform.position.y, 0);
}
else if (target.transform.position.x < -target.rectTransform.lossyScale.x)
{
target.transform.position = new Vector3(Screen.width, target.transform.position.y, 0);
}
if (target.transform.position.y >= Screen.height)
{
target.transform.position = new Vector3(target.transform.position.x, -target.rectTransform.lossyScale.y, 0);
}
else if (target.transform.position.y < -target.rectTransform.lossyScale.y)
{
target.transform.position = new Vector3(target.transform.position.x, Screen.height, 0);
}
}
/// <summary>
/// 追踪算法
/// </summary>
void Track_AIAdvanced()
{
//计算与追踪目标的方向向量
float vx = target.transform.position.x - this.transform.position.x;
float vy = target.transform.position.y - this.transform.position.y; float length = PointDistance_2D(vx, vy);
//如果达到距离就追踪
if(length<MIN_TrackingDis)
{
vx = MIN_trackingRate * vx / length;
vy = MIN_trackingRate * vy / length;
moveVx += vx;
moveVy += vy; //增加一点扰动
if(Random.Range(1,10)==1)
{
vx = Random.Range(-1, 1);
vy = Random.Range(-1, 1);
moveVx += vx;
moveVy += vy;
}
length = PointDistance_2D(moveVx,moveVy); //如果导弹飞的速度太快就让它慢下来
if(length>MAX_trackingVel)
{
//让它慢下来
moveVx *= 0.75f;
moveVy *= 0.75f;
} }
//如果不在追踪范围内,随机运动
else
{
if(Random.Range(1,10)==1)
{
vx= Random.Range(-2, 2);
vy = Random.Range(-2, 2);
moveVx += vx;
moveVy += vy;
}
length = PointDistance_2D(moveVx, moveVy); //如果导弹飞的速度太快就让它慢下来
if (length > MAX_trackingVel)
{
//让它慢下来
moveVx *= 0.75f;
moveVy *= 0.75f;
}
} this.transform.position += new Vector3(moveVx * Time.deltaTime, moveVy * Time.deltaTime, 0);
}
/// <summary>
/// 计算从零点到这个点的距离
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
float PointDistance_2D(float x,float y)
{
//使用了泰勒展开式来计算,有3.5%的误差,直接使用开方计算会比较慢,但是测试了我的电脑好像没有什么变化可能是数据量不大体现不出来
/*x = Mathf.Abs(x);
y = Mathf.Abs(y);
float mn = Mathf.Min(x, y);//获取x,y中最小的数
float result = x + y - (mn / 2) - (mn / 4) + (mn / 8);*/ float result = Mathf.Sqrt(x * x + y * y);
return result;
} void CheckMoveBoundary()
{
//检测是否超出了边界
if (this.transform.position.x >= Screen.width)
{
this.transform.position = new Vector3(-this.GetComponent<Image>().rectTransform.lossyScale.x, 0, 0);
}
else if (this.transform.position.x < -this.GetComponent<Image>().rectTransform.lossyScale.x)
{
this.transform.position = new Vector3(Screen.width, this.transform.position.y, 0);
}
if (this.transform.position.y >= Screen.height)
{
this.transform.position = new Vector3(this.transform.position.x, -this.GetComponent<Image>().rectTransform.lossyScale.y, 0);
}
else if (this.transform.position.y < -this.GetComponent<Image>().rectTransform.lossyScale.y)
{
this.transform.position = new Vector3(this.transform.position.x, Screen.height, 0);
}
}
}
最后附上工程的下载地址,里面是我用Unity5.1.1写的如图的演示程序,还包括之前两篇文章中的演示程序。点击打开链接
Unity人工智能学习—确定性AI算法之追踪算法二的更多相关文章
- Unity人工智能学习—确定性AI算法之追踪算法一
转自http://blog.csdn.net/zhangxiao13627093203/article/details/47451063 尽管随机运动可能完全不可预知,它还是相当无趣的,因为它完全是以 ...
- AI简单平移追踪算法
1.比较坐标追踪法 追踪者会不停地比较自身和目标的x坐标和y坐标,每x和y上一个单位的移动为一个周期,该算法虽然简单好用,但实用性差且不智能化,如果追踪者数量增加,路线会显得单调,由于都是先走个对角线 ...
- 浅谈压缩感知(九):正交匹配追踪算法OMP
主要内容: OMP算法介绍 OMP的MATLAB实现 OMP中的数学知识 一.OMP算法介绍 来源:http://blog.csdn.net/scucj/article/details/7467955 ...
- AI 经典书单 | 人工智能学习该读哪些书
转载 2018年01月16日 00:00:00 人工智能相关岗位中,涉及到的内容包含: 算法.深度学习.机器学习.自然语言处理.数据结构.Tensorflow.Python .数据挖掘.搜索开发. ...
- 【AI】微软人工智能学习笔记(二)
微软Azure机器学习服务 01|机器学习概述 首先上一张图, 这个图里面的大神是谁我也不清楚反正,但是看起来这句话说得很有哲理就贴出来了. 所以在人工智能领域下面的这个机器学习,到底是一个什么样的概 ...
- AI人工智能学习数据集
AI人工智能学习数据集,列表如下. 商务合作,科技咨询,版权转让:向日葵,135—4855__4328,xiexiaokui#qq.com boston_house_prices.csvbreast_ ...
- AI入门之KNN算法学习
一.什么是KNN算法 kNN(k-NearestNeighbor),也就是k最近邻算法.顾名思义,所谓K最近邻,就是k个最近的邻居的意思.也就是在数据集中,认为每个样本可以用离他最距离近的k个邻居来代 ...
- 2017人工智能元年,AI在喧嚣和质疑中一路走来
前百度首席科学家吴恩达说:就像100年前的电力.20年前的互联网一样,AI也会改变每一个产业! 有人说,现在就像1995年,那一年,第一家互联网公司--网景上市,一天之内大涨208%,互联网正式登上历 ...
- 对弈类游戏的人工智能(4)--游戏AI的落地
前言: 对弈类游戏的智能算法, 网上资料颇多, 大同小异. 然而书上得来终觉浅, 绝知此事要躬行. 结合了自己的工程实践, 简单汇总整理下. 一方面是对当年的经典<<PC游戏编程(人机博弈 ...
随机推荐
- Paint与Canvas的简单用法
参考:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=278237 自定义View 重写onDraw方法 package com. ...
- DevExpress 学习使用之 LookUpEdit
我的机器上,Winform 控件中的 LookUp 有1+3 种,在我们国家也被称为 4 种,你们那儿呢? 这 1+3 种 LookUpEdit 分别是 LookUpEdit.GridLookUpEd ...
- AngularJS框架速写
最近在把玩AngularJS框架,之前也看过流行的Backbone,不过AngularJS给人的感觉完全不同,它走的是一条高帅富之路. 按照官方的说法,AngularJS是一套依赖注入的MVC开发套件 ...
- BEncoding的编码与解码
BEncoding的编码与解码 1. BEncoding规则 BEncoding是BitTorrent用在传输数据结构的编码方式,我们最熟悉的“种子”文件,它里面的元数据就是 BEncoding ...
- 完整显示当前日期和时间的JS代码(2007年2月25日星期日正午12:42:48)
代码演示效果为“2007年2月25日星期日正午12:42:48”. 使用方法:将下面的JS代码放到你想要显示的页面中(支持HTML页面),然后在你想要显示时间的位置插入下面的代码即可 <div ...
- Android开发(25)--framebyframe帧动画并实现启动界面到主界面的跳转
Drawable animation可以加载Drawable资源实现帧动画.AnimationDrawable是实现Drawable animations的基本类.推荐用XML文件的方法实现Drawa ...
- Hadoop完全分布式搭建过程中遇到的问题小结
前一段时间,终于抽出了点时间,在自己本地机器上尝试搭建完全分布式Hadoop集群环境,也是借助网络上虾皮的Hadoop开发指南系列书籍一步步搭建起来的,在这里仅代表hadoop初学者向虾皮表示衷心的感 ...
- [Thinkbayes]贝叶斯思维读书笔记-2-火车头问题
今天,我们继续我们的笔记. 作者在第三章继续举了一个例子.火车头问题(读者在此可能会觉得这个问题没有意义,但相信随着深入阅读,这个问题会被解答). 这个举例恰到好处,能够让我深入理解到底应该如何假设, ...
- ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第五章:排序、分页和路由
本章的重点是对产品信息增加排序和分页的功能,以及使用ASP.NET Routing特性添加更加友好的URL支持. 注意:如果你想按照本章的代码编写示例,你必须完成第四章或者直接从www.apress. ...
- 一口一口吃掉Hexo(一)
如果你想得到更好的阅读效果,请访问我的个人网站 ,版权所有,未经许可不得转载! 这里是我的个人博客网站,点击这里你可以到我的首页瞧瞧.我之前使用的是第三方的博客平台--博客园,点击这里可以看到我的博客 ...