2015-03-10 15:30:07 operhero1990 阅读数 1182
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity4.3游戏开发项目实战(龚老师编著)第二章太空射击

 

1、摄像头:透视投影Perspective和正交投影Orthographic的区别。这是个2D游戏,所以选择后者。

2、碰撞检测:游戏里飞机发射子弹击碎岩石,岩石撞碎飞机都需要用到碰撞检测。

      碰撞检测过程中需要为撞击与被撞击物体加上碰撞体。子弹使用胶囊碰撞体(CapsuleCollider),飞机和岩石使用立方体碰撞体(Box Collider),并且勾选Is Trigger选项。

      撞击者(攻击方)需要添加刚体(Rigidbody)。

      撞击响应函数这里使用的是void OnTriggerEnter(Collider other),其中用other.tag == "Player"(飞机的tag是Player)来判断是否碰撞到了飞机,而projectile则是子弹。 http://blog.csdn.net/Monzart7an/article/details/22739421这篇文章详细分析了碰撞检测。

3、动画:岩石被击碎和飞机爆炸都会有爆炸动画。岩石爆炸总共有7帧图像,打包成一幅308*49的图片。所以可以设置Tiling属性的X=0.143表示只显示原图X轴的七分之一,而改变Offset中的X则可显示不同帧画面。这里直接贴代码:

using UnityEngine;
using System.Collections;

public class ExplosionController : MonoBehaviour {

	public int index = 0;
	public int frameNumber = 7;

	float frameRate = 0;
	float myTime = 0;
	int myIndex = 0;

	// Use this for initialization
	void Start () {
		frameRate = 1.0f / frameNumber;	
	}
	
	// Update is called once per frame
	void Update () {
		myTime += Time.deltaTime;
		myIndex = (int)(myTime * frameNumber);
		index = myIndex % frameNumber;

		renderer.material.mainTextureScale = new Vector2 (frameRate, 1);
		renderer.material.mainTextureOffset = new Vector2 (index * frameRate, 0);

		if (index == frameNumber - 1) {
						Destroy (gameObject);
				}
	}
}

4、记录最高分数:其实就是保存和读取一个变量到本地。这里使用的是PlayerPrefs.SetInt("highScore")和PlayerPresf.GetInt("highScore")的方法,u3D会将变量名和值保存为键值对的形式。

5、切换场景:首先定义不同的场景(New Scene),调用Application.LoadLevel("场景名”)。

2018-02-04 19:52:54 s1314_JHC 阅读数 877
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

这部分内容关注的是游戏性的提升,包括音效、计分等功能的实现。
传送门:
太空射击(Space Shooter)流程介绍与代码分析(下)

11.添加音效
音效分配3种,爆炸音效、发射子弹音效和背景音效。其中爆炸音效将音频文件直接拖入爆炸素材中即可,如下所示。


对于背景音效文件,我们可以拖入GameController,并勾选loop,这样在游戏开始时即可自动循环播放。


而发射子弹的音效,在PlayerControl中实现,打开代码文件。添加定义和实现代码

    public AudioClip weaponFire;    //添加音效
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) &&Time.time > nextFireTime)
        if (Input.GetButton ("Fire1")&&Time.time > nextFireTime)
        {
            audio.PlayOneShot(weaponFire);    //播放音效
            nextFireTime = Time.time + fireRate;
            Instantiate    //shooting function
                (
                bullet,
                bulletPosition.transform.position,
                bulletPosition.transform.rotation
                    );
        }
    }
}
即可,之后将音效拖入其中即可实现。


此时,需向Playership中添加一个AudioSource,否则会报错。
12.销毁爆炸效果及计分功能
在之前的进度中,我们实现了大部分游戏功能,但是无法消除爆炸效果,如下所示。


本部分就介绍如何解决这一问题。
新建一个脚本,DestroyExplosion,写入
using UnityEngine;
using System.Collections;
public class DestroyExplosion : MonoBehaviour {
    public float lifetime;
    void Start () {
        Destroy (this.gameObject, lifetime);
    }
}
即可

之后将这一脚本拖入各个爆炸效果中,如下所示即可。


分数显示:
在4.6.9中不能像教程那样添加GUIText,因此使用一个替代的Text,来代替。GameObject——>UI——>Text添加即可。GUIText的定义与Text差不多。
例如:public GUIText scoreText  与public Text ScoreText对应即可,调用函数等操作方法是一样的。


在GameController中要构建累加分数的函数,并在外部进行调用。
其定义与累加函数如下。
    private int score;
    public void AddScore(int v)
    {
        score += v;
        scoreText.text = "Score:  " + score;
    }
即可。
分数添加完毕后,就有了一个问题,在哪个外部函数进行调用呢?只有在子弹击中陨石之后才能进行加分,因此我们在DestroyByContact中的陨石爆炸处进行调用。
  1. 在DestroyByContact中,我们新建一个GameController对象gameController,之后通过gameController调用加分函数。
  2. 在void Start()中添加一个GameObject对象gameControllerObject,将Hierarchy中的GameControl的Tag设置一下,作为查找标记,如下图所示。
  3. 如果gameControllerObject找到GameControl的Tag,将gameControllerObject.GetComponent<GameController>()赋给gameController,此时gameController即可调用GameControl中的函数。
  4. 用gameController调用AddScore函数,完成分数的添加。
上述流程变量名相似,多理解几遍即可,这也是一种常用的使用“Tag”调用函数的方法。DestroyByContact的代码如下。


using UnityEngine;
using System.Collections;
public class DestroyByCotact : MonoBehaviour {
    
    public GameObject explosion;
    public GameObject playerExplosion;
    private GameController gameController;    //步骤1,新建GameController对象
    public int score = 10;
    void Start()
    {
        GameObject gameControllerObject = GameObject.FindWithTag ("GameController");    //步骤2,查找GameControl
        if (gameControllerObject != null)
        {
            gameController = gameControllerObject.GetComponent<GameController>();    //步骤3,若步骤2查找到,赋值给gameController
        }
        if (gameControllerObject == null)
        {
            Debug.Log("could not find the gamecontroller");
        }
    }
    void OnTriggerEnter (Collider other)
    {
        if (other.gameObject.tag == "Boundary")     //if other.gameObject belongs to "Boundary",do nothing.
        {
            return;
        }
        if (other.gameObject.tag == "Player")     //if other.gameObject belongs to "Player",destroy the playership.
        {
            Instantiate (playerExplosion, this.transform.position, this.transform.rotation);
            gameController.GameOver();
        }
        Destroy (other.gameObject);
        gameController.AddScore (score);    //步骤4,进行加分
        Destroy (this.gameObject);
        Instantiate (explosion, this.transform.position, this.transform.rotation);    //destroy the asteriod
    }
}
13.GameOver之后的操作
游戏结束后的操作包括以下几个:
  1. 陨石不再产生
  2. 显示游戏结束
  3. 按某个键重新开始游戏。
本节主要介绍这几个功能的实现。
在GameControl中新建一个bool值,用以判断游戏是否结束,并添加两个文本用以实现游戏结束与重新开始的提示(即2、3的操作),定义与函数实现如下。
    private bool gameOver = false;
    public void GameOver()
    {
        gameOver = true;
        gameOverText.text = "Game Over!";
        helpText.text = "Press 'R' to Restart";
    }
之后实现陨石不再产生的操作(即1),在产生陨石函数中添加判断语句并break,如下
    IEnumerator SpawnWave()
    {
        yield return new WaitForSeconds(gameStartTime);
        while (true)
        {
            for (int i=0; i<10; i++)
            {
                Spawn ();
                yield return new WaitForSeconds (waitTime);
            }
            yield return new WaitForSeconds(waveTime);
            if(gameOver) break;    //若结束,则break
        }
    }
函数定义实现后,需要确定何时调用GameOver,我们可以在DestroyByContact中的飞机爆炸中进行调用。代码如下
if (other.gameObject.tag == "Player")     
        {
            Instantiate (playerExplosion, this.transform.position, this.transform.rotation);
            gameController.GameOver();    //12节已经建立了Tag的关系,因此 gameController可以直接调用GameContrl中的GameOver函数
        }
对于重新开始游戏,我们可以在GameControl中用Update函数进行实现,代码如下
    void Update () {
        if (gameOver && Input.GetKeyDown (KeyCode.R))
        {
            Application.LoadLevel(Application.loadedLevel);    //重新加载游戏函数
        }
至此,所有的函数功能都以实现,游戏已经可以正常运行。

总结:Space Shooter作为一个初学者很容易上手的游戏,实现起来难度不大。之后将会逐步加大难度,进行更高难度游戏的开发学习。
2019-07-04 13:37:57 weixin_33997389 阅读数 465
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

步骤四:创建敌人

创建敌人的方式与创建主角类似,不过敌人的行为需要由计算机来控制,它将从上方迎着主角缓慢飞出来,并左右来回移动:

01:创建Enemy.cs脚本,添加代码:

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 [AddComponentMenu("MyGame/Enemy")]
 5 public class Enemy : MonoBehaviour
 6 {
 7 
 8     //移动速度
 9     public float m_Movespeed = 1;
10     //旋转速度
11     public float m_RotationSpeed = 30;
12     public Transform m_transform;
13     void Start()
14     {
15         m_transform = this.transform;
16     }
17 
18     void Update()
19     {
20         UpdateMove();
21     }
22 
23     protected void UpdateMove()
24     {
25         //左右移动
26         float rx = Mathf.Sin(Time.time) * Time.deltaTime;
27         //前进
28         m_transform.Translate(new Vector3(rx, 0, -m_Movespeed * Time.deltaTime));
29     }
30 }
View Code

UpdateMove函数用来执行敌人的移动,使用了Sin函数使游戏体在x方向的移动始终在(-1,1)区间内,敌人在飞行的同时还会左右迂回;在Project窗口找到Enemy.fbx文件,拖动到Hierarchy窗口,然后参考前面内容为其创建Prefab,指定Enemy脚本作为其组件。然后将Prefab从Project窗口拖动到游戏场景中,然后在Hierarchy窗口选中Enemy按Ctrl+D复制多个,然后再Scene窗口中自己排列下位置就OK了。

游戏运行后:

步骤五:添加物理碰撞

现在的游戏虽然有了主角、敌人,也可以发射子弹,但主角和敌人之间却没有任何的交互。我们需要分别给主角、子弹、敌人添加碰撞体,并添加触发碰撞的代码,使其在发生碰撞的时候产生交互。

01:先给敌人添加碰撞体,在Scene面板选中任意一个敌人,在菜单栏选择Component->Physics->Box Collider为敌人添加一个立方体碰撞体组件,在后在Inspector窗口找到Box Collider组件,选中Is Trigger,使其具有触发作用:

02:接着在菜单栏选择Component->Physics->Rigidbody为敌人添加一个刚体组件,所有需要参与物理计算的游戏体都需要有一个刚体组件才能正常工作。在Insperctor->Rigidbody取消选择Use Gravity去掉重力作用影响,选中Is Kinematic使游戏体运动不受物理模拟影响,现在已经为一个敌人添加了物理碰撞效果组件,然后再Insperctor最上面找到Apply按钮点击,这样所有的Enemy都更新了此物理碰撞的设置。此处如果是在编辑器的Project窗口修改原始敌人的Prefab的属性,那么场景中的所有的敌人都会自动更新与Prefab一样的属性设置,如图:

然后参考给敌人设置物理碰撞组件的做法,给主角和子弹也类似的设置。

03:接下来触发碰撞,上面已经给主角、敌人、子弹添加了碰撞体,但是运行游戏的时候看不到任何的互动效果,我们将要为他们分别指定一个Tag标识,然后添加触发碰撞事件的代码,在菜单栏选择Edit->Project Settings->Tags在size中输入2,创建两个tag,名为PlayerRocket和Enemy,如图:

然后在Project窗口选择敌人的Prefab,在Inspector窗口设置Tag为Enemy;选择子弹的Prefab,在Inspector窗口设置它的Tag为PlayerRocket;选择主角设置他的Tag为Player,这个Tag是Unity预设在工程内的。

然后打开敌人Enemy.cs脚本,添加一个生命属性:

    public float m_life = 10;

    void OnTriggerEnter(Collider other) //这是一个派生自MonoBehaviour的函数,在碰撞体互相接触时
                                      //会被触发
    {
        if (other.tag.CompareTo("PlayerRocket") == 0)//如果碰到的物体是主角子弹PlayerRocket
        {
            Rocket rocket = other.GetComponent<Rocket>();//获得对方碰撞提的Rocket脚本组件
            if (rocket != null)
            {
                m_life -= rocket.m_power;
                if (m_life <= 0)
                {
                    Destroy(this.gameObject);//如果生命小于等于0就自动销毁
                }
            }
        }
        else if (other.tag.CompareTo("Player") == 0)
        {
            m_life = 0;
            Destroy(this.gameObject);//如果碰到主角就立即自动销毁
        }
    }

  然后在子弹Rocket.cs脚本中也添加一个OnTriggerEnter函数,当子弹撞击到敌人,则自我销毁。

void OnTriggerEnter(Collider other)
    {
        if (other.tag.CompareTo("Enemy") == 0)
        {
            return;
        }
        Destroy(this.gameObject);
    }

  然后在主角Player.cs脚本中添加一个生命属性,添加一个OnTriggerEnter函数,当主角与非自己发出的子弹相碰撞的时候都会损失一些生命,当生命为0时候自行销毁。

public float m_life = 3;

    void OnTriggerEnter(Collider other)
    {
        if (other.tag.CompareTo("PlayerRocket") != 0)//如果主角与非己方子弹相撞
        {
            m_life -= 1;
            if (m_life <= 0)
            {
                Destroy(this.gameObject);
            }
        }
    }

  此时我们注意到当敌人没有与主角或者主角的子弹发生碰撞的时候就会一直存活,从而造成了资源的浪费,这时候我们需要添加一个空的游戏体,把他放到最下面,然后让他的范围可以控制到整个下方横向区域,添加物理碰撞组件,为他指定一个名为Bound的Tag,然后在Enemy.cs中添加一句代码,当敌人没有被子弹消灭和主角碰撞消灭的时候飞到屏幕下方与之碰撞就会自行销毁。

 else if (other.tag.CompareTo("Bound") == 0)
        {
            m_life = 0;
            Destroy(this.gameObject);//如果碰到边界就立即自动销毁
        }

  步骤六:添加高级敌人(可以向主角发射子弹的敌人)

01:在Project窗口找到Enemy2.fbx模型,为其创建Prefab,为其创建脚本SuperEnemy.cs,该类继承自Enemy.cs,然后打开Enemy.cs,,将UpdateMove()方法写成Vitual方法,然后再SuperEnemy.cs中重写该方法,同时将新敌人的Tag改为Enemy:

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/SuperEnemy")]
public class SuperEnemy : Enemy
{
    protected override void UpdateMove()
    {
        //向前移动
        m_transform.Translate(new Vector3(0, 0, -m_Movespeed * Time.deltaTime));
    }
}

  此时运行游戏发现新敌人缓慢向前移动

02:新敌人向主角发射子弹

使用rocket.fbx创建一个新的子弹Prefab,取名为EnemyRocket,为其创建新的材质,使用rocket2.png作为贴图,使敌人的子弹看上去与主角的子弹不同,为敌人添加RigidBody和Box Collider组件(这里我添加组件的时候子弹就发不出来了,不知道为啥???),为敌人子弹新建一个名为EnemyRocket的Tag,创建EnemyRocket.cs脚本,继承自Rocket类:

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/EnemyRocket")]
public class EnemyRocket : Rocket
{
    void OnTriggerEnter(Collider other)
    {
        if (other.tag.CompareTo("Player") == 0)
        {
            return;
        }
        Destroy(this.gameObject);
    }
}

  将EnemyRocket的脚本指定给敌人子弹的Prefab,在Inspector窗口设置EnemyRocket组件,降低敌人子弹的移动速度,增加生存时间,然后关联SuperEnemy和子弹,在SuperEnemy.cs脚本中添加代码:

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/SuperEnemy")]
public class SuperEnemy : Enemy
{
    public Transform m_rocket;
    protected float m_fireTimer = 2;//控制发射子弹的时间间隔
    protected Transform m_player;//用来指向主角的飞船

    void Awake()//Awake方法继承自MonoBehaviour它会在游戏体实例化时执行一次,并先于Start方法
    {
        GameObject obj = GameObject.FindGameObjectWithTag("Player");//获得主角的游戏体实例
        if (obj != null)
        {
            m_player = obj.transform;
        }
    }
    protected override void UpdateMove()
    {
        m_fireTimer -= Time.deltaTime;
        if (m_fireTimer <= 0)
        {
            m_fireTimer = 2;
            if (m_player != null)
            {
                Vector3 relativePos = m_transform.position - m_player.position;
                //Quaternion.LookRotation使子弹在初始化时朝向主角的方向
                Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos));
            }
        }
        //向前移动
        m_transform.Translate(new Vector3(0, 0, -m_Movespeed * Time.deltaTime));
    }
}

  然后选择SuperEnemy的Prefab,在Inspector窗口中选择Rocket属性,与敌人的子弹的Prefab相关联,然后运行游戏。

注意:我在添加子弹游戏体的时候如果是添加了Box Collider就会看不到子弹了,不知道是不是坐标的问题??????

下面是添加声音和特效...

 

转载于:https://www.cnblogs.com/yk123/p/4907308.html

2016-06-25 18:01:14 qq_35423268 阅读数 535
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

Unity3D 视频教程列表,共 91 套

[000001]《Unity3D Platform 中文视频教程》[7课时]
[000002]《Unity3D 游戏蛮荒之地教学视频》[15课时]
[000003]《Unity3D 坦克克星视频教程》[9课时]
[000004]《Unity3D 太空射击游戏中文视频》[17课时]
[000005]《Unity3D 切水果视频教程》[9课时]
[000006]《Unity3D 精神時光屋》[5课时]
[000007]《Unity3D 机器人之战视频教程》[14课时]
[000008]《Unity3D 愤怒的小鸟 中文视频教程》[12课时]
[000009]《Unity3D 超级玛丽奥视频教程》[7课时]
[000010]《Unity3D Playmaker基础视频教程》[7课时]
[000011]《Unity3D AboutCG JavaScript 初级教程》[4课时]
[000012]《Unity3D 2D超级玛丽奥高级版 系列教程》[68课时]
[000013]《Unity3D 4.0 视频教程》[7课时]
[000014]《Unity3D C#4.0语言 视频教程》[40课时]
[000015]《Unity3D GUI设计 视频教程》[1课时]
[000016]《Unity3D JiaByNew 投篮游戏 视频教程》[1课时]
[000017]《Unity3D 动作冒险解谜游戏特效案例制作教程》[16课时]
[000018]《Unity3D 海海 基础操作 视频教程》[5课时]
[000019]《Unity3D 脚本着色器基础入门训练》[7课时]
[000020]《Unity3D 宣雨松入门三课》[3课时]
[000021]《Unity3D 游戏大鬼战斗制作视频教程》[16课时]
[000022]《Unity3D (Lynda出品)角色动画系统视频教程(英语)》[42课时]
[000023]《Unity3D (Zbooa出品)Scifi Third Person Game Tutorial(英语)》[35课时]
[000024]《Unity3D (蓝铅笔)特效系统学习课程》[7课时]
[000026]《Unity3D 2D超级玛丽高级教程(英语)(附工程源码)》[25课时]
[000027]《Unity3D Android Development With Unity(英语)》[3课时]
[000028]《Unity3D iGUI快速搭建UI教程和插件安装包(英语)》[6课时]
[000029]《Unity3D Lightmapping光影贴图视频教程(英语)》[4课时]
[000030]《Unity3D NGUI教程(英语)》[16课时]
[000031]《Unity3D Playmaker基础教程(英语_带中文字幕)》[7课时]
[000032]《Unity3D Uni2D最牛逼的2D插件教程和插件安装包(英语)》[6课时]
[000033]《Unity3D 必学C#4.0语言视频教程(附工程源码)》[20讲]
[000034]《Unity3D 反馈系统制作视频教程(附工程源码)》[11课时]
[000035]《Unity3D 工作技巧视频教程(附工程源代码)》[11课时]
[000036]《Unity3D 游戏开发培训视频教程》[13课时]
[000037]《Unity3D 游戏引擎的基础入门视频教程》[20课时]
[000038]《Unity3D 中文序列教程-Tookit2D》[4课时]
[000056]《Unity3D (SIKI案例公开课)飞机大战录制课程》[7课时]
[000057]《Unity3D (SIKI老师)通过示例讲解C#》[12课时]
[000059]《Unity3D AboutCG 初级视频教程》[37课时]
[000058]《Unity3D AboutCG Playmaker 入门到精通》[8课时]
[000060]《Unity3D ARGP网络游戏实战全套》[24课时]
[000061]《Unity3D C#实例讲解打砖块游戏》[8课时]
[000062]《Unity3D C#语言基础课程》[31课时]
[000063]《Unity3D Mecanim动画系统》[14课时]
[000064]《Unity3D Student 初学者系列教程》[15课时]
[000065]《Unity3D Student 基础系列视频教程》[10课时]
[000066]《Unity3D Swing Copters游戏制作教程》[12课时]
[000067]《Unity3D 北京某培训机构 视频课程》[26课时]
[000068]《Unity3D 插件之NGUI完整开发课程》[41课时]
[000069]《Unity3D 传智播客公开课 视频教程》[9课时]
[000070]《Unity3D 大型RPG视频教程》[30课时]
[000071]《Unity3D 动画系统 视频教程》[1课时]
[000072]《Unity3D 龚老师 大炮射击飞碟 系列视频教程》[8课时]
[000073]《Unity3D 龚老师 屠龙战机 视频教程》[15课时]
[000074]《Unity3D 龚老师 小鱼战士 视频教程》[5课时]
[000075]《Unity3D 官网标准教程(英文)》[11课时]
[000076]《Unity3D 光影贴图 视频教程》[4课时]
[000077]《Unity3D 基础入门视频教程》[15课时]
[000078]《Unity3D 基础入门之Roll-a-Ball滚动小球》[16课时]
[000079]《Unity3D 基础入门之进入Unity的世界》[14课时]
[000080]《Unity3D 角色动画系统 视频教程》[52课时]
[000081]《unity3D 开发 《2048》游戏案例公开课录制课程》[11课时]
[000082]《Unity3D 内核架构深度剖析》[1课时]
[000083]《Unity3D 跑酷游戏逃离地球实例教程》[31课时]
[000084]《Unity3D 使用DF开发应用程序基础-计算器案例》[2课时]
[000085]《Unity3D 使用Unity开发FlappyBird案例》[4课时]
[000086]《Unity3D 特效系统学习视频课程》[7课时]
[000087]《Unity3D 围住神经猫 视频课程》[12课时]
[000088]《Unity3D 游戏插件 Daikon Forge GUI 视频教程》[47课时]
[000089]《Unity3D 筑梦天下 高级应用 视频教程》[5课时]
[000090]《Unity3D 脚本语言学习之C#语言》[9课时]
[000091]《Unity3D 基础入门之进入Unity的世界》[15课时]
[000092]《Unity3D 脚本语言学习之Javascript语言》[59课时]
[000093]《Unity3D 脚本语言学习之Python语言》[61课时]
[000094]《Unity3D 知识体系入门课程》[18课时]
[000095]《Unity3D RPG游戏黑暗之光案例视频教程》[110课时]
[000096]《Unity3D 动作游戏全攻略视频教程》[29课时]
[000097]《Unity3D 经典入门课程基础打砖块实例教程》[7课时]
[000098]《Unity3D 炉石传说制作全套视频教程》[24课时]
[000099]《Unity3D 屠龙战机全套制作视频教程》[15课时]
[000100]《Unity3D 游戏蛮牛 编程系列教程》[第五季][61课时]
[000101]《Unity3D 游戏蛮牛 公开课》[第一季][108课时]
[000102]《Unity3D 游戏蛮牛 2D进阶公开课》[第二季][37课时]
[000103]《Unity3D 游戏蛮牛 游戏开发中高级美术》[第三季][26课时]
[000104]《Unity3D 游戏蛮牛 插件系列教程》[第四季][83课时]
[000105]《Unity3D 游戏蛮牛 手机游戏实战类完整实例》[第六季][63课时]
[000106]《Unity3D 游戏蛮牛 虚拟现实系列实例》[第七季][49课时]
[000107]《Unity3D 游戏蛮牛 游戏开发中高级美术》[第八季][40课时]
[000108]《Unity3D CS之战局域网射击游戏案例视频教程》[28课时]
[000110]《Unity3D 黑暗奇侠RPG剧情类游戏案例视频教程》[55课时]

链接网址:http://www.baojihua.cn/?k=Unity
2019-09-11 18:23:01 q764424567 阅读数 1172
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

一、前言

我们的太空射击游戏受到古老的街机游戏的启发
我们将利用物理等各种不同的Unity特征(包括刚体和碰撞器)、动画(Mecanim),脚本(C#),预制体,阴影和 Sprite Editor。

效果图:

在这里插入图片描述

二、源码

UI资源和源代码请搜索QQ群:1040082875下载

三、正文

版本

Unity 5.0.1f1

1.相机调整

首先,我们将选择主照相机,将Background颜色改为黑色,并将Size调整为10:

在这里插入图片描述

2.创建背景

空间纹理
我们的背景应该包括一个恒星的图像,滚动向下滚动,所以它似乎是在太空飞行的球员。我们首先画一个256 x 512PX空间背景在我们的绘图工具中的选择:
在这里插入图片描述
注意:右击图像,选择另存为。并将其保存在项目的Assets/Sprites文件夹。

导入设置:
在这里插入图片描述
注意:通常我们会将2D游戏的纹理类型设置为Sprite。但是使用UV贴图滚动纹理只适用于Texture,不适用于Sprite。Sprite是完美的像素,但滚动它们需要一个着色器,这对本教程来说太复杂了。

3.添加Quad

好吧,让我们把背景添加到我们的游戏中。我们会选择GameObject->3D Object->Quad给我们的游戏添加一个四边形:
在这里插入图片描述
注意:我们使用Quad在2D游戏中,因为Texture (而不是Sprite)可以添加到它。

现在我们来看一下Inspector,比例尺它的高宽比和我们的背景纹理是一样的:
在这里插入图片描述

我们也会将它重命名为Background:
Quad Renamed

并移除Mesh Collider因为我们不需要它(这是3D游戏):
Remove Mesh Collider
之后,我们可以从项目区看到Background:
Quad with Default Material

如果我们按下Play然后我们可以看到我们的空间背景,它仍然非常黑暗:
Dark Background

4.Unlit Shader

背景是黑暗的,因为它当前使用Standard只有当场景中有灯光时,着色器才会使事情变得明亮。
我们不会使用任何类型的灯光或阴影,所以让我们选择Unlit>Texture着色器:
Background with Unlit Texture Shader

如果我们按下Play再一次,我们可以在不太暗的情况下看到背景恒星:
Unlit Background ingame

5.UV映射

如果我们仔细观察一下阴影的特性,我们就可以看到我们的紫外线了。Tiling和Offset在此:
Background UV Properties
随意使用这些属性,看看它们如何改变背景。
Tiling会通过改变偏移量会改变纹理的位置。
如果我们设置Y偏移量对于像这样的值0.1, 0.2, 0.3等等,我们已经可以看到滚动发生了。

当然,为了达到滚动效果,我们不希望每秒手动更改偏移量60次。
我们会写一个Script处理好了。
让我们点击添加组件按钮,然后选择新脚本,命名为UVScroll.cs:
在这里插入图片描述
让我们创建一个新的Scripts文件夹并将脚本移动到其中:
UVScroll Script in Project Area

现在,我们可以双击脚本以便打开它:

using UnityEngine;
using System.Collections;

public class UVScroll : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

我们不需要Start或者Update函数,让我们移除它们。
修改UV映射在LateUpdate函数。
我们还将添加一个公共变量,让我们可以在检查器中修改滚动速度:

using UnityEngine;
using System.Collections;

public class UVScroll : MonoBehaviour {
    public Vector2 speed;

    void LateUpdate() {
        GetComponent<Renderer>().material.mainTextureOffset = speed * Time.time;
    }
}

注意:虽然看起来很简单,但是这里有很多事情发生在幕后。首先,我们使用了Vector2为了我们speed变量,以确保我们可以修改x(横向)和y(垂直)速度。我们使用GetComponent()访问renderer 组件。使用GetComponent().Matter确保UV偏移量不会被永久修改,就像手工修改它时的情况一样。相反,通过使用GetComponent().Matter统一创建材料的运行时脚本,并在游戏停止后删除它。此外,我们使用mainTextureOffset属性修改主纹理的UV偏移量。然后我们用Time.time实现滚动效果,请执行以下操作:Time.time是游戏开始后的时间。既然这段时间总是平稳地增长,我们不妨把它用于滚动。而且我们把时间乘以速度让它慢下来或者让它变快。因为我们速度变量是Vector2,在将它与之相乘后,它仍将是一个Time.Time…所以最后我们得到了一个新的Vector2将用于偏移两变化.

让我们保存脚本,现在我们可以修改速度了。
我们将设置y速度(用于垂直滚动)以我们所希望的速度离开
x速度(水平滚动)在0
因此,它根本不水平滚动:
UV Scroll in Inspector with Speed

6.滚动空间纹理

如果我们按下Play然后我们可以看到我们的背景向下滚动,就像我们在太空中飞行一样:
在这里插入图片描述

这个效果很好,但是我们会更进一步改善视差滚动,给它增加更多的深度。

7.视差滚动

我们将实现最简单形式的视差滚动,简单地覆盖两个背景纹理,并以不同的速度滚动他们。顶部的滚动速度总是快于底部的滚动。就像我们在太空中飞行一样,离我们很近的恒星也会飞过来。
滚动条比那些真的很远的星星走得更快。

让我们画另一个纹理,它大部分是透明的,里面有几颗白色的星星:
在这里插入图片描述
注意:右击图像,选择另存为。并将其保存在项目的Assets/Sprites文件夹。

导入设置
在这里插入图片描述
新建一个Quad作为Background的子物体:
在这里插入图片描述
将新的Quad重命名为Stars。Scale设置为(1,1,1):
在这里插入图片描述
注意:我们可以将scale设置为(1, 1, 1)因为父GameObject已经有一个坐标为为(8, 16, 1)。因为这些恒星是它的子对象,它们会自动地被这个比例放大。因此,我们的恒星已经有了与恒星纹理相同的长径比。

我们还将删除Mesh Collider:
在这里插入图片描述
我们接着改变stars的纹理,我们将选择Unlit->Transparent因为我们大部分的纹理都是透明的:
在这里插入图片描述
我们希望星星比背景更快地向下滚动,所以让我们选择
Add Component->Scripts->UVScroll然后设置Y速度到0.06:
在这里插入图片描述
如果我们按下Play然后我们可以看到一些美丽的视差滚动:
在这里插入图片描述
注意:视差滚动是2D游戏开发中最令人佩服的视觉效果之一。它所需要的只是两个纹理,以不同的速度滚动。

8.边界

边界碰撞器
我们将增加4个边框,以确保船只不能飞出它。
我们将添加四个碰撞器。然后我们将修改每个碰撞器,
使其中一个在左边,一个在右边,一个在顶部,另一个在底部:
在这里插入图片描述
下面是它在场景:
在这里插入图片描述
边界脚本
我们要确保子弹和敌舰在他们到达任何边界时立即摧毁他们。

让我们添加一个新脚本,名字叫做Border.cs,双击打开,删除Stat和Update函数,添加OnCollisionEnter2D函数,以便在与边界发生冲突时得到通知:

using UnityEngine;
using System.Collections;

public class Border : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D coll) {
        // Do Stuff..
    }
}

现在,每当有东西与边界相撞时,我们都想摧毁它,除非它是玩家的飞船:

void OnCollisionEnter2D(Collision2D coll) {
    if (coll.gameObject.name != "PlayerShip")
        Destroy(coll.gameObject);
}

我们要做的就是保持现场整洁。现在,每当一艘船或一颗子弹到达界面外,它们就会自动被摧毁。

9.玩家飞船

飞船图片
让我们为玩家创造一艘漂亮的太空船。
我们将使用像Paint.NET这样的工具画一个32 x 32px飞船。
我们还将创建两个动画,一个空闲和一个飞行动画。(当用户按上箭头键时,会播放飞行动画).

我们需要一个96x64px图像保存我们所有的动画。第一行将保存Fly动画,第2行将保存空闲动画:
在这里插入图片描述
注意:右击图像,选择另存为。并将其保存在项目的Assets/Sprites文件夹。

导入设置
在这里插入图片描述
设置Sprite Mode为Multiple,然后点击Sprite Editor:
在这里插入图片描述
我们会切片图像为32x32px格网:
在这里插入图片描述
点击Apple,然后关闭Sprite Editor
在这里插入图片描述

10.制作飞船动画

好的,现在我们有3片fly动画和2用于idle动画。选择前3片,然后将其从项目区拖入到场景:
在这里插入图片描述
保存到ShipAnimation文件夹,命名为fly.anim.

对于最后两个切片,我们将重复相同的过程,并将其保存为idle.anim.

如果我们按下Play然后我们就可以看到我们刚才拖到场景中的两个动画:
在这里插入图片描述
清理
在场景中删除ship_3,然后在项目中删除ship_3动画状态机:
在这里插入图片描述
在这里插入图片描述

11.飞船动画状态机

让我们双击ship_0在我们的ShipAnimation文件夹,这样我们就可以看到Animator窗口:
在这里插入图片描述
我们添加一个bool类型参数Flying,来判断飞船是否在飞行:

在这里插入图片描述
添加idle状态
这个fly状态已经在动画器中,所以让我们添加idle状态,只需拖动idle.anim文件从ShipAnimation文件夹进入Animator:
在这里插入图片描述
然后将两个状态链接起来,我们将选择fly状态,然后右键单击它,选择Make Transition然后拖动Make Transition选择idle状态:
在这里插入图片描述
添加白色箭头,禁用Has Exit Time,然后添加切换条件Flying = false:
在这里插入图片描述
注意:我们希望从fly到idle的时候,Flying是false

之后,我们创建了另一个Make Transition从…idle到fly:
在这里插入图片描述
点击白色箭头,设置条件为Flying=true:
在这里插入图片描述

12.飞船移动

玩家应该能够通过按箭头键来控制飞船。但是不应该能穿过流星,敌舰或其他我们可能在太空遇到的东西。

为了使它成为物理世界的一部分,我们需要在我们的飞船上增加一个碰撞器和刚体。
在这里插入图片描述
在这里插入图片描述
注意:我们将Gravity Scale设为0,因为在游戏中不存在重力。我们还启用了Fixed Angle以确保物理引擎在发生碰撞时不会试图旋转飞船。

好了,既然飞船的无弹力都准备好了,接着就要去实现移动了,我们应该使用刚体组件的移动,我们可以使用AddForce和velocity

velocity 是运动方向 * 速度。以下图片显示了不同的运动方向:
在这里插入图片描述
我们新建一个脚本Move.cs,双击打开,然后删除Stat和Update函数,添加一个speed变量:

using UnityEngine;
using System.Collections;

public class Move : MonoBehaviour {
    // Ship Speed
    public float speed = 5;
}

添加FixedUpdate函数:

using UnityEngine;
using System.Collections;

public class Move : MonoBehaviour {
    // Ship Speed
    public float speed = 5;

    void FixedUpdate() {

    }
}

接着就检查用户的输入,比如WSAD,或者左右上下箭头。
我们可以使用GetAxis函数,来自动检查水平和垂直轴的输入,然后返回-1 (左)和1 (右)。或0如果什么都没有按的话:

void FixedUpdate() {
    // Get Input from Arrow Keys, WSAD, Gamepads, ...
    float h = Input.GetAxisRaw("Horizontal");
    float v = Input.GetAxisRaw("Vertical");
}

现在我们可以用我们的h和v值以创建dir用speed然后让它成为刚体的velocity:

void FixedUpdate() {
    // Get Input from Arrow Keys, WSAD, Gamepads, ...
    float h = Input.GetAxisRaw("Horizontal");
    float v = Input.GetAxisRaw("Vertical");

    // Set the Rigidbody's Velocity
    Vector2 dir = new Vector2(h, v);
    GetComponent<Rigidbody2D>().velocity = dir.normalized * speed;
}

注意:我们使用了normalized方向,以确保它的长度总是准确的。这是必要的,以防止船太快地移动到对角线方向(例如,当向上和右箭头键同时按下)。这个问题是基于这样一个数学事实:(1, 0)有长度1,但是向量(1, 1)实际上有长度1.41。我们还把方向乘以速度让它变得更长。这就是让飞船移动得更快的原因。

运动本身已经完成,但我们仍然必须设置动画状态机的Flying参数,以使动画能够正确地查看。
这很容易,我们所要做的就是访问Animator组件,然后使用其SetBool函数将我们的参数设置为true或者false
取决于垂直方向(Y)方向:

void FixedUpdate() {
    // Get Input from Arrow Keys, WSAD, Gamepads, ...
    float h = Input.GetAxisRaw("Horizontal");
    float v = Input.GetAxisRaw("Vertical");

    // Set the Rigidbody's Velocity
    Vector2 dir = new Vector2(h, v);
    GetComponent<Rigidbody2D>().velocity = dir.normalized * speed;

    // Set Animation Parameter
    GetComponent<Animator>().SetBool("Flying", (v > 0));
}

注:表达式(v>0)结果为bool值。如果v大于0它是true不然的话flase。

如果我们按下Play然后我们可以用箭头键移动飞船:
在这里插入图片描述

13.发射子弹

玩家应该能够用空格键发射子弹。让我们创建一个新的C#脚本来实施射击。
新建脚本FirePlayer.cs,双击打开,然后Stat函数,添加一个public的GameObject对象:

using UnityEngine;
using System.Collections;

public class FirePlayer : MonoBehaviour {
    // Bullet Prefab
    public GameObject bullet;

    // Update is called once per frame
    void Update () {

    }
}

按空格生成子弹:

using UnityEngine;
using System.Collections;

public class FirePlayer : MonoBehaviour {
    // Bullet Prefab
    public GameObject bullet;

    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown(KeyCode.Space))
            Instantiate(bullet,
                        transform.position,
                        Quaternion.identity);
    }
}

注意:transform.position是当前的位置和Quaternion.identity是默认的旋转。

我们希望确保玩家自己的子弹不会与玩家的飞船相撞:

// Update is called once per frame
void Update () {
    if (Input.GetKeyDown(KeyCode.Space)) {
        // Spawn the Bullet
        GameObject g = (GameObject) Instantiate(bullet,
                                                transform.position,
                                                Quaternion.identity);
        // Ignore Bullet<->Player collisions
        Physics2D.IgnoreCollision(g.GetComponent<Collider2D>(),
                                  transform.parent.GetComponent<Collider2D>());
    }
}

注意:使用transform.parent(在层次结构中引用GameObject的父级)以后会用到

现在,如果我们将脚本添加到游戏中,然后按空格键,那么子弹就会被实例化在飞船的内部,这看起来很奇怪。为了防止这种情况发生,我们将创建两个BulletSpawn略高于船的位置。

让我们创建两个空对象,并且设置PlayerShip为父对象,命名为BulletSpawnLeft和BulletSpawnRight:
在这里插入图片描述
BulletSpawnLeft设置到略高于船左翼的位置:
在这里插入图片描述
BulletSpawnRight设置到略高于船右翼的位置:
在这里插入图片描述
我们不能真正看到两个生成点在场景中的位置,因为它们只是空的游戏对象。你可以给他们每个人一个Gizmo然后就可以看到他们在场景中的位置:
在这里插入图片描述
注意:Gizmo只是一个视觉助手,它只显示在场景中,而不是在最后的游戏中。

以下是与Gizmo一起出现的两个生成位置:
在这里插入图片描述
然后我们给飞船添加组件FirePlayer.cs:
在这里插入图片描述
这样就会对按空格键做出反应。我们只需要创建子弹,这样两个生成点就可以发射它。

飞船Tag
我们需要一种方法来确定某个游戏对象是否是一艘飞船。现在只有PlayerShip在我们的场景中,我们只需检查一下名字。但一旦有不同名称的多艘船,我们就需要一个更好的解决方案。
在这里插入图片描述
让我们选择加上标签…。从标记列表中添加一个Ship标签:
在这里插入图片描述
之后,我们可以选择PlayerShip然后再分配Ship贴在上面:
在这里插入图片描述
注意:我们可以在脚本里使用gameObject.tag

14.制作子弹

子弹纹理
让我们创造一个子弹纹理,这样飞船就可以拍摄了。我们将使用16 x 16PX图像:
在这里插入图片描述
注意:右击图像,选择另存为。并将其保存在项目的Assets/Sprites文件夹。

导入设置
在这里插入图片描述
拖入到场景中:
在这里插入图片描述

15.子弹物理

添加碰撞器和刚体
在这里插入图片描述

16.让子弹飞

接下来,我们会让子弹飞向某个方向。如果我们再想一想,玩家的子弹,敌人的子弹,以及敌人的飞船本身,在默认情况下都必须飞向某个特定的方向。因此,让我们为每个脚本创建一个脚本。

新建脚本ContinuousVelocity.cs,双击打开,删除Start函数和Update函数,添加FixedUpdate函数:

using UnityEngine;
using System.Collections;

public class ContinuousVelocity : MonoBehaviour {
    // The Velocity
    public Vector2 velocity;

    void FixedUpdate() {
        GetComponent<Rigidbody2D>().velocity = velocity;
    }
}

注:从理论上讲,只要将速度设为一次就足够了。然而,我们要为飞船与其他船只相撞的情况做准备。要保证船在碰撞后始终保持运动,唯一的办法就是一次又一次地设定速度。

我们还将指定一个速度,使它飞得相当快:
在这里插入图片描述

17.子弹造成伤害

新建脚本BulletDamage.cs,双击打开,删除Stat和Update函数,添加OnCollisionEnter2D函数:

using UnityEngine;
using System.Collections;

public class BulletDamage : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D coll) {
        // Do Stuff...
    }
}

在这里,我们可以检查子弹撞上的是否是一艘船,在这种情况下,我们可以摧毁它:

void OnCollisionEnter2D(Collision2D coll) {
    // Collided with a Ship? Then destroy it.
    if (coll.gameObject.tag == "Ship")
        Destroy(coll.gameObject);
}

注意:我们将给我们所有的船贴上标签,所以我们可以在这里检查,不用担心。我们用Destroy函数从场景中删除游戏对象。

我们不希望子弹与某物相撞后留在现场,所以让我们销毁它:

using UnityEngine;
using System.Collections;

public class BulletDamage : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D coll) {
        // Collided with a Ship? Then destroy it.
        if (coll.gameObject.tag == "Ship")
            Destroy(coll.gameObject);

        // Destroy Bullet in any case
        Destroy(gameObject);
    }
}

18.子弹预制体

我们不希望子弹一直在场景中,我们只想在玩家真正开火的时候拥有它。

创建预制体,将子弹从Hierarchy中拖到我们的项目区Prefab文件夹中的重命名为BulletPlayer:
在这里插入图片描述
现在子弹被保存在我们的项目区我们可以随时把它加载到游戏里。
让我们从Hierarchy删除子弹因为我们不需要它从一开始就在那里。

玩家发射子弹
创建了子弹后,我们现在可以使用BulletPlayer预制件让飞船开枪。

让我们选择PlayerShip对象的两个子对象BulletSpawn。然后拖动BulletPlayer从项目区进入FirePlayer脚本子弹插槽:
在这里插入图片描述
如果我们按下Play然后我们可以在按空格键上发射两颗子弹:
在这里插入图片描述

19.敌人的子弹

我们将为敌舰再制造一颗子弹。这一次,它将是一个黄色Sprite:
在这里插入图片描述
注意:右击图像,选择另存为。并将其保存在项目的Assets/Sprites文件夹。

现在,我们可以重复我们用于红色子弹的完全相同的工作流程。然后,我们将创建一个BulletEnemy预制体并设定速度向下飞行。

最后的结果如下:
在这里插入图片描述

20.敌人

创建纹理
让我们在游戏中加入一些敌人。我们首先画一个32 x 32 Px敌舰形象:
在这里插入图片描述
注意:右击图像,选择另存为。并将其保存在项目的Assets/Sprites文件夹。

导入设置
在这里插入图片描述
创建游戏对象

现在我们可以把敌人Sprites从项目区拖入到场景来创建一个游戏对象。

添加碰撞器和刚体
选中敌人然后添加组件:
Circle Collider 2D
在这里插入图片描述
在这里插入图片描述
敌人运动
选中敌人,然后添加组件Continuous Velocity.cs,然后设定一个较小的下行速度:
在这里插入图片描述
敌人Tag
让我们把我们的敌舰分类,就像我们对待玩家的飞船一样。我们将Tag设置为Ship然后子弹就能摧毁它:
在这里插入图片描述
发射子弹
就像我们对玩家飞船所做的一样,我们也会在敌人的前面设一个子弹生成点,重命名为BulletSpawn:

在这里插入图片描述
我们将把点定位在船底。也可以指定一个Gizmo以便于识别:
在这里插入图片描述
新建一个脚本FireEnemy.cs,双击打开,删除Update函数,添加两个公有变量,一个用于子弹预制件,一个用于射击间隔:

using UnityEngine;
using System.Collections;

public class FireEnemy : MonoBehaviour {
    // The Bullet Prefab
    public GameObject bullet;

    // The firing Interval
    public float interval = 2;

    // Use this for initialization
    void Start () {

    }
}

现在我们可以用Unity的InvokeRepeting函数每隔几秒钟实例化一个新的子弹:

using UnityEngine;
using System.Collections;

public class FireEnemy : MonoBehaviour {
    // The Bullet Prefab
    public GameObject bullet;

    // The firing Interval
    public float interval = 2;

    // Use this for initialization
    void Start () {
        // Call Fire every few seconds
        InvokeRepeating("Fire", interval, interval);
    }

    void Fire() {
        // Spawn the Bullet
        GameObject g = (GameObject)Instantiate(bullet,
                                               transform.position,
                                               Quaternion.identity);

        // Ignore Bullet<->Enemy Ship collisions
        Physics2D.IgnoreCollision(g.GetComponent<Collider2D>(),
                                  transform.parent.GetComponent<Collider2D>());
    }
}

保存脚本并查看Inspector,然后拖动BulletEnemy预置体到脚本中子弹插槽:
在这里插入图片描述
如果我们按下Play现在我们可以看到敌舰每隔几秒钟就发射一颗子弹:
在这里插入图片描述
敌人不必从一开始就出现在现场,相反,我们会在稍后进行。所以让我们把它重命名为EnemyShip,然后拖入到Prefabs文件夹:
在这里插入图片描述
让我们在Hierarchy中删除这个对象

21.生成敌人

让我们创建5个空游戏对象,命名为Spawner,然后设置Gizmo,我们将它们放到场景的顶端:

  • (-3, 7)
  • (-1.5, 7)
  • (0, 7)
  • (1.5, 7)
  • (3, 7)

下面是它在场景:
在这里插入图片描述
选中所有的Spawner,添加脚本Spawn.cs,双击打开:

using UnityEngine;
using System.Collections;

public class Spawn : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

我们已经知道如何实例化每隔几秒钟就生成一次:

using UnityEngine;
using System.Collections;

public class Spawn : MonoBehaviour {
    // The Ship
    public GameObject ship;

    // The Interval
    public float interval = 1;

    // Use this for initialization
    void Start () {
        InvokeRepeating("SpawnNext", interval, interval);
    }

    void SpawnNext () {
        Instantiate(ship, transform.position, Quaternion.identity);
    }
}

保存脚本后,我们可以将EnemyShip从项目区拖入到Ship插槽:
在这里插入图片描述
然后给每个Spawner设置一个不同的间隔Interval。

如果我们按下Play现在我们可以看到几艘敌舰在游戏的顶端生成:
在这里插入图片描述
现在我们就可以开始太空射击游戏了:
在这里插入图片描述

22.摘要

在本教程中,我们创建了一个天空射击游戏Unity版本的框架,我们学习各种技巧完成了这件事,现在该由读者来使游戏尽可能的有趣了。

可以实施各种改进,例如:

  • 爆炸
  • 更多敌舰
  • 菜单
  • 输赢的屏幕
  • 更多动画
  • 高分
  • 飞船升级
  • 不同关卡

博文 来自: niehanmin
没有更多推荐了,返回首页