Unity3D基础教程:简单AI编写

1. Unity简单AI编写

由于这次介绍的AI很简单,代码直接贴上,AI分成四个状态:思考,转身,移动,攻击,这里只是初步实现,所以想实现简单点的操作,就像自动范围内随机移动,锁敌攻击,超出距离复位,近距离察觉等。

Enemy_AI.js
private var Regression : Vector3;
public var Player_Prefab : Transform;
public var Enemy_State : String;
public var Doing : boolean = true;
public var Range : float = 4.0;
public var Bullet : Transform;
public var Bullet_Prefab : Transform;
//初始化敌人方向和位置
function Start()
{
transform.localEulerAngles.y = Random.value * 360;
Regression = transform.position;
}
//敌人行动模式
public var Thinking : boolean = true;
public var Thinking_Time : float = 1.0;
private var relativePos : Vector3;
private var rotation : Quaternion;
public var Facing : boolean = false;
public var Facing_Time : float = 2.0;
public var Facing_Speed : float = 2.0;
public var Moving : boolean = false;
public var Moving_Speed : float = 0.5;
public var Moving_Time : float = 4.0;
public var Moving_Back : boolean = false;
public var Attacking : boolean = false;
private var Bullet_DO : boolean = true;
public var Bullet_CD : float = 0.2;
//随机移动方位
private var R_Position : Vector3;
function Update ()
{
if(Attacking)
{
Enemy_State = "Attacking";
Facing = true;
Moving = true;
//Doing = true;
Thinking = false;
var dist2 = Vector3.Distance(Regression, transform.position);
if(dist2 > 20)
{
relativePos = Regression - transform.position;
rotation = Quaternion.LookRotation(relativePos);
Attacking = false;
Moving_Back = true;
}
}
if(!Moving_Back)
{
var dist = Vector3.Distance(Player_Prefab.position, transform.position);
if(dist > 100)
{
Attacking = false;
return;
}
else if(dist < 5)
{
Attacking = true;
}
RayJudge();
}
transform.localEulerAngles.x = 0;
transform.localEulerAngles.z = 0;
if(Thinking && !Attacking && !Moving_Back)
{
Enemy_State = "Thinking";
if(Doing)
{
StartCoroutine(Think(Thinking_Time));
Doing = false;
}
}
if(Facing)
{
Enemy_State = "Facing";
if(Attacking)
{
relativePos = Player_Prefab.position - transform.position;
rotation = Quaternion.LookRotation(relativePos);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed * 4);
}
else if(Moving_Back)
{
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed * 4);
}
else
{
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed);
if(Doing)
{
StartCoroutine(Face(Facing_Time));
Doing = false;
}
}
}
if(Moving)
{
Enemy_State = "Moving";
if(Moving_Back)
{
transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed * 6);
}
else if(dist > 2)
{
if(Attacking)
{
transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed * 4);
}
else
{
transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed);
}
}
if(Doing && !Attacking)
{
StartCoroutine(Move(Moving_Time));
Doing = false;
}
}
}
//前方锁敌
function RayJudge()
{
var layerMask = 1 << 2;
layerMask = ~layerMask;
var hit : RaycastHit;
if(Physics.Raycast (transform.position, transform.TransformDirection(Vector3.forward), hit, 20,layerMask))
{
var distanceToForward = hit.distance;
if(hit.transform.tag == "Player")
{
Attacking = true;
if(Bullet_DO)
{
var Create = Instantiate (Bullet_Prefab, Bullet.position, Quaternion.identity);
Create.rigidbody.AddForce (Bullet.forward * 1000);
StartCoroutine(Wait(Bullet_CD));
Bullet_DO = false;
}
}
}
}
function Wait(waitTime : float)
{
yield WaitForSeconds (waitTime);
Bullet_DO = true;
}
function Move(waitTime : float)
{
print("Move");
if(Moving_Back)
{
yield WaitForSeconds (waitTime * 0.4);
}
else
{
yield WaitForSeconds (waitTime + Random.value * 2);
}
Thinking = true;
Moving_Back = false;
Moving = false;
Facing = false;
Doing = true;
}
function Face(waitTime : float)
{
print("Face");
yield WaitForSeconds (waitTime + Random.value);
Facing = false;
Thinking = false;
Moving = true;
Doing = true;
}
function Think(waitTime : float)
{
print("Thinking");
yield WaitForSeconds (waitTime + Random.value);
R_Position = Regression + Random.insideUnitSphere * Range;
R_Position.y = Regression.y;
relativePos = R_Position - transform.position;
rotation = Quaternion.LookRotation(relativePos);
Thinking = false;
Moving = false;
Facing = true;
Doing = true;
}

