Unity实现经验条动态自适应

在游戏开发中,经验有用到分段式经验条的情况,但是这种分段式分辨率仅仅靠Unity自带的锚点或者以宽,或者高,或者Expand模式等,无法做到完美适配,因此就需要通过代码根据窗口不同的分辨率计算得到比例,然后动态赋值进行自适应。

正常的经验条在正常屏幕比例下的显示情况
在这里插入图片描述

当我宽度进行拉伸时,发现背景和经验条就不适配了
在这里插入图片描述

当我以高度进行拉伸时,也是如此,因此我们就需要通过代码进行动态适配

在这里插入图片描述

这是Unity中按照标准自定义分辨率显示的经验条,是通过Grid Layout Group组件下设置了10张同样的图片,将图片的Image Type改为Filled,利用Fill Amount属性对每格经验条的比例进行显示,这里的Cell Size也是根据整个画布的长度,以及每个Item之间的间隙,计算出来的,我的Canvas分辨率是1334 * 768,因此Canvas的长度是1334,Exp的图标的Width是76,经验条的背景的小间隙的左边是8,右边是10,每个Item的间隙是10,我们10个Item,就意味着有9个间隙,因此1334- (8+10+76 + 9 x 10) = 1150, 由于有10个Item,因此每个Item的长度就是115,因此这个Cell Size就是115
在这里插入图片描述
在写代码进行动态适配之前,我们还需要对Canvas做一个基础设置,就是我们以高进行拉伸以自适应宽度,如果你想以宽进行拉伸自适应也是可以的
在这里插入图片描述

我们首先得到是当前Canvas的高度 / 当前实际屏幕高度,得到当前画布和真实屏幕高度的比值,通过这个比值计算出当前屏幕的宽度,接下来我们要计算每个经验格子的宽度,于是就将我们根据动态计算的出来的 (当前屏幕宽度- 184)/ 10 = 单个格子经验条的宽度,这个184其实就是上面说的(8+10+76 + 9 x 10)就是这些间隙,得到之后,将格子背景,和格子本身的Grid Layout Group的Width进行赋值,便可以实现动态自适应。

/// <summary>
        /// 经验条根据Canvas以Height拉伸进行自适应宽度
        /// </summary>
        private void AutoAdaptExp()
        {
            float rate = 1.0f * Consts.ScreenHeight / Screen.height;
            float screenWidth = Screen.width * rate;
            float width = (screenWidth - 184) / 10;
            mItemGridGroup.cellSize = new Vector2(width, 7);
            mBGGridGroup.cellSize = new Vector2(width, 7);
        }

        private void Update()
        {
            if (Time.frameCount % 10 == 0)
            {
                AutoAdaptExp();
            }
        }

测试结果,以高度进行拉伸,完美适配
在这里插入图片描述
以宽度进行拉伸,也是完美适配
在这里插入图片描述

适配完成后,就简单说下如何根据经验赋值,通常来说就是通过当前经验和当前等级所需经验的比值得到Index,小于Index也就是代表index是满的经验,大于Index说明这个经验值不足,唯一需要计算的就是等于Index的情况,通过取余得到当前格子的经验,与整个格子经验的比值就得得到当前Image的fillAmount,下面贴出代码

        private void RefreshUI()
        {
            PlayerData pd = LoginScene.Instance.PlayerData;
            AutoAdaptExp();
            Image[] itemImgs = mItemGridGroup.GetComponentsInChildren<Image>();
            int exp = (int)(1.0f * PECommon.GetExpUpByLv(pd.lv) / 100) * 100 / itemImgs.Length;
            int index = pd.exp / exp;
            for (int i = 0; i < itemImgs.Length; i++)
            {
                Image img = itemImgs[i];
                if (i < index)
                {
                    img.fillAmount = 1;
                }
                else if (i == index)
                {
                    float a = (pd.exp % (exp * index * 1.0f)) / exp;
                    img.fillAmount = (pd.exp % (exp * index * 1.0f)) / exp;
                }
                else
                {
                    img.fillAmount = 0;
                }
            }
        }
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值