Giter Site home page Giter Site logo

feifeid47 / unity-async-uiframe Goto Github PK

View Code? Open in Web Editor NEW
233.0 8.0 31.0 756 KB

简单易用的Unity异步UI框架。 足够轻量,无第三方依赖。 兼容多种资源管理系统(Addressable、YooAssets等)。支持使用HybridCLR热更新。 支持自动引用。 支持对UI面板的销毁控制,使内存优化更方便。 支持子UI,子子UI,子子子UI......

License: Apache License 2.0

C# 100.00%
unity unity3d ugui uiframework uiframe

unity-async-uiframe's Issues

导入报错

Assets\Editor\Scripts\UIAutoReference.cs(24,13): error CS0103: The name 'PrefabStage' does not exist in the current context

建议将 OnAssetRequest 签名改一下,返回Task

    public static Func<Type, Task<GameObject>> OnAssetRequest;

    private static async Task<GameObject> RequestInstance(Type type)
        {
            ...
            var refInstance = await OnAssetRequest?.Invoke(type);//此处可能需要进一步判空
            ...
            return instance;
        }

使用:

using Feif.UIFramework;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
    Dictionary<Type, GameObject> handles=new Dictionary<Type, GameObject>();
    void Start()
    {
        UIFrame.OnAssetRequest += OnAssetRequest;
    }

    private async Task<GameObject> OnAssetRequest(Type type)
    {
        var handle = (GameObject)null;
        if (!handles.ContainsKey(type))
        {
            handle=handles[type] ;
        }
        await Task.Yield(); // 这个演示了调用异步,与签名的 async 呼应,此处可改为资源管理的 异步api
        return handle;
    }
}

Task 默认情况下在 webgl不支持,可以取巧支持“异步”
VolodymyrBS/WebGLThreadingPatcher#3

有top层和hud的实现吗

看起来是只有panel层和window层
我不知道window层算不算子层,能不能独立于panel的控制。。比如做hud,它需要做成top层,不管panel和window怎么切换,hud都不会动,除非有需要主动隐藏它。

UIFrame中Release函数,迭代器修改了自己

UIFrame中Release函数,迭代器修改了自己

///


/// 强制释放已经关闭的UI,即使UI的AutoDestroy为false,仍然释放该资源
///

public static void Release()
{
foreach (var item in instances)
{
if (item.Value != null && !item.Value.activeInHierarchy)
{
UIFrame.Destroy(item.Value);
OnAssetRelease?.Invoke(item.Key);
instances.Remove(item.Key);
}
}
}

子UI打开会产生父UI之外的UI实例化Gameobject,是否有不新增实例子UI的方法。

private void UpdateSelect()
{
this.btnSign.ToggleActive(this.mSelectIndex == 0);
this.btnDailyTask.ToggleActive(this.mSelectIndex == 1);
this.btnWeekTask.ToggleActive(this.mSelectIndex == 2);
this.btnAchievement.ToggleActive(this.mSelectIndex == 3);

        for (int i = 0; i < this.Children.Count; i++)
        {
            if (i == this.mSelectIndex)
            {
                UIFrame.Show(this.Children[i]);
            }
            else
            {
                UIFrame.Hide(this.Children[i]);
            }
        }
    }

我想在WebGL上用..但是Task.Delay() 不能在WebGL上使用..我就把整个框架替换成了UniTask

可以全局将作者的 Task 替换成 UniTask ,唯一需要更改的一个地方
这个地方需要改成 AsyncLazy 以支持委托中的多次 await

/// <summary>
/// 资源请求
/// </summary>
public static event Func<Type, AsyncLazy<GameObject>> OnAssetRequest;
private static async UniTask<GameObject> RequestInstance(Type type, UIData data)
        {
            if (type == null) throw new NullReferenceException();

            if (instances.TryGetValue(type, out var instance)) return instance;

            var assetRequestTask = await OnAssetRequest?.Invoke(type)!;
            
            var parent = IsPanel(assetRequestTask.GetComponent<UIBase>()) ? PanelLayer : WindowLayer;
            instance = await UIFrame.Instantiate(assetRequestTask, parent, data);
            instances[type] = instance;
            return instance;
        }

这个是后面用到的地方
以作者Demo 1 中的资源加载为例 核心初始化的脚本更改后:

using Feif.UI;
using Feif.UIFramework;
using System;
using System.Threading.Tasks;
using Cysharp.Threading.Tasks;
using UnityEngine;

namespace Feif
{
    public class Demo1Launcher : MonoBehaviour
    {
        [SerializeField] private GameObject stuckPanel;

        // 使用UIFrame时要先确保UIFrame的Awake已经执行过了
        private void Start()
        {
            // 注册资源请求释放事件
            UIFrame.OnAssetRequest += OnAssetRequest;
            UIFrame.OnAssetRelease += OnAssetRelease;
            // 注册UI卡住事件
            // 加载时间超过0.5s后触发UI卡住事件
            UIFrame.StuckTime = 0.5f;
            UIFrame.OnStuckStart += OnStuckStart;
            UIFrame.OnStuckEnd += OnStuckEnd;

            var data = new UITestAData();
            data.Title = "This is UITestA";
            UIFrame.Show<UITestA>(data);
        }
        // 资源请求事件,type为UI脚本的类型
        // 可以使用Addressables,YooAssets等第三方资源管理系统
        private AsyncLazy<GameObject> OnAssetRequest(Type arg)
        {
            var lazy = UniTask.Lazy(async () =>
                await MyLoadAsync(arg)
            );
            return lazy;
        }

        private async UniTask<GameObject> MyLoadAsync(Type type)
        {
            GameObject obj;
            if (UIFrame.IsPanel(type))
            {
                obj = await Resources.LoadAsync<GameObject>($"Demo1/Panel/{type.Name}") as GameObject;

            }
            else
            {
                obj = await Resources.LoadAsync<GameObject>($"Demo1/Window/{type.Name}") as GameObject;
            }

            return obj;
        }
        
        // 资源释放事件
        private void OnAssetRelease(Type type)
        {
            // TODO
        }

        private void OnStuckStart()
        {
            stuckPanel.SetActive(true);
        }

        private void OnStuckEnd()
        {
            stuckPanel.SetActive(false);
        }
    }
}

加个功能:在创建 UIFrameSettings 时自动捕获代码模板。

效果如下:
autosigned

代码如下:

using UnityEngine;

namespace Feif.UIFramework.Editor
{
    [CreateAssetMenu(fileName = "UIFrameSetting", menuName = "UIFrame/UIFrameSetting", order = 0)]
    public class UIFrameSetting : ScriptableObject
    {
        public TextAsset UIBaseTemplate;
        public TextAsset UIComponentTemplate;
        public TextAsset UIPanelTemplate;
        public TextAsset UIWindowTemplate;
        public bool AutoReference = true;

#if UNITY_EDITOR
        private void Reset()
        {
            var ms = UnityEditor.MonoScript.FromScriptableObject(this);
            var path = UnityEditor.AssetDatabase.GetAssetPath(ms);
            Debug.Log($"{nameof(UIFrameSetting)}:   path = {path}");
            var resPath = System.IO.Path.GetDirectoryName(path).Replace("Scripts", "Resources");
            var fields = GetType().GetFields();
            foreach (var field in fields)
            {
                if (field.Name.EndsWith("Template"))
                {
                    var file = System.IO.Path.Combine(resPath, $"{field.Name}.txt");
                    var res = UnityEditor.AssetDatabase.LoadAssetAtPath<TextAsset>(file);
                    field.SetValue(this, res);
                }
            }
            UnityEditor.EditorUtility.SetDirty(this);
        }
#endif
    }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.