Unity官方教程《Tanks》學(xué)習(xí)筆記(三)

本系列文章是根據(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的生命條,也就是下圖的形式,有一圈綠色生命條包圍在坦克的周圍:


Tank Health

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

Pivot

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

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

接著,我們考慮,由于生命條是圍繞在坦克周圍的,也就是該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配置

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


Anchor Presets

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


HealthSlider

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


Background

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


Fill

接著,我們找到/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。

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);
    }
}

編輯完畢后,我們要對其公有變量進行初始化:


TankHealth變量初始化

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容