unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据

这篇具有很好参考价值的文章主要介绍了unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现思路如下:

1、定义一个二维数组数据类

2、奖数据类标记为 Serializable  并实现 unity内置的  ISerializationCallbackReceiver接口,接口提供了序列化和反序列化方法,参见官方文档(文档中给出了字典的序列化方法):Unity - Scripting API: ISerializationCallbackReceiver

3、使用unity序列化系统可识别的数据存储二维数组中的数据,这里使用一维数组

4、将数据类作为变量,重写主体类的inspector编辑器面板,并提供数据操作方法

代码如下:

数据类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class DataGrid2 : ISerializationCallbackReceiver
{
    #region 数据类内容
    /// <summary>
    /// 行名
    /// </summary>
    [HideInInspector] public List<string> rowNames = new List<string>();
    /// <summary>
    /// 列名
    /// </summary>
    [HideInInspector] public List<string> columnNames = new List<string>();

    [SerializeField] public string[,] data = new string[0, 0];

    #endregion

    #region 序列化与反序列化操作
    [HideInInspector]
    public string[] serializedArray;
    public void OnBeforeSerialize()
    {
        int rows = rowNames.Count;
        int cols = columnNames.Count;
        serializedArray = new string[rows * cols];
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                serializedArray[i * cols + j] = data[i, j];
            }
        }

    }
    public void OnAfterDeserialize()
    {
        int rows = rowNames.Count;
        int cols = columnNames.Count;
        data = new string[rows, cols];
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                data[i, j] = serializedArray[i * cols + j];
            }
        }
    }
    #endregion

    #region 对数据内容的操作
    public void AddRow()
    {
        rowNames.Add("RowName");
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            if (i == rowNames.Count - 1)
            {
                for (int j = 0; j < columnNames.Count; j++)
                {
                    newData[i, j] = "0";
                }
            }
            else
            {
                for (int j = 0; j < columnNames.Count; j++)
                {
                    newData[i, j] = data[i, j];
                }
            }

        }
        data = newData;
    }
    public void DeletedRow()
    {
        rowNames.RemoveAt(rowNames.Count - 1);
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            for (int j = 0; j < columnNames.Count; j++)
            {
                newData[i, j] = data[i, j];
            }

        }
        data = newData;
    }
    public void AddColumn()
    {
        columnNames.Add("ColumnName");
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            for (int j = 0; j < columnNames.Count; j++)
            {
                if (j == columnNames.Count - 1)
                    newData[i, j] = "0";
                else
                    newData[i, j] = data[i, j];
            }
        }
        data = newData;
    }
    public void DeletedColumn()
    {
        columnNames.RemoveAt(columnNames.Count - 1);
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            for (int j = 0; j < columnNames.Count; j++)
            {
                newData[i, j] = data[i, j];
            }

        }
        data = newData;
    }
    public void CleraData()
    {
        rowNames.Clear();
        columnNames.Clear();
        data = new string[0, 0];
    }
    #endregion

}

编辑器重写

public class TestDataGrid2 : MonoBehaviour
{
    public string name = "常规变量";
    public DataGrid2 data = new DataGrid2();
}

 文章来源地址https://www.toymoban.com/news/detail-716440.html

using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

[CustomEditor(typeof(TestDataGrid2))]
public class TestDataGrid2Editor : Editor
{
    GUIStyle green = new GUIStyle(EditorStyles.textArea);
    GUIStyle red = new GUIStyle(EditorStyles.textArea);
    TestDataGrid2 DG2;
    private void Awake()
    {
        DG2 = (TestDataGrid2)target;
    }
    float width = 0;
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        EditorGUILayout.LabelField("这是一个二维数组的配置文件,默认使用 string 类型");
        EditorGUILayout.LabelField("data : ");
        EditorGUILayout.BeginVertical();
        if (GUILayout.Button("清空数据"))
        {
            DG2.data.CleraData();
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.TextField($"{DG2.data.rowNames.Count}行/{DG2.data.columnNames.Count}列", red);
        for (int j = 0; j < DG2.data.columnNames.Count; j++)
        {
            DG2.data.columnNames[j] = EditorGUILayout.TextField(DG2.data.columnNames[j].ToString(), green);
        }
        EditorGUILayout.EndHorizontal();
        for (int i = 0; i < DG2.data.rowNames.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            DG2.data.rowNames[i] = EditorGUILayout.TextField(DG2.data.rowNames[i], green);
            for (int j = 0; j < DG2.data.columnNames.Count; j++)
            {
                DG2.data.data[i, j] = EditorGUILayout.TextField(DG2.data.data[i, j].ToString());
            }
            EditorGUILayout.EndHorizontal();
        }


        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("++添加尾行++"))
        {
            DG2.data.AddRow();
        }
        GUILayout.Space(15);
        if (GUILayout.Button("--删除尾行--"))
        {
            DG2.data.DeletedRow();
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("++添加尾列++"))
        {
            DG2.data.AddColumn();
        }
        GUILayout.Space(15);
        if (GUILayout.Button("--删除尾列--"))
        {
            DG2.data.DeletedColumn();
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();
        serializedObject.ApplyModifiedProperties();
    }
}

面板效果如图

unity 二维数组序列化,unity笔记,c#,unity

unity 二维数组序列化,unity笔记,c#,unity

 附:将数据类作为持久化数据保存,提取编辑器面板类,在作为变量使用时,也作为子面板绘制

数据类

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "DataGrid", menuName = "DataGrid", order = 10)]
public class DataGrid : ScriptableObject, ISerializationCallbackReceiver
{
    #region 数据内容
    [HideInInspector] public List<string> rowNames = new List<string>();
    [HideInInspector] public List<string> columnNames = new List<string>();
    [SerializeField]
    public string[,] data = new string[0, 0];
    #endregion
    #region  序列化和反序列化
    [HideInInspector]
    public string[] serializedArray;
    public void OnBeforeSerialize()
    {
        int rows = rowNames.Count;
        int cols = columnNames.Count;
        serializedArray = new string[rows * cols];
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                serializedArray[i * cols + j] = data[i, j];
            }
        }

    }

    public void OnAfterDeserialize()
    {
        int rows = rowNames.Count;
        int cols = columnNames.Count;
        data = new string[rows, cols];
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                data[i, j] = serializedArray[i * cols + j];
            }
        }
    }
    #endregion

    #region 数据操作
    public void AddRow()
    {
        rowNames.Add("RowName");
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            if (i == rowNames.Count - 1)
            {
                for (int j = 0; j < columnNames.Count; j++)
                {
                    newData[i, j] = "0";
                }
            }
            else
            {
                for (int j = 0; j < columnNames.Count; j++)
                {
                    newData[i, j] = data[i, j];
                }
            }

        }
        data = newData;
    }
    public void DeletedRow()
    {
        rowNames.RemoveAt(rowNames.Count - 1);
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            for (int j = 0; j < columnNames.Count; j++)
            {
                newData[i, j] = data[i, j];
            }

        }
        data = newData;
    }
    public void AddColumn()
    {
        columnNames.Add("ColumnName");
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            for (int j = 0; j < columnNames.Count; j++)
            {
                if (j == columnNames.Count - 1)
                    newData[i, j] = "0";
                else
                    newData[i, j] = data[i, j];
            }
        }
        data = newData;
    }
    public void DeletedColumn()
    {
        columnNames.RemoveAt(columnNames.Count - 1);
        string[,] newData = new string[rowNames.Count, columnNames.Count];
        for (int i = 0; i < rowNames.Count; i++)
        {
            for (int j = 0; j < columnNames.Count; j++)
            {
                newData[i, j] = data[i, j];
            }

        }
        data = newData;
    }
    public void CleraData()
    {
        rowNames.Clear();
        columnNames.Clear();
        data = new string[0, 0];
    }
    #endregion
}

 编辑器面板

using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(DataGrid))]
public class DataGridEditor : Editor
{
    DataGrid grid;
    GUIStyle green = new GUIStyle(EditorStyles.textArea);
    GUIStyle red = new GUIStyle(EditorStyles.textArea);
    private void Awake()
    {
        grid = (DataGrid)target;
        green.normal.textColor= Color.green;
        red.normal.textColor= Color.red;

    }
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        EditorGUILayout.LabelField("这是一个二维数组的配置文件,默认使用 string 类型");
        EditorGUILayout.LabelField("data : ");
        EditorGUILayout.BeginVertical();
        if (GUILayout.Button("清空数据"))
        {
            grid.CleraData();
            EditorUtility.SetDirty(grid);
            AssetDatabase.SaveAssets();
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.TextField($"{grid.rowNames.Count}行/{grid.columnNames.Count}列", red);
        for (int j = 0; j < grid.columnNames.Count; j++)
        {
            grid.columnNames[j] = EditorGUILayout.TextField(grid.columnNames[j].ToString(), green);
        }
        EditorGUILayout.EndHorizontal();
        for (int i = 0; i < grid.rowNames.Count; i++)
        {
            EditorGUILayout.BeginHorizontal();
            grid.rowNames[i] = EditorGUILayout.TextField(grid.rowNames[i], green);
            for (int j = 0; j < grid.columnNames.Count; j++)
            {
                grid.data[i, j] = EditorGUILayout.TextField(grid.data[i, j].ToString());
            }
            EditorGUILayout.EndHorizontal();
        }


        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("++添加尾行++"))
        {
            grid.AddRow();
            EditorUtility.SetDirty(grid);
            AssetDatabase.SaveAssets();
        }
        GUILayout.Space(15);
        if (GUILayout.Button("--删除尾行--"))
        {
            grid.DeletedRow();
            EditorUtility.SetDirty(grid);
            AssetDatabase.SaveAssets();
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.BeginHorizontal();

        if (GUILayout.Button("++添加尾列++"))
        {
            grid.AddColumn();
            EditorUtility.SetDirty(grid);
            AssetDatabase.SaveAssets();
        }
        GUILayout.Space(15);
        if (GUILayout.Button("--删除尾列--"))
        {
            grid.DeletedColumn();
            EditorUtility.SetDirty(grid);
            AssetDatabase.SaveAssets();
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();
        if (GUILayout.Button("保存/更新"))
        {
            EditorUtility.SetDirty(grid);
            AssetDatabase.SaveAssets();
        }
        serializedObject.ApplyModifiedProperties();
    }
}

