Unity3D上路_01-2D太空射击游戏

Unity3D官网: http://unity3d.com
4.3.4     : http://netstorage.unity3d.com/unity/UnitySetup-4.3.4.exe
破解文件   : http://pan.baidu.com/s/1qWk9ZHi 
本篇博文资源: http://pan.baidu.com/s/1rOb1s

一。打开及创建

1.打开工程

1)打开工程

如果是初次打开,选择Open Other...
Unity3D上路_01-2D太空射击游戏_第1张图片

如果不是初次打开,FileOpenProject...Open Other...
Unity3D上路_01-2D太空射击游戏_第2张图片

如果安装Unity时选择了SimpleProject,可以打开/Documents\Unity Projects\4-0_AngryBots工程。

2)打开关卡(场景)

可以直接在Project面板的Assets里找到AngryBots.unity文件打开
Unity3D上路_01-2D太空射击游戏_第3张图片

或者从FileOpenScene,找到工程目录的Assets目录里,打开AngryBots.unity文件
Unity3D上路_01-2D太空射击游戏_第4张图片

2.Scene面板操作

Unity3D上路_01-2D太空射击游戏_第5张图片

视图操作:

    按下鼠标中键:            平移视图
    Alt+ 左键:                 旋转视图
    Alt+ 右键(或滚轮):    推拉视图

3.常用面板

Unity3D上路_01-2D太空射击游戏_第6张图片

4.新建工程

1)创建新工程

FileNewProjectCreateNewProject
Unity3D上路_01-2D太空射击游戏_第7张图片

2)新建脚本文件

Unity3D上路_01-2D太空射击游戏_第8张图片

3)在MonoDevelop中编辑代码

using UnityEngine;
using System.Collections;
public class HelloWorld : MonoBehaviour {
    /** 在屏幕显示 **/
    void OnGUI() {
        // 标签文本尺寸
        GUI.skin.label.fontSize = 100;
        // 标签(显示区域(x,y,w宽,h高),“显示文本”)
        GUI.Label(new Rect(10, 10, Screen.width, Screen.height), "HelloWorld!!!");
    }
}


4)给主相机添加指令

Assets中点住脚本文件,拖放到Hierarchy中的“MainCamera”主相机。
Unity3D上路_01-2D太空射击游戏_第9张图片

或者,先在Hierarchy里选中“MainCamera”主相机,然后从“Component”菜单的“Scripts”里选中脚本。
Unity3D上路_01-2D太空射击游戏_第10张图片

当主相机处于选中状态,从“Inspector”面板中可用看到用于相机的指令文件。
Unity3D上路_01-2D太空射击游戏_第11张图片

5.测试

Unity3D上路_01-2D太空射击游戏_第12张图片

6.保存关卡-HelloWorld

1)保存当前场景(关卡)文件

FileSave Scene AS
Unity3D上路_01-2D太空射击游戏_第13张图片

2)添加场景为关卡

FileBuild Settings... 
然后从Project下的Assets面板,拖动HelloWorld.unity文件到弹出的BuildSettings窗口中,
Unity3D上路_01-2D太空射击游戏_第14张图片

或者点击BuildSettings窗口里的AddCurrent按钮选择场景文件。

3)配置工程(游戏)发布信息

Unity3D上路_01-2D太空射击游戏_第15张图片

4.发布游戏

Unity3D上路_01-2D太空射击游戏_第16张图片

5.代码编辑器配置

MonoDevelop可能用起来不顺手,可用安装VS使之默认作为Unity的代码编辑器。
VS主程序:/MicrosoftVisualStudio12.0\Common7\IDE\devenv.exe
Unity3D上路_01-2D太空射击游戏_第17张图片

二。创建3D对象-游戏体

1.为工程添加资源文件

1)方法1

直接打开工程目录下的Assets文件夹。或在Assets面板的留空出右键,Show in Explorer,打开Assets目录,
Unity3D上路_01-2D太空射击游戏_第18张图片

然后将资源文件放入即可。

2)方法2

或者右键Assets面板,选择“Import New Asset...”,导入资源文件夹,
Unity3D上路_01-2D太空射击游戏_第19张图片

2.新建关卡

FileNew Scene,然后保存为Level01.unity
Unity3D上路_01-2D太空射击游戏_第20张图片

3.创建游戏角色(3D对象)

GameObjectCreate OtherPlane
Unity3D上路_01-2D太空射击游戏_第21张图片

4.创建材质

Unity3D上路_01-2D太空射击游戏_第22张图片

5.为材质选择贴图

Unity3D上路_01-2D太空射击游戏_第23张图片

根据需要,修改Shader类型。这里改为 TransparentCutoutDiffuse
Unity3D上路_01-2D太空射击游戏_第24张图片

6.3D对象应用材质

1)方法1

Unity3D上路_01-2D太空射击游戏_第25张图片

2)方法2

这一步可以直接从Assets中拖动材质球到Scene中的Plane上。
Unity3D上路_01-2D太空射击游戏_第26张图片

3)方法3

或者使用这种方法,
Unity3D上路_01-2D太空射击游戏_第27张图片

7.创建其它游戏体

1)创建Plane,命名为Plane_Star
2)创建材质球,
3)关联。
Unity3D上路_01-2D太空射击游戏_第28张图片

三。创建UV动画

1.为对象添加动画

1)选择游戏体创建Animation

首先在SceneHierarchy中选中Plane_Star,然后WindowAnimation
Unity3D上路_01-2D太空射击游戏_第29张图片

2)创建新剪辑

然后,在新打开的Animation面板上,左键点击播放按钮下的条状区域,创建剪辑,
Unity3D上路_01-2D太空射击游戏_第30张图片

Assets中生成一个.anim文件外,还生成一个.controller文件,
Unity3D上路_01-2D太空射击游戏_第31张图片

2.添加动画元素

Unity3D上路_01-2D太空射击游戏_第32张图片

Unity3D上路_01-2D太空射击游戏_第33张图片

3.添加关键帧

本例将z数值修改为0.5即可,
Unity3D上路_01-2D太空射击游戏_第34张图片

四。摄像机

1.环境光

EditRenderSetting
Inspector面板,修改Ambient Light
Unity3D上路_01-2D太空射击游戏_第35张图片

2.配置相机视图

Scene中修改视图到合适角度,点击Hierarchy中的主相机,GameObjectAlign With View
或者从属性面板手动修改主相机的参数,
Unity3D上路_01-2D太空射击游戏_第36张图片

3.创建点光源

GameObjectCreate OtherPoint Light。然后再Inspector面板配置参数,
Unity3D上路_01-2D太空射击游戏_第37张图片

五。加载模型为3D对象

1.添加3D模型为游戏角色(玩家飞机)

Unity3D上路_01-2D太空射击游戏_第38张图片

修改属性,以和Plane_Star_Animation动画匹配,
Unity3D上路_01-2D太空射击游戏_第39张图片

2.为飞机添加脚本

1)创建脚本文件

using UnityEngine;
using System.Collections;

[AddComponentMenu("MyGame/Player")]
// 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名
public class Player : MonoBehaviour {

    /**
     * 构造函数不可用于初始化
     **/

    // 基速度
    public float m_speed = 1;	// public类型的变量可以在Inspector中配置

	// 每渲染一帧动画,即调用一次
	void Update () {
        float movev = 0;    // 垂直方向速度
        float moveh = 0;    // 水平方向速度

        // 向上箭头
        if (Input.GetKey(KeyCode.UpArrow)) {
            movev -= m_speed * Time.deltaTime;
        }

        /**
         * Input包装输入功能,包括键盘、鼠标、触控
         * Time.deltaTime表示每一帧被渲染的时刻,时长?
         **/

        // 向下箭头
        if (Input.GetKey(KeyCode.DownArrow)) {
            movev += m_speed * Time.deltaTime;
        }

        // 向左
        if (Input.GetKey(KeyCode.LeftArrow)) {
            moveh += m_speed * Time.deltaTime;
        }

        // 向右
        if (Input.GetKey(KeyCode.RightArrow)) {
            moveh -= m_speed * Time.deltaTime;
        }

        // this即Player
        this.transform.Translate(new Vector3(moveh, 0, movev));
        /**
         * 物理转换器
         * this.transform调用游戏体的Transform组件
         * Transform包装移动、旋转、缩放
         * Vector3(x, y, z)
         **/
	}
}


2)关联游戏体

选择飞机,ComponentMyGamePlayer

3.制作子弹

1)创建子弹游戏体

首先,将子弹的fbx文件拖入Hierarchy中,创建一个3D场景对象-游戏角色-游戏体,
Unity3D上路_01-2D太空射击游戏_第40张图片

2)创建子弹控制脚本

然后在Assets中创建一个和子弹角色同名的脚本文件,
Unity3D上路_01-2D太空射击游戏_第41张图片

打开子弹脚本,编辑代码,

using UnityEngine;
using System.Collections;

[AddComponentMenu ("MyGame/Rocket") ]

/**
 * 子弹
 **/
public class Rocket : MonoBehaviour {

    public float m_speed = 10;      // 速度
    public float m_liveTime = 1;    // 生命
    public float m_power = 1.0f;    // 威力

	void Update () {
        m_liveTime -= Time.deltaTime;   // 没渲染一帧,生命值即减少一定时间
        if (m_liveTime <= 0)
        {
            Destroy(this.gameObject);   // 当生命值,销毁子弹对象
        }
        // 速度越来越慢
        this.transform.Translate(new Vector3(0, 0, - m_speed * Time.deltaTime));
	}
}


3)脚本关联对象

把子弹脚本文件关联到子弹游戏体-游戏对象上,
Unity3D上路_01-2D太空射击游戏_第42张图片

4)创建预制体-Prefab

需要重复使用的游戏体,应将其只作为Prefab
在Assets中右键创建一个Prefab,并修改为和子弹3D对象相同的名字,
Unity3D上路_01-2D太空射击游戏_第43张图片

5)子弹预制体

从Hierarchy中拖放子弹对象到Assets中的Prefab上,
Unity3D上路_01-2D太空射击游戏_第44张图片

从场景中删除自动添加的子弹,
Unity3D上路_01-2D太空射击游戏_第45张图片

6)修改飞机脚本

再修改飞机脚本

using UnityEngine;
using System.Collections;

[AddComponentMenu("MyGame/Player")]
// 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名
public class Player : MonoBehaviour {

    // 飞机基速度
    public float m_speed = 1;

    // 子弹控制器
    public Transform m_rocket;

    // 子弹速率
    public float m_rocketRate = 0;

	// 每渲染一帧动画,即调用一次
	void Update () {
        float moveh = 0;    // 水平方向速度
        float movev = 0;    // 垂直方向速度

        // 向上箭头
        if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime;  }
        // 向下箭头
        if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; }
        // 向左
        if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; }
        // 向右
        if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; }

        // 子弹速率虽渲染帧数的增加而降低
        m_rocketRate -= Time.deltaTime;

        // 空格,发射子弹
        if (m_rocketRate <= 0) {
            m_rocketRate = 0.1f;

            if (Input.GetKey(KeyCode.Space)) {
                // 不能用new方法创建对象,只能是Instantiate
                Instantiate(m_rocket, this.transform.position, this.transform.rotation);
            }
        }

        this.transform.Translate(new Vector3(moveh, 0, movev));
	}
}


7)关联飞机属性的子弹对象

Hierarchy中或从场景中选择飞机,然后切换到Inspector面板,在PlayerScript)下找到Rocket属性,从Assets中拖放子弹的Prefab体到这里,
Unity3D上路_01-2D太空射击游戏_第46张图片

最后,测试即可。
空格键发射子弹。

4.创建敌人

1)创建敌人游戏体

Assets中拖放敌人模型fbx文件到Hierarchy中,创建敌人游戏体。这时场景中也会默认添加敌人的游戏对象,
Unity3D上路_01-2D太空射击游戏_第47张图片

2)创建敌人控制脚本,并关联游戏体

Enemy.cs文件,

using UnityEngine;
using System.Collections;

/** 由电脑控制敌人 **/

[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour {

    // 速度
    public float m_speed = 1;

    // 旋转速度
    protected float m_rotSpeed = 60;

    // 变向间隔时间
    protected float m_timer = 1.5f;

    // 当前游戏体的控制器
    protected Transform m_transform;

    void Start() {
        m_transform = this.transform;
    }

    /** 每帧更新一次 **/
    void Update() {
        m_timer -= Time.deltaTime;
        if (m_timer <= 0) {
            m_timer = 3;	// 3秒旋转一次

            // 改变旋转方向
            m_rotSpeed = -m_rotSpeed;
        }

        // 旋转方向
        m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World);

        // 前进
        m_transform.Translate(new Vector3(m_speed * Time.deltaTime, 0, 0));
    }
}


3)创建敌人预制体Prefab

同创建子弹预制体的步骤:
Assets中右键创建Prefab-敌人预制体,并修改名称和敌人游戏体相同。然后从Hierarchy中拖动敌人游戏体到敌人预制体上,再把场景中的敌人3D对象删除即可。

4)在场景中添加更多敌人

首先从Assets中拖动敌人的Prefab预制体到场景中,然后选中敌人PrefabCtrl+D,多次复制,修改位置。
Unity3D上路_01-2D太空射击游戏_第48张图片

六。物体碰撞

1.给敌人添加碰撞体

首先在Scene-场景中选择一个敌人游戏体,然后ComponentPhysicsBox Collider
Unity3D上路_01-2D太空射击游戏_第49张图片

然后继续操作,打开Inspector面板,找到Box Collider模块,勾选Is Trigger
Unity3D上路_01-2D太空射击游戏_第50张图片

2.给敌人添加刚体

紧接上一步,已经添加碰撞体的敌人游戏体被选择,ComponentPhysicsRigidbody
Unity3D上路_01-2D太空射击游戏_第51张图片

然后,打开Inspector面板,找到Rigidbody模块。去除勾选Use Gravity,选中Is Kinematic
Unity3D上路_01-2D太空射击游戏_第52张图片

3.为其它敌人游戏体拷贝设置

继续上面的操作,在设置完毕的游戏体选中的状态下,返回Inspector面板顶部,点击Prefab条目的Apply按钮,
Unity3D上路_01-2D太空射击游戏_第53张图片

查看其它敌人游戏体,和第一个的属性是相同的,
Unity3D上路_01-2D太空射击游戏_第54张图片

上面3步可以直接在Assets中操作敌人的Prefab文件,这样就不用执行第3步的拷贝了,
Unity3D上路_01-2D太空射击游戏_第55张图片

4.为飞机和子弹添加碰撞体及刚体

Assets中选中敌人的Prefab文件。

然后ComponentPhysicsBox Collider
打开Inspector面板,找到Box Collider模块,勾选Is Trigger

ComponentPhysicsRigidbody
打开Inspector面板,找到Rigidbody模块。去除勾选Use Gravity,选中Is Kinematic

Hierarchy中选择飞机的游戏体,执行同样的操作。

5.为游戏角色创建标签tag

1)创建标签

首先,创建tagEditProject SettingTags and Layers
Unity3D上路_01-2D太空射击游戏_第56张图片

2)填写标签

自动打开属性面板。在Element*中填写标签,本例需要填写两个,“PlayerRocket”和“Enemy”,
Unity3D上路_01-2D太空射击游戏_第57张图片

3)为游戏体配置标签

然后为子弹和敌人游戏体添加标签。Enemytag是“Enemy”,Rockettag是“PlayerRocket”,
Unity3D上路_01-2D太空射击游戏_第58张图片 

最后为飞机添加标签。Player这个标签是Unity预设的,
Unity3D上路_01-2D太空射击游戏_第59张图片

6.修改游戏体的控制脚本

1)敌人游戏体控制脚本

using UnityEngine;
using System.Collections;

/** 由电脑控制敌人 **/
[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour {
    // 速度
    public float m_speed = 1;
    // 旋转速度
    protected float m_rotSpeed = 60;
    // 变向间隔时间
    protected float m_timer = 1.5f;
    // 当前游戏体的控制器
    protected Transform m_transform;

    // 生命值
    public float m_life = 10;

    /** 物体发生碰撞时调用,继承自MonoBehaviour的函数。重写 **/
    void OnTriggerEnter(Collider other) {
        /**
            other:碰撞体。如果当前敌人对象碰撞的是 子弹 
         */
        if (other.tag.CompareTo("PlayerRocket") == 0) {
            // 当前当前碰撞体的标签,获取其所属游戏体
            Rocket rocket = other.GetComponent<Rocket>();
            // 获取到了
            if (rocket != null) {
                // 当前敌人的生命值递减
                m_life -= rocket.m_power;
                if (m_life <= 0) {
                    Destroy(this.gameObject);
                }
            }
        }
        /**  other:碰撞体。如果当前敌人对象碰撞的是 飞机  */
        else if (other.tag.CompareTo("Player") == 0) {
            // 当前敌人对象之间销毁
            m_life = 0;
            Destroy(this.gameObject);
        }
    } 

    void Start() { m_transform = this.transform; }

    /** 每帧更新一次 **/
    void Update() {
        m_timer -= Time.deltaTime;
        if (m_timer <= 0) {
            m_timer = 3;

            //改变旋转方向
            m_rotSpeed = -m_rotSpeed;
        }

        // 旋转方向
        m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World);
        // 前进
        m_transform.Translate(new Vector3(m_speed * Time.deltaTime, 0, 0));
    }
}


2)子弹游戏体控制脚本

using UnityEngine;
using System.Collections;
[AddComponentMenu ("MyGame/Rocket") ]

/**
 * 子弹
 **/
public class Rocket : MonoBehaviour {

    public float m_speed = 10;      // 速度
    public float m_liveTime = 1;    // 生命
    public float m_power = 1.0f;    // 威力

    /** 碰撞检测 other:与子弹发生碰撞的游戏体**/
    void OnTriggerEnter (Collider other) {
        // 如果发生碰撞的 不是 敌人
        if (other.tag.CompareTo("Enemy") != 0) {
            // 什么也不做,退出函数。
            return;
        }
        // 碰撞的是敌人,销毁 子弹自身
        Destroy(this.gameObject);
    } 

	void Update () {
        m_liveTime -= Time.deltaTime;   // 没渲染一帧,生命值即减少一定时间
        if (m_liveTime <= 0) {
            Destroy(this.gameObject);   // 当生命值,销毁子弹对象
        }
        // 速度越来越慢
        this.transform.Translate(new Vector3(0, 0, - m_speed * Time.deltaTime));
	}
}


3)飞机游戏体控制脚本

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/Player")]
/** 飞机 
 * 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名 **/
public class Player : MonoBehaviour {
    // 飞机基速度
    public float m_speed = 1;
    // 子弹控制器
    public Transform m_rocket;
    // 子弹速率
    public float m_rocketRate = 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);
            }
        }
    } 

	// 每渲染一帧动画,即调用一次
	void Update () {
        float moveh = 0;    // 水平方向速度
        float movev = 0;    // 垂直方向速度
        // 向上箭头
        if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime;  }
        // 向下箭头
        if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; }
        // 向左
        if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; }
        // 向右
        if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; }
        // 子弹速率虽渲染帧数的增加而降低
        m_rocketRate -= Time.deltaTime;
        if (m_rocketRate <= 0) {
            m_rocketRate = 0.1f;
            // 空格,发射子弹
            if (Input.GetKey(KeyCode.Space)) {
                // 不能用new方法创建对象,只能是Instantiate
                Instantiate(m_rocket, this.transform.position, this.transform.rotation);
            }
        }
        this.transform.Translate(new Vector3(moveh, 0, movev));
	}
}


7.拦截敌人的空游戏体-界限

1)创建一个空游戏体

2)创建tag标签bound

Unity3D上路_01-2D太空射击游戏_第60张图片

3)使用空游戏体创建Prefab-界限预制体

ProjectAssets目录创建Prefab,关联bound空游戏体。然后可以删除Hierarchy里的GameObject
为预制体添加 BoxCollider-盒子碰撞体 和 Rigidbody-刚体 属性,
Unity3D上路_01-2D太空射击游戏_第61张图片

4)将界限预制体放入Scene

配置合适的大小和位置。还要记得为预制体添加“bound”标签,
Unity3D上路_01-2D太空射击游戏_第62张图片

5)修改敌人游戏体控制脚本

using UnityEngine;
using System.Collections;

/** 由电脑控制敌人 **/
[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour {
    // 速度
    public float m_speed = 1;
    // 旋转速度
    protected float m_rotSpeed = 60;
    // 变向间隔时间
    protected float m_timer = 1.5f;
    // 当前游戏体的控制器
    protected Transform m_transform;

    // 生命值
    public float m_life = 10;

    /** 物体发生碰撞时调用,继承自MonoBehaviour的函数。重写 **/
    void OnTriggerEnter(Collider other) {
        /**
            other:碰撞体。如果当前敌人对象碰撞的是 子弹 
         */
        if (other.tag.CompareTo("PlayerRocket") == 0) {
            // 当前当前碰撞体的标签,获取其所属游戏体
            Rocket rocket = other.GetComponent<Rocket>();

            // 获取到了
            if (rocket != null) {
                // 当前敌人的生命值递减
                m_life -= rocket.m_power * 5;
                if (m_life <= 0) {
                    Destroy(this.gameObject);
                }
            }
        }
        /**  other:碰撞体。如果当前敌人对象碰撞的是 飞机  */
        else if (other.tag.CompareTo("Player") == 0) {
            // 当前敌人对象之间销毁
            m_life = 0;
            Destroy(this.gameObject);
        }
        /**  如果当前敌人对象碰撞的是 bound  */
        else if (other.tag.CompareTo("bound") == 0) {
            m_life = 0;
            Destroy(this.gameObject);
        } 
    }

    void Start() { m_transform = this.transform; }

    /** 每帧更新一次 **/
    void Update() {
        m_timer -= Time.deltaTime;
        if (m_timer <= 0) {
            m_timer = 3;

            //改变旋转方向
            m_rotSpeed = -m_rotSpeed;
        }

        // 旋转方向
        m_transform.Rotate(Vector3.up, m_rotSpeed * Time.deltaTime, Space.World);
        // 前进
        m_transform.Translate(new Vector3(m_speed * Time.deltaTime, 0, 0));
    }
}


8.Boss敌机

1)修改普通敌机控制脚本

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour {
    public float m_speed = 1;
    protected float m_rotSpeed = 60;
    protected float m_timer = 1.5f;
    protected Transform m_transform;
    public float m_life = 10;
    void OnTriggerEnter(Collider other) { 略 }
  void Start() { m_transform = this.transform; }
  
    /** 每帧更新一次 **/
    /** 供子类继承的方法
     * virtual 子类必须被重新的
     **/
    protected virtual void Update() { 略 }
}


2)新建Boss敌机控制脚本

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/SuperEnemy")]

/** 继承自Enemy **/
public class SuperEnemy : Enemy {

    /** 重写 父类中的virtual方法 **/
    protected override void Update() {
        /** 位移 
         * 继承自父类的属性 m_transform **/
        m_transform.Translate(new Vector3(0, 0, - m_speed * Time.deltaTime));
    }
}


3)创建敌机预制体

首先,在ProjectAssets目录新建一个Prefab,命名为SuperEnemy
然后,将Assets中的Boss敌人模型fbx文件拖放到Prefab预制体上,
接着,关联SuperEnemy.cs控制脚本到预制体上,
然后,为Boss敌人预制体添加盒子碰撞体、刚体属性并配置,
同时,修改Tag标签为“Enemy”,
拖放Boss敌机预制体到Scene中。
Unity3D上路_01-2D太空射击游戏_第63张图片

4)为Boss创建超级子弹-SuperRocket

首先,使用子弹模型创建超级子弹游戏体,
    从Assets中拖动子弹的fbx文件到Hierarchy

其次,使用游戏体创建预制体
    从Hierarchy中拖放子弹游戏体到Assets中的prefab上,并修改prefab文件的名称为SuperRocket
    创建好prefab文件后,删除Hierarchy中的子弹游戏体

再次,创建超级子弹使用的特殊材质球,
Unity3D上路_01-2D太空射击游戏_第64张图片

然后,修改超级子弹的材质,
    选中Hierarchy中的超级子弹,切换到到Inspector面板,打开MeshRenderer项目,展开Materials子项目,点击Element*条目后的圆心点,选中材质球,
    Unity3D上路_01-2D太空射击游戏_第65张图片

而后EditProjectSettingsTagsandLayers,添加“SuperRocket”标签,
    Unity3D上路_01-2D太空射击游戏_第66张图片

接着,创建SuperRocket.cs控制脚本,

  using UnityEngine;
  using System.Collections;
  
  [AddComponentMenu("MyGame/SuperRocket")]
  
  /** 继承自子弹 **/
  public class SuperRocket : Rocket {
  
      /** 重写碰撞检测方法 **/
      void OnTriggerEnter(Collider other) {
  
          // 如果发生碰撞的 不是 飞机
          if (other.tag.CompareTo("Player") != 0) {
              // 什么也不做,退出函数。
              return;
          }
          // 碰撞的是敌人,销毁 子弹自身
          Destroy(this.gameObject);
          Debug.Log("超级子弹碰玩家====---");
      }
  }

继而,为超级子弹预制体添加标签,添加盒子碰撞体、刚体属性,添加控制代码关联,
    Unity3D上路_01-2D太空射击游戏_第67张图片

继续,修改Boss敌机的控制代码,

  using UnityEngine;
  using System.Collections;
  [AddComponentMenu("MyGame/SuperEnemy")]
  /** 继承自Enemy **/
  public class SuperEnemy : Enemy {
      // 超级子弹
      public Transform m_rocket;
      // 发射时间间隔
      public float m_fireTimer = 2;
      // 射击目标
      protected Transform m_player;
      /** 初始化函数,在游戏开始时系统自动调用。
       * 当一个脚本实例被载入时Awake被调用。
       * Awake用于在游戏开始之前初始化变量或游戏状态。
       * 在脚本整个生命周期内它仅被调用一次
       * **/
      void Awake() {
          // 获取 玩家 对象
          GameObject obj = GameObject.FindGameObjectWithTag("Player");
          if (obj != null) {
              // 初始化自己的射击目标
              m_player = obj.transform;
          }
      } 
      /** 重写 父类中的virtual方法 **/
      protected override void Update() {
          // 发射速度越来越慢
          m_fireTimer -= Time.deltaTime;
          if (m_fireTimer <= 0) {
              m_fireTimer = 2;
              if (m_player != null) {
                  // 获取当前玩家的相对位置
                  Vector3 relativePos = m_transform.position - m_player.position;
                  // 创建实例(实例对象-子弹,当前Boss敌机位置,朝向(玩家的位置))
                  Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos));
              }
          } 
          /** 位移 
           * 继承自父类的属性 m_transform **/
          m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime * 0.5f));
          Debug.Log("Boss敌机来袭.............");
      }
  }

最后,关联Boss机的超级子弹属性,
    Unity3D上路_01-2D太空射击游戏_第68张图片

七。声音

1.使用unitypackage格式资源

1)导入Package

Project/Assets中右键,Import PackageCustomPackage....
Unity3D上路_01-2D太空射击游戏_第69张图片

2)选择unitypackage文件

Unity3D上路_01-2D太空射击游戏_第70张图片

3)筛选资源文件

Unity3D上路_01-2D太空射击游戏_第71张图片

导入的各种格式资源:
Unity3D上路_01-2D太空射击游戏_第72张图片

4)导出unitypackage文件

如果希望其他人或在其它项目方便使用自己的资源,可以右键Export Package...,导出为unitypackage文件:
Unity3D上路_01-2D太空射击游戏_第73张图片

2.为玩家飞机添加声音组件

Unity3D上路_01-2D太空射击游戏_第74张图片

3.修改玩家飞机控制脚本

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/Player")]
/** 飞机 
 * 这个类名,即场景中角色的名称,也就是Hierarchy中的对象名 **/
public class Player : MonoBehaviour {
    // 飞机基速度
    public float m_speed = 2;
    // 子弹控制器
    public Transform m_rocket;
    // 子弹速率
    public float m_rocketRate = 0;
    // 生命值
    public float m_life = 2;

    public Transform m_transform;

    // 声音
    public AudioClip m_shootClip;
    // 声音文件
    protected AudioSource m_audio;
    // 爆炸效果
    public Transform m_explosionFX;

    void Start() {
        m_transform = this.transform;
        m_audio = this.audio;
    }

    /** 碰撞函数 **/
    void OnTriggerEnter(Collider other) {
        // 如果和飞机发生碰撞的 不是自己发射的 子弹
        if (other.tag.CompareTo("PlayerRocket") != 0) {
            m_life -= 1;
            if (m_life <= 0) {

                // 实例化一个爆炸(实例对象,位置,四元素.身份)
                Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);

                Destroy(this.gameObject);
                Debug.Log("飞机坠毁 …… ……");
            }
        }
    }

    // 每渲染一帧动画,即调用一次
    void Update() {
        float moveh = 0;    // 水平方向速度
        float movev = 0;    // 垂直方向速度
        // 向上箭头
        if (Input.GetKey(KeyCode.UpArrow)) { movev -= m_speed * Time.deltaTime; }
        // 向下箭头
        if (Input.GetKey(KeyCode.DownArrow)) { movev += m_speed * Time.deltaTime; }
        // 向左
        if (Input.GetKey(KeyCode.LeftArrow)) { moveh += m_speed * Time.deltaTime; }
        // 向右
        if (Input.GetKey(KeyCode.RightArrow)) { moveh -= m_speed * Time.deltaTime; }
        // 子弹速率虽渲染帧数的增加而降低
        m_rocketRate -= Time.deltaTime;
        if (m_rocketRate <= 0) {
            m_rocketRate = 0.1f;
            // 空格,发射子弹
            if (Input.GetKey(KeyCode.Space)) {
                // 不能用new方法创建对象,只能是Instantiate
                Instantiate(m_rocket, this.transform.position, this.transform.rotation);

                // 播放声音
                m_audio.PlayOneShot(m_shootClip);
            }
        }
        m_transform.Translate(new Vector3(moveh, 0, movev));
    }
}


4.关联属性

Unity3D上路_01-2D太空射击游戏_第75张图片

还要检查Explosion.prefab文件的声音关联
Unity3D上路_01-2D太空射击游戏_第76张图片

5.为敌人和Boss添加声音

1)分别选择敌人和Boss敌机的prefab文件,ComponentAudioAudio Source

2)修改敌人的控制脚本,

  using UnityEngine;
  using System.Collections;
  [AddComponentMenu("MyGame/Enemy")]
  public class Enemy : MonoBehaviour {
      public float m_speed = 1;
      protected float m_rotSpeed = 60;
      protected float m_timer = 1.5f;
      protected Transform m_transform;
      public float m_life = 10;
  
      // 爆炸效果
      public Transform m_explosionFX; 
      // 声音
      public AudioClip m_shootClip; 
      // 声音文件
      protected AudioSource m_audio; 
  
      /** 物体发生碰撞时调用,继承自MonoBehaviour的函数。重写 **/
      void OnTriggerEnter(Collider other) {
          if (other.tag.CompareTo("PlayerRocket") == 0) {
              Rocket rocket = other.GetComponent<Rocket>();
              Debug.Log("PlayerRocket=========");
              if (rocket != null) {
                  m_life -= rocket.m_power * 5;
  
                  if (m_life <= 0) {
                      /** 实例化一个爆炸(实例对象,位置,四元素.身份) **/
                      Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); 
  
                      Destroy(this.gameObject);
                  }
              }
          }
          /**  other:碰撞体。如果当前敌人对象碰撞的是 飞机  */
          else if (other.tag.CompareTo("Player") == 0) {
              // 当前敌人对象之间销毁
              m_life = 0;
              /** 如果碰到了飞机,发射爆炸 **/
              Instantiate(m_explosionFX, m_transform.position, Quaternion.identity); 
              Destroy(this.gameObject);
              Debug.Log("敌人碰飞机====");
          }
          else if (other.tag.CompareTo("bound") == 0) { 略 }
      }
  
      void Start() {
          m_transform = this.transform;
          m_audio = this.audio; 
      }
      protected virtual void Update()  { 略 }
  }


3)修改Boss的控制脚本,

  using UnityEngine;
  using System.Collections;
  [AddComponentMenu("MyGame/SuperEnemy")]
  public class SuperEnemy : Enemy {
      public Transform m_rocket;
      public float m_fireTimer = 2;
      protected Transform m_player;
      void Awake() { 略 }
  
      protected override void Update() {
          m_fireTimer -= Time.deltaTime;
          if (m_fireTimer <= 0) {
              m_fireTimer = 2;
              if (m_player != null) {
                  Vector3 relativePos = m_transform.position - m_player.position;
  
                  Instantiate(m_rocket, m_transform.position, Quaternion.LookRotation(relativePos));
  
                  /*** 射击时播放声音 ***/
                  m_audio.PlayOneShot(m_shootClip); 
              }
          }
          m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime * 0.5f));
      }
  }


4)分别关联两种敌人的属性,
Unity3D上路_01-2D太空射击游戏_第77张图片

八。敌机的自动诞生

1.创建生产设备空游戏体

注意修改xyz属性,
Unity3D上路_01-2D太空射击游戏_第78张图片

2.生成设备控制脚本

using UnityEngine;
using System.Collections;

public class EnemySpawn : MonoBehaviour {

    // 敌机类型
    public Transform m_enemy;

    // 诞生时间间隔。速度:3秒生产一架
    protected float m_timer = 3;

    // 当前生产设备
    protected Transform m_transform;

	// 初始化生产设备
	void Start () {
        m_transform = this.transform;
	}
	
	// 更新游戏
	void Update () {
        // 间隔越来越短
        m_timer -= Time.deltaTime;

        // 重新配置生产敌机的速度
        if (m_timer <= 0) {
            m_timer = Random.value * 5.0f;  // 最大为5

            if (m_timer <= 3) {
                m_timer = 3;
            }

            // 创建敌机实例(敌机类型,敌机位置-当前生产设备的位置),相对于世界坐标或父坐标
            Instantiate(m_enemy, m_transform.position, Quaternion.identity);
        }
	}
}


3.关联生产设备的控制脚本和空游戏体

Assets中拖动脚本文件到Hierarchy中的空游戏体上,
Unity3D上路_01-2D太空射击游戏_第79张图片

4.创建生产设备预制体

右键AssetsCreate,创建2Prefab
Hierarchy中拖动空游戏体到预制体上,
最后删除空游戏体,
Unity3D上路_01-2D太空射击游戏_第80张图片

5.配置预制体属性

做完这一步,就可以将预制体拖放到Scene中测试了,
Unity3D上路_01-2D太空射击游戏_第81张图片

6.生产设备的显示

目前加入Scene中敌机生产设备默认是不显示的,不利于我们的设计制作。进行下面的操作可以在Scene中显现它们的位置,但最终发布的游戏以及测试中不会显示。

1)创建Gizmos资源包

Unity3D上路_01-2D太空射击游戏_第82张图片

2)添加显示图片

在新建的“gizmos”目录中放入一张图片,
Unity3D上路_01-2D太空射击游戏_第83张图片

3)修改生产设备控制脚本

using UnityEngine;
using System.Collections;
public class EnemySpawn : MonoBehaviour {
    public Transform m_enemy;
    protected float m_timer = 3;
    protected Transform m_transform;
	void Start () { 略 }
	void Update () { 略 }

    // 在Scene中显示图标
    void OnDrawGizmos() {
        Gizmos.DrawIcon(transform.position, "spawn.png", true);
    } 
}


九。游戏UI

1.UI控制脚本GM.cs

using UnityEngine;
using System.Collections;

[AddComponentMenu("MyGame/GameManager")]
public class GameManager : MonoBehaviour {

    public static GameManager Instance;

    // 得分
    public int m_score = 0;

    // 历史最高得分
    public static int m_hiscore = 0;

    // 主角
    protected Player m_player;

    // 背景音乐
    public AudioClip m_musicClip;

    // 声音源
    protected AudioSource m_Audio;

    void Awake() {
        // 自身实例。单例
        Instance = this;
    }

	// 初始化
	void Start () {

        m_Audio = this.audio;

        // 获取主角
        GameObject obj = GameObject.FindGameObjectWithTag("Player");
        if (obj != null) {
            m_player = obj.GetComponent<Player>();
        }
	
	}
	
	// 每帧渲染一次
	void Update () {

        // 循环播放背景音乐
        if (!m_Audio.isPlaying) {
            m_Audio.clip = m_musicClip; // 音乐文件
            m_Audio.Play();             // 播放
        }

        // 暂停游戏
        // Time.timeScale 时间缩放,时间的速度
        // 按下ESC键
        if (Time.timeScale > 0 && Input.GetKeyDown(KeyCode.Escape)) {
            // 时间的速度为0,时间静止
            Time.timeScale = 0;
        }
	}

    /** 专用绘制UI界面 **/
    void OnGUI() {

        // 游戏暂停时显示-------------------------------------

        // 游戏暂停 --- 当时间静止
        if (Time.timeScale == 0) {
            // 在屏幕绘制两个按钮

            // 继续游戏按钮
            // Buttom 按钮(区域,文字)
            // Rect 四方区域(x,y,w,h)
            if (GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.4f, 100, 30), "继续游戏")) {
                // 时间按原速度(正常速度)流失
                Time.timeScale = 1;
            }

            // 退出游戏按钮
            if (GUI.Button(new Rect(Screen.width * 0.5f - 50, Screen.height * 0.6f, 100, 30), "退出游戏")) {
                // 退出游戏
                Application.Quit();
            }
        }
        
        // 以下当玩家创建后显示--------------------------------

        int life = 0;
        if (m_player != null) {
            // 获得主角的生命值
            life = (int)m_player.m_life;
        }
        else {  // 游戏结束
            
            GUI.skin.label.fontSize = 50;   // 字号
            GUI.skin.label.alignment = TextAnchor.LowerCenter;  // 对齐
            GUI.Label(new Rect(0, Screen.height * 0.2f, Screen.width, 60), "游戏失败"); // 标签

            GUI.skin.label.fontSize = 20;   // 字号
            // 显示按钮
            if (GUI.Button(new Rect(Screen.width*0.5f-50, Screen.height*0.5f, 100, 30), "再试一次")) {
                // 读取当前关卡
                // Application.LoadLevel 读取下一个关卡,当前关卡的一切对象都被销毁
                // Application.loadedLevelName 当前关卡
                Application.LoadLevel(Application.loadedLevelName);
            }
        }

        // 以下一直显示---------------------------------------

        GUI.skin.label.fontSize = 15;                       // 字号
        GUI.skin.label.alignment = TextAnchor.LowerLeft;    // 对齐位置

        // 显示主角生命
        GUI.Label(new Rect(5, 5, 100, 30), "生命值" + life);
        // 显示最高分
        GUI.Label(new Rect(0, 5, Screen.width, 90), "历史最高得分 " + m_hiscore);
        // 显示当前得分
        GUI.Label(new Rect(0, 125, Screen.width, 30), "得分" + m_score);
    }

    // 增加分数
    // point即敌机控制类Enemy中的属性m_point
    public void AddScore( int point ) {
        m_score += point;

        // 更新高分纪录
        if (m_hiscore < m_score)
            m_hiscore = m_score;
    }
}


2.创建管理器GM

1)创建空游戏体

GameObjectCreate Empty,空对象创建在Hierarchy面板中,将其重命名为“GameManager”。这个空游戏体会自动加入到Scene中。

2)创建AudioSource

选中GameManagerComponentAudioAudio Source

3)关联控制脚本

Assets中拖放GM.csHierarchy中的GM上。

4)设置背景音乐

首先,修改声音文件的立体声类型。2D声音和摄像机的距离无关,不会忽大忽小;3D声音会根据发声体与相机的距离而变大变小。
Unity3D上路_01-2D太空射击游戏_第84张图片

然后,打开GMInspector属性面板,Script项目,配置MusicClip
Unity3D上路_01-2D太空射击游戏_第85张图片

3.修改敌机控制脚本

Unity3D上路_01-2D太空射击游戏_第86张图片

做完这一步即可运行测试,

using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour {
    public float m_speed = 1;
    protected float m_rotSpeed = 60;
    protected float m_timer = 1.5f;
    protected Transform m_transform;
    public float m_life = 10;
    public Transform m_explosionFX;
    public AudioClip m_shootClip;
    protected AudioSource m_audio;

    // 分数值
    public int m_point = 10; 

    void OnTriggerEnter(Collider other) {
        if (other.tag.CompareTo("PlayerRocket") == 0) {
            Rocket rocket = other.GetComponent<Rocket>();
            if (rocket != null) {
                m_life -= rocket.m_power * 5;
                if (m_life <= 0) {
                    Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
                    Destroy(this.gameObject);

                    // 调用游戏管理器的增加分数的方法
                    GameManager.Instance.AddScore(m_point); 
                }
            }
        }
        else if (other.tag.CompareTo("Player") == 0) { 略 }
        else if (other.tag.CompareTo("bound") == 0) { 略 }
    }
    void Start() { 略 }
    protected virtual void Update()  { 略 }
}


4.修改欢迎界面

1)修改HelloWorld关卡脚本

using UnityEngine;
using System.Collections;
public class HelloWorld : MonoBehaviour {
    void OnGUI() {
        GUI.skin.label.fontSize = 100;
        GUI.Label(new Rect(10, 10, Screen.width, Screen.height), "HelloWorld!!!");
  // 按钮(区域(x, y, w, h), 文字)
        if (GUI.Button(new Rect(Screen.width/2 - 100, Screen.height/2 - 50, 100, 30), "开始游戏")) {
            // Level01 关卡名称,.unity文件的名称
            Application.LoadLevel("Level01");
        } 
    }
}


2)创建背景

首先,FileSave Scene,保存当前的关卡Level01

然后,在Assets中双击打开之前的关卡HelloWorld
Unity3D上路_01-2D太空射击游戏_第87张图片

接着,选择Assets中的一张图片,GameObjectCreate OtherGUI Texture
Unity3D上路_01-2D太空射击游戏_第88张图片

十。游戏发布

1.在发布设置添加全部关卡

Unity3D上路_01-2D太空射击游戏_第89张图片

2.玩家信息设置

紧跟上一步点击“Player Setting...”,
或者,EditProject SettingsPlayer

1)基本设置

Unity3D上路_01-2D太空射击游戏_第90张图片

2)分辨率

Unity3D上路_01-2D太空射击游戏_第91张图片

3)图标详细设置

Unity3D上路_01-2D太空射击游戏_第92张图片

4)游戏启动画面

Unity3D上路_01-2D太空射击游戏_第93张图片 

5)其它设置

Unity3D上路_01-2D太空射击游戏_第94张图片

3.发布游戏

Unity3D上路_01-2D太空射击游戏_第95张图片

- end

资源:
     本篇博文《Unity3D上路》: http://pan.baidu.com/s/1c0y5Cuk

你可能感兴趣的:(游戏,cocos2d,C#,unity,unity3d,3D,box2D)