147 lines
4.7 KiB
C#
147 lines
4.7 KiB
C#
using System;
|
|
#if UNITY_EDITOR
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
#endif
|
|
|
|
namespace Golems.Attributes
|
|
{
|
|
/// <summary>
|
|
/// Show the EditorInspectableLevel property on the field.
|
|
/// </summary>
|
|
[AttributeUsage(AttributeTargets.Field)]
|
|
public class ShowLevelAttribute : Attribute
|
|
{
|
|
public bool ShowWhenNotPlaying
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
public ShowLevelAttribute()
|
|
{
|
|
ShowWhenNotPlaying = false;
|
|
}
|
|
|
|
public ShowLevelAttribute(bool showWhenNotPlaying)
|
|
{
|
|
ShowWhenNotPlaying = showWhenNotPlaying;
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
private const BindingFlags k_ShowLevelBindingFlags = BindingFlags.Public | BindingFlags.NonPublic |
|
|
BindingFlags.Instance | BindingFlags.DeclaredOnly;
|
|
|
|
private static readonly List<FieldInfo> s_Fields = new List<FieldInfo>();
|
|
|
|
private static GUIStyle s_LabelStyle = null;
|
|
|
|
private const string k_EditorLevelProperty = "EditorInspectableLevel";
|
|
|
|
public static void EditorShowLevelInfo(UnityEngine.Object target, string label)
|
|
{
|
|
s_Fields.Clear();
|
|
|
|
GetShowLevelAttributeFields(target, s_Fields, EditorApplication.isPlaying);
|
|
|
|
if (s_Fields.Count <= 0)
|
|
{
|
|
return;
|
|
}
|
|
if (!string.IsNullOrEmpty(label))
|
|
{
|
|
if (s_LabelStyle == null)
|
|
{
|
|
s_LabelStyle = EditorStyles.boldLabel;
|
|
s_LabelStyle.richText = true;
|
|
}
|
|
EditorGUILayout.LabelField(label, s_LabelStyle);
|
|
}
|
|
|
|
var origIndent = EditorGUI.indentLevel;
|
|
EditorGUI.indentLevel += 1;
|
|
for (int i = 0; i < s_Fields.Count; i++)
|
|
{
|
|
var field = s_Fields[i];
|
|
|
|
var niceName = ObjectNames.NicifyVariableName(field.Name);
|
|
var fieldValue = field.GetValue(target);
|
|
if (fieldValue != null)
|
|
{
|
|
var levelProperty = GetLevelNoSideEffectsProperty(fieldValue);
|
|
|
|
if (levelProperty != null)
|
|
{
|
|
var levelValue = levelProperty.GetValue(fieldValue);
|
|
var level = levelValue;
|
|
EditorGUI.BeginDisabledGroup(true);
|
|
EditorGUI.EndDisabledGroup();
|
|
}
|
|
else
|
|
{
|
|
EditorGUILayout.LabelField($"{niceName} does not implement LevelNoSideEffects");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
EditorGUILayout.LabelField($"{niceName} is null");
|
|
}
|
|
}
|
|
EditorGUI.indentLevel = origIndent;
|
|
}
|
|
|
|
private static void GetShowLevelAttributeFields(object target, List<FieldInfo> resList, bool appPlaying)
|
|
{
|
|
int count = 0;
|
|
for (var currentType = target.GetType(); currentType != null; currentType = currentType.BaseType)
|
|
{
|
|
if (count == 100)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var fields = currentType.GetFields(k_ShowLevelBindingFlags);
|
|
|
|
//
|
|
// Search for ShowLevelAttribute within each field on this Object
|
|
//
|
|
for (int i = 0, counti = fields.Length; i < counti; ++i)
|
|
{
|
|
var field = fields[i];
|
|
var showLevelAttribute = field.GetCustomAttribute<ShowLevelAttribute>(true);
|
|
if (showLevelAttribute == null)
|
|
continue;
|
|
|
|
if (!appPlaying && !showLevelAttribute.ShowWhenNotPlaying)
|
|
{
|
|
continue;
|
|
}
|
|
resList.Add(field);
|
|
}
|
|
|
|
count += 1;
|
|
}
|
|
}
|
|
|
|
private static PropertyInfo GetLevelNoSideEffectsProperty(object fieldValue)
|
|
{
|
|
var properties = fieldValue.GetType().GetProperties(BindingFlags.GetProperty |
|
|
BindingFlags.Public | BindingFlags.Instance);
|
|
|
|
for (int i = 0; i < properties.Length; i++)
|
|
{
|
|
var property = properties[i];
|
|
|
|
if (k_EditorLevelProperty.CompareTo(property.Name) == 0)
|
|
{
|
|
return property;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
#endif
|
|
}
|
|
} |