 效果:

unity 二维数组序列化,unity笔记,c#,unity

 作为变量使用(借助 Editor.CreateEditor 方法):

unity 二维数组序列化,unity笔记,c#,unity

效果如下:

unity 二维数组序列化,unity笔记,c#,unity

 

 

到了这里,关于unity 通过 二维数组序列化 实现二维数组在编辑器面板查看和配置数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RabbitMQ 消息对象通过 Jackson 库消息转化器 序列化/反序列化 天坑!

    目录 1. 报错的背景 2. 问题分析 3. 最佳解决办法 a)使用 RabbitMQ 发送消息时,发送消息的类型为 MapString, Object,map 里面我 put 了一个 String, Long 类型,如下图: b)这里有一个前提:我清楚使用 org.springframework.amqp.rabbit.core.RabbitTemplate 来发送消息到 RabbitMQ 队列时,消息的序列

    2024年04月15日
    浏览(51)
  • Unity | 序列化(Serialized)和反序列化(NonSerialized)是什么意思

    一、什么是序列化 官方叙述: 序列化是将对象的状态信息转换为可以存储或传输的形式的过程。 人话叙述: 我们平时输入的代码,实际上是不能储存或者传输的,所以我们需要翻译一下,翻译成能储存或者翻译的文字,这个翻译的过程叫做序列化。 二、什么要序列化 问题

    2024年02月11日
    浏览(39)
  • Unity基于Google Protobuf序列化和反序列化小案例

    1.协议定义,简单实现传玩家的2D坐标    2.在Unity的Assets目录下创建一个Plugins文件夹(必须这样命名),此文件专门存放扩展文件, 再新建文件夹BaseInfolibrary,将Google.Protobuf.dll拖入  3.新建一个Test.cs脚本  脚本中引入命名空间 代码改进:通用序列化模板(只用来序列化Message)

    2024年02月15日
    浏览(24)
  • Unity序列化

    Unity 的序列化是作用于 C# 类的字段 而非属性。 序列化规则 对于需要被序列化的字段,需要遵守一些规则 访问修饰符是 public ,或者具有 SerializeField 特性 非 static 非 const 可以被序列化的字段类型 基础数据结构( int , float , double , bool , string 等) 枚举(32 位 或 以下) 固定大

    2024年02月06日
    浏览(33)
  • Unity——脚本与序列化

    数据序列化有以下几个主要的应用场景和目的: 1. 持久化存储:序列化可以将对象或数据结构转换为字节序列,使得其可以被存储在磁盘上或数据库中。通过序列化,我们可以将应用程序中运行时的数据持久化保存,以便在后续运行时重新加载和使用。 2. 数据传输:序列化

    2024年01月18日
    浏览(32)
  • unity中,什么是序列化资源?

    好的,以下是序列化资源(Serialized Asset)的详细解释,包括介绍、方法和举例: 在Unity中,序列化资源是指将Unity场景或预制件中的对象及其属性保存到磁盘上的文件中,以便在将来将其还原为原始状态。序列化资源文件可以包括场景文件(.unity)和预制件文件(.prefab),它

    2024年02月10日
    浏览(30)
  • 在Unity中使用Protobuf进行序列化

    目录 1.介绍 1.1 什么是Protobuf 1.2 Protobuf和其他数据序列化方案对比 2.下载Protobuf 2.1 方案一 使用VS的Nuget包管理器进行安装(推荐) 2.1.1安装Protobuff包 2.1.2拷贝.dll文件 2.2 方案二 从Github下载并自己生成.dll 2.2.1 下载Probuff 2.2.2 VS打开解决方案 2.2.3 安装.NET SDK 2.2.4 生成.dll文件 3

    2024年04月12日
    浏览(34)
  • Unity XML3——XML序列化

    ​ 序列化:把对象转化为可传输的字节序列过程称为序列化,就是把想要存储的内容转换为字节序列用于存储或传递 ​ 反序列化:把字节序列还原为对象的过程称为反序列化,就是把存储或收到的字节序列信息解析读取出来使用 1.准备数据结构 2.进行序列化 XmlSerializer:用

    2024年02月15日
    浏览(29)
  • 【工具篇】SerializableDictionary字典序列化Unity面板显示

    目录 一:导入插件 二:创建目标字典类 三:生成数据  四:自定义配置数据 Unity本身对字典这种数据结构没有序列

    2024年02月15日
    浏览(28)
  • 网络数据通信—ProtoBuf实现序列化和反序列化

    目录 前言 1.环境搭建 2. centos下编写的注意事项 3.约定双端交互接口 4.约定双端交互req/resp 5. 客户端代码实现 6.服务端代码实现 Protobuf还常用于通讯协议、服务端数据交换场景。那么在这个示例中,我们将实现一个网络版本的通讯录,模拟实现客户端与服务端的交互,通过P

    2024年02月04日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包