当前位置: 首页 > article >正文

Unity加载界面制作

效果

UI部分

结构

说下思路:

        因为是加载界面,所以最上层是一个Panel阻止所有的UI交互,这个Panel如果有图片就加一个图片,如果没有可以把透明度调到最大,颜色设为黑色.

        下面最核心的就是一个进度条了,有图片的话,将进度条的底放进来,将进度条锚点设为下中,将滑动块的尺寸设为0.

        然后将Handle的image组件移除,因为不使用这个展示滑块UI,而只使用它的功能.

        因为我将一个滑块图片放入之后使用Set Native Size来恢复尺寸,锚点将发生变化(我遇到的锚点变为左下),然后保存设置滑块会变回默认的锚点导致滑块变形,如下锚点

        这会导致位置偏差,即便我在保存前将锚点设为和此相同的情况,也不行.所以我直接将滑块尺寸设为0,将Handle的Image组件移除,在Handle下面再设置一个Image和Text,这样就避免的我们自身的滑块UI受到影响,最后调整一下我们的滑块位置.

        最后就是加载条了,如下结构设置一个image,尺寸和滑动条尺寸相同,但是:将Pivot设置为0, 0.5就是将自身中心设为最左端.将scale的x设为0.这样我们就可以通过将滑动条的滑动值设置给x,让加载条和加载进度保持一致

UI拼接部分就完毕了,你可以在Panel下继续添加其他装饰组件.

脚本部分

这样命名

using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

namespace JKD_Config.UI
{
    public class PopPanel_showScrollbar : MonoBehaviour
    {
        public Scrollbar scrollbar;

        public Transform img_loadingBottom;
        public TextMeshProUGUI text_showLoadingValue;

        Progress<float> progress;
        float currentProgress = 0;

        public void Init(IProgress<float> loadingProgress)
        {
            scrollbar = transform.GetComponentInChildren<Scrollbar>();
            scrollbar.value = 0;

            img_loadingBottom = scrollbar.transform.Find("img_loadingBottom");
            img_loadingBottom.localScale = new Vector3(0, 1, 1);

            text_showLoadingValue = transform.GetComponentInChildren<TextMeshProUGUI>();
            text_showLoadingValue.text = "";

            gameObject.SetActive(true);
            progress = ((Progress<float>)loadingProgress);
            progress.ProgressChanged += OnValueChanged;//注意线程安全
        }

        private void OnValueChanged(object _, float progress)
        {
            currentProgress = progress;
        }

        private void Update()
        {
            scrollbar.value = currentProgress;
            img_loadingBottom.localScale = new Vector3(currentProgress, 1, 1);
            text_showLoadingValue.text = string.Format("{0:P}", currentProgress);

            if (currentProgress >= 0.9f)
            {
                gameObject.SetActive(false);
                progress.ProgressChanged -= OnValueChanged;
                progress = null;
                currentProgress = 0;
            }
        }
    }
}

        这个脚本很简单,初始化的时候就激活这个面板,进入加载界面,接受一个IProgress<float> loadingProgress对象,这是.net中常用的报告进度的对象,我们获取这个对象目的是为了将我们的回调方法注册进去(即OnValueChanged方法).

        这里你可能疑惑为什么我的回调里面只是传递了一个float,而UI相关的更新却放在了Update中,而不是将UI更新直接放到回调方法中.为了保证线程安全,IProgress<float> loadingProgress对象拿到我们的回调是在后台线程执行的,而Unity的组件只能在主线程执行,所以才"多此一举".

示例

private IProgress<float> loadingProgress = new Progress<float>(); 
private void OnProgress(AssetLoaderContext assetLoaderContext, float progress)
        {
            Debug.Log($"Loading Model. Progress: {progress}");
            if (!Fm_BackModLib.Inst.popPanel_showScrollbar.gameObject.activeInHierarchy)
            {
                Fm_BackModLib.Inst.popPanel_showScrollbar.Init(loadingProgress);
            }

            loadingProgress.Report(progress);
        }

        假设你在进行一个耗时操作,这个OnProgress会不停地调用来传递一个float告知进度,这时我们就可以new一个进度对象,初始化我们的进度面板,然后因为OnProgress会不停地调用,进度对象的Report方法会传递进度.


http://www.kler.cn/news/362210.html

相关文章:

  • blender 三种曲线r Curve转化为hair curves
  • 打开游戏提示丢失(或找不到)XINPUT1_3.DLL的多种解决办法
  • Rust的泛型基础与实践
  • 构建后端为etcd的CoreDNS的容器集群(二)、下载最新的etcd容器镜像
  • 11. 盛最多水的容器 - 力扣(LeetCode)
  • linux介绍与基本指令
  • Docker:安装 Syslog-ng 的技术指南
  • Build an Android project and get a `.apk` file on a Debian 11 command line
  • Java项目-基于Springboot的车辆充电桩项目(源码+说明).zip
  • c++基础算法练习(1)
  • Android SELinux——调试工具audio2allow介绍(十三)
  • Linux系列-Linux的常见指令(三)
  • 错误0x80070522:客户端没有所需的特权
  • C++ set和map的模拟实现
  • 在Debian上安装向日葵
  • 深度学习-卷积神经网络-基于VGG16模型, 实现猫狗二分类(文末附带数据集下载链接, 长期有效)
  • oracle_查询建表语句
  • 【毕业设计】基于SpringBoot的网上商城系统
  • 【C语言刷力扣】2006.差的绝对值为K的数对数目
  • CTFHUB技能树之SQL——布尔盲注
  • 前端模块化技术 IIFE、CMD、UMD
  • 智能去毛刺:2D视觉引导机器人如何重塑制造业未来
  • MySQL 指定字段排序
  • 信息搜集 --前端js打点
  • 九、SQL 进阶之路:深入探索数据库查询的艺术
  • Chromium html<textarea>c++接口定义