本系列文章是根据官方视频教程而写下的学习笔记,原官方视频教程网址:https://unity3d.com/cn/learn/tutorials/s/tanks-tutorial
系列其他笔记传送门
Unity官方教程《Tanks》学习笔记(一)
Unity官方教程《Tanks》学习笔记(二)
Unity官方教程《Tanks》学习笔记(四)
Unity官方教程《Tanks》学习笔记(五)
本小节的目的是制作Tank的生命条,也就是下图的形式,有一圈绿色生命条包围在坦克的周围:
首先,我们确保Scene View是在Pivot状态下的,而不是Center状态:
接着,我们在Hierarchy根目录下创建一个Slider(Create——>UI——>Slider),接着会看到生成如下两样东西:
当创建一个UI元素时,Unity会自动为我们生成一个Canvas和EventSystem,而Slider则成为Canvas的一个子对象。接着,选中EventSystem,把里面的Horizontal Axis改为HorizontalUI和Vertical Axis改为VerticalUI,这样做的意义是不与用户操作坦克移动的输入产生冲突:
接着,我们考虑,由于生命条是围绕在坦克周围的,也就是该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删除,因为我们不需要用到滑动图标。接着,复选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转动
}
}
既然坦克有生命值,那么当坦克的生命值降为0的时候,会发生什么?答案是会爆炸,那么我们就需要坦克爆炸的效果,素材已经为我们准备好了。在Prefabs文件夹下,找到TankExplosion预制件,把它拖拽到Hierarchy根目录。选中TankExplosion,为它添加AudioSource,AudioClip选择为TankExplosion,取消Play On Awake以及Loop,然后点击右上角的Apply,使得改动在Prefabs的预制件生效,然后删除在Hierarchy下的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);
}
}
编辑完毕后,我们要对其公有变量进行初始化:
最后,点击Tank中右上角的Apply,使其应用到预制件中,保存当前Scene。