起因:
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();
}
}
}