First Commit
This commit is contained in:
184
Assets/Attributes/Editor/ButtonEditor.cs
Normal file
184
Assets/Attributes/Editor/ButtonEditor.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using Golems.Attributes;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Golems
|
||||
{
|
||||
public partial class AttributesEditor
|
||||
{
|
||||
private const BindingFlags k_ButtonBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public |
|
||||
BindingFlags.NonPublic;
|
||||
|
||||
/// <summary>
|
||||
/// Map between Method names and parameters for Methods
|
||||
/// </summary>
|
||||
private Dictionary<string, object[]> m_Parameters = new Dictionary<string, object[]>();
|
||||
|
||||
private void OnInspectorGUIButtonAttribute ()
|
||||
{
|
||||
var methods = target.GetType().GetMethods(k_ButtonBindingFlags);
|
||||
|
||||
//
|
||||
// Search for Button Attribute within Each Method on this Object
|
||||
//
|
||||
for (int i = 0, counti = methods.Length; i < counti; ++i)
|
||||
{
|
||||
var method = methods[i];
|
||||
var buttonAttribute = method.GetCustomAttribute<Button>(false);
|
||||
if (buttonAttribute == null)
|
||||
continue;
|
||||
|
||||
var name = string.IsNullOrEmpty(buttonAttribute.Ident) ? method.Name : buttonAttribute.Ident;
|
||||
//
|
||||
// Invoke Method with parms on button pressed
|
||||
//
|
||||
if (GUILayout.Button(name))
|
||||
{
|
||||
m_Parameters.TryGetValue(name, out var parms);
|
||||
if (parms != null)
|
||||
{
|
||||
var p = new List<object>();
|
||||
for (int j = 0, countj = parms.Length; j < countj; ++j)
|
||||
{
|
||||
p.Add(parms[j]);
|
||||
//
|
||||
// Skip over array size
|
||||
//
|
||||
if (parms[j].GetType().IsArray) ++j;
|
||||
}
|
||||
method.Invoke(target, p.ToArray());
|
||||
} else method.Invoke(target, parms);
|
||||
}
|
||||
EditorGUI.indentLevel++;
|
||||
SetUpParameters(name, method);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set up Parameters for use on Method Invocation
|
||||
/// </summary>
|
||||
private void SetUpParameters(string name, MethodInfo method)
|
||||
{
|
||||
var parameterInfo = method.GetParameters();
|
||||
if (parameterInfo.Length <= 0) return;
|
||||
|
||||
//
|
||||
// Check if Method has already has its parameters setup.
|
||||
// If not create a new array and add to dict.
|
||||
//
|
||||
if (!m_Parameters.TryGetValue(name, out var parameters))
|
||||
{
|
||||
var p = new List<object>(parameterInfo.Length);
|
||||
for (int i = 0, counti = parameterInfo.Length; i < counti; ++i)
|
||||
{
|
||||
p.Add(default);
|
||||
|
||||
//
|
||||
// If we have an Array add an additional parameter for size
|
||||
//
|
||||
if (parameterInfo[i].ParameterType.IsArray)
|
||||
{
|
||||
p.Add(default);
|
||||
}
|
||||
}
|
||||
m_Parameters.Add(name, p.ToArray());
|
||||
}
|
||||
|
||||
if (parameters == null) return;
|
||||
|
||||
//
|
||||
// Iterate over each parameter and set up relevant display Field.
|
||||
//
|
||||
for (int i = 0, counti = parameters.Length, pi = 0; i < counti; ++i, ++pi)
|
||||
{
|
||||
var paramName = parameterInfo[pi].Name;
|
||||
if (parameterInfo[pi].ParameterType == typeof(int))
|
||||
{
|
||||
int val = parameters[i] == null ? 0 : (int)parameters[i];
|
||||
parameters[i] = EditorGUILayout.IntField(paramName, val);
|
||||
}
|
||||
else if (parameterInfo[pi].ParameterType == typeof(float))
|
||||
{
|
||||
float val = parameters[i] == null ? 0 : (float)parameters[i];
|
||||
parameters[i] = EditorGUILayout.FloatField(paramName, val);
|
||||
}
|
||||
else if (parameterInfo[pi].ParameterType == typeof(string))
|
||||
{
|
||||
string val = String.IsNullOrEmpty((string)parameters[i]) ? "" : (string)parameters[i];
|
||||
parameters[i] = EditorGUILayout.TextField(paramName, val);
|
||||
}
|
||||
else if (parameterInfo[pi].ParameterType == typeof(bool))
|
||||
{
|
||||
bool val = parameters[i] != null && (bool)parameters[i];
|
||||
parameters[i] = EditorGUILayout.Toggle(paramName, val);
|
||||
}
|
||||
else if (parameterInfo[pi].ParameterType == typeof(char))
|
||||
{
|
||||
string val = "";
|
||||
if (parameters[i] != null)
|
||||
{
|
||||
val = ((char)parameters[i]).ToString();
|
||||
}
|
||||
|
||||
val = EditorGUILayout.TextField(paramName, val);
|
||||
if (!String.IsNullOrEmpty(val))
|
||||
{
|
||||
parameters[i] = val[0];
|
||||
}
|
||||
}
|
||||
else if (parameterInfo[pi].ParameterType == typeof(Sprite))
|
||||
{
|
||||
Sprite val = parameters[i] != null ? (Sprite)parameters[i] : default;
|
||||
parameters[i] = EditorGUILayout.ObjectField(paramName, val, typeof(Sprite), false) as Sprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// GameObject Array support - copy me around if we want more Inspector Button Arrays
|
||||
//
|
||||
if (parameterInfo[pi].ParameterType.IsArray)
|
||||
{
|
||||
//
|
||||
// We can Safely assume next item is index
|
||||
//
|
||||
var arraySizeIndex = i + 1;
|
||||
int size = parameters[arraySizeIndex] == null ? 0 : (int)parameters[arraySizeIndex];
|
||||
parameters[arraySizeIndex] = EditorGUILayout.IntField($"{paramName} Size: ", size);
|
||||
|
||||
var arrayParameter = (GameObject[]) parameters[i] ?? new GameObject[0];
|
||||
|
||||
if (arrayParameter.Length != size)
|
||||
{
|
||||
Array.Resize(ref arrayParameter, size);
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
for (int j = 0, countj = size; j < countj; ++j)
|
||||
{
|
||||
GameObject val = arrayParameter[j] == null ? default : arrayParameter[j];
|
||||
arrayParameter[j] = EditorGUILayout.ObjectField($"{paramName} - {j}", val, typeof(UnityEngine.GameObject), true) as GameObject;
|
||||
}
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
parameters[i] = arrayParameter;
|
||||
|
||||
//
|
||||
// Advance an extra step to skip Array size
|
||||
//
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject val = (UnityEngine.GameObject) parameters[i];
|
||||
parameters[i] = EditorGUILayout.ObjectField(paramName, val, parameterInfo[pi].ParameterType, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user