本系列文章是根據(jù)官方視頻教程而寫下的學(xué)習(xí)筆記,原官方視頻教程網(wǎng)址:https://unity3d.com/cn/learn/tutorials/s/tanks-tutorial
系列其他筆記傳送門
Unity官方教程《Tanks》學(xué)習(xí)筆記(一)
Unity官方教程《Tanks》學(xué)習(xí)筆記(二)
Unity官方教程《Tanks》學(xué)習(xí)筆記(四)
Unity官方教程《Tanks》學(xué)習(xí)筆記(五)
本小節(jié)的目的是制作Tank的生命條,也就是下圖的形式,有一圈綠色生命條包圍在坦克的周圍:

首先,我們確保Scene View是在Pivot狀態(tài)下的,而不是Center狀態(tài):

接著,我們在Hierarchy根目錄下創(chuàng)建一個Slider(Create——>UI——>Slider),接著會看到生成如下兩樣?xùn)|西:

當(dāng)創(chuàng)建一個UI元素時,Unity會自動為我們生成一個Canvas和EventSystem,而Slider則成為Canvas的一個子對象。接著,選中EventSystem,把里面的Horizontal Axis改為HorizontalUI和Vertical Axis改為VerticalUI,這樣做的意義是不與用戶操作坦克移動的輸入產(chǎn)生沖突:

接著,我們考慮,由于生命條是圍繞在坦克周圍的,也就是該Slider是跟隨坦克移動的,所以我們需要讓該Slider成為Tank的一個子對象,這樣他們的position就能同步了,操作很簡單,把Canvas(而不是Slider)拖拽到Tank下,成為它的子對象。
然后,我們對Canvas的一些屬性作出修改:
1、修改Canvas的position值為(0,0.1,0);修改Width和Height為(3.5,3.5);修改Rotation為(90,0,0)。
2、修改Canvas的渲染模式Render Mode為 World Space。
3、修改Canvas Scaler下的Reference Pixels Per Unit為1。
如下圖所示:

展開Canvas,對Slider重命名為HealthSlider,然后展開HealthSlider,有如下幾個子元素:Background、Fill Area、HandleSliderArea。我們把HandleSliderArea刪除,因為我們不需要用到滑動圖標。接著,復(fù)選HealthSlider、Background、Fill Area和Fill,點擊Anchor Presets,按住ALT選中右下角的選項:

選中HealthSlider,作以下改動:
①點擊取消Interactable
②Transition選擇為None
③Max Value選擇為100.

選中Background,作以下改動:
①在Source Image中,選擇圖片資源為HealthWheel
②在Color中,把Alpha值改為80

選中Fill(Fill是Fill Area的子對象),作以下改動:
①Source Image,選擇圖片為HealthWheel
②在Color中,把Alpha值改為150
③ImageType改為 Filled
④Fill Origin選擇為Left
⑤取消選擇Clockwise

接著,我們找到/Scripts/UI 文件夾下的UIDirectionControl腳本,把它拖拽到HealthSlider下。我們來看看這個腳本的作用是什么:
using UnityEngine;
public class UIDirectionControl : MonoBehaviour
{
public bool m_UseRelativeRotation = true;
private Quaternion m_RelativeRotation;
private void Start()
{
m_RelativeRotation = transform.parent.localRotation; //初始角度
}
private void Update()
{
if (m_UseRelativeRotation)
transform.rotation = m_RelativeRotation; //每一幀的更新都把角度重置為初始角度
//也就是固定Slider的角度,不讓它隨著Tank轉(zhuǎn)動
}
}
既然坦克有生命值,那么當(dāng)坦克的生命值降為0的時候,會發(fā)生什么?答案是會爆炸,那么我們就需要坦克爆炸的效果,素材已經(jīng)為我們準備好了。在Prefabs文件夾下,找到TankExplosion預(yù)制件,把它拖拽到Hierarchy根目錄。選中TankExplosion,為它添加AudioSource,AudioClip選擇為TankExplosion,取消Play On Awake以及Loop,然后點擊右上角的Apply,使得改動在Prefabs的預(yù)制件生效,然后刪除在Hierarchy下的TankExplosion。

完成以上改動后,我們接下來要思考一個問題,坦克的生命條UI界面有了,但還需要讓它動態(tài)地減少,即在坦克受到傷害的時候會扣血,那么該怎么實現(xiàn)呢?答案是我們需要一個腳本,對坦克的生命值進行控制。在/Scripts/Tank文件夾內(nèi)找到TankHealth.cs文件,把它拖拽到Tank下,然后打開它,我們來編輯一下:
using UnityEngine;
using UnityEngine.UI;
public class TankHealth : MonoBehaviour
{
public float m_StartingHealth = 100f; //初始生命值
public Slider m_Slider; //slider,生命條
public Image m_FillImage; //生命條的填充
public Color m_FullHealthColor = Color.green; //滿血的時候是綠色
public Color m_ZeroHealthColor = Color.red; //低血量狀態(tài)是紅色
public GameObject m_ExplosionPrefab; //爆炸效果的預(yù)制件
private AudioSource m_ExplosionAudio; //Audio
private ParticleSystem m_ExplosionParticles; //爆炸的粒子效果
private float m_CurrentHealth;
private bool m_Dead; //是否已經(jīng)死亡
private void Awake()
{
//初始化的時候就準備好爆炸效果的實例
m_ExplosionParticles = Instantiate(m_ExplosionPrefab).GetComponent<ParticleSystem>();
m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource>();
//未激活狀態(tài)
m_ExplosionParticles.gameObject.SetActive(false);
}
private void OnEnable()
{
m_CurrentHealth = m_StartingHealth;
m_Dead = false;
SetHealthUI();
}
/**
* 外部調(diào)用,當(dāng)坦克受傷的時候調(diào)用該函數(shù)
*/
public void TakeDamage(float amount)
{
// Adjust the tank's current health, update the UI based on the new health and check whether or not the tank is dead.
m_CurrentHealth -= amount;
SetHealthUI();
//如果坦克的血量低于0并且是存活的,那么判定為死亡
if(m_CurrentHealth <= 0f && !m_Dead){
OnDeath();
}
}
private void SetHealthUI()
{
// Adjust the value and colour of the slider.
m_Slider.value = m_CurrentHealth;
//對Fill填充物的顏色做出改變
//Color.Lerp 顏色的線性插值,通過第三個參數(shù)在顏色1和2之間插值。
m_FillImage.color = Color.Lerp(m_ZeroHealthColor,m_FullHealthColor,m_CurrentHealth / m_StartingHealth);
}
private void OnDeath()
{
// Play the effects for the death of the tank and deactivate it.
m_Dead = true;
//修改粒子系統(tǒng)的坐標為坦克死亡時候的坐標
m_ExplosionParticles.transform.position = transform.position;
m_ExplosionParticles.gameObject.SetActive(true);
//播放爆炸效果以及爆炸音效
m_ExplosionParticles.Play();
m_ExplosionAudio.Play();
gameObject.SetActive(false);
}
}
編輯完畢后,我們要對其公有變量進行初始化:

最后,點擊Tank中右上角的Apply,使其應(yīng)用到預(yù)制件中,保存當(dāng)前Scene。