Last active
January 8, 2021 08:49
-
-
Save terence410/1ca817ae22d844efefb5c23f24d78b83 to your computer and use it in GitHub Desktop.
Custom Odin Attribute
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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('|'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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