目录

1.什么是ScriptableObject

2.创建一个ScriptableObject类

3.CreateInstance简单使用

4.So转JSON存取

5.通过Excel配置So文件


1.什么是ScriptableObject

ScriptableObject - Unity 手册

        如题,一个可以在Unity编辑器中方便编辑数据的工具

        其概述

        在unity之中如何操作:

        一个让需要的类去继承该类,并且序列化或者有公共变量,即可在Inspector窗口看到它们

2.创建一个ScriptableObject类

        先让需要的类去继承ScriptableObject

使用CreateAssetMenu创建一个ScriptableObjec配置文件

[CreateAssetMenu(fileName ="文件名" ,menuName ="菜单名",order =0)]

当我的脚本中写了如下变量之后:

  public int a;
  public string b;
  [SerializeField]
  private GameObject c;

该文件就会出现对应的变量


3.CreateInstance简单使用

 首先,我有一个继承ScriptableObject的脚本,里面有三个变量和一个打印方法

[CreateAssetMenu(fileName ="文件名" ,menuName ="菜单名",order =0)]
public class LearnScripttableObject : ScriptableObject
{
    public int a;
    public string b;
    [SerializeField]
    private GameObject c;
    public void printinfo()
    {
        Debug.Log(a);
        Debug.Log(b);
        Debug.Log(c);
    }
}

        之后可以到其他脚本之中进行创建并修改

   private void Awake()
   { 
   dates = ScriptableObject.CreateInstance<LearnScripttableObject>();
       dates.a = 10;
       dates.b = "任意字符串";
       dates.printinfo();
   }

4.So转JSON存取

Unity数据持久化 之 Json序列化与反序列化_unity json 反序列化-CSDN博客

Unity数据持久化 之 LitJson序列化与反序列化_unity litjson-CSDN博客

这里以Utility作演示

public class ScritableObjectPersistence :MonoBehaviour
{
    LearnScripttableObject dates;

    private void Awake()
    { 
    dates = ScriptableObject.CreateInstance<LearnScripttableObject>();
        dates.a = 10;
        dates.b = "任意字符串";
        dates.printinfo();
        string str =JsonUtility.ToJson(dates);
        File.WriteAllText(Application.persistentDataPath+"text.json",str);
        print(Application.persistentDataPath);
    }   
}

取(override原有的数据)

    string newstr = File.ReadAllText(Application.persistentDataPath + "text.json");
    JsonUtility.FromJsonOverwrite(newstr, dates);

5.通过Excel配置So文件

        下面是我写的一个做本地化的脚本 可以不用关心其内部逻辑

        想要做的是 将下面这个表格读取到So文件之中

        如果你发现和你的编辑器不太一样 是因为我使用了Odin插件        

之后一键导表 

 

补充编辑器拓展代码: 

using System;
using System.Collections.Generic;
using System.IO;
using OfficeOpenXml;
using UnityEditor;
using UnityEngine;
using UnityEngine.Video;

namespace MieMieFrameTools
{
    public class ExcelLocalizationImporterEditor : EditorWindow
    {
        private LocalizationSetting localizationSettingInstance;
        private string excelFilePath;
        private string dragDropFeedback = "拖放 Excel 文件到此区域";
        private GUIStyle normalStyle;
        private GUIStyle draggedStyle;

        [MenuItem("MieMieFrameTools/Excel/本地化Excel导入工具")]
        static void OpenWindow()
        {
            GetWindow<ExcelLocalizationImporterEditor>("本地化Excel导入工具");
        }

        void OnEnable()
        {
            normalStyle = new GUIStyle
            {
                alignment = TextAnchor.MiddleCenter,
                normal = new GUIStyleState { background = EditorGUIUtility.whiteTexture },
                border = new RectOffset(2, 2, 2, 2),
                padding = new RectOffset(10, 10, 10, 10)
            };
            normalStyle.normal.textColor = Color.grey;

            var grayTex = new Texture2D(1, 1);
            grayTex.SetPixel(0, 0, new Color(0.85f, 0.85f, 0.85f));
            grayTex.Apply();
            draggedStyle = new GUIStyle(normalStyle)
            {
                normal = new GUIStyleState { background = grayTex, textColor = Color.black }
            };
        }

        void OnGUI()
        {
            GUILayout.Label("本地化Excel导入工具", EditorStyles.boldLabel);
            GUILayout.Space(10);

            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            GUILayout.Label("LocalizationSetting 实例", EditorStyles.boldLabel);
            localizationSettingInstance = (LocalizationSetting)EditorGUILayout.ObjectField(
                localizationSettingInstance, typeof(LocalizationSetting), false);
            EditorGUILayout.EndVertical();

            GUILayout.Space(10);

            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            GUILayout.Label("Excel 文件导入", EditorStyles.boldLabel);

            Rect dropArea = GUILayoutUtility.GetRect(0f, 60f, GUILayout.ExpandWidth(true));
            if (string.IsNullOrEmpty(excelFilePath))
            {
                GUI.Box(dropArea, dragDropFeedback, normalStyle);
            }
            else
            {
                GUI.Box(dropArea, Path.GetFileName(excelFilePath), draggedStyle);
            }

            HandleDragAndDrop(dropArea);
            EditorGUILayout.EndVertical();

            GUILayout.Space(10);

            if (GUILayout.Button("执行导入", GUILayout.Height(30)))
            {
                if (localizationSettingInstance == null)
                {
                    EditorUtility.DisplayDialog("错误", "请先选择 LocalizationSetting 实例", "确定");
                    return;
                }
                if (string.IsNullOrEmpty(excelFilePath))
                {
                    EditorUtility.DisplayDialog("错误", "请先拖放 Excel 文件", "确定");
                    return;
                }

                ImportLocalizationFromExcel(excelFilePath, localizationSettingInstance);
                EditorUtility.SetDirty(localizationSettingInstance);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                EditorUtility.DisplayDialog("成功", "导入完成", "确定");
            }
        }

        void HandleDragAndDrop(Rect area)
        {
            Event currentEvent = Event.current;
            switch (currentEvent.type)
            {
                case EventType.DragUpdated:
                case EventType.DragPerform:
                    if (area.Contains(currentEvent.mousePosition))
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
                        if (currentEvent.type == EventType.DragPerform)
                        {
                            DragAndDrop.AcceptDrag();
                            foreach (string draggedPath in DragAndDrop.paths)
                            {
                                if (draggedPath.EndsWith(".xlsx"))
                                {
                                    excelFilePath = draggedPath;
                                    Repaint();
                                }
                                else
                                {
                                    EditorUtility.DisplayDialog("错误", "仅支持 .xlsx 文件", "确定");
                                }
                            }
                        }
                    }
                    break;

                case EventType.DragExited:
                    if (string.IsNullOrEmpty(excelFilePath))
                    {
                        dragDropFeedback = "拖放 Excel 文件到此区域";
                        Repaint();
                    }
                    break;
            }
        }

        static void ImportLocalizationFromExcel(string filePath, LocalizationSetting localizationSetting)
        {
            localizationSetting.dataBag = new Dictionary<string, LocalizationTypeAllData>();

            FileInfo file = new FileInfo(filePath);
            using (ExcelPackage package = new ExcelPackage(file))
            {
                ExcelWorksheet worksheet = package.Workbook.Worksheets[1];

                // 动态获取列索引
                int resourceTypeCol = -1;
                int resourcePathCol = -1;
                List<int> languageColumns = new List<int>();
                List<E_LanuageType> languageTypes = new List<E_LanuageType>();

                for (int col = 1; col <= worksheet.Dimension.End.Column; col++)
                {
                    string colName = worksheet.Cells[1, col].Value?.ToString()?.Trim();
                    if (Enum.TryParse<E_LanuageType>(colName, true, out var languageType))
                    {
                        languageColumns.Add(col);
                        languageTypes.Add(languageType);
                    }
                    else if (colName == "资源类型")
                    {
                        resourceTypeCol = col;
                    }
                    else if (colName == "资源路径")
                    {
                        resourcePathCol = col;
                    }
                }

                if (resourceTypeCol == -1 || resourcePathCol == -1 || languageColumns.Count == 0)
                {
                    Debug.LogError("Excel 列结构不正确,缺少必要列");
                    return;
                }

                int rowCount = worksheet.Dimension.End.Row;
                for (int row = 2; row <= rowCount; row++)
                {
                    var typeName = worksheet.Cells[row, 1].Value?.ToString()?.Trim();
                    var contentKey = worksheet.Cells[row, 2].Value?.ToString()?.Trim();
                    var resourceType = worksheet.Cells[row, resourceTypeCol].Value?.ToString()?.Trim();
                    var resourcePath = worksheet.Cells[row, resourcePathCol].Value?.ToString()?.Trim();

                    if (string.IsNullOrEmpty(typeName) || string.IsNullOrEmpty(contentKey))
                    {
                        continue;
                    }

                    if (!localizationSetting.dataBag.ContainsKey(typeName))
                    {
                        localizationSetting.dataBag[typeName] = new LocalizationTypeAllData();
                    }

                    LocalizationTypeAllData typeAllData = localizationSetting.dataBag[typeName];
                    LocalizationModel model = null;
                    foreach (var m in typeAllData.GetIModelList())
                    {
                        if (m.contentKey == contentKey)
                        {
                            model = m;
                            break;
                        }
                    }

                    if (model == null)
                    {
                        model = new LocalizationModel(contentKey);
                        typeAllData.GetIModelList().Add(model);
                    }

                    for (int i = 0; i < languageColumns.Count; i++)
                    {
                        var languageType = languageTypes[i];
                        var content = worksheet.Cells[row, languageColumns[i]].Value?.ToString()?.Trim();

                        L_Object lObject = null;
                        switch (resourceType.ToLower())
                        {
                            case "文本":
                                if (string.IsNullOrEmpty(content))
                                {
                                    continue; // 文本内容为空则跳过
                                }
                                lObject = new L_Text { content = content };
                                break;
                            case "图片":
                                if (string.IsNullOrEmpty(resourcePath) || resourcePath.ToLower().Equals("null"))
                                {
                                    continue; // 图片资源路径为 null 则跳过
                                }
                                lObject = new L_Image { content = UnityEngine.Resources.Load<Sprite>(resourcePath) };
                                break;
                            case "音频":
                                if (string.IsNullOrEmpty(resourcePath) || resourcePath.ToLower().Equals("null"))
                                {
                                    continue; // 音频资源路径为 null 则跳过
                                }
                                lObject = new L_Audio { content = UnityEngine.Resources.Load<AudioClip>(resourcePath) };
                                break;
                            case "视频":
                                if (string.IsNullOrEmpty(resourcePath) || resourcePath.ToLower().Equals("null"))
                                {
                                    continue; // 视频资源路径为 null 则跳过
                                }
                                lObject = new L_Video { content = UnityEngine.Resources.Load<VideoClip>(resourcePath) };
                                break;
                            case "textmeshpro":
                                if (string.IsNullOrEmpty(content))
                                {
                                    continue; // 文本内容为空则跳过
                                }
                                lObject = new L_Tmp { content = content };
                                break;
                            case "精灵图":
                                if (string.IsNullOrEmpty(resourcePath) || resourcePath.ToLower().Equals("null"))
                                {
                                    continue; // 精灵图资源路径为 null 则跳过
                                }
                                lObject = new L_Sprite { content = UnityEngine.Resources.Load<Sprite>(resourcePath) };
                                break;
                            default:
                                continue;
                        }

                        if (lObject != null)
                        {
                            model.lanuageModeDict[languageType] = lObject;
                        }
                    }
                }
            }
        }
    }
}

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