Skip to content

Instantly share code, notes, and snippets.

@terence410
Last active January 8, 2021 08:49
Show Gist options
  • Save terence410/1ca817ae22d844efefb5c23f24d78b83 to your computer and use it in GitHub Desktop.
Save terence410/1ca817ae22d844efefb5c23f24d78b83 to your computer and use it in GitHub Desktop.
Custom Odin Attribute
public class MyMono: MonoBehaviour {
[SelectAsset(SelectFileType.GameObject, "Assets/", "collider", ".wav|.prefab")]
public string MyPrefab;
[SelectAsset(SelectFileType.AudioClip, "Assets/Resources/BGM/", "", ".wav|.mp3")]
public string MyAudioClip;
}
public enum SelectFileType
{
GameObject,
AudioClip
}
public class SelectAssetAttribute : Attribute
{
public SelectFileType SelectFileType;
public string Directory;
public string Prefix;
public string[] Extensions;
public SelectAssetAttribute(SelectFileType selectFileType, string directory, string prefix = "", string extension = "")
{
SelectFileType = selectFileType;
Directory = directory;
Prefix = prefix;
Extensions = extension.Split('|');
}
}
using System.Text.RegularExpressions;
using Quantum.Attributes;
using Sirenix.Utilities.Editor;
using UnityEditor;
using UnityEngine;
namespace Sirenix.OdinInspector.Editor.Drawers
{
[DrawerPriority(0.3, 0.0, 0.0)]
public sealed class SelectAssetAttributeStringDrawer : OdinAttributeDrawer<SelectAssetAttribute, string>
{
private static int _controlIdCounter = 0;
private int _controlId = 0;
private Object _invalidSelectedObject;
protected override void DrawPropertyLayout(GUIContent label)
{
IPropertyValueEntry<string> valueEntry = this.ValueEntry;
this.CallNextDrawer(label);
// show asset dialog
if (GUILayout.Button($"Select in {Attribute.Directory}"))
{
_controlId = ++_controlIdCounter;
if(Attribute.SelectFileType == SelectFileType.GameObject)
EditorGUIUtility.ShowObjectPicker<GameObject>(null, false, Attribute.Prefix, _controlId);
if(Attribute.SelectFileType == SelectFileType.AudioClip)
EditorGUIUtility.ShowObjectPicker<AudioClip>(null, false, Attribute.Prefix, _controlId);
}
// select the object
string commandName = Event.current.commandName;
if (commandName == "ObjectSelectorClosed" && EditorGUIUtility.GetObjectPickerControlID() == _controlId)
{
var selectedObject = EditorGUIUtility.GetObjectPickerObject();
if (selectedObject != null)
{
AssetDatabase.TryGetGUIDAndLocalFileIdentifier(selectedObject.GetInstanceID(), out string guid,
out long file);
{
var path = AssetDatabase.GUIDToAssetPath(guid);
Debug.Log($"Selected File: guid: {guid}, path: {path}, file: {file}, name: {selectedObject.name}");
var result = (MatchPattern(path, Attribute.Directory, Attribute.Extensions));
if (result != null)
{
valueEntry.SmartValue = selectedObject.name;
_invalidSelectedObject = null;
}
else
{
valueEntry.SmartValue = "";
_invalidSelectedObject = selectedObject;
}
}
}
}
if (_invalidSelectedObject != null)
{
SirenixEditorGUI.ErrorMessageBox($"Invalid selected object: {_invalidSelectedObject.name}");
}
}
private string MatchPattern(string path, string directory, string[] extensions)
{
foreach (var extension in extensions)
{
var pattern = "" + directory + "(.*)" + extension;
Match m = Regex.Match(path, pattern, RegexOptions.IgnoreCase);
if (m.Success)
{
if (m.Groups.Count > 1)
{
return m.Groups[1].Captures[0].ToString();
}
}
}
return null;
}
private Object GetPrefab(string directory, string filename, string[] extensions)
{
if (filename != "")
{
foreach (var extension in extensions)
{
var path = directory + filename + extension;
var asset = AssetDatabase.LoadMainAssetAtPath(path);
if (asset != null)
return asset;
}
}
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment