unity3d应用实例之太空大战
今天为大家详细介绍Unity3D应用实例——太空大战。这是我找到的一篇相关文章,感兴趣的朋友也可以自己动手尝试制作。
这是一个简单的太空大战DEMO,整个游戏包含两个部分:开始游戏界面和游戏主界面。游戏中的敌人分为两种,一种是简单敌人,只会触碰主角;另一种是复杂敌人,能够发射子弹。下面我们将逐步进行开发。
1. 导入相关资源
首先,我们需要导入相关资源。在Unity的Assets中单击弹出选择框,选择Import Package -> Custom Package。
2. 创建开始游戏场景
2.1 创建新场景
点击菜单栏中的File -> New Scene来创建一个新场景,并将其命名为start。
2.2 创建背景图
开始场景较为简单,包含一个标题、一个开始游戏按钮和一张背景图。我们先点击菜单栏的GameObject -> Create Other -> GUI Texture来创建背景图,将其命名为GameBg,并在Texture里选择mars.png作为背景图。
2.3 创建标题和按钮
接下来,我们在代码里创建标题和按钮。创建一个CS脚本,命名为TitleScreen,代码如下:
using UnityEngine;
using System.Collections;
[AddComponentMenu("MyGame/TitleScreen")]
public class TitleScreen : MonoBehaviour {
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update () {
}
void OnGUI()
{
GUI.skin.label.fontSize = 80;
GUI.skin.label.alignment = TextAnchor.LowerCenter;
GUI.Label(new Rect(0, 30 * 2, Screen.width, 100), "太空大战");
if(GUI.Button(new Rect(Screen.width * 0.5f - 100 * 2, Screen.height * 0.6f, 200 * 2, 30 * 2), "开始游戏"))
{
// 读取当前关卡
Application.LoadLevel("Level1");
}
}
}
将该脚本挂到摄像机上,点击按钮时会跳转到下一个场景。
3. 创建游戏主场景
3.1 创建新场景
创建第二个场景,步骤与创建第一个场景相同,将其命名为Level1。
3.2 创建火星模型
新建一个Plane作为火星的模型,命名为XqPlane。然后新建一个材质,命名为Background,选择mars.png作为贴图,将shader属性设置为Transparent -> Cutout -> Diffuse,以去掉星球四周的黑框,最后为火星模型指定该材质。
3.3 创建星空模型
同样的方法创建一个星空的模型,命名为XkPlane,设置好材质属性和贴图。
3.4 让星空动画移动
目前星空是静止的,我们希望它能上下移动。点击菜单栏Window -> Animation打开动画选项,在Animation选项里点击Add Curve创建一个新动画,命名为XkAnimation。接着点击Mesh Renderer -> Material._Main Tex_ST选项,在Material._Main Tex_ST.w里将值从0到 -1,到30帧的时候改为 -1,并设置循环。运行后,星空背景会往下移动。
3.5 调整摄像机和添加光源
调整摄像机位置,使其向下对准星球,然后创建一个点光源来照亮星球,并设置光源的位置、范围等属性。
4. 创建主角飞船
4.1 导入飞船模型
将Player.fbx直接拖到Hierarchy中,将Y轴坐标设为0,并旋转180°,使飞船头朝上。
4.2 编写控制脚本
创建一个CS脚本,命名为Player,代码如下:
public class Player : MonoBehaviour {
public float m_speed = 1;
protected Transform m_transform;
void Start ()
{
m_transform = this.transform;
}
// Update is called once per frame
void Update ()
{
// 纵向移动距离
float movev = 0;
// 横向移动距离
float moveh = 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;
}
this.m_transform.Translate(new Vector3(moveh, 0, movev));
}
}
这样我们就可以通过方向键控制飞船移动了。
5. 让飞船发射子弹
5.1 创建子弹模型
在资源中找到rocket.fbx模型文件,拖到Hierarchy中创建子弹的游戏体。对于重复使用的游戏体,我们要做成预设体Prefab。打开菜单栏Assets -> Create -> Prefab,创建一个新的预设体,命名为Rocket。
5.2 编写子弹脚本
创建一个CS脚本,命名为Rocket,代码如下:
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;
protected Transform m_transform;
// Use this for initialization
void Start ()
{
m_transform = this.transform;
}
// Update is called once per frame
void Update ()
{
m_liveTime -= Time.deltaTime;
if(m_liveTime <= 0)
{
Destroy(this.gameObject);
}
this.m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime));
}
}
将子弹脚本挂到子弹Prefab上。
5.3 修改Player脚本实现发射功能
修改Player脚本,当按下空格或是鼠标左键时发射子弹,同时为了控制发射频率,定义一个变量,每隔0.1秒发射一次,修改后的代码如下:
// 控制发射频率的变量
private float m_rocketRate = 0;
void Update ()
{
m_rocketRate -= Time.deltaTime;
if(m_rocketRate <= 0)
{
m_rocketRate = 0.1f;
if(Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0))
{
// 这里假设m_rocket是子弹预设体
Instantiate(m_rocket, m_transform.position, m_transform.rotation);
}
}
}
6. 创建简单敌人
6.1 导入敌人模型
找到Enemy.fbx文件拖到Hierarchy中,创建敌人Prefab,命名为Enemy。
6.2 编写敌人脚本
创建一个CS脚本,命名为Enemy,代码如下:
using System.Collections;
[AddComponentMenu("MyGame/Enemy")]
public class Enemy : MonoBehaviour {
// 速度
public float m_speed = 1;
// 旋转速度
protected float m_rotspeed = 30;
// 变相间隔时间
protected float m_timer = 1.5f;
// 生命
public float m_life = 10;
protected Transform m_transform;
public int m_point = 10;
// Use this for initialization
void Start ()
{
m_transform = this.transform;
}
// Update is called once per frame
void Update ()
{
UpdateMove ();
}
protected virtual void UpdateMove()
{
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 (0, 0, -m_speed * Time.deltaTime));
}
}
将脚本挂到敌人Prefab上,敌人会每隔3秒改变一次旋转方向。
7. 添加物理碰撞检测
7.1 添加碰撞体和刚体
给敌人、主角飞船和子弹都添加碰撞体和刚体组件。在敌人的box Collider属性中,选中Is Trigger使其具有触发作用;在rigidbody组件中,取消选中Use Gravity去掉重力影响,选中Is Kinematic使游戏体的运动不受物理模拟影响。
7.2 设置Tag标示
选择Edit -> Project Settings -> Tag and Layers,设置相关的Tag,如PlayerRocket、Player、Enemy等。
7.3 修改脚本实现碰撞逻辑
修改Enemy.cs脚本
添加生命属性和OnTriggerEnter函数,当敌人与子弹或主角飞船碰撞时,根据情况减少生命并处理销毁逻辑:
// 生命
public float m_life = 10;
// 假设m_explosionFX是爆炸特效预设体
public GameObject m_explosionFX;
void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo ("PlayerRocket") == 0)
{
Rocket rocket = other.GetComponent<Rocket> ();
m_life -= rocket.m_power;
if (m_life <= 0) {
// 假设GameManager.Instance.AddScroe是添加分数的方法
GameManager.Instance.AddScroe(m_point);
Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
Destroy (this.gameObject);
}
}
else if (other.tag.CompareTo ("Player") == 0)
{
m_life = 0;
Instantiate(m_explosionFX, m_transform.position, Quaternion.identity);
Destroy(this.gameObject);
}
}
修改Rocket.cs脚本
添加OnTriggerEnter函数,当子弹撞到敌人时销毁自身:
void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo ("Enemy") == 0) {
Destroy (this.gameObject);
}
}
修改Player.cs脚本
添加生命属性和OnTriggerEnter函数,主角飞船与任何己方子弹以外的碰撞体相撞都会损失一点生命,生命为0时销毁自身:
// 生命
public float m_life = 3;
// 假设m_explosionFX是爆炸特效预设体
public GameObject m_explosionFX;
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);
}
}
}
8. 处理敌人出界逻辑
创建一个空的游戏体,命名为bound,添加bound的tag和相关物理组件。修改Enemy.cs脚本,当敌人与bound碰撞时,销毁自身:
void OnTriggerEnter(Collider other)
{
if (other.tag.CompareTo ("bound") == 0)
{
m_life = 0;
Destroy(this.gameObject);
Debug.Log("---destroy");
}
}
通过以上步骤,我们就完成了一个简单的太空大战DEMO。你可以根据自己的需求进一步扩展和优化该游戏。
