这种就是简单易实现的,非常没有个性。
因此我们不妨设计一个富有个性的每个血条单独出现的血条
由于我很久没有更新了,而且在这一段时间我换了一个游戏素材,不再是自己画的空洞骑士了,而是可以在Uniy官网Asset Store上免费下载的SunnyLand
地址是:
OK我们把资源导入到Unity以后。然后先把人物的动画制作完成,不会的话建议看看我之前做的关于人物Animation的。然后我以空洞骑士为例就用空洞骑士的素材,先找到UI中的Health
这四种随便选择,然后我们就裁剪好拖到创建的Canvas的左上角,将锚点设置在左上角以后改尺寸都能固定住,然后自己调整好大小。
接下来将 创建一个空对象叫HpManagement我们把上面的第二张图作为空血条,第一张图为满的血条 先创建五个HpBackGround作为空血条,并在空血条上制作它的子对象满血条。并将它们都设置为预设体Prefab。
接着我们在空对象HpManagement上创建脚本就叫HpManagement
以下便是脚本内容
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HpManagement : MonoBehaviour
{
public int health;
public int numsOfHeart;
public Sprite emptyHeart;
public Sprite fullHeart;
public Image[] hearts;
//满血条的图像
public Image[] heartImages;
//空血条的图像
public Image[] hpImages;
void Start()
{
//通过标签获取PlayerHealth脚本
GameController.playerHealth = GameObject.FindGameObjectWithTag("Player").GetComponent
}
// Update is called once per frame
void Update()
{
//通过PlayerHealth获取当前血量
health = GameController.playerHealth.GetHealth();
//检查血量是否有异常
CheckHp();
}
public void CheckHp()
{
for (int i = 0; i < hpImages.Length; i++)
{
//检查血量是否大于最大血条
if (health > numsOfHeart)
{
health = numsOfHeart;
}
//判断是满的还是空的
if (i < health)
{
hearts[i].sprite = fullHeart;
}
else
{
hearts[i].sprite = emptyHeart;
}
//用于判断多余血条
if (i < numsOfHeart)
{
hpImages[i].enabled = true;
}
else
{
hpImages[i].enabled = false;
}
}
}
public void GetHealth(int health)
{
this.health = health;
}
}
这段代码需要解释一下,GameController脚本是用来存储各个脚本的静态变量,方便直接拿来调用,GameController如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameController : MonoBehaviour
{
public static PlayerHealth playerHealth;
public static bool isGameAlive = true;
public static PlayerController playerController;
}
PlayerHealth也是拿来判断血量的以及受伤时的效果,如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
public int startingHealth;
public int currentHealth;
public float hurtSpeed;
public float killTime;
public float hitboxCD;
private Animator myAnim;
private CapsuleCollider2D capColl2D;
public Collider2D circoll2D;
private Rigidbody2D rigi2D;
private void Awake()
{
currentHealth = startingHealth;
}
void Start()
{
rigi2D = GetComponent
capColl2D = GetComponent
myAnim = GetComponent
}
void Update()
{
}
public void DamagePlayer(int damage)
{
//限制当前血量大于0小于最大血量
currentHealth = Mathf.Clamp(currentHealth - damage, 0, startingHealth);
if(currentHealth <= 0)
{
//播放死亡动画
myAnim.SetTrigger("Death");
rigi2D.isKinematic = true;
//游戏设置为死亡,PlayerController的所有函数都无法运行
GameController.isGameAlive = false;
Time.timeScale = 0.5f;
}
//受伤时碰撞框消失,相当于无敌状态
capColl2D.enabled = false;
//碰撞框恢复
StartCoroutine(RestoreTime());
}
IEnumerator RestoreTime()
{
yield return new WaitForSeconds(hitboxCD);
capColl2D.enabled = true;
}
//获取当前生命值给HpManagement调用
public int GetHealth()
{
return currentHealth;
}
public void AddHealth(int _value)
{
currentHealth = Mathf.Clamp(currentHealth - _value, 0, startingHealth);
}
void KillPlayer()
{
Destroy(gameObject);
}
在PlayerCotoller中判断游戏存活void Update()
{
if (GameController.isGameAlive)
{
CheckOnGround();
Movement();
SwitchAnimation();
Jump();
Crouch();
}
}
别忘了在Death的动画最后一帧加入人物死亡的函数的事件
还要记得在Enemy的脚本中添加OnTriigerEnter2Dl来判断一下private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
if (other.GetType().ToString() == "UnityEngine.CapsuleCollider2D")
{
if (GameController.playerHealth.currentHealth > 0 && !GameController.playerController.CheckFall())
{
playerHealth.DamagePlayer(damage);
}
}
}
}
可见掉血成功