问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Unity中人物属性面板UI的构成

创作时间:
作者:
@小白创作中心

Unity中人物属性面板UI的构成

引用
CSDN
1.
https://blog.csdn.net/qq_65230893/article/details/139078044

在许多游戏中,角色属性面板UI是必不可少的组件,用于显示角色的血量、蓝条、防御等关键属性。本文将通过一个简单的示例,详细介绍如何在Unity中实现一个包含血量、蓝条和护甲的角色属性面板。

角色中的属性构成

在此次demo中角色属性包含血量、蓝条和护甲。我们首先在Player脚本中定义。

//上限
public float MaxHp = 3f;
public float MaxMp = 5f;
public float MaxDefense = 5f;
//初始血量
private float hp = 3f;
private float mp = 5f;
private float defense = 5f;

UI面板中绑定各个字段

我们可以简单设置一个UI的面板。其中保证文字的一致性,我们可以让"/"左侧的文字居右,右侧的文字居左。

角色脚本中更新数据的同时唤醒事件

为了保证数据的更新一致性,可以添加一个事件,用于在数据更新时通知UI面板更新。为了区分变更的到底是哪个数据,需要现在UI挂载的脚本添加一个枚举类,用于区分传递的数据。

UI面板挂载的脚本:

public enum Attr
{
    HP,
    MP,
    DEFENSE,
}

这样,在角色脚本中就可以通过UI脚本中的Attr发送不同的数据。

//在数据发生变化时唤醒该事件,并传递一个属性
public event EventHandler<OnAttrChangedEventArgs> OnAttrChanged;
public class OnAttrChangedEventArgs : EventArgs
{
    public PlayerAttributePanelUI.Attr attr;
}
public float HP
{
    get { return hp; }
    set
    {
        if (hp != value)
        {
            hp = value;
            OnAttrChanged?.Invoke(this, new OnAttrChangedEventArgs
            {
                attr = PlayerAttributePanelUI.Attr.HP
            });
        }
    }
}
public float MP
{
    get { return mp; }
    set
    {
        if(mp != value)
        {
            mp = value;
            OnAttrChanged?.Invoke(this, new OnAttrChangedEventArgs
            {
                attr = PlayerAttributePanelUI.Attr.MP
            });
        }
    }
}
public float DEFENSE
{
    get { return defense; }
    set
    {
        if(defense != value)
        {
            defense = value;
            OnAttrChanged?.Invoke(this, new OnAttrChangedEventArgs
            {
                attr = PlayerAttributePanelUI.Attr.DEFENSE
            });
        }
    }
}

UI面板脚本中订阅事件并同步更新

在UI脚本中我们就可以根据接收到的数据来实时更新。

private void UpdateUI(Attr attr)
{
    switch (attr)
    {
        case Attr.HP:
            hpText.text = Player.Instance.HP.ToString();
            hpMaxText.text = Player.Instance.MaxHp.ToString();
            hpBar.fillAmount = Player.Instance.HP / Player.Instance.MaxHp;
            break;
        case Attr.MP:
            mpText.text = Player.Instance.MP.ToString();
            mpMaxText.text = Player.Instance.MaxMp.ToString();
            mpBar.fillAmount = Player.Instance.MP / Player.Instance.MaxMp;
            break;
        case Attr.DEFENSE:
            defenseText.text = Player.Instance.DEFENSE.ToString();
            defenseMaxText.text = Player.Instance.MaxDefense.ToString();
            defenseBar.fillAmount = Player.Instance.DEFENSE / Player.Instance.MaxDefense;
            break;
    }
}

在事件唤醒的时候调用UpdateUI函数即可。

private void Player_OnAttrChanged(object sender, Player.OnAttrChangedEventArgs e)
{
    UpdateUI(e.attr);
}

完整代码

Player

public class Player : MonoBehaviour
{
    public static Player Instance { get; private set; }
    public event EventHandler<OnAttrChangedEventArgs> OnAttrChanged;
    public class OnAttrChangedEventArgs : EventArgs
    {
        public PlayerAttributePanelUI.Attr attr;
    }
    //上限
    public float MaxHp = 3f;
    public float MaxMp = 5f;
    public float MaxDefense = 5f;
    private float hp = 3f;
    private float mp = 5f;
    private float defense = 5f;
    public float HP
    {
        get { return hp; }
        set
        {
            if (hp != value)
            {
                hp = value;
                OnAttrChanged?.Invoke(this, new OnAttrChangedEventArgs
                {
                    attr = PlayerAttributePanelUI.Attr.HP
                });
            }
        }
    }
    public float MP
    {
        get { return mp; }
        set
        {
           if(mp != value)
            {
                mp = value;
                OnAttrChanged?.Invoke(this, new OnAttrChangedEventArgs
                {
                    attr = PlayerAttributePanelUI.Attr.MP
                });
            }
        }
    }
    public float DEFENSE
    {
        get { return defense; }
        set
        {
            if(defense != value)
            {
                defense = value;
                OnAttrChanged?.Invoke(this, new OnAttrChangedEventArgs
                {
                    attr = PlayerAttributePanelUI.Attr.DEFENSE
                });
            }
        }
    }
}

PlayerAttributePanelUI

public class PlayerAttributePanelUI : MonoBehaviour
{
    public enum Attr
    {
        HP,
        MP,
        DEFENSE,
    }
    private void Start()
    {
        Player.Instance.OnAttrChanged += Player_OnAttrChanged;
    
        UpdateUI(Attr.HP);
        UpdateUI(Attr.MP);
        UpdateUI(Attr.DEFENSE);
    }
    private void UpdateUI(Attr attr)
    {
        switch (attr)
        {
            case Attr.HP:
                hpText.text = Player.Instance.HP.ToString();
                hpMaxText.text = Player.Instance.MaxHp.ToString();
                hpBar.fillAmount = Player.Instance.HP / Player.Instance.MaxHp;
                break;
            case Attr.MP:
                mpText.text = Player.Instance.MP.ToString();
                mpMaxText.text = Player.Instance.MaxMp.ToString();
                mpBar.fillAmount = Player.Instance.MP / Player.Instance.MaxMp;
                break;
            case Attr.DEFENSE:
                defenseText.text = Player.Instance.DEFENSE.ToString();
                defenseMaxText.text = Player.Instance.MaxDefense.ToString();
                defenseBar.fillAmount = Player.Instance.DEFENSE /                     Player.Instance.MaxDefense;
                break;
        }
    }
    private void Player_OnAttrChanged(object sender, Player.OnAttrChangedEventArgs e)
    {
        UpdateUI(e.attr);
    }
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号