跟大家分享一个简单的小游戏,适合刚刚接触Unity的童鞋,有不对的地方请提出,我们一起学习~
首先要明确游戏的主要过程是什么,很简略哈,不好意思~(谢谢推荐一些方便画图的软件给我哟)。游戏的模式如下,一个火箭从A出发,在玩家WAD键盘控制下,躲避障碍物C,最终落在平台B上,这样就成功完成一个关卡,进入下一关。
在明确游戏的主要过程之后,就是要明确游戏的设计层次。在这个推进器小游戏中,最核心的设计层是什么,然后进一步完善什么,这样一步步完成整个游戏过程的设计。(个人的一些想法,我就记录下来了,当然游戏复杂了层次分类就更复杂)
在明确游戏的主要过程和设计的大致流程后,接下来我就要开始打开我们所热爱的Unity3D,那给予你无限创造可能的神笔,将在你的手中描绘出怎样的美景呢~ 好了,又表达完我对游戏的热爱之情后,我们打开Unity3D的项目选择界面,我们可以新建一个项目,然后取个名字,最好是英文的~平台Template选择3D,接下来点击CreatProject我们就开始了。
首先呢,我们要先创造一个火箭的模型,这个不难,用GameObject里的3D object来做构建一些方块,然后用WER分别是位移,旋转和缩放来做成一个火箭,然后同样的道理,做两个平台,一个作为launch-pad发射平台,一个作为landing-pad着陆平台,紧接着,再做一些障碍物,英文叫obstacle,再做一个背景,由于这里我们的游戏场景很小,于是我们可以做一个大的黑板作为背景,这样就有感觉了,不用去调lighting毕竟我们新手先不要一开始就去深入细节的小地方~就这样,我们创作了一个基本的环境,这也是体现大家创意的时候,我就把我的放在这里供大家参考哈~(做的确实有点乱......)
![scene视图](https://i-blog.csdnimg.cn/blog_migrate/705a3f7db2daecf597b17daf9a81ae8c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2d78a955bf3cdf805c2cda9b657ced21.png)
这样场景就算搭建好了,简单吧,就是Ctrl+D复制cube不停地变换搭成一个洞穴的感觉,然后一个飞船在里面探险,小心别撞到墙!就是这么一个游戏~注意把gameobject分好类(也就是hierarchy里的东西),归类放在一起,也给物体材质取好名字~
然后呢,我们就开始考虑设计层次的最核心的问题,怎么让rocket飞起来呢?我们一起学着编辑脚本吧!新建C#script重命名为rocketmovement,然后双击进入visualstudio2017进行编写。
首先给rocket一个刚体组件component里的rigidbody(是刚体才符合牛顿定律呀~)要能够按照WAD来上左右的运动,首先要让计算机获取键盘输入,然后做出给出相应的反应,两个参数是可以在inspector里调节的,用来调节向上和转向的速度。
public class rocketmovement : MonoBehaviour {
public float paramsup = 500f;
public float paramsturn = 300f;
Rigidbody rb;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
if (Input.GetKey(KeyCode.W))
{
rb.AddRelativeForce(Vector3.up * Time.deltaTime * paramsup);
}
if (Input.GetKey(KeyCode.A))
{
rb.transform.Rotate(Vector3.forward * Time.deltaTime * paramsturn);
}
if (Input.GetKey(KeyCode.D))
{
rb.transform.Rotate(-Vector3.forward * Time.deltaTime * paramsturn);
}
}
}
将脚本放到rocket上,就可以用WAD来控制火箭运动了,是不是很有趣!确实是的,接下更有趣,我们怎么样让火箭碰撞了不同的物体然后给出不同的反馈:
private void OnCollisionEnter(Collision collision)
{
switch (collision.gameObject.tag)
{
case "Player":
print("It's OK");
break;
case "Finish":
print("Success");
break;
default:
print("dead");
break;
}
}
OnCollisionEnter专门用来检测碰撞,根据撞到物体的tag来做出不同的反应。测试一下,在console那里有输出结果,说明没有问题!接着,我们要做的就是让rocket有不同的状态,处于alive可以控制,处于dead就坠毁失控,处于success就晋级下一关~是不是渐渐看到游戏在向你招手,一步步来就成了。
enum State {alive ,dead , success };
State state = new State();//声明有三个状态
分别在update()和OnconllisionEnter()后面加上if(state != State.alive){return;}这样,撞到墙体就会坠毁(失控),成功就等待进入下一个场景~至此,大体的游戏逻辑就已经结束啦!
在这里,我们需要修饰一下,游戏嘛,来点炫酷的效果?所以来简单加个粒子效果和声音。
用Public particlesystem 实例化三种粒子,用Public AudioClip 实例化三种声音,然后在合适的地方调用他们,要注意让他们何时停止~(代码暂时这里不放出来,后面会给出总的代码)
这样,我们的一个关卡就已经做好啦,接着,我们把hierarchy里的gameobject拖到project里做成预制体(prefabs),为制作下一个关卡提供方便,于是,我们保存该场景为scene1,接着复制scene1生成scene2,在现有场景下修改,修改后就保存成scene2,第二关就做好啦~
然后利用UnityEngine.SceneManagement来调用下一关或者前一关场景,这样,游戏就做完啦!
完整代码如下(我只做了四个场景,并且做了个obstaclemovement脚本,让障碍物或者landingpad移动):
using UnityEngine;
using UnityEngine.SceneManagement;
public class rocketmovement : MonoBehaviour {
public AudioClip mainsound;
public AudioClip deadsound;
public AudioClip successdound;
public ParticleSystem mainparticle;
public ParticleSystem deadparticle;
public ParticleSystem successparticle;
public float paramsup = 500f;
public float paramsturn = 300f;
public AudioSource audiosource;
Rigidbody rb;
enum State {alive ,dead , success };
State state = new State();
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
audiosource = GetComponent<AudioSource>();
state = State.alive;
}
// Update is called once per frame
void Update ()
{
xiangshang();
zhuangxiang();
}
private void zhuangxiang()
{
if (state != State.alive) { return; }
if (Input.GetKey(KeyCode.A))
{
rb.transform.Rotate(Vector3.forward * Time.deltaTime * paramsturn);
}
if (Input.GetKey(KeyCode.D))
{
rb.transform.Rotate(-Vector3.forward * Time.deltaTime * paramsturn);
}
}
private void xiangshang()
{
if (state != State.alive) { mainparticle.Stop(); return; }
if (Input.GetKey(KeyCode.W))
{
if (!audiosource.isPlaying)
{
audiosource.PlayOneShot(mainsound);
}
mainparticle.Play();
rb.AddRelativeForce(Vector3.up * Time.deltaTime * paramsup);
}
else
{
audiosource.Stop();
mainparticle.Stop();
}
}
private void OnCollisionEnter(Collision collision)
{
if (state != State.alive) { return; }
switch (collision.gameObject.tag)
{
case "Player":
print("It's OK");
break;
case "Finish":
audiosource.Stop();
audiosource.PlayOneShot(successdound);
successparticle.Play();
state = State.success;
Invoke("GoNextScene", 2f);
print("Success");
break;
default:
audiosource.Stop();
audiosource.PlayOneShot(deadsound);
deadparticle.Play();
state = State.dead;
Invoke("GoBackScene", 2f);
print("dead");
break;
}
}
void GoNextScene()
{
int currentscene = SceneManager.GetActiveScene().buildIndex;
int nextscene = currentscene + 1;
if (nextscene == SceneManager.sceneCountInBuildSettings)
{
nextscene = currentscene;
}
SceneManager.LoadScene(nextscene);
}
void GoBackScene()
{
int currentscene = SceneManager.GetActiveScene().buildIndex;
int nextscene = currentscene - 1;
if (nextscene <= 0)
{
nextscene = 0;
}
SceneManager.LoadScene(nextscene);
}
}
下面是obstaclemovement脚本:
using UnityEngine;
public class obstaclemovement : MonoBehaviour {
[SerializeField] Vector3 movement = new Vector3(10f, 0f, 0f);
[Range(0, 1)] [SerializeField] float movementfactor;
public float perid = 4f;
Vector3 startposition;
// Use this for initialization
void Start () {
startposition = transform.position;
}
// Update is called once per frame
void Update () {
if (perid <= Mathf.Epsilon) { return; }
float cycle = Time.time / perid;
float tau = Mathf.PI * 2;
movementfactor = (Mathf.Sin(tau * cycle) /2f) + 0.5f;
transform.position = startposition + movement * movementfactor;
}
}
其实,我们改善一下粒子和声音,在Blender等建模软件中建立火箭模型和环境模型,再换其他合适的光照,增加一些GUI包括记录时间和分数等等等,就这么一些代码,就可以做很多事情了,完全可以践行你的想象力!
我也将其package共享在云盘,需要的小伙伴自取~
其中有一些细节我没有都能写出来,如果你看到有什么疑惑后者我觉得我哪里可以改进的,欢迎评论~谢谢!
云盘链接如下: