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里我们还需要进行一些设置:
把该拖的东西拖进他们的地方。到此为止,我们玩家的生命就设置完成。