LZ-Says:学习,就要有无畏的精神,该干就干,who 怕 who?
前言
Unity内置了官方学习的API,下面附上一个演示图:
点击Help,选择Scripting Reference即可。
而今天,我们一起来玩个小游戏练练手~
游戏运行效果演示
一、初始化游戏环境
Step 1:创建一个名为:Roll A Ball工程
Step 2:保存当前场景
首先在Assets目录下创建Scene目录,此目录主要用于存放我们游戏中的场景。
Step 3:创建地面
右键选择3D Object选择Plane,并设置为世界坐标原点,然后将此场景命名为:Land。
Step 4:创建主角
在我们这个游戏中,游戏主角是一个小球。
创建完成之后,发现小球位置不是很合适,所以我们需要修改下小球的位置,让其稍微偏离地面。
Step 5:修改地面大小
Step 6:创建材质
材质,类似我们的样式。
这里关于游戏物体引用材质有俩种办法:
直接将材质拖动到游戏物体上;
将材质拖动到模型视图窗口中的模型上即可。
好了,到此完成游戏环境初始化。
二、控制小球在地面上移动
Step 1:为小球添加刚体组件
那么什么是刚体组件呢?
刚体组件:模拟物理效果。是对应的物体具有物理效果。
那么我们先运行下当前,看看当前不添加是什么效果:
那么添加之后,又是什么效果呢?
看到木有,小球具有了物体效果,所以会下降。
Step 2:通过C#脚本控制主角动作
首先在Project目录下创建Script,我们接下来的脚本文件都会存放于此。
而创建脚本并关联游戏物体,有俩种方式:
右键创建脚本,点击添加脚本并搜索,点击即可;
点击添加脚本,搜索时输入自定义的脚本名称,选择脚本语言,最后执行创建并添加。
下面附上演示图:
而接下来打开脚本文件,简单来看一下:
Start():用于存放初始化脚本内容;
Update():用于放置多次更新脚本内容。
脚本文件如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
private Rigidbody rd;
// Use this for initialization
// 用于存放初始化
void Start()
{
// 1.得到游戏物体身上的刚体组件
rd = GetComponent<Rigidbody>();
}
// Update is called once per frame
// 用户存放持续更新
void Update()
{
// 2.控制移动 x y z
// 给刚体施加一个力
rd.AddForce(new Vector3(1, 0, 0));
}
}
下面来看下目前运行效果:
三、通过键盘按键控制小球的移动
下面,我们来改造,改造小球直接通过键盘按键移动。
// Update is called once per frame
// 用户存放持续更新
void Update()
{
// 2.控制移动 x y z
// 给刚体施加一个力
// 3.获取键盘上的按键,通过按键去控制小球移动
// (A左 D右)
float h = Input.GetAxis("Horizontal");
// 4.获取前后 W前 S后
float v = Input.GetAxis("Vertical");
rd.AddForce(new Vector3(h, 0, v));
}
我们一起来看下效果图:
小伙伴说了,你这速度不行啊,我想随时更改速度怎么破?
很easy,定义一个速度变量,然后再移动过程中进行相乘即可。
那么代码中又改如何实现呢?
public class Player : MonoBehaviour {
private Rigidbody rd;
public int force = 5;
// Use this for initialization
// 用于存放初始化
void Start()
{
// 1.得到游戏物体身上的刚体组件
rd = GetComponent<Rigidbody>();
}
// Update is called once per frame
// 用户存放持续更新
void Update()
{
// 2.控制移动 x y z
// 给刚体施加一个力
// 3.获取键盘上的按键,通过按键去控制小球移动
// (A左 D右)
float h = Input.GetAxis("Horizontal");
// 4.获取前后 W前 S后
float v = Input.GetAxis("Vertical");
rd.AddForce(new Vector3(h, 0, v)*force);
}
}
那么接下来,我们一起来看下演示图:
嗯哼,效果是不是很nice?立竿见影,有木有?
四、控制相机的跟随
首先,我们先来微调下相机的角度,Scene视图右下角便是相机预览窗体:
接着,我们运行简单来看下效果:
可以发现,我们的相机并没有跟随小球视野而变换,看的十分别扭。那么接下来,让我们通过脚本去触发相机跟随小球视野变换吧~
而这里需要注意,相机跟随小球视野变化,也就是相机和小球的一个位置的变化,也就是他俩之间保持位移不变即可。
为相机创建脚本:
定义Transform组件并指定Player:
那么这时候也就以为这Player引用到了Transform组件,下面进行具体操作。
public class FollowTarget : MonoBehaviour {
// 定义跟随的主角
public Transform playerTranform;
// 获取偏离量
private Vector3 offset;
// Use this for initialization
void Start () {
// 访问主角的位置偏移
offset = transform.position - playerTranform.position;
}
// Update is called once per frame
void Update () {
// 主角的位置加偏移量得到相机的位置
transform.position = playerTranform.position + offset;
}
}
一起来看下效果:
五、控制小球的移动范围
首先,我们来观察下,我们之前实现的效果:
我们发现小球滚动到边缘的地方会直接掉落下去,那么现在我们为地形添加墙体。
嗯哼,效果是不相对来说比较好了呢?
六、创建可收集的食物
首先为了保证结构统一,我们先来调整下工程:
首先,我们需要创建一个实物,当然游戏当中会包含很多这个实物,目前来讲先创建一个即可,之前创建材质,修改其颜色,如下:
由于我们游戏当中会有很多很多这样的实物,那么为了方便,我们一般会统一定义一个模型,也就是模板,然后去引用,这样做的好处在于,对于有修改的需求时,我们只需要修改一个即可实现全部修改,如下效果演示图:
七、控制实物的旋转
首先,我们基于上图完成的模板去在我们的地面上进行摆放一圈,如下:
接下来定义我们的脚本文件,去控制实物的旋转:
在脚本文件中通过组件设置旋转:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PickUp : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
// 通过transform组件控制旋转等
// 大约一秒调用60次 也就相当于60帧
transform.Rotate(new Vector3(0,1,0));
}
}
一起来看效果:
八、碰撞检测
我们的主角已经设置完毕,物体模板也已经Okay,那么怎么控制小球去吃这个物体呢?一起来看~
Unity当中为我们提供了几种不同的检测方案:
碰撞检测
触发检测
射线检测
而今天,我们运用到了碰撞检测和触发检测。那么什么又是碰撞检测,什么优势触发检测呢?
碰撞检测,也就是在游戏中判断一个游戏物体和另外一个游戏物体是否发生碰撞。而碰撞检测,实际上是刚体发出的一个检测,所以,接下来我们将对刚体进行一些操作,使其实现小球碰撞实体后,实体销毁。
碰撞发生时会具有一些状态,例如我们Button按下的时候,也会有类似触摸、按下,松开等状态,那么这些在Unity中刚体所对应的又是什么呢?
还是看官方文档吧~~~
OnCollisionEnter:当碰撞触发生时会触发,只会触发一次;
OnCollisionExit:当碰撞触结束时会触发,只会触发一次;
OnCollisionStay:当碰撞触发时会触发,只要俩个物体触发,就会触发多次;
首先我们在Player中设置监听,监听下看看角色碰撞的物体:
void OnCollisionEnter(Collision collision) {
// 获取当前碰撞的游戏物体
// 获取碰撞到的游戏物体身上的Colloder
// collision.colloder;
// 获取碰撞到的游戏物体的名称
string name = collision.collider.name;
// 输出内容
print(name);
}
运行查看效果:
这个时候,我们又该怎么知道角色究竟碰撞到了哪儿些物体呢?
Android中,我们曾为某些控件设置Tag,去标识,而在Unity中,我们同样可以通过Tag去区别我们的角色究竟碰撞了哪儿些游戏物体:
而接下来,我们去控制角色碰撞之后,游戏物体消失:
void OnCollisionEnter(Collision collision) {
// 获取当前碰撞的游戏物体
// 获取碰撞到的游戏物体身上的Colloder
// collision.colloder;
// 获取碰撞到的游戏物体的名称
// string name = collision.collider.name;
// 输出内容
// print(name);
// 判断当前碰撞是否为我们的角色
if (collision.collider.tag == "PickUp") {
// 销毁碰撞的游戏物体
Destroy(collision.collider.gameObject);
}
}
同样查看一下运行效果:
九、触发检测控制主角捡起食物
在上面的示例图中,大家会发现,小球在吃正方体时,会发生一个碰撞,也就是简单的停顿现象,那么怎么控制吃的时候不阻碍我们小球的运动呢,很easy,设置触发检测即可,如下:
那么碰撞检测和触发检测区别在哪儿呢?
碰撞检测会实际触发物体效果,类似碰撞,而触发则不会。
So,添加触发检测如下:
// 触发检测
void OnTriggerEnter(Collider collider) {
if (collider.tag == "PickUp")
{
// 销毁碰撞的游戏物体
Destroy(collider.gameObject);
}
}
查看效果,看看小球在吃东西的时候会不会有阻碍效果:
是不是很圆滑呢?
十、显示分数和胜利检测
我们假设要在游戏左上角显示当前分数,应该怎么玩呢?
首先当然定义一个Text,如下:
要记得使用Alt选择Text摆放位置。
之后,创建一个成功提示Text,在满足条件时进行显示即可。
这里直接贴出player代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Player : MonoBehaviour {
private Rigidbody rd;
public Text text;
// 定义一个游戏物体
public GameObject winText;
public int force = 5;
private int score = 0;
// Use this for initialization
// 用于存放初始化
void Start()
{
// 1.得到游戏物体身上的刚体组件
rd = GetComponent<Rigidbody>();
}
// Update is called once per frame
// 用户存放持续更新
void Update()
{
// 2.控制移动 x y z
// 给刚体施加一个力
// 3.获取键盘上的按键,通过按键去控制小球移动
// (A左 D右)
float h = Input.GetAxis("Horizontal");
// 4.获取前后 W前 S后
float v = Input.GetAxis("Vertical");
rd.AddForce(new Vector3(h, 0, v)*force);
}
// 碰撞检测 会发生实际的物理效果
void OnCollisionEnter(Collision collision) {
// 获取当前碰撞的游戏物体
// 获取碰撞到的游戏物体身上的Colloder
// collision.colloder;
// 获取碰撞到的游戏物体的名称
// string name = collision.collider.name;
// 输出内容
// print(name);
// 判断当前碰撞是否为我们的角色
if (collision.collider.tag == "PickUp") {
// 销毁碰撞的游戏物体
Destroy(collision.collider.gameObject);
}
}
// 触发检测
void OnTriggerEnter(Collider collider) {
if (collider.tag == "PickUp")
{
score++;
text.text = "当前分数为:" + score + "分";
if (score == 8) {
// 激活游戏组件
winText.SetActive(true);
}
// 销毁碰撞的游戏物体
Destroy(collider.gameObject);
}
}
}
游戏效果如下:
十一、游戏打包以及运行
这里需要注意的是:
选择File后选择Build Settings,之后选择要发布的环境以及场景;
打包生成的文件要一并打包交付,不然无法运行。
还有最最最重要的一点,时刻准备保存!!!
欢迎关注个人公众号
不定时发布博文,用心,搞公众号~
赞赏
如果感觉LZ写的不错,来个赞赏~