基于Odin的常见小工具ScriptableObjectCreator存在ToHashSet二义性时的解决方案
Posted rk_21125
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Odin的常见小工具ScriptableObjectCreator存在ToHashSet二义性时的解决方案相关的知识,希望对你有一定的参考价值。
注:提供给对链式调用不熟悉的人的解决方案
网上随处可见的基于Odin的小工具ScriptableObjectCreator如果发生【以下方法或属性之间的调用具有二义性:“Sirenix.Utilities.LinqExtensions.ToHashSet<T>(System.Collections.Generic.IEnumerable<T>)”和“System.Linq.Enumerable.ToHashSet<TSource>(System.Collections.Generic.IEnumerable<TSource>”】
static HashSet<Type> scriptableObjectTypes = AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
.Where(t => t.IsClass &&
typeof(ScriptableObject).IsAssignableFrom(t) &&
!typeof(EditorWindow).IsAssignableFrom(t) &&
!typeof(Editor).IsAssignableFrom(t)).ToHashSet();
把ToHashSet提出来,限定调用
static HashSet<Type> scriptableObjectTypes = System.Linq.Enumerable.ToHashSet(AssemblyUtilities.GetTypes(AssemblyTypeFlags.CustomTypes)
.Where(t => t.IsClass &&
typeof(ScriptableObject).IsAssignableFrom(t) &&
!typeof(EditorWindow).IsAssignableFrom(t) &&
!typeof(Editor).IsAssignableFrom(t)));
本文来自博客园,作者:rkmao,转载请注明原文链接:https://www.cnblogs.com/rkmao/p/17294762.html
基于Odin插件简单ScriptableObject数据管理类
前言 : 该类基于官方视屏略微修改的基类,通过继承即可实现指定数据管理
using Sirenix.OdinInspector;
using Sirenix.OdinInspector.Editor;
using Sirenix.Utilities.Editor;
using System;
using UnityEditor;
using UnityEngine;
namespace EditorModules
public class BaseDataEditor<T> : OdinMenuEditorWindow where T : ScriptableObject
protected Type dataType;
protected string path;
private CreateNewData<T> newData;
protected override void OnDestroy()
base.OnDestroy();
if (newData != null)
DestroyImmediate(newData.data);
/// <summary>
/// 提供子类初始化数据使用
/// </summary>
/// <param name="dataType"></param>
/// <param name="path"></param>
protected void InitData(Type dataType, string path)
this.dataType = dataType;
this.path = path;
protected override OdinMenuTree BuildMenuTree()
CreateNewData<T> newData = new CreateNewData<T>(path);
//构建菜单
var tree = new OdinMenuTree();
tree.Config.DrawSearchToolbar = true;//开启搜索状态
tree.Add("Creat New Data", newData);
tree.AddAllAssetsAtPath(dataType.Name, "Assets/Game Data/", dataType, true, true);
tree.Selection.SelectionConfirmed += x => EditorGUIUtility.PingObject(x.SelectedValue as T);//双击跳转选择对象的目录
return tree;
protected override void OnBeginDrawEditors()
//gets reference to currently selected item
OdinMenuTreeSelection selected = this.MenuTree.Selection;
SirenixEditorGUI.BeginHorizontalToolbar();
T asset = selected.SelectedValue as T;
string path = AssetDatabase.GetAssetPath(asset);
GUILayout.FlexibleSpace();
if (SirenixEditorGUI.ToolbarButton("Ping"))
EditorGUIUtility.PingObject(asset);
else if (SirenixEditorGUI.ToolbarButton("Show In Explorer"))
EditorUtility.RevealInFinder(path);
else if (SirenixEditorGUI.ToolbarButton("Delete Current"))
AssetDatabase.DeleteAsset(path);
AssetDatabase.SaveAssets();
SirenixEditorGUI.EndHorizontalToolbar();
public class CreateNewData<T> where T : ScriptableObject
[InlineEditor(ObjectFieldMode = InlineEditorObjectFieldModes.Hidden)]
public T data;
private string path;
public CreateNewData(string path)
data = ScriptableObject.CreateInstance<T>();
this.path = path;
[Button("Add New Data", ButtonSizes.Large, ButtonStyle.FoldoutButton)]
private void CreateData(string dataName)
AssetDatabase.CreateAsset(data, "Assets/" + path + "/" + dataName + ".asset");
AssetDatabase.SaveAssets();
//create new instance of SO
data = ScriptableObject.CreateInstance<T>();
使用例子:
using UnityEditor;
namespace EditorModules
public class ActionDataEditor : BaseDataEditor<ActionData>
[MenuItem("Tools/Data Editor/Action Data")]
public static void ShowEditor() => GetWindow<ActionDataEditor>();
protected override void OnEnable()
base.OnEnable();
InitData(typeof(ActionData), "Game Data/ActionData");
(其中,Game Data/ActionData 为创建的ScriptableObject在Assets的路径)
实现效果
本文来自博客园,作者:rkmao,转载请注明原文链接:https://www.cnblogs.com/rkmao/p/17294760.html
以上是关于基于Odin的常见小工具ScriptableObjectCreator存在ToHashSet二义性时的解决方案的主要内容,如果未能解决你的问题,请参考以下文章
很好用的Unity编辑器扩展工具 Odin Inspector教程
Unity3D Editor Undo回退效果实现3 Odin相关