3.提示面板

3.提示面板


3.1 拼面板

创建普通通用按钮

创建窗口组件和窗口内部组件。对着示意图拼。命名规则要符合窗口的命名规则。


选择好资源和代码的发布的路径 进行发布


注意:对于一个面板我们要用到两个代码,一个是FGUI发布的代码,用于自动获取对象的,另一个是继承WIndow类的代码,用来写逻辑的。这样每次发布代码,也不会覆盖掉逻辑。两套代码放到不同的路径下


3.2 功能制作

导入字体到Resources文件夹下 把音乐文件设置为导出 在UIManager构造函数中设置字体和音乐

//默认字体
UIConfig.defaultFont = "UI/STHUPO";
//默认音效
UIPackage.AddPackage("UI/Public");
UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Public/btnMusic");

UIManager构造函数中绑定注册所有自定义类

//注册相关的代码
LoginBinder.BindAll();

在UIManager添加加载组件方法。传入包名和组件名。遍历加载包和依赖包。创建组件并返回。

/// <summary>
/// 加载组件 
/// </summary>
/// <param name="packageName">包名</param>
/// <param name="componentName">组件名</param>
/// <returns></returns>
public GComponent LoadComponent(string packageName, string componentName)
{
    //加载包
    UIPackage package = UIPackage.AddPackage("UI/" + packageName);
    //加载依赖包
    foreach (var item in package.dependencies)
    {
        UIPackage.AddPackage("UI/" + item["name"]);
    }
    
    GComponent component = UIPackage.CreateObject(packageName, componentName).asCom;
    //component.MakeFullScreen();
    return component;
}

创建TipWindow类 继承Window 注意让FGUI发布出来的代码加上前缀重新发布防止重名

public class TipWindow : Window
{
}

重写初始化方法中加载TipWindow对应的UI组件并设置为内容面板,将内容面板设置为全屏显示, 设置该窗口为模态(禁止和其他窗口交互)

protected override void OnInit()
{
    base.OnInit();

    // 加载TipWindow对应的UI组件并设置为内容面板
    this.contentPane = UIManager.Instance.LoadComponent("Login", "TipWindow");

    // 将内容面板设置为全屏显示
    this.contentPane.MakeFullScreen();

    // 设置该窗口为模态(禁止和其他窗口交互)
    this.modal = true;
}

创建公共改变提示信息的方法,把当前Window的contentPane转成UI_TipWindow得到其frame中的文本并设置

public void ChangeInfo(string info)
{
    // 通过窗口关联的组件转化成对应的组件拓展类(因为在管理器中注册了,所以可以转换类型)
    // 然后获取其中的组件或元件,并修改其内容
    (this.contentPane as UI_TipWindow).m_frame.m_txtInfo.text = info;
}

给提示窗口添加显示和隐藏动效。直接右键空白区域改变透明度让提示窗口淡入淡出。

重写显示和隐藏动效的方法。在动画播完的回调后再调用基类的显示和隐藏动效的方法。否则因为先调用了基类方法会先被显示或隐藏则动效不生效。

protected override void DoShowAnimation()
{
    // 播放内容面板上名为"show"的过渡动画,并在动画完成后调用基类的DoShowAnimation方法
    this.contentPane.GetTransition("show").Play(base.DoShowAnimation);
}

protected override void DoHideAnimation()
{
    // 播放内容面板上名为"hide"的过渡动画,并在动画完成后调用基类的DoHideAnimation方法
    this.contentPane.GetTransition("hide").Play(base.DoHideAnimation);
}

创建Main脚本 进行提示窗口的测试

void Start()
{
    TipWindow win = UIManager.Instance.ShowWindow<TipWindow>();
    win.ChangeInfo("欢迎进入游戏");
}

3.3 代码

UIManager

using FairyGUI;
using Login;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIManager
{
    private static UIManager instance = new UIManager();
    public static UIManager Instance => instance;
    //用于存储已经显示的 UI面板
    private Dictionary<string, GComponent> panelDic = new Dictionary<string, GComponent>();
    //用于存储已经显示的 窗口
    private Dictionary<string, Window> windowDic = new Dictionary<string, Window>();
        
    private UIManager()
    {
        //默认字体
        UIConfig.defaultFont = "UI/STHUPO";
        //默认音效
        UIPackage.AddPackage("UI/Public");
        UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Public/btnMusic");

        //适配相关的设置
        GRoot.inst.SetContentScaleFactor(1365, 768, UIContentScaler.ScreenMatchMode.MatchHeight);

        //设置模态半透明程度
        UIConfig.modalLayerColor = new Color(0, 0, 0, 0.5f);

        //注册相关的代码
        LoginBinder.BindAll();
    }

    //组件名和面板类名 是一致的 
    public T ShowPanel<T>(string packageName) where T:GComponent
    {
        Type panelType = typeof(T);
        string panelName = panelType.Name;
        //如果字典中有该面板的名字 证明已经创建过了 直接返回即可
        if (panelDic.ContainsKey(panelName))
        {
            panelDic[panelName].visible = true;
            return panelDic[panelName] as T;
        }

        //加载包和依赖包 
        //由于从Resources文件夹中加载包 会帮助我们判断重复没有 所以 这里既是重复执行也没什么问题
        UIPackage package = UIPackage.AddPackage("UI/" + packageName);
        foreach (var item in package.dependencies)
        {
            UIPackage.AddPackage("UI/" + item["name"]);
        }

        //创建组件面板
        GComponent panel = UIPackage.CreateObject(packageName, panelName).asCom;
        //把组件的尺寸设置的和逻辑分辨率一致
        panel.MakeFullScreen();
        GRoot.inst.AddChild(panel);
        //和父对象建立 宽高关联 这样 分辨率变化时 面板也不会出问题
        panel.AddRelation(GRoot.inst, RelationType.Size);

        //进行批处理 DC优化 开关开启
        panel.fairyBatching = true;
        //把当前显示的面板存起来 用于之后的隐藏
        panelDic.Add(panelName, panel);

        //把父类转换成对应的 子类
        return panel as T;
    }

    //显示窗口方法
    public T ShowWindow<T>() where T:Window,new()
    {
        Type type = typeof(T);
        string windowName = type.Name;

        //判断有没有面板
        if (windowDic.ContainsKey(windowName))
        {
            windowDic[windowName].Show();
            return windowDic[windowName] as T;
        }

        //创建并显示面板
        T win = new T();
        win.Show();

        //记录字典中
        windowDic.Add(windowName, win);

        return win;
    }

    public void HidePanel<T>(bool isDispose = false) where T:GComponent
    {
        Type panelType = typeof(T);
        string panelName = panelType.Name;
        //如果没有面板显示着  就直接返回
        if (!panelDic.ContainsKey(panelName))
            return;
        //希望移除面板
        if( isDispose )
        {
            //移除面板 并且从字典中移除
            panelDic[panelName].Dispose();
            panelDic.Remove(panelName);
        }
        //希望只是失活
        else
        {
            panelDic[panelName].visible = false;
        }
    }

    //隐藏窗口方法
    public void HideWindow<T>(bool isDispose = false)
    {
        Type type = typeof(T);
        string windowName = type.Name;

        if (windowDic.ContainsKey(windowName))
        {
            if(isDispose)
            {
                windowDic[windowName].Dispose();
                windowDic.Remove(windowName);
            }
            else
            {
                windowDic[windowName].Hide();
            }
        }
            
    }

    public T GetPanel<T>() where T:GComponent
    {
        Type panelType = typeof(T);
        string panelName = panelType.Name;
        //如果有这个面板 直接返回
        if (panelDic.ContainsKey(panelName))
            return panelDic[panelName] as T;

        return null;
    }

    //得到窗口
    public T GetWindow<T>() where T:Window
    {
        Type type = typeof(T);
        string windowName = type.Name;

        if (windowDic.ContainsKey(windowName))
        {
            return windowDic[windowName] as T;
        }

        return null;
    }

    //主要用于销毁所有面板 和 资源垃圾回收的方法
    public void ClearPanel(bool isGC = false)
    {
        //销毁所有面板 并且清空字典
        foreach (var item in panelDic.Values)
        {
            item.Dispose();
        }
        panelDic.Clear();

        if(isGC)
        {
            //释放所有包资源
            UIPackage.RemoveAllPackages();
            //垃圾回收
            GC.Collect();
        }
    }

    //清除所有窗口
    public void ClearWindow(bool isGC = false)
    {
        //销毁所有面板 并且清空字典
        foreach (var item in windowDic.Values)
        {
            item.Dispose();
        }
        windowDic.Clear();
        if(isGC)
        {
            //释放所有包资源
            UIPackage.RemoveAllPackages();
            //垃圾回收
            GC.Collect();
        }
    }


    /// <summary>
    /// 加载组件 
    /// </summary>
    /// <param name="packageName">包名</param>
    /// <param name="componentName">组件名</param>
    /// <returns></returns>
    public GComponent LoadComponent(string packageName, string componentName)
    {
        //加载包
        UIPackage package = UIPackage.AddPackage("UI/" + packageName);
        //加载依赖包
        foreach (var item in package.dependencies)
        {
            UIPackage.AddPackage("UI/" + item["name"]);
        }

        GComponent component = UIPackage.CreateObject(packageName, componentName).asCom;
        //component.MakeFullScreen();
        return component;
    }
}

TipWindow

using FairyGUI;  // 导入FairyGUI命名空间,用于使用UI组件
using Login;     // 导入Login命名空间,用于使用登录相关功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TipWindow : Window
{
    protected override void OnInit()
    {
        base.OnInit();

        // 加载TipWindow对应的UI组件并设置为内容面板
        this.contentPane = UIManager.Instance.LoadComponent("Login", "TipWindow");

        // 将内容面板设置为全屏显示
        this.contentPane.MakeFullScreen();

        // 设置该窗口为模态(禁止和其他窗口交互)
        this.modal = true;
    }

    public void ChangeInfo(string info)
    {
        // 通过窗口关联的组件转化成对应的组件拓展类(因为在管理器中注册了,所以可以转换类型)
        // 然后获取其中的组件或元件,并修改其内容
        (this.contentPane as UI_TipWindow).m_frame.m_txtInfo.text = info;
    }

    protected override void DoShowAnimation()
    {
        // 播放内容面板上名为"show"的过渡动画,并在动画完成后调用基类的DoShowAnimation方法
        this.contentPane.GetTransition("show").Play(base.DoShowAnimation);
    }

    protected override void DoHideAnimation()
    {
        // 播放内容面板上名为"hide"的过渡动画,并在动画完成后调用基类的DoHideAnimation方法
        this.contentPane.GetTransition("hide").Play(base.DoHideAnimation);
    }
}

Main

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    void Start()
    {
        TipWindow win = UIManager.Instance.ShowWindow<TipWindow>();
        win.ChangeInfo("欢迎进入游戏");
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