Odin插件OnlyEditor模式在ForceBinary模式下的使用

起因:

1.Odin插件如果是源码的模式,或者Unity非ForceText模式下使用时。不支持OnlyEditor

2.OnlyEditor模式,仅支持Editor文件夹内的逻辑可用,且出包时,包体内没有相关代

需求:

1.希望Odin仅仅作为一个Editor下的工具使用,且只使用其自定义属性,和一些窗口。用来做一些工具开发,非常方便。

2.项目使用是Force Binary模式。 插件提供的OnlyEditor开关无法使用

3.把整个插件移到Editor文件夹下

解决思路:

1.查看了OnlyEditor的解释,大致意思是,Odin有一套序列化系统,如果不使用该系统。可以使用OnlyEditor模式

2.查看了插件提供的OnlyEditor相关的代码(反编译查看dll)。代码内识别了是否是源码模式,是否是ForceText模式。 只有两者都满足,才可以使用。

3.真正处理OnlyEditor的逻辑,主要有三部分。

a:修改了dll的平台设置

b:把代码移动到了Editor文件夹下

c:修改了几个config以及link.xml

解决办法:

真正处理OnlyEditor的逻辑,通过反射的方式,重新实现了一下。

上代码(需要放到插件sirenix文件夹内即可)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Sirenix.OdinInspector.Editor;
using UnityEditor;
using UnityEngine;
using Sirenix.Utilities;
using Sirenix.Serialization;

namespace Sirenix
{
    public class OdinOnlyEditor : MonoBehaviour
    {
        [MenuItem("Tools/Odin Inspector/限Editor下使用")]
        private static void OnlyEditor()
        {
            EditorOnlyModeConfig editorModeCfg = EditorOnlyModeConfig.Instance;
            Type type = typeof(EditorOnlyModeConfig);
            editorModeCfg.Update();
            BindingFlags flag = BindingFlags.NonPublic | BindingFlags.Instance;
            string[] files = type.GetField("globalAssemblyFiles", flag).GetValue(editorModeCfg) as string[];
            foreach (string str in ((IEnumerable<string>) files).Concat<string>((IEnumerable<string>) files))
            {
                if (File.Exists(str + ".backup.txt"))
                    File.Delete(str + ".backup.txt");
                File.Copy(str + ".meta", str + ".backup.txt");
            }

            string[] searchInFolders = new string[1]
            {
                SirenixAssetPaths.SirenixAssembliesPath.TrimEnd('/')
            };
            foreach (string asset in AssetDatabase.FindAssets("link", searchInFolders))
            {
                string assetPath = AssetDatabase.GUIDToAssetPath(asset);
                if (assetPath.ToLower().EndsWith(".xml"))
                {
                    if (File.Exists(assetPath + ".backup.txt"))
                        AssetDatabase.DeleteAsset(assetPath + ".backup.txt");
                    AssetDatabase.MoveAsset(assetPath, assetPath + ".backup.txt");
                }
            }
            string assetPath1 = AssetDatabase.GetAssetPath(GlobalConfig<GlobalSerializationConfig>.Instance);
            string fileName = Path.GetFileName(assetPath1);
            if (!File.Exists(SirenixAssetPaths.OdinEditorConfigsPath + fileName))
                AssetDatabase.MoveAsset(assetPath1, SirenixAssetPaths.OdinEditorConfigsPath + fileName);
            string str1 = SirenixAssetPaths.OdinPath + "Scripts/";
            string str2 = str1 + "Editor/";
            string[] SerializerScriptFiles = new string[2]
            {
                "VectorIntFormatters.cs",
                "SerializedNetworkBehaviour.cs"
            };
            foreach (string serializerScriptFile in SerializerScriptFiles)
            {
                string str3 = str1 + serializerScriptFile;
                string str4 = str2 + serializerScriptFile;
                if (File.Exists(str3))
                {
                    if (File.Exists(str4))
                        File.Delete(str4);
                    File.Move(str3, str4);
                    File.Delete(str3 + ".meta");
                }
            }
            BindingFlags priStatic = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static;
            string[] platformSpecificAssemblyFiles = type.GetField("platformSpecificAssemblyFiles", priStatic).GetValue(editorModeCfg) as string[];
            string[] globalAssemblyFiles = type.GetField("globalAssemblyFiles", priStatic).GetValue(editorModeCfg) as string[];
            string ExcludeFromEverything = type.GetField("ExcludeFromEverything", priStatic).GetValue(editorModeCfg) as string;
            string ExcludeFromEverythingExceptEditor = type.GetField("ExcludeFromEverythingExceptEditor", priStatic).GetValue(editorModeCfg) as string;
            BindingFlags pri = BindingFlags.Instance | BindingFlags.NonPublic;
            var SetPluginImportSettings = type.GetMethod("SetPluginImportSettings", pri);
            foreach (string specificAssemblyFile in platformSpecificAssemblyFiles)
            {
                object[] pars = new object[] {specificAssemblyFile + ".meta", ExcludeFromEverything };
                SetPluginImportSettings.Invoke(editorModeCfg, pars);
            }

            foreach (string globalAssemblyFile in globalAssemblyFiles)
            {
                object[] pars = new object[] {globalAssemblyFile + ".meta", ExcludeFromEverythingExceptEditor };
                SetPluginImportSettings.Invoke(editorModeCfg, pars);
            }
            AssetDatabase.Refresh();
            editorModeCfg.Update();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Odin插件中,使用ReorderableList可以实现可拖动的列表,方便对数组或列表进行排序。具体实现步骤如下: 1. 引入命名空间 ```csharp using Sirenix.Utilities.Editor; ``` 2. 定义一个ReorderableList变量 ```csharp private ReorderableList list; ``` 3. 在构造函数中初始化ReorderableList ```csharp public MyEditorWindow() { // ... list = new ReorderableList(myList, typeof(MyType), true, true, true, true); list.drawHeaderCallback += DrawHeader; list.drawElementCallback += DrawElement; list.onAddCallback += AddItem; list.onRemoveCallback += RemoveItem; } ``` 在这里,我们首先定义一个ReorderableList变量,然后在构造函数中初始化该变量。其中,myList是一个MyType类型的List,表示我们要对该列表进行排序。第二个参数typeof(MyType)表示列表中的元素类型是MyType类型。接下来的4个bool参数分别表示:是否可以拖动元素、是否可以插入元素、是否可以删除元素以及是否可以多选元素。最后,我们为ReorderableList的4个事件回调分别添加对应的回调方法,用于自定义列表的行为。 4. 实现ReorderableList的4个回调方法: ```csharp private void DrawHeader(Rect rect) { EditorGUI.LabelField(rect, "My List"); } private void DrawElement(Rect rect, int index, bool isActive, bool isFocused) { var item = myList[index]; EditorGUI.BeginChangeCheck(); item = (MyType)EditorGUI.ObjectField(rect, item, typeof(MyType), true); if (EditorGUI.EndChangeCheck()) { myList[index] = item; } } private void AddItem(ReorderableList list) { myList.Add(null); } private void RemoveItem(ReorderableList list) { myList.RemoveAt(list.index); } ``` 在这里,我们分别实现了DrawHeader()、DrawElement()、AddItem()和RemoveItem()方法。其中,DrawHeader()方法用于绘制列表的标题,DrawElement()方法用于绘制列表中的元素,AddItem()和RemoveItem()方法分别用于添加和删除元素。在DrawElement()方法中,我们使用ObjectField来绘制列表项,并在ObjectField的值发生变化时,更新列表中对应元素的值。 5. 在OnGUI()方法中绘制ReorderableList ```csharp public void OnGUI() { // ... list.DoLayoutList(); } ``` 在这里,我们在OnGUI()方法中调用ReorderableList的DoLayoutList()方法,用于绘制整个ReorderableList。 6. 运行代码,你会发现ReorderableList已经可以实现可拖动的列表了。 希望我的回答能够帮到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值