工程截图(这里是9个拿枪的敌人- - 蓝色为控制角色,WASD控制行动) 

 

2.Unity学习过程中的一些细节分析

1.获取位置坐标:当你translate.position获取的不是物体在世界的坐标时可以试试translate. localRotation

2.改变旋转角度:这里多半是用translate.localRotation= Quaternion.Euler(x,y,z);

3.如何更改鼠标指针图片,这也是羽化以后可能遇到的问题,这里只能简单分析下,首先把鼠标默认指针隐藏掉Screen.showCursor=flase;再用个粒子或者图片代替,具体位置可以用Camera.main.ScreenToWorldPoint()和Input.mousePosition获得。但有个问题就产生了,UI会遮挡鼠标,鼠标图片用UI代替总感觉不妥。。。所以羽化还没想出解决方法- -

4.有关过场Loading的制作,一张图片还好说,换个Scene或者写个UI都能解决,动态Loading的是用Application.LoadLevelAsync可以达到效果,或者是预加载,具体可以看看羽化无缝地图研究博文里面的一个别墅例子。

5.也许有一天你也会遇到脚本用C#编写时遇到一些莫名其妙的错误,所以这里羽化建议动态脚本命令最好用js写。。。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
欢迎体验AI1.0 1 ------------ 运行本软件需要JRE(java运行时)1.5.0_08以上版本。 运行方法:在program目录下,右键点击AI10.jar,选打开方式为“java platform standard edition binary”即可。 2 ------------ 界面介绍: 界面左侧是一个树(load数据后显示树结构),右侧上方是您在树上点选的节点的信息的显示与编辑区,右侧中间是命令的输入区,右侧下方是输出区。 您会发现界面上有很多按钮,其实他们都是我调试程序用的,您只需了解几个按钮即可。 File菜单的“Set default dir”是设置选择载入、导出文件的默认目录, “save as”是将树保存为文件,“load”则是将文件中保存的树装入到程序中来(会覆盖原有树的呦~~,记得先save)。 Script菜单的“save script as”是将命令区的内容存入文件,“load script”是将文件读入命令区(覆盖原有的命令)。 右侧中部的“Execute”按钮可以执行命令区的命令,可以用鼠标选择一部分命令为高亮,而只执行选择的命令。 ***注意***需要人工将右下的输出区的滚动条滚到最下!(作者在此道歉了,但作者毕竟是技艺不精啊……) 右侧中部的“CLO”是清除输出区的按钮,“—”则是在输出区加横线的按钮。 3 ------------ 功能介绍: ***注意***使用前需LOAD目录import_me下的template.dat。(或LOAD您以前保存的树,但要确认模板的存在。) 之后就可以运行各种命令了。 但是命令是有限的。 ***注意***从那张源代码截图可看出本软件支持的命令…… 还有就是import_me目录下的developing.txt是我开发时积累的命令脚本,大家可以导入玩一玩。 4 ------------ 欢迎批评与建议。 作者:cmpltrtok 电邮:cmpltrtok@sina.com 5 ------------ 命令列表: 作者还是不放心,把命令列表一下: 删除分类……。 删除……属于……。 ……是一种……不是一种……。 ……是一种……。 ……是一个……不是一个……。 ……是一个……。 ……是一种……(吗)? ……是一个……(吗)? ……是什么? ……是……吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小姑娘很大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值