Created
February 7, 2021 12:07
-
-
Save BigHandInSky/e8ee87e179b1a48adf791272f62922de to your computer and use it in GitHub Desktop.
An editor field to quickly pick Ink knots from inside a given sub-folder in Assets
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; | |
namespace _project.utilities | |
{ | |
/// <summary> | |
/// Struct that is used for an editor GUI to simplify picking an ink knot from the Assets folder | |
/// </summary> | |
[Serializable] | |
public struct StoryKnot | |
{ | |
public string name; | |
public StoryKnot( string n ) => name = n; | |
public bool IsValid => !string.IsNullOrEmpty( name ); | |
} | |
} |
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.Collections.Generic; | |
using System.IO; | |
using _project.utilities; | |
using UnityEditor; | |
using UnityEngine; | |
namespace _project | |
{ | |
[CustomPropertyDrawer( typeof(StoryKnot) )] | |
public class StoryKnotDrawer : PropertyDrawer | |
{ | |
private static Dictionary<string, List<string>> _fileToKnotsLookup = new Dictionary<string, List<string>>(); | |
private string _selectedName = ""; | |
public override void OnGUI( | |
Rect position, | |
SerializedProperty property, | |
GUIContent label ) | |
{ | |
label = EditorGUI.BeginProperty( position, label, property ); | |
Rect contentPosition = EditorGUI.PrefixLabel(position, label); | |
EditorGUI.BeginChangeCheck(); | |
var nameProperty = property.FindPropertyRelative( "name" ); | |
var buttonLabel = string.IsNullOrEmpty( nameProperty.stringValue ) | |
? "Pick knot name" | |
: nameProperty.stringValue; | |
if ( EditorGUI.DropdownButton( contentPosition, new GUIContent( buttonLabel ), | |
FocusType.Passive ) ) | |
{ | |
if ( _fileToKnotsLookup.Count == 0 ) | |
{ | |
FetchKnots(); | |
} | |
ConstructThenShowMenu(); | |
} | |
if ( !string.IsNullOrEmpty( _selectedName ) ) | |
{ | |
nameProperty.stringValue = _selectedName; | |
_selectedName = ""; | |
} | |
EditorGUI.EndChangeCheck(); | |
EditorGUI.EndProperty(); | |
} | |
public override float GetPropertyHeight( SerializedProperty property, GUIContent label ) | |
{ | |
return EditorGUIUtility.singleLineHeight; | |
} | |
#region Menu | |
private void FetchKnots() | |
{ | |
_fileToKnotsLookup.Clear(); | |
var folderPath = "Assets/_content/writing"; | |
var guids = AssetDatabase.FindAssets( "", new []{ folderPath } ); | |
foreach ( var guid in guids ) | |
{ | |
var path = AssetDatabase.GUIDToAssetPath( guid ); | |
if ( path.EndsWith( ".ink" ) ) | |
{ | |
var splits = path.Split( '/' ); | |
var knots = LoadInkThenParse( path ); | |
var reduced = path.Remove( 0, folderPath.Length + 1 ); | |
//Debug.Log( $"path? {path}" ); | |
//Debug.Log( $" reduced: {reduced}, split: {splits[splits.Length - 1]}" ); | |
//Debug.Log( $"knots: [{string.Join( ",", knots )}]" ); | |
_fileToKnotsLookup.Add( reduced, knots ); | |
} | |
// ignore .jsons | |
} | |
} | |
private List<string> LoadInkThenParse( string path ) | |
{ | |
List<string> value = new List<string>(); | |
using ( var reader = File.OpenText( path ) ) | |
{ | |
var line = ""; | |
while ( !reader.EndOfStream ) | |
{ | |
line = reader.ReadLine(); | |
if ( line.StartsWith( "==" ) ) | |
{ | |
line = line.Replace( "==", "" ); | |
line = line.Trim(); | |
value.Add( line ); | |
} | |
} | |
} | |
return value; | |
} | |
private void ConstructThenShowMenu() | |
{ | |
GenericMenu menu = new GenericMenu(); | |
foreach ( var pair in _fileToKnotsLookup ) | |
{ | |
string root = pair.Key; | |
foreach ( var s in pair.Value ) | |
{ | |
AddMenuItemForKnot( menu, $"{root}/{s}", s ); | |
} | |
} | |
menu.ShowAsContext(); | |
} | |
void AddMenuItemForKnot(GenericMenu menu, string menuPath, string knot) | |
{ | |
menu.AddItem(new GUIContent(menuPath), _selectedName.Equals(knot), OnStringSelected, knot); | |
} | |
void OnStringSelected(object knot) | |
{ | |
_selectedName = (string)knot; | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment