天天看點

unity——Survival Shooter:UI&玩家生命

5.UI

接下來我們要加入遊戲的UI。你可能注意到了我們的人物其實并沒有一個生命條,這樣我們就不能愉快的奪取他人的性命了。是以這一步主要是在螢幕上加上生命條的UI。

我們要進入2D的世界。

首先是在Scene中添加一個叫做Canvas的GameObject。在unity中,所有的UI是畫在Canvas上的,也就是畫布。并且畫布神奇的地方在于不用我們去定義它的大小,畫布的大小根據玩家可見的螢幕大小而改變。我們隻要把UI放在合适的相對位置就可以了。

添加Canvas,下一步我們要添加一個元件叫Canvas Group。這個元件可以使我們的UI具有透明度,并且可以修改元件的可互動性。我們要把可互動性去掉,因為我們不希望玩家可以把自己的生命條不斷地往回拖,同時我們要去掉Block Raycasts的選項。因為在之前的操作中我們已經發射了神奇的轉向光波,我們不希望它被這個功能阻礙掉。

unity——Survival Shooter:UI&玩家生命

and now 我們就要往這個畫布裡添加不同的UI了。添加UI的方式就是在Canvas下面增添不同的GameObject,我們直接選擇空的GO。命名為HealthUI。你會在Canvas裡面看到一個聖殿騎士一樣的标志。那麼接下來我們要将它放置在整個畫布的左下角,在Inspector裡有個準星一樣的圖示,我們選擇它,把錨點和坐标都移動到左下角(按住alt 和 shift)。設定寬和高。

接下來在HealthUI裡有兩點:心的icon和生命條。

首先在HealthUI裡我們添加一個子對象在UI-image添加一個image,設定它的寬高都為30。然後在Image Source裡面選擇小心心的icon。

接下來是生命條,我們在同級增添一個UI-Slider的對象。這實際上是一個拖動條,就像是ios7之前蘋果的鎖屏界面。打開Slider的子菜單,我們會發現裡面有兩樣:Fill Area和handle。同樣,我們不希望他是可以互動的,是以handle這一部分直接删掉。slider内部的Interactable也可以不選擇,但是在之前Canvas裡面我們已經将所有的元件設定為了不可互動,是以這裡勾不勾選都無所謂。同樣的,因為它肯定不參與互動,我們将transistion選擇none。最後我們把MaxValue設定為100,同時把目前的Value變為100。

接下來我們要将玩家受傷的效果放大一點,因為之前看到的我們的生命條太小了一點,我們希望這個受傷的效果更明顯一點。是以在Canvas下我們再添加一個Image。我們希望在受傷的時候螢幕shua的變紅,是以在之前那個準星的地方,我們按住alt并選擇鋪滿螢幕。我們将整個的顔色設定為社會粉,這個時候滿螢幕都會是小豬佩奇的顔色,不要方,我們将圖檔的alpha值設定為0。

unity——Survival Shooter:UI&玩家生命

6.玩家生命

接下來我們要給我們的小角色一點生命值,這樣一來敵人就可以無情的殺害他。接着我們要給敵人一點可憐的生命值。

我們把PlayerHealth的腳本加到可愛的小角色身上。

public int startingHealth = 100;
    public int currentHealth;
    public Slider healthSlider;
    public Image damageImage;
    public AudioClip deathClip;
    public float flashSpeed = 5f;
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);
           

so,我們的變量依次是:玩家開始的生命值,玩家目前時刻的生命值,我們之前加進去的生命條、受傷圖像、死亡音效。接下來兩個變量是我們受傷動畫的參數,一個是這個恐怖的紅色圖像閃過的時間,另外一個是它的顔色(是以之前調不調顔色都無所謂,因為這裡已經設定了顔色,但是透明度一定要是0,否則一開始就會看到它)。

Animator anim;
    AudioSource playerAudio;
    PlayerMovement playerMovement;
    //PlayerShooting playerShooting;
    bool isDead;
    bool damaged;
           

這裡是剩下的其他私有變量,值得注意的是,我們使用了另外一個自己編寫的類playerMovement。下面的兩個bool值一個來判定我們的角色是不是死了,另一個判定角色是否是受傷。

void Awake ()
    {
        anim = GetComponent <Animator> ();
        playerAudio = GetComponent <AudioSource> ();
        playerMovement = GetComponent <PlayerMovement> ();
        //playerShooting = GetComponentInChildren <PlayerShooting> ();
        currentHealth = startingHealth;
    }
           

Awake沒什麼好說的,初始化一堆變量,把目前生命值回滿。

void Update ()
    {
        if(damaged)
        {
            damageImage.color = flashColour;
        }
        else
        {
            damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }
        damaged = false;
    }
           

在Update裡面,我們看到如果角色受傷,我們将damageImage的顔色設定為我們想要的顔色。如果沒有受傷,我們把這張DamageImage淡出,使用Lerp把他變成人民大衆能接受的顔色。然後把Damaged置為flase。應當注意的是,每次Update的時間極其短,是以實際上判定受傷和淡出圖檔發生在不同的時間片裡。

public void TakeDamage (int amount)
    {
        damaged = true;

        currentHealth -= amount;

        healthSlider.value = currentHealth;

        playerAudio.Play ();

        if(currentHealth <= 0 && !isDead)
        {
            Death ();
        }
    }
           

ok如果我們被咬了,首先damaged變成true。減去生命值,把生命條挪一下,播放音樂,如果沒有血條了,我們就挂了。

void Death ()
    {
        isDead = true;

        //playerShooting.DisableEffects ();

        anim.SetTrigger ("Die");

        playerAudio.clip = deathClip;
        playerAudio.Play ();

        playerMovement.enabled = false;
        //playerShooting.enabled = false;
    }
           

那麼一旦挂掉了,我們将bool值置為true。把動畫AC置為Die的動畫,播放死去的音效。這裡一定注意的是,我們并沒有增加一個新的audio Source,而是直接把已經有的AudioSource元件的聲音來源更換了,注意!隻要有了該元件,就可以在代碼端随時替換内容。最後我們把一些隻有活着的時候才有用的代碼失效掉。

public void RestartLevel ()
    {
        SceneManager.LoadScene (0);
    }
           

那麼一旦死亡,我們的整個場景重置為Scene0。

完整代碼:

注意包含的頭檔案

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.SceneManagement;


public class PlayerHealth : MonoBehaviour
{
    public int startingHealth = 100;
    public int currentHealth;
    public Slider healthSlider;
    public Image damageImage;
    public AudioClip deathClip;
    public float flashSpeed = 5f;
    public Color flashColour = new Color(1f, 0f, 0f, 0.1f);


    Animator anim;
    AudioSource playerAudio;
    PlayerMovement playerMovement;
    //PlayerShooting playerShooting;
    bool isDead;
    bool damaged;


    void Awake ()
    {
        anim = GetComponent <Animator> ();
        playerAudio = GetComponent <AudioSource> ();
        playerMovement = GetComponent <PlayerMovement> ();
        //playerShooting = GetComponentInChildren <PlayerShooting> ();
        currentHealth = startingHealth;
    }


    void Update ()
    {
        if(damaged)
        {
            damageImage.color = flashColour;
        }
        else
        {
            damageImage.color = Color.Lerp (damageImage.color, Color.clear, flashSpeed * Time.deltaTime);
        }
        damaged = false;
    }


    public void TakeDamage (int amount)
    {
        damaged = true;

        currentHealth -= amount;

        healthSlider.value = currentHealth;

        playerAudio.Play ();

        if(currentHealth <= 0 && !isDead)
        {
            Death ();
        }
    }


    void Death ()
    {
        isDead = true;

        //playerShooting.DisableEffects ();

        anim.SetTrigger ("Die");

        playerAudio.clip = deathClip;
        playerAudio.Play ();

        playerMovement.enabled = false;
        //playerShooting.enabled = false;
    }


    public void RestartLevel ()
    {
        SceneManager.LoadScene (0);
    }
}

           

OKAY,我們現在回去unity。在inspector裡我們還需要進行一些設定:

unity——Survival Shooter:UI&amp;玩家生命

把該拖的東西拖進他們的地方。到此為止,我們玩家的生命就設定完成。