Unity3D入门学习——火箭小游戏

跟大家分享一个简单的小游戏,适合刚刚接触Unity的童鞋,有不对的地方请提出,我们一起学习~

首先要明确游戏的主要过程是什么,很简略哈,不好意思~(谢谢推荐一些方便画图的软件给我哟)。游戏的模式如下,一个火箭从A出发,在玩家WAD键盘控制下,躲避障碍物C,最终落在平台B上,这样就成功完成一个关卡,进入下一关。

 在明确游戏的主要过程之后,就是要明确游戏的设计层次。在这个推进器小游戏中,最核心的设计层是什么,然后进一步完善什么,这样一步步完成整个游戏过程的设计。(个人的一些想法,我就记录下来了,当然游戏复杂了层次分类就更复杂)

在明确游戏的主要过程和设计的大致流程后,接下来我就要开始打开我们所热爱的Unity3D,那给予你无限创造可能的神笔,将在你的手中描绘出怎样的美景呢~ 好了,又表达完我对游戏的热爱之情后,我们打开Unity3D的项目选择界面,我们可以新建一个项目,然后取个名字,最好是英文的~平台Template选择3D,接下来点击CreatProject我们就开始了。

 首先呢,我们要先创造一个火箭的模型,这个不难,用GameObject里的3D object来做构建一些方块,然后用WER分别是位移,旋转和缩放来做成一个火箭,然后同样的道理,做两个平台,一个作为launch-pad发射平台,一个作为landing-pad着陆平台,紧接着,再做一些障碍物,英文叫obstacle,再做一个背景,由于这里我们的游戏场景很小,于是我们可以做一个大的黑板作为背景,这样就有感觉了,不用去调lighting毕竟我们新手先不要一开始就去深入细节的小地方~就这样,我们创作了一个基本的环境,这也是体现大家创意的时候,我就把我的放在这里供大家参考哈~(做的确实有点乱......)

scene视图
scene视图​​​
Game视图(我把obstacles土灰色换成了紫红色,感觉好看些)

这样场景就算搭建好了,简单吧,就是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共享在云盘,需要的小伙伴自取~

其中有一些细节我没有都能写出来,如果你看到有什么疑惑后者我觉得我哪里可以改进的,欢迎评论~谢谢!

云盘链接如下:

https://pan.baidu.com/s/1MSt5vvKZ8HyN_NGkz8vgXg

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现一个简单的火箭发射可以分为以下几个步骤: 1. 创建一个火箭模型,可以使用Unity内置的3D模型或者自己导入模型。 2. 在场景中创建一个火箭发射器对象,并将火箭模型作为其子对象。 3. 创建一个脚本,用于控制火箭发射。在脚本中定义火箭的速度、发射角度等属性,并编写启动火箭的代码。 4. 在发射器对象中添加一个空的游戏对象,用于标记火箭发射的起点位置。 5. 在脚本中使用Instantiate方法实例化火箭对象,并设置其初始位置和速度。 下面是一个简单的代码实现: ```csharp public class RocketLaunch : MonoBehaviour { public GameObject rocketPrefab; // 火箭预制体 public float rocketSpeed = 10f; // 火箭速度 public float launchAngle = 45f; // 火箭发射角度 private Transform launchPoint; // 发射起点 void Start() { launchPoint = transform.Find("LaunchPoint"); } void Update() { if (Input.GetKeyDown(KeyCode.Space)) { LaunchRocket(); } } void LaunchRocket() { GameObject rocket = Instantiate(rocketPrefab, launchPoint.position, Quaternion.identity); Rigidbody rocketRigidbody = rocket.GetComponent<Rigidbody>(); float launchAngleRad = launchAngle * Mathf.Deg2Rad; Vector3 launchDirection = new Vector3(Mathf.Cos(launchAngleRad), Mathf.Sin(launchAngleRad), 0f); rocketRigidbody.velocity = launchDirection * rocketSpeed; } } ``` 在脚本中,我们首先定义了火箭预制体、火箭速度和发射角度等属性,然后在Start方法中找到火箭发射起点的位置。 在Update方法中检测玩家是否按下了空格键,如果按下了则调用LaunchRocket方法发射火箭。 在LaunchRocket方法中,我们首先使用Instantiate方法实例化一个火箭对象,并将其位置设置为发射起点的位置。 然后计算火箭发射方向和速度,并将其赋值给火箭的刚体组件,从而启动火箭的运动。 最后,在场景中将火箭发射器对象拖入该脚本的Inspector面板中即可。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值