上海Unity3D培训
达内上海市场营销中心

15026646613

热门课程

Unity简单AI编写

  • 时间:2018-06-29 17:24
  • 发布:达内u3d培训
  • 来源:上海达内

开发环境

Window7

Unity3D 3.4.1

MB525defy Android 2.2.1

这次是一个简单的AI编写,没有仿照任何一个人的做法,羽化因为觉得很有趣在工作时心血来潮简单写的一个,平时也可以Demo演示用用,写的时间不长,但 也将就能用,以后把这AI完善了再传上来分享,有什么好的AI书籍推荐都可以给羽化留言,喜欢的朋友可以拿去看看,虽然写得很简陋,不接受嘲讽-0-

本次学习:

1. Unity简单AI编写

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

1. Unity简单AI编写

由于这次介绍的AI很简单,羽化就把代码直接贴上,AI分成四个状态:思考,转身,移动,攻击,有经验的人认为羽化这样写得不对,由于这里只是初步实现, 所以羽化想实现简单点的操作,就像自动范围内随机移动,锁敌攻击,超出距离复位,近距离察觉等,这里代码送上。这次没有写Android的控制器,但肯定 可以在Android下用的-0-

Enemy_AI.js

[C#] 纯文本查看 复制代码

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203private 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;

}

还是那句话,代码本身并不难,羽化也是初学者写不出让人觉得高深的代码-0-,高手也许看一眼就知道这是一个简单的状态切换判断而已,羽化也是从原来 Android游戏经验中提取出来的,因为原来都有个FrameWork,框架控制着整个游戏构成,于是就想像AI也能如此,这种敌人AI要有更多的随机 性和针对性才能让人觉得真实吧,代码没什么优化,也许效率不是很好,以后估计要添加复杂地形寻路,技能释放,攻击站位判断等内容了,话说原来杨写的那AI 真叫个凶残。。。

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写。

上一篇:Unity环境搭建
下一篇:3D网页游戏场景打包与加载
选择城市和中心
贵州省

广西省

海南省

免费学习5天VIP课程