5.UI
接下來我們要加入遊戲的UI。你可能注意到了我們的人物其實并沒有一個生命條,這樣我們就不能愉快的奪取他人的性命了。是以這一步主要是在螢幕上加上生命條的UI。
我們要進入2D的世界。
首先是在Scene中添加一個叫做Canvas的GameObject。在unity中,所有的UI是畫在Canvas上的,也就是畫布。并且畫布神奇的地方在于不用我們去定義它的大小,畫布的大小根據玩家可見的螢幕大小而改變。我們隻要把UI放在合适的相對位置就可以了。
添加Canvas,下一步我們要添加一個元件叫Canvas Group。這個元件可以使我們的UI具有透明度,并且可以修改元件的可互動性。我們要把可互動性去掉,因為我們不希望玩家可以把自己的生命條不斷地往回拖,同時我們要去掉Block Raycasts的選項。因為在之前的操作中我們已經發射了神奇的轉向光波,我們不希望它被這個功能阻礙掉。
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。
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裡我們還需要進行一些設定:
把該拖的東西拖進他們的地方。到此為止,我們玩家的生命就設定完成。