5.1 基本概念
在这个游戏里面,我们的坏蛋就是一个圆球,顾名思义,坏蛋坏蛋,就是蛋的形状吗!
5.2 摄像机推过去
上一节整出来的底座在游戏界面看的不舒服,所以老余打算调整一下Camera的位置和角度,这样在游戏界面能看到一个舒服的全景:
可以用鼠标拖拽,也可以在Transform输入下图的数值定位Camera,然后Game 界面就是像下图那样:
Position X=-2, Y=58.9, Z=-61
Rotation X=65, Y=0, Z=0
Camera处的Clear Flags改成Solid Color,老余不想看见天空,并且选了一个自己喜欢的背景颜色。
小图看的不过瘾,老余把游戏视图放到最大,想看一下最后在Windows上的效果,结果整的小余又小激动了一下:
5.3 论坏蛋是怎么练成的
跟新生成一个Cube一个道理,老余生成了一个球体Sphere,代表坏蛋的“蛋”,拽到代表出发点的方块那里,“蛋”需要放大一点,原尺寸的2.5倍吧。
然后同理,老余给这个“蛋”做了一个蓝色的材质,毕竟这个又土又绿的原装货太丑了,整的小余都不爱看
弄好了就如下面那张图一样,老余还觉得不过瘾,打算用锥光打一下
他把Directional Light拽到起点附近,重点关照了一下我们的小“蛋”。
做完敌人,老余很专业的把Enemy拖到了Prefab,因为多年的经验告诉他,敌人是随机生成的,不是像这样固定放在图上。
有图有真相,老余的专业性是以往的工作造就的,所以说一分耕耘,一份收获。
5.4 大海航行靠灯塔
小“蛋”自己不会按照我们的路线跑,接下来就要做指引的路标了,老余给它起了一个英文的名字叫Waypoint,路标集合就是Waypoints,这个上面就做过,行了,都是老朋友,老余飞快地干了起来。因为路标在玩游戏的时候不能让小余看见,所以用的是Empty
点击左上角哪个带三角的立方体图标,我们可以指定这个Empty Object的图标,为了醒目一点,老余选了红色菱形。
老余接着在拐角的地方放置这些不可见的路标,这个Waypoint也要做成Prefab,要批量使用的,以后用来指引小“蛋”:
每一个拐弯的地方都要放路标Waypoint
在终点必须放一个路标,不然小蛋就回不去终点了😊
5.5 编程老本行来了
游戏最终还是要靠代码驱动的,老余以前是Java程序员,虽然U3D支持Javascript和C#,但是老余还是毫不犹豫的选择了C#,为什么?这么简单的道理,自己琢磨啦。
首先在路标集合Waypoints那里点Add Component,在下拉列表中选择New script,代码名称叫做Waypoints,然后点Create and Add按钮。老余很自觉的把Waypoints代码拉到Scripts目录下面。
其次,还要靠代码驱动小蛋行动,这一次,老余不打算马上动态生成敌人,所以先拽了Prefab里面的Enemy上去,先达到运动的效果,记住饭要一口一口的吃,软件是多次迭代出来的。
随后老余用同样的方法生成了Enemy的C# Script。
先看一下路标集合Waypoints,千言万语都在注释上面了
using UnityEngine;
public class Waypoints : MonoBehaviour
{
public static Transform[] points;
private void Awake()
{
points = new Transform[transform.childCount]; // 遍历本Waypoints集合下的所有Waypoint,并赋给points数组
for (int i = 0; i < points.Length; i++)
{
points[i] = transform.GetChild(i);
}
}
}
再看一下Enemy的C#脚本
using UnityEngine;
public class Enemy : MonoBehaviour
{
public float speed = 10f; // 坏蛋速度
private Transform target; // 当前路标
private int wavepointIndex = 0;
private void Start()
{
target = Waypoints.points[0]; // 初始化为第一个路标
}
private void Update()
{
Vector3 dir = target.position - transform.position; // 算出来路标和自己的距离及方向
transform.Translate(dir.normalized * speed * Time.deltaTime, Space.World); // 往这个方向移动,Time.deltaTime是保障不同性能的机器移动速度一致
if (Vector3.Distance(transform.position, target.position) <= 0.4f) // 当距离路标很近的时候,找下一个路标
{
GetNextWaypoint();
}
}
void GetNextWaypoint()
{
// 如果到达终点路标,就销毁本对象,Sphere消失
if (wavepointIndex >= Waypoints.points.Length -1)
{
Destroy(this.gameObject);
return;
}
wavepointIndex++;
target = Waypoints.points[wavepointIndex]; // 找到下一个路标
}
}
最后老余运行了一下游戏,很有成就感的观赏了今天的成果,敌人出动啦!当然,毫无意外的,小余又在啃他的手指头了