栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

简单的UI框架 | 四、开发UIManager的单例和JsonUtlity调试

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

简单的UI框架 | 四、开发UIManager的单例和JsonUtlity调试

简单的UI框架

开发UIManager的单例和JsonUtlity调试


文章目录
  • 简单的UI框架
  • 一、UIManager的单例
  • 二、JsonUtlity调试
  • 总结



一、UIManager的单例

首先我们要知道什么是单例模式?
单例模式是比较常见的一种设计模式,目的是保证一个类只能有一个实例,而且自行实例化并向整个系统提供这个实例,避免频繁创建对象,节约内存。
单例模式的核心:
1、定义一个静态的对象,在外部访问,在内部构造。
2、构造方法私有化。

private static UIManager _instance;

    public static UIManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new UIManager();
            }
            return _instance;
        }
    }

标准的单例模式为上述代码,我们试着分析一下!
首先建立一个私有的静态变量 _instance。
这个变量什么时候赋值呢,这时候我们定义一个get方法。
当变量为空的时候我们就创建一个。

    private UIManager()
    {
        ParseUITypeJson();
    }

UIManager是一个私有的构造方法,他只能在类的内部调用,所以在这里是可以构造的。
这样的话我们在外界只需要访问这个静态的方法就可以。
当我们第一次访问这个静态方法的时候,这个变量是为空的,这样他就会创建这个UIManager。
这样在外界我们只需要UIManager.Instance就可以访问了,当我们在外面访问的时候,它就会自动构造访问ParseUITypeJson方法,就会去解析我们的Json文件。
这里面我们测试一下,我们建立一个测试方法:

  public void Test()
    {
        string path;
        panelPathDict.TryGetValue(UIType.Knapsack, out path);
        Debug.Log(path);
    }

然后我们新建一个脚本来调用这个方法:

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

public class GameRoot : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        UIManager.Instance.Test();
    }
}

当我们通过UIManager访问这个Instance时,他就会执行Get方法,他就会调用UIManager方法,就会调用ParseUITypeJson方法自动解析Json文件,然后再调用Text方法的时候就会直接输出里面的信息。

我们回到Unity中运行一下
发现控制面板报错

发现是Json文件解析的时候出现错误,那我们接下来对JsonUtility进行调试。

二、JsonUtlity调试

既然我们的Json解析不了这个类型的,那么我们就不要让他解析了。

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

[Serializable]
public class UIPanelInfo
{
    [NonSerialized]
    public UIType panelType;
    public string path;
}

**[NonSerialized]**表示不去解析。
不去解析怎么办,我们就把他变成字符串类型的通过get set方法使用。

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

[Serializable]
public class UIPanelInfo
{
   [NonSerialized]
    public UIType panelType;
    public string panelTypeString
    {
        get 
        {
            return panelType.ToString();
        }
        set 
        {
            UIType type = (UIType)System.Enum.Parse(typeof(UIType), value);
            panelType = type;
        }
    }
    public string path;
}

把Json文件中的panelType全部改成panelTypeString。
现在只有
public string panelTypeString
public string path;
实现序列话和反序列化的过程。
我们怎么样字符串转化成枚举类型,我只需要这个类每次解析完之后转化一下即可。
我们就需要给他一个get set方法,get方法用来序列化,set方法用来反序列化。
序列化的时候我们只需要取值所以只需要return就可以了。
set方法我们需要把这个值转化为UIType类型的。
这里我们用要System.Enum中的Parse方法,Parse方法可以用来转换一个特点的类型,typeof我们需要取到要转化的类型,value就代表字符串,就是我们要转化的值。
枚举类型我们不能用as UIType来转换类型,我们就只能使用强制转换。

再运行的时候我们发现还是报错,那么我们使用另一种方式!
让我们的UIPanelType继承与一个接口

public class UIPanelInfo : ISerializationCallbackReceiver

Unity无法自动序列化Dictionary数据结构,解决思路是,我们将Dictionary的数据存储在可以序列化的结构里(如List),然后通过Dictionary与可序列化结构的互操作,来完成Dictionary的存储与加载,而这个互操作的时机,就是ISerializationCallbackReceiver接口的实现。
这个接口会自带两个构造方法:

    public void OnAfterDeserialize()
    {
        throw new NotImplementedException();
    }

    public void OnBeforeSerialize()
    {
        throw new NotImplementedException();
    }

第一个构造方法时反序列化之后调用这个方法。
第二个构造方法时序列化之前调用这个方法。
反序列化是指从文本信息到对象的过程。序列化与之相反。
我们每次要序列化的时候先把属性先更改一下调用OnBeforeSerialize(),
序列化完成之后我们把文本转化成我们想要的枚举类型调用OnAfterDeserialize()。
所以我们只需要将两个构造方法改成:

    public void OnAfterDeserialize()
    {
        UIType type = (UIType)System.Enum.Parse(typeof(UIType), panelTypeString);
        panelType = type;
    }

    public void OnBeforeSerialize()
    {

    }

将value改成panelTypeString,即我们要转化的值。

接下来我们再运行一下。

这样我们就运行成功了!

总结

今天我们学会了如何构造一个标准的单例模式,同时我们也学会了当Unity无法自动自动序列化的时候,我们可以对脚本更改的两种方法。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/906037.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号