Unity官方教程《Tanks》学习笔记(三)

2018-02-09  本文已影响1070人  丶蓝天白云梦

本系列文章是根据官方视频教程而写下的学习笔记,原官方视频教程网址:https://unity3d.com/cn/learn/tutorials/s/tanks-tutorial

系列其他笔记传送门
Unity官方教程《Tanks》学习笔记(一)
Unity官方教程《Tanks》学习笔记(二)
Unity官方教程《Tanks》学习笔记(四)
Unity官方教程《Tanks》学习笔记(五)

本小节的目的是制作Tank的生命条,也就是下图的形式,有一圈绿色生命条包围在坦克的周围:


Tank Health

首先,我们确保Scene View是在Pivot状态下的,而不是Center状态:

Pivot
接着,我们在Hierarchy根目录下创建一个Slider(Create——>UI——>Slider),接着会看到生成如下两样东西:
Slider
当创建一个UI元素时,Unity会自动为我们生成一个Canvas和EventSystem,而Slider则成为Canvas的一个子对象。接着,选中EventSystem,把里面的Horizontal Axis改为HorizontalUI和Vertical Axis改为VerticalUI,这样做的意义是不与用户操作坦克移动的输入产生冲突:
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删除,因为我们不需要用到滑动图标。接着,复选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转动
    }
}

既然坦克有生命值,那么当坦克的生命值降为0的时候,会发生什么?答案是会爆炸,那么我们就需要坦克爆炸的效果,素材已经为我们准备好了。在Prefabs文件夹下,找到TankExplosion预制件,把它拖拽到Hierarchy根目录。选中TankExplosion,为它添加AudioSource,AudioClip选择为TankExplosion,取消Play On Awake以及Loop,然后点击右上角的Apply,使得改动在Prefabs的预制件生效,然后删除在Hierarchy下的TankExplosion。

TankExplosion

完成以上改动后,我们接下来要思考一个问题,坦克的生命条UI界面有了,但还需要让它动态地减少,即在坦克受到伤害的时候会扣血,那么该怎么实现呢?答案是我们需要一个脚本,对坦克的生命值进行控制。在/Scripts/Tank文件夹内找到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;    //低血量状态是红色
    public GameObject m_ExplosionPrefab;           //爆炸效果的预制件
    
    
    private AudioSource m_ExplosionAudio;          //Audio
    private ParticleSystem m_ExplosionParticles;   //爆炸的粒子效果
    private float m_CurrentHealth;  
    private bool m_Dead;                           //是否已经死亡


    private void Awake()
    {
        //初始化的时候就准备好爆炸效果的实例
        m_ExplosionParticles = Instantiate(m_ExplosionPrefab).GetComponent<ParticleSystem>();
        m_ExplosionAudio = m_ExplosionParticles.GetComponent<AudioSource>();
        //未激活状态
        m_ExplosionParticles.gameObject.SetActive(false);
    }


    private void OnEnable()
    {
        m_CurrentHealth = m_StartingHealth;
        m_Dead = false;

        SetHealthUI();
    }
    
    /**
     * 外部调用,当坦克受伤的时候调用该函数
     */
    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 颜色的线性插值,通过第三个参数在颜色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;
        
        //修改粒子系统的坐标为坦克死亡时候的坐标
        m_ExplosionParticles.transform.position = transform.position;
        m_ExplosionParticles.gameObject.SetActive(true);

        //播放爆炸效果以及爆炸音效
        m_ExplosionParticles.Play();
        m_ExplosionAudio.Play();

        gameObject.SetActive(false);
    }
}

编辑完毕后,我们要对其公有变量进行初始化:


TankHealth变量初始化

最后,点击Tank中右上角的Apply,使其应用到预制件中,保存当前Scene。

上一篇下一篇

猜你喜欢

热点阅读