Created
November 3, 2019 00:11
-
-
Save CapitanLiteral/d8c58856e08faf5e107f123bf35d1192 to your computer and use it in GitHub Desktop.
Editor to display all editable prefabs
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 static ScriptableObject DrawColoredList(ScriptableObject scriptableObject, int i, ScriptableObject selected) | |
{ | |
if (scriptableObject == selected) | |
GUILayout.BeginHorizontal(EditorStyle.GetSelectedStyle()); | |
else if (i % 2 == 0) | |
GUILayout.BeginHorizontal(EditorStyle.GetGreyedOutStyle()); | |
else | |
GUILayout.BeginHorizontal(); | |
if (GUILayout.Button(scriptableObject.name, EditorStyle.ListElementStyle)) | |
{ | |
selected = scriptableObject; | |
} | |
return selected; | |
} |
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; | |
using System.Collections.Generic; | |
using UnityEditor; | |
using UnityEngine; | |
public static class EditorWindowExtensions | |
{ | |
public static void Save(this EditorWindow window) | |
{ | |
var data = JsonUtility.ToJson(window, false); | |
EditorPrefs.SetString(window.GetType().ToString(), data); | |
} | |
public static void Load(this EditorWindow window) | |
{ | |
var data = EditorPrefs.GetString(window.GetType().ToString(), JsonUtility.ToJson(window, false)); | |
JsonUtility.FromJsonOverwrite(data, window); | |
} | |
} |
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; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public static class EditorStyle | |
{ | |
public static GUIStyle GreyedOutStyle { get; } = GetGreyedOutStyle(); | |
public static GUIStyle SelectedStyle { get; } = GetSelectedStyle(); | |
public static Texture2D GreyedOut { get; } = MakeTex(1, 1, new Color(1.0f, 1.0f, 1.0f, 0.1f)); | |
public static Texture2D Selected { get; } = MakeTex(1, 1, new Color(1.0f, 0.0f, 0.0f, 0.5f)); | |
public static GUIStyle ListElementStyle { get; } = GetListBtnStyle(); | |
public static Texture2D MakeTex(int width, int height, Color col) | |
{ | |
var pix = new Color[width * height]; | |
for (int i = 0; i < pix.Length; i++) | |
{ | |
pix[i] = col; | |
} | |
var result = new Texture2D(width, height); | |
result.SetPixels(pix); | |
result.Apply(); | |
return result; | |
} | |
private static GUIStyle GetListBtnStyle() | |
{ | |
var s = new GUIStyle(); | |
s.normal.textColor = Color.white; | |
s.margin.bottom = 3; | |
s.margin.top = 2; | |
return s; | |
} | |
public static GUIStyle GetGreyedOutStyle() | |
{ | |
GUIStyle style = new GUIStyle(); | |
style.normal.background = EditorStyle.GreyedOut; | |
return style; | |
} | |
public static GUIStyle GetSelectedStyle() | |
{ | |
GUIStyle style = new GUIStyle(); | |
style.normal.background = EditorStyle.Selected; | |
return style; | |
} | |
} |
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; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using UnityEditor; | |
using UnityEditor.Compilation; | |
using UnityEngine; | |
using Object = UnityEngine.Object; | |
public class PrefabEditor : EditorWindow | |
{ | |
private ScriptableObject selected; | |
private Dictionary<Type, List<ScriptableObject>> m_editables = new Dictionary<Type, List<ScriptableObject>>(); | |
private Dictionary<string, Type> m_types = new Dictionary<string, Type>(); | |
private List<string> m_options; | |
[SerializeField] private int leftColumnSize = 200; | |
//Left Right Top Down | |
[SerializeField] private Margins<int> margins = new Margins<int>(10, 40, 40, 40); | |
[SerializeField] private int popUpSelected = 0; | |
Vector2 leftMenuScrollPos; | |
Vector2 rightMenuScrollPos; | |
#region UnityRelated | |
[MenuItem("Window/ScriptableObjects/Editor", false, 5)] | |
public static void ShowWindow() | |
{ | |
//Show existing window instance. If one doesn't exist, make one. | |
GetWindow(typeof(PrefabEditor)); | |
} | |
private void OnEnable() | |
{ | |
LoadEditableScriptableObject(); | |
this.Load(); | |
} | |
protected void OnDisable() { this.Save(); } | |
private void OnProjectChange() { LoadEditableScriptableObject(); } | |
private void OnGUI() | |
{ | |
Rect left = LeftColumnRect(); | |
Rect right = RightColumnRect(); | |
LeftColumn(left); | |
RightColumn(right); | |
} | |
#endregion | |
#region LayoutRects | |
private Rect RightColumnRect() | |
{ | |
Rect right = position; | |
right.position = new Vector2(margins.Left + leftColumnSize, margins.Top); | |
right.width = position.width - leftColumnSize; | |
return right; | |
} | |
private Rect LeftColumnRect() | |
{ | |
Rect left = position; | |
left.position = new Vector2(margins.Left, margins.Top); | |
left.width = leftColumnSize; | |
return left; | |
} | |
private Rect LeftColumnTopRect() | |
{ | |
Rect left = LeftColumnRect(); | |
left.height = left.height * 0.8f; | |
return left; | |
} | |
private Rect LeftColumnBottomRect() | |
{ | |
Rect left = LeftColumnRect(); | |
left.position = new Vector2(left.position.x, left.height * 0.8f); | |
left.height = left.height * 0.2f; | |
return left; | |
} | |
#endregion | |
#region Layouts | |
private void RightColumn(Rect right) | |
{ | |
GUILayout.BeginArea(right); | |
rightMenuScrollPos = EditorGUILayout.BeginScrollView(rightMenuScrollPos, | |
GUILayout.Width(position.width - leftColumnSize - margins.Left), | |
GUILayout.Height(position.height - margins.Top)); | |
if (selected != null) | |
{ | |
var editor = Editor.CreateEditor(selected); | |
editor.OnInspectorGUI(); | |
} | |
EditorGUILayout.EndScrollView(); | |
GUILayout.EndArea(); | |
} | |
private void LeftColumn(Rect left) | |
{ | |
LeftColumTop(); | |
LeftColumnBottom(); | |
} | |
private void LeftColumTop() | |
{ | |
Type selectedType = GetSelectedScriptableObjectType(); | |
GUILayout.BeginArea(LeftColumnTopRect()); | |
popUpSelected = EditorGUILayout.Popup(popUpSelected, m_options.ToArray()); | |
leftMenuScrollPos = EditorGUILayout.BeginScrollView(leftMenuScrollPos, GUILayout.Width(leftColumnSize), | |
GUILayout.Height(LeftColumnTopRect().height - margins.Down)); | |
if (selectedType != null) | |
{ | |
if (selected != null) | |
{ | |
if (selectedType != selected.GetType()) | |
{ | |
selected = m_editables[selectedType][0]; | |
} | |
} | |
List<ScriptableObject> editableScriptableObjects = m_editables[selectedType]; | |
DrawScriptableObjects(editableScriptableObjects); | |
} | |
else | |
{ | |
EditorGUILayout.LabelField("No editable assets found"); | |
EditorGUILayout.LabelField("try this [EditableScriptableObject]"); | |
} | |
EditorGUILayout.EndScrollView(); | |
GUILayout.EndArea(); | |
} | |
private void LeftColumnBottom() | |
{ | |
GUILayout.BeginArea(LeftColumnBottomRect()); | |
DrawCreateAsset(); | |
GUILayout.EndArea(); | |
} | |
#endregion | |
#region MainLogic | |
private void DrawCreateAsset() | |
{ | |
if (GetSelectedScriptableObjectType() != null) | |
{ | |
Type type = GetSelectedScriptableObjectType(); | |
if (GUILayout.Button($"New {type}")) | |
{ | |
CreateAsset(type); | |
} | |
} | |
} | |
private Type GetSelectedScriptableObjectType() | |
{ | |
return popUpSelected > m_options.Count || !m_types.ContainsKey(m_options[popUpSelected]) | |
? null | |
: m_types[m_options[popUpSelected]]; | |
} | |
private void CreateAsset(Type type) | |
{ | |
string path = EditorUtility.SaveFilePanel("Save textures to folder", | |
$"{Application.dataPath}/ScriptableObjects/", | |
"New " + type, "asset"); | |
if (path.Length != 0) | |
{ | |
Debug.Log(path); | |
} | |
Object newAsset = CreateInstance(type); | |
string newAssetPath = path; | |
Debug.Log(newAssetPath); | |
string relativePath = path.Substring(path.IndexOf("Assets/", StringComparison.Ordinal)); | |
AssetDatabase.CreateAsset(newAsset, relativePath); | |
AssetDatabase.SaveAssets(); | |
AssetDatabase.Refresh(); | |
EditorUtility.FocusProjectWindow(); | |
Selection.activeObject = newAsset; | |
selected = (ScriptableObject) newAsset; | |
} | |
private void DrawScriptableObjects(List<ScriptableObject> editableScriptableObjects) | |
{ | |
int i = 0; | |
foreach (var scriptableObject in editableScriptableObjects) | |
{ | |
if (selected == null) | |
{ | |
selected = scriptableObject; | |
} | |
selected = EditorDrawers.DrawColoredList(scriptableObject, i, selected); | |
i++; | |
GUILayout.EndHorizontal(); | |
} | |
} | |
private void LoadEditableScriptableObject() | |
{ | |
var types = EditorUtils.GetTypesWith<EditableScriptableObject>(false); | |
m_editables = new Dictionary<Type, List<ScriptableObject>>(); | |
m_types = new Dictionary<string, Type>(); | |
m_options = new List<string>(); | |
foreach (var type in types) | |
{ | |
EditorUtils.FindAssetsByType(type); | |
m_editables.Add(type, new List<ScriptableObject>()); | |
if (type.IsSubclassOf(typeof(ScriptableObject))) | |
{ | |
var resources = Resources.FindObjectsOfTypeAll(type); | |
foreach (var resource in resources) | |
{ | |
m_editables[type].Add((ScriptableObject) resource); | |
} | |
m_types.Add(type.ToString(), type); | |
m_options.Add(type.ToString()); | |
} | |
} | |
} | |
#endregion | |
} |
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 static partial class EditorUtils | |
{ | |
public static bool TryGetFolderToLoad(out string path) | |
{ | |
path = ""; | |
var activeObject = Selection.activeObject; | |
if (TryGetObjectPath(activeObject, out path)) | |
{ | |
return true; | |
} | |
return false; | |
} | |
public static void SaveAsset<T>(T model, string name) where T : Object | |
{ | |
var activeObject = Selection.activeObject; | |
string path; | |
if (TryGetObjectPath(activeObject, out path)) | |
{ | |
ProjectWindowUtil.CreateAsset(model, path + "/"+name); | |
} | |
} | |
public static bool TryGetObjectPath(Object activeObject, out string path) | |
{ | |
path = ""; | |
if (activeObject == null) | |
{ | |
path = "Assets"; | |
} | |
else | |
{ | |
path = AssetDatabase.GetAssetPath(activeObject); | |
} | |
if (path.Length > 0) | |
{ | |
if (!Directory.Exists(path)) | |
{ | |
var lastSlash = path.LastIndexOf('/'); | |
path = path.Substring(0, lastSlash + 1); | |
} | |
return true; | |
} | |
return false; | |
} | |
public static void DrawButton(Action OnButtonPressed) | |
{ | |
DrawButton(ObjectNames.NicifyVariableName(OnButtonPressed.Method.Name), OnButtonPressed); | |
} | |
public static void DrawButton(string label, Action OnButtonPressed) | |
{ | |
if (GUILayout.Button(label)) | |
{ | |
OnButtonPressed?.Invoke(); | |
} | |
} | |
public static IEnumerable<Type> GetTypesWith<TAttribute>(bool inherit) | |
where TAttribute : Attribute | |
{ | |
return AppDomain.CurrentDomain.GetAssemblies() | |
.SelectMany(a => a.GetTypes()) | |
.Where(t => t.IsDefined(typeof(TAttribute), inherit)); | |
} | |
public static List<T> FindAssetsByType<T>() where T : Object | |
{ | |
List<T> assets = new List<T>(); | |
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(T))); | |
for( int i = 0; i < guids.Length; i++ ) | |
{ | |
string assetPath = AssetDatabase.GUIDToAssetPath( guids[i] ); | |
T asset = AssetDatabase.LoadAssetAtPath<T>( assetPath ); | |
if( asset != null ) | |
{ | |
assets.Add(asset); | |
} | |
} | |
return assets; | |
} | |
public static List<Object> FindAssetsByType(Type type) | |
{ | |
List<Object> assets = new List<Object>(); | |
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", type)); | |
for( int i = 0; i < guids.Length; i++ ) | |
{ | |
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]); | |
var asset = AssetDatabase.LoadAssetAtPath(assetPath, type); | |
if( asset != null ) | |
{ | |
assets.Add(asset); | |
} | |
} | |
return assets; | |
} | |
} | |
public class Margins<T> | |
{ | |
public Margins(T top, T down, T left, T right) | |
{ | |
Top = top; | |
Down = down; | |
Left = left; | |
Right = right; | |
} | |
public Margins() { | |
} | |
public T Top { get; set; } | |
public T Down { get; set; } | |
public T Left { get; set; } | |
public T Right { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment