Unity3D--學習太空射擊遊戲製作(三)

步驟四:創建敵人

創建敵人的方式與創建主角類似,不過敵人的行爲需要由計算機來控制,它將從上方迎着主角緩慢飛出來,並左右來回移動:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章