HumanoidControl_Free/Editor/Tools/Condition_Editor.cs
Pascal Serrarens 17741d862a First commit
2022-01-12 10:50:57 +01:00

243 lines
11 KiB
C#

using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace Passer {
public class Condition_Editor {
public static string GetConditionLabel(SerializedProperty conditionProp) {
SerializedProperty targetProp = conditionProp.FindPropertyRelative("targetGameObject");
if (targetProp.objectReferenceValue == null)
return "";
string targetName = targetProp.objectReferenceValue.ToString();
int braceIndex = targetName.IndexOf('(');
if (braceIndex > 0)
targetName = targetName.Substring(0, braceIndex - 1);
string label = "[" + targetName + "]";
SerializedProperty propertyNameProp = conditionProp.FindPropertyRelative("fullPropertyName");
string propertyName = propertyNameProp.stringValue;
label += propertyNameProp.stringValue;
SerializedProperty propertyTypeProp = conditionProp.FindPropertyRelative("propertyType");
Condition.PropertyType propertyType = (Condition.PropertyType)propertyTypeProp.intValue;
SerializedProperty operandIndexProp = conditionProp.FindPropertyRelative("operandIndex");
int operandIndex = operandIndexProp.intValue;
switch (propertyType) {
case Condition.PropertyType.Bool:
label += " " + Condition.boolOperands[operandIndex];
break;
case Condition.PropertyType.Int:
label += " " + Condition.intOperands[operandIndex];
SerializedProperty intConstantProp = conditionProp.FindPropertyRelative("intConstant");
label += " " + intConstantProp.intValue;
break;
case Condition.PropertyType.Float:
label += " " + Condition.floatOperands[operandIndex];
SerializedProperty floatConstantProp = conditionProp.FindPropertyRelative("floatConstant");
label += " " + floatConstantProp.floatValue;
break;
case Condition.PropertyType.Object:
label += " " + Condition.objectOperands[operandIndex];
break;
}
return label;
}
public static void ConditionInspector(SerializedProperty conditionProp) {
if (conditionProp == null)
return;
GUIStyle style = new GUIStyle(GUI.skin.box) {
margin = new RectOffset(0, 0, 0, 0)
};
Rect rect = EditorGUILayout.BeginVertical(style);
GUI.Box(rect, "", style);
int indentLevel = EditorGUI.indentLevel;
EditorGUI.indentLevel = 1;
SerializedProperty targetProp = ConditionTargetInspector(conditionProp);
ConditionPropertyInspector(conditionProp, targetProp);
EditorGUILayout.BeginHorizontal();
ConditionOperandInspector(conditionProp);
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel = indentLevel;
EditorGUILayout.EndVertical();
}
public static void AppendNewCondition(SerializedProperty conditionsProp) {
int conditionsCount = conditionsProp.arraySize;
conditionsProp.InsertArrayElementAtIndex(conditionsCount);
SerializedProperty functionCallProp = conditionsProp.GetArrayElementAtIndex(conditionsCount);
SerializedProperty targetProp = functionCallProp.FindPropertyRelative("targetGameObject");
targetProp.objectReferenceValue = null;
}
#region Target
protected static SerializedProperty ConditionTargetInspector(SerializedProperty conditionProp) {
SerializedProperty targetProp = conditionProp.FindPropertyRelative("targetGameObject");
GUIContent text = new GUIContent(
"Target",
"The Object on which the method is called"
);
EditorGUILayout.ObjectField(targetProp, text);
return targetProp;
}
#endregion
#region Property
private static System.Type ConditionPropertyInspector(SerializedProperty conditionProp, SerializedProperty targetProp) {
string componentType = "";
Object callTarget = targetProp.objectReferenceValue;
if (callTarget != null && callTarget.GetType() != typeof(GameObject))
componentType = callTarget.GetType().Name;
List<Condition.PropertyType> propertyTypes;
string[] propertyNames = GetPropertyNames(targetProp, out propertyTypes);
SerializedProperty fullPropertyNameProp = conditionProp.FindPropertyRelative("fullPropertyName");
//SerializedProperty propertyNameProp = conditionProp.FindPropertyRelative("propertyName");
int propertyNameIndex = GetPropertyIndex(/*componentType,*/ fullPropertyNameProp.stringValue, propertyNames);
propertyNameIndex = EditorGUILayout.Popup("Property", propertyNameIndex, propertyNames);
if (propertyNameIndex >= 0 && propertyNameIndex < propertyNames.Length) {
string fullPropertyName = propertyNames[propertyNameIndex];
SetProperty(conditionProp, targetProp, fullPropertyName, propertyTypes[propertyNameIndex]);
}
return null;
}
private static string[] GetPropertyNames(SerializedProperty targetProp, out List<Condition.PropertyType> propertyTypes) {
GameObject targetObject = (GameObject)targetProp.objectReferenceValue;
if (targetObject == null) {
propertyTypes = new List<Condition.PropertyType>();
return new string[0];
}
// Get all components for the targetObejct
Component[] components = targetObject.GetComponents<Component>();
// For each component, add the properties
List<string> nameList = new List<string>();
propertyTypes = new List<Condition.PropertyType>();
AddPropertyNames(ref nameList, ref propertyTypes, targetObject);
foreach (Component component in components) {
AddPropertyNames(ref nameList, ref propertyTypes, component);
}
string[] names = new string[nameList.Count];
for (int i = 0; i < nameList.Count; i++) {
names[i] = nameList[i];
}
return names;
}
private static void AddPropertyNames(ref List<string> names, ref List<Condition.PropertyType> types, Object component) {
if (component == null)
return;
System.Type componentType = component.GetType();
PropertyInfo[] properties = componentType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < properties.Length; i++) {
if (BlackListed(properties[i].Name))
continue;
if (properties[i].PropertyType == typeof(float) ||
properties[i].PropertyType == typeof(int) ||
properties[i].PropertyType == typeof(bool) ||
properties[i].PropertyType == typeof(Object)
) {
names.Add(componentType.Name + "/" + properties[i].Name);
types.Add(Condition.GetFromType(properties[i].PropertyType));
}
}
}
private static string[] blackList = {
};
private static bool BlackListed(string propertyName) {
foreach (string blackListEntry in blackList) {
if (propertyName == blackListEntry)
return true;
}
return false;
}
private static int GetPropertyIndex(/*string componentType,*/ string propertyName, string[] propertyNames) {
for (int i = 0; i < propertyNames.Length; i++) {
if (propertyName == propertyNames[i])
return i;
}
return -1;
}
private static void SetProperty(
SerializedProperty conditionProp, SerializedProperty targetProp,
string fullPropertyName, Condition.PropertyType propertyType) {
//int slashPos = fullPropertyName.LastIndexOf("/");
GameObject callTargetObject = Event_Editor.GetTargetGameObject(targetProp);
if (callTargetObject != null) {
//string componentType = fullPropertyName.Substring(0, slashPos);
targetProp.objectReferenceValue = callTargetObject;
}
SerializedProperty fullPropertyNameProp = conditionProp.FindPropertyRelative("fullPropertyName");
fullPropertyNameProp.stringValue = fullPropertyName;
SerializedProperty propertyTypeProp = conditionProp.FindPropertyRelative("propertyType");
propertyTypeProp.intValue = (int)propertyType;
}
#endregion
#region Operand
private static void ConditionOperandInspector(SerializedProperty conditionProp) {
SerializedProperty propertyTypeProp = conditionProp.FindPropertyRelative("propertyType");
SerializedProperty operandIndexProp = conditionProp.FindPropertyRelative("operandIndex");
Condition.PropertyType propertyType = (Condition.PropertyType)propertyTypeProp.intValue;
switch (propertyType) {
case Condition.PropertyType.Bool:
operandIndexProp.intValue = EditorGUILayout.Popup(" ", operandIndexProp.intValue, Condition.boolOperands);
break;
case Condition.PropertyType.Int:
operandIndexProp.intValue = EditorGUILayout.Popup(operandIndexProp.intValue, Condition.intOperands, GUILayout.MaxWidth(120));
SerializedProperty intConstantProp = conditionProp.FindPropertyRelative("intConstant");
intConstantProp.intValue = EditorGUILayout.IntField(intConstantProp.intValue);
break;
case Condition.PropertyType.Float:
operandIndexProp.intValue = EditorGUILayout.Popup(operandIndexProp.intValue, Condition.floatOperands, GUILayout.MaxWidth(120));
SerializedProperty floatConstantProp = conditionProp.FindPropertyRelative("floatConstant");
floatConstantProp.floatValue = EditorGUILayout.FloatField(floatConstantProp.floatValue);
break;
case Condition.PropertyType.Object:
operandIndexProp.intValue = EditorGUILayout.Popup(operandIndexProp.intValue, Condition.objectOperands);
break;
default:
return;
}
}
#endregion
}
}