1. Unity3D简单AI编写
由于这次介绍的AI很简单,代码直接贴上,AI分成四个状态:思考,转身,移动,攻击,这里只是初步实现,所以想实现简单点的操作,就像自动范围内随机移动,锁敌攻击,超出距离复位,近距离察觉等。
1 Enemy_AI.js
2
3 private var Regression : Vector3;
4 public var Player_Prefab : Transform;
5 public var Enemy_State : String;
6 public var Doing : boolean = true;
7 public var Range : float = 4.0;
8 public var Bullet : Transform;
9 public var Bullet_Prefab : Transform;
10 //初始化敌人方向和位置
11 function Start()
12 {
13 transform.localEulerAngles.y = Random.value * 360;
14 Regression = transform.position;
15 }
16 //敌人行动模式
17 public var Thinking : boolean = true;
18 public var Thinking_Time : float = 1.0;
19 private var relativePos : Vector3;
20 private var rotation : Quaternion;
21 public var Facing : boolean = false;
22 public var Facing_Time : float = 2.0;
23 public var Facing_Speed : float = 2.0;
24 public var Moving : boolean = false;
25 public var Moving_Speed : float = 0.5;
26 public var Moving_Time : float = 4.0;
27 public var Moving_Back : boolean = false;
28 public var Attacking : boolean = false;
29 private var Bullet_DO : boolean = true;
30 public var Bullet_CD : float = 0.2;
31 //随机移动方位
32 private var R_Position : Vector3;
33 function Update ()
34 {
35 if(Attacking)
36 {
37 Enemy_State = "Attacking";
38 Facing = true;
39 Moving = true;
40 //Doing = true;
41 Thinking = false;
42 var dist2 = Vector3.Distance(Regression, transform.position);
43 if(dist2 > 20)
44 {
45 relativePos = Regression - transform.position;
46 rotation = Quaternion.LookRotation(relativePos);
47 Attacking = false;
48 Moving_Back = true;
49 }
50 }
51 if(!Moving_Back)
52 {
53 var dist = Vector3.Distance(Player_Prefab.position, transform.position);
54 if(dist > 100)
55 {
56 Attacking = false;
57 return;
58 }
59 else if(dist < 5)
60 {
61 Attacking = true;
62 }
63 RayJudge();
64 }
65 transform.localEulerAngles.x = 0;
66 transform.localEulerAngles.z = 0;
67 if(Thinking && !Attacking && !Moving_Back)
68 {
69 Enemy_State = "Thinking";
70 if(Doing)
71 {
72 StartCoroutine(Think(Thinking_Time));
73 Doing = false;
74 }
75 }
76 if(Facing)
77 {
78 Enemy_State = "Facing";
79 if(Attacking)
80 {
81 relativePos = Player_Prefab.position - transform.position;
82 rotation = Quaternion.LookRotation(relativePos);
83 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed * 4);
84 }
85 else if(Moving_Back)
86 {
87 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed * 4);
88 }
89 else
90 {
91 transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * Facing_Speed);
92 if(Doing)
93 {
94 StartCoroutine(Face(Facing_Time));
95 Doing = false;
96 }
97 }
98 }
99 if(Moving)
100 {
101 Enemy_State = "Moving";
102 if(Moving_Back)
103 {
104 transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed * 6);
105 }
106 else if(dist > 2)
107 {
108 if(Attacking)
109 {
110 transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed * 4);
111 }
112 else
113 {
114 transform.Translate(Vector3.forward * Time.deltaTime * Moving_Speed);
115 }
116 }
117 if(Doing && !Attacking)
118 {
119 StartCoroutine(Move(Moving_Time));
120 Doing = false;
121 }
122 }
123 }
124 //前方锁敌
125 function RayJudge()
126 {
127 var layerMask = 1 << 2;
128 layerMask = ~layerMask;
129 var hit : RaycastHit;
130 if(Physics.Raycast (transform.position, transform.TransformDirection(Vector3.forward), hit, 20,layerMask))
131 {
132 var distanceToForward = hit.distance;
133 if(hit.transform.tag == "Player")
134 {
135 Attacking = true;
136 if(Bullet_DO)
137 {
138 var Create = Instantiate (Bullet_Prefab, Bullet.position, Quaternion.identity);
139 Create.rigidbody.AddForce (Bullet.forward * 1000);
140 StartCoroutine(Wait(Bullet_CD));
141 Bullet_DO = false;
142 }
143 }
144 }
145 }
146 function Wait(waitTime : float)
147 {
148 yield WaitForSeconds (waitTime);
149 Bullet_DO = true;
150 }
151 function Move(waitTime : float)
152 {
153 print("Move");
154 if(Moving_Back)
155 {
156 yield WaitForSeconds (waitTime * 0.4);
157 }
158 else
159 {
160 yield WaitForSeconds (waitTime + Random.value * 2);
161 }
162 Thinking = true;
163 Moving_Back = false;
164 Moving = false;
165 Facing = false;
166 Doing = true;
167 }
168 function Face(waitTime : float)
169 {
170 print("Face");
171 yield WaitForSeconds (waitTime + Random.value);
172 Facing = false;
173 Thinking = false;
174 Moving = true;
175 Doing = true;
176 }
177 function Think(waitTime : float)
178 {
179 print("Thinking");
180 yield WaitForSeconds (waitTime + Random.value);
181 R_Position = Regression + Random.insideUnitSphere * Range;
182 R_Position.y = Regression.y;
183 relativePos = R_Position - transform.position;
184 rotation = Quaternion.LookRotation(relativePos);
185 Thinking = false;
186 Moving = false;
187 Facing = true;
188 Doing = true;
189 }
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写。