Unity引擎2D游戏开发,血量更新逻辑的实现
思路

能够发现Fill Amount就是控制血量条长度的控件,它是一个百分比值,则可以通过当前血量除以最大血量得到当前血量的百分比。那么,也就能控制血量条的长度了。
编写基本的更新逻辑
创建C#文件

将C#文件挂载到Player State Bar上

在C#文件中调用UI组件前,需要调用UI组件库
using UnityEngine.UI;
在PlayerStateBar C#文件中,创建三个全局变量,分别代表绿色血条、红色血条和精力条
// 绿色血条
public Image healthImage;
// 红色血条
public Image healthDelayImage;
// 精力条
public Image powerImage;
在Hierarchy中拖动Image到各自的位置

在PlayerStateBar中创建OnHealthChange()方法,用于处理血量变更时执行的代码
/// <summary>
/// 接受Health的变更百分比
/// </summary>
/// <param name="percentage">百分比:current / Max</param>
public void OnHealthChange(float percentage)
{
    healthImage.fillAmount = percentage;
}
创建关于血量的ScriptableObject事件
这时候就需要从Player的Character中传递血量数据到此处,那么怎么样才能安全的完整的跨物体甚至跨场景来传递数值呢?
这时候需要利用ScriptableObject进行传递,它是一个持久化存储在项目中的资产文件类型,例如

后缀名为.Asset
在Scripts下创建ScriptableObject文件夹,并创建CharacterEventSO。因为是利用ScriptableObject来创建事件,因此以EventSO结尾

打开CharacterEventSO C#文件,继承ScriptableObject
public class CharacterEventSO : ScriptableObject
{
}
在上面写上描述用以生成ScriptableObject资产文件
[CreateAssetMenu(fileName = "Event/CharacterEventSO")]
public class CharacterEventSO : ScriptableObject
{
}
这样就能在Project窗口中添加此资产文件

创建一个UnityAction的全局变量,用于传递Character数据
// 只传递Character数据
public UnityAction<Character> OnEventRised;
创建RaiseEvent()事件启动方法
/// <summary>
/// 启动事件
/// </summary>
/// <param name="character">谁想启动这个事件,就把自己的Character传递进去</param>
public void RaiseEvent(Character character)
{
    OnEventRised?.Invoke(character);
}
在Assets中创建Events文件夹,在内部创建SriptableObject事件

接下来,在Character代码脚本当中,只要血量发生变化就调用EventSO,把当前血量传递过去
用Unity Event进行广播,则在Character C#脚本中,添加如下全局变量
public UnityEvent<Character> OnHealthChange;
然后在Player的Character中,将上述的ScriptableObject Event拖入,并选择RaiseEvent()方法。从而,当人物血量有了变化,即可广播出去。

接下来,Player State Bar来监听,因为要使血条栏变少
监听ScriptableObject事件
在Hierarchy中,创建一个GameObject,用于监听所有关于UI的事件

在Scripts下,创建一个UIManager的C#脚本

绑定到UI Manager下

C#代码中,创建一个CharacterEventSO的全局变量
public class UIManager : MonoBehaviour
{
    [Header("事件监听")]
    public CharacterEventSO healthEvent;
}
在UI Manager中,绑定Character Event SO的Event文件

此时,就能够成功监听Character Event SO的Event文件,利用了Character Event SO的Event文件进行中间件传递了一些数据
继续编写血条更新逻辑
在UIManager C#脚本中,创建OnEnable()方法和OnDisable()方法。并在内部添加OnHealthEvent事件进行监听
private void OnEnable()
{
    healthEvent.OnEventRised += OnHealthEvent;
}
private void OnDisable()
{
    healthEvent.OnEventRised -= OnHealthEvent;
}
OnEnable()即启动事件方法,OnDisable()为关闭事件方法,两者均为固定方法
由于需要对血条栏进行控制,所以添加状态栏的全局变量
public PlayerStateBar playerStateBar;
然后创建OnHealthEvent()方法,在内部对血条进行计算,并赋予给playerStateBar的OnHealthChange()方法
private void OnHealthEvent(Character character)
{
    var percentage = character.currentHealth / character.maxHealth;
    playerStateBar.OnHealthChange(percentage);
}
打开Hierarchy,选中UI Manager,将对应的组件拖入

打开Character,虽然创建了OnHealthChange变量,但是并没有对其进行调用。那么就需要在受伤时和初始化时进行调用
public void TakeDamage(Attack attacker)
{
    if (invulnerable)
    {
        return;
    }
    if (currentHealth - attacker.damage > 0) 
    {
        currentHealth -= attacker.damage;
        TriggerInvulnerable();
        // 执行受伤
        OnTakeDamage?.Invoke(attacker.transform);
    } else
    {
        currentHealth = 0;
        // 触发死亡
        onDie?.Invoke();
    }
    // 进行血条的扣除
    OnHealthChange?.Invoke(this);
}
private void Start()
{
    currentHealth = maxHealth;
    OnHealthChange?.Invoke(this);
}
红色血条的扣除
打开PlayerStateBar脚本,由于healthDelayImage要跟随healthImage变化,所以在Update()中进行
判断红色血条是否大于绿色血条的值,如果大于,则扣除时间的修正进行变化
private void Update()
{
    if (healthDelayImage.fillAmount > healthImage.fillAmount)
    {
        healthDelayImage.fillAmount -= Time.deltaTime;
    }
}


 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号