Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 208d626100
commit f74c547a13
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,180 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Reflection;
using System;
using System.Linq;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMPropertyEmitter), true)]
[CanEditMultipleObjects]
public class MMPropertyEmitterDrawer : MMPropertyPickerDrawer
{
protected Color _mmBlue = new Color(0.2235294f, 0.6745098f, 1f);
protected Color _mmRed = MMColors.Orangered;
protected override void FillAuthorizedTypes(PropertyPickerViewData viewData)
{
viewData._authorizedTypes = new Type[]
{
typeof(float),
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Quaternion),
typeof(int),
typeof(bool)
};
}
/// <summary>
/// Defines the height of the drawer
/// </summary>
/// <param name="property"></param>
/// <param name="label"></param>
/// <returns></returns>
public override float AdditionalHeight(PropertyPickerViewData viewData)
{
int additionalLines = 0;
if (viewData._TargetObject != null)
{
if ((viewData._selectedPropertyIndex != 0) && (viewData._propertyType != null))
{
additionalLines = 1;
if (viewData._propertyType == typeof(bool))
{
additionalLines = 2;
}
if (viewData._propertyType == typeof(float))
{
additionalLines = 4;
}
if (viewData._propertyType == typeof(int))
{
additionalLines = 4;
}
if (viewData._propertyType == typeof(Vector2))
{
additionalLines = 5;
}
if (viewData._propertyType == typeof(Vector3))
{
additionalLines = 5;
}
if (viewData._propertyType == typeof(Vector4))
{
additionalLines = 5;
}
if (viewData._propertyType == typeof(Quaternion))
{
additionalLines = 5;
}
}
if (Application.isPlaying)
{
additionalLines += 1;
}
}
viewData._numberOfLines = viewData._numberOfLines + additionalLines;
return PropertyPickerViewData._lineHeight * additionalLines + PropertyPickerViewData._lineMargin * additionalLines - 1;
}
/// <summary>
/// Draws the inspector
/// </summary>
/// <param name="position"></param>
/// <param name="property"></param>
/// <param name="label"></param>
protected override void DisplayAdditionalProperties(Rect position, SerializedProperty property, GUIContent label, PropertyPickerViewData viewData)
{
float lineHeight = PropertyPickerViewData._lineHeight;
float lineMargin = PropertyPickerViewData._lineMargin;
Rect additional1Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 4, position.width, lineHeight);
Rect additional2Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 5, position.width, lineHeight);
Rect additional3Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 6, position.width, lineHeight);
Rect additional4Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 7, position.width, lineHeight);
Rect additional5Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 8, position.width, lineHeight);
Rect additional6Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 9, position.width, lineHeight);
Rect additional7Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 10, position.width, lineHeight);
Rect additional8Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 11, position.width, lineHeight);
Rect additional9Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 12, position.width, lineHeight);
Rect additional10Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 13, position.width, lineHeight);
// displays the related properties
if ((viewData._selectedPropertyIndex != 0) && (viewData._propertyType != null))
{
if (viewData._propertyType == typeof(bool))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("BoolRemapFalse"), new GUIContent("Remap False"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("BoolRemapTrue"), new GUIContent("Remap True"), true);
}
if (viewData._propertyType == typeof(float))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("FloatRemapMinToZero"), new GUIContent("RemapToZero"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("FloatRemapMaxToOne"), new GUIContent("RemapToOne"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ClampMin"), new GUIContent("ClampMin"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ClampMax"), new GUIContent("ClampMax"), true);
}
if (viewData._propertyType == typeof(Vector2))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("Vector2Option"), new GUIContent("Target axis"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("FloatRemapMinToZero"), new GUIContent("RemapToZero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("FloatRemapMaxToOne"), new GUIContent("RemapToOne"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ClampMin"), new GUIContent("ClampMin"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("ClampMax"), new GUIContent("ClampMax"), true);
}
if (viewData._propertyType == typeof(Vector3))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("Vector3Option"), new GUIContent("Target axis"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("FloatRemapMinToZero"), new GUIContent("RemapToZero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("FloatRemapMaxToOne"), new GUIContent("RemapToOne"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ClampMin"), new GUIContent("ClampMin"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("ClampMax"), new GUIContent("ClampMax"), true);
}
if (viewData._propertyType == typeof(Vector4))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("Vector4Option"), new GUIContent("Target axis"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("FloatRemapMinToZero"), new GUIContent("RemapToZero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("FloatRemapMaxToOne"), new GUIContent("RemapToOne"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ClampMin"), new GUIContent("ClampMin"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("ClampMax"), new GUIContent("ClampMax"), true);
}
if (viewData._propertyType == typeof(Quaternion))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("Vector3Option"), new GUIContent("Target axis"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("QuaternionRemapMinToZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("QuaternionRemapMaxToOne"), new GUIContent("Remap One"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ClampMin"), new GUIContent("ClampMin"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("ClampMax"), new GUIContent("ClampMax"), true);
}
if (viewData._propertyType == typeof(int))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("IntRemapMinToZero"), new GUIContent("RemapToZero"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("IntRemapMaxToOne"), new GUIContent("RemapToOne"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ClampMin"), new GUIContent("ClampMin"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ClampMax"), new GUIContent("ClampMax"), true);
}
}
if ((viewData._TargetObject != null) && (viewData._selectedPropertyIndex != 0) && (viewData._propertyType != null) && (Application.isPlaying))
{
// if the application is playing, we display a progress bar
float level = property.FindPropertyRelative("Level").floatValue;
DrawLevelProgressBar(position, level, _mmBlue, _mmRed, viewData);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bbf5e7decc40e8d4e9a6ad8c5046c26d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,557 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Reflection;
using System;
using System.Linq;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMPropertyPicker), true)]
public class MMPropertyPickerDrawer : PropertyDrawer
{
public class PropertyPickerViewData
{
public UnityEngine.Object _TargetObject;
public GameObject _TargetGameObject;
public const int _lineHeight = 20;
public const int _lineMargin = 2;
public int _selectedComponentIndex = 0;
public int _selectedPropertyIndex = 0;
public const string _undefinedComponentString = "<Undefined Component>";
public const string _undefinedPropertyString = "<Undefined Property>";
public bool _initialized = false;
public string[] _componentNames;
public List<Component> _componentList;
public string[] _propertiesNames;
public List<string> _propertiesList;
public Type _propertyType = null;
public int _numberOfLines = 0;
public Color _progressBarBackground = new Color(0, 0, 0, 0.5f);
public Type[] _authorizedTypes;
public bool _targetIsScriptableObject;
}
private Dictionary<string, PropertyPickerViewData> _propertyPickerViewData = new Dictionary<string, PropertyPickerViewData>();
/// <summary>
/// Defines the height of the drawer
/// </summary>
/// <param name="property"></param>
/// <param name="label"></param>
/// <returns></returns>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (!_propertyPickerViewData.TryGetValue(property.propertyPath, out var viewData))
{
viewData = new PropertyPickerViewData();
_propertyPickerViewData[property.propertyPath] = viewData;
}
Initialization(property, viewData);
viewData._numberOfLines = 2;
if (viewData._TargetObject != null)
{
viewData._numberOfLines = 3;
if (viewData._selectedComponentIndex != 0)
{
viewData._numberOfLines = 4;
}
}
if (viewData._targetIsScriptableObject)
{
viewData._numberOfLines = 4;
}
return PropertyPickerViewData._lineHeight * viewData._numberOfLines + PropertyPickerViewData._lineMargin * viewData._numberOfLines - 1 + AdditionalHeight(viewData);
}
public virtual float AdditionalHeight(PropertyPickerViewData viewData)
{
return 0f;
}
/// <summary>
/// Initializes the dropdowns
/// </summary>
/// <param name="property"></param>
protected virtual void Initialization(SerializedProperty property, PropertyPickerViewData viewData)
{
if (viewData._initialized)
{
return;
}
FillAuthorizedTypes(viewData);
FillComponentsList(property, viewData);
FillPropertyList(property, viewData);
GetComponentIndex(property, viewData);
GetPropertyIndex(property, viewData);
viewData._propertyType = GetPropertyType(property, viewData);
viewData._initialized = true;
}
protected static bool AuthorizedType(Type[] typeArray, Type checkedType)
{
foreach (Type t in typeArray)
{
if (t == checkedType)
{
return true;
}
}
return false;
}
protected virtual void FillAuthorizedTypes(PropertyPickerViewData viewData)
{
viewData._authorizedTypes = new Type[]
{
typeof(String),
typeof(float),
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Quaternion),
typeof(int),
typeof(bool),
typeof(Color)
};
}
#if UNITY_EDITOR
/// <summary>
/// Draws the inspector
/// </summary>
/// <param name="position"></param>
/// <param name="property"></param>
/// <param name="label"></param>
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (!_propertyPickerViewData.TryGetValue(property.propertyPath, out var viewData))
{
viewData = new PropertyPickerViewData();
_propertyPickerViewData[property.propertyPath] = viewData;
}
Initialization(property, viewData);
// rectangles
Rect targetLabelRect = new Rect(position.x, position.y, position.width, PropertyPickerViewData._lineHeight);
Rect targetObjectRect = new Rect(position.x, position.y + (PropertyPickerViewData._lineHeight + PropertyPickerViewData._lineMargin), position.width, PropertyPickerViewData._lineHeight);
Rect targetComponentRect = new Rect(position.x, position.y + (PropertyPickerViewData._lineHeight + PropertyPickerViewData._lineMargin) * 2, position.width, PropertyPickerViewData._lineHeight);
Rect targetPropertyRect = new Rect(position.x, position.y + (PropertyPickerViewData._lineHeight + PropertyPickerViewData._lineMargin) * 3, position.width, PropertyPickerViewData._lineHeight);
EditorGUI.BeginProperty(position, label, property);
EditorGUI.LabelField(targetLabelRect, new GUIContent(property.name));
EditorGUI.indentLevel++;
// displays the target object selector
// property.serializedObject.Update(); // removed to prevent blocking upper parts of the inspector
EditorGUI.BeginChangeCheck();
EditorGUI.PropertyField(targetObjectRect, property.FindPropertyRelative("TargetObject"), new GUIContent("Target Object"), true);
if (EditorGUI.EndChangeCheck())
{
property.serializedObject.ApplyModifiedProperties();
viewData._TargetObject = property.FindPropertyRelative("TargetObject").objectReferenceValue as UnityEngine.Object;
FillComponentsList(property, viewData);
viewData._selectedComponentIndex = 0;
viewData._selectedPropertyIndex = 0;
SetTargetComponent(property, viewData);
if (viewData._targetIsScriptableObject)
{
FillPropertyList(property, viewData);
}
}
// displays a label for scriptable objects
if (viewData._targetIsScriptableObject)
{
EditorGUI.LabelField(targetComponentRect, "Type", "Scriptable Object");
}
// displays the component dropdown for gameobjects
if ((viewData._componentNames != null) && (viewData._componentNames.Length > 0))
{
EditorGUI.BeginChangeCheck();
viewData._selectedComponentIndex = EditorGUI.Popup(targetComponentRect, "Component", viewData._selectedComponentIndex, viewData._componentNames);
if (EditorGUI.EndChangeCheck())
{
SetTargetComponent(property, viewData);
viewData._selectedPropertyIndex = 0;
FillPropertyList(property, viewData);
}
}
// displays the properties dropdown
if (((viewData._selectedComponentIndex != 0) || viewData._targetIsScriptableObject) && (viewData._propertiesNames != null) && (viewData._propertiesNames.Length > 0))
{
EditorGUI.BeginChangeCheck();
viewData._selectedPropertyIndex = EditorGUI.Popup(targetPropertyRect, "Property", viewData._selectedPropertyIndex, viewData._propertiesNames);
if (EditorGUI.EndChangeCheck())
{
SetTargetProperty(property, viewData);
}
}
DisplayAdditionalProperties(position, property, label, viewData);
EditorGUI.indentLevel--;
EditorGUI.EndProperty();
}
#endif
protected virtual void DisplayAdditionalProperties(Rect position, SerializedProperty property, GUIContent label, PropertyPickerViewData viewData)
{
}
protected virtual void DrawLevelProgressBar(Rect position, float level, Color frontColor, Color negativeColor, PropertyPickerViewData viewData)
{
Rect levelLabelRect = new Rect(position.x, position.y + (PropertyPickerViewData._lineHeight + PropertyPickerViewData._lineMargin) * (viewData._numberOfLines - 1), position.width, PropertyPickerViewData._lineHeight);
Rect levelValueRect = new Rect(position.x - 15 + EditorGUIUtility.labelWidth + 4, position.y + (PropertyPickerViewData._lineHeight + PropertyPickerViewData._lineMargin) * (viewData._numberOfLines - 1), position.width, PropertyPickerViewData._lineHeight);
float progressX = position.x - 5 + EditorGUIUtility.labelWidth + 60;
float progressY = position.y + (PropertyPickerViewData._lineHeight + PropertyPickerViewData._lineMargin) * (viewData._numberOfLines - 1) + 6;
float progressHeight = 10f;
float fullProgressWidth = position.width - EditorGUIUtility.labelWidth - 60 + 5;
bool negative = false;
float displayLevel = level;
if (level < 0f)
{
negative = true;
level = -level;
}
float progressLevel = Mathf.Clamp01(level);
Rect levelProgressBg = new Rect(progressX, progressY, fullProgressWidth, progressHeight);
float progressWidth = MMMaths.Remap(progressLevel, 0f, 1f, 0f, fullProgressWidth);
Rect levelProgressFront = new Rect(progressX, progressY, progressWidth, progressHeight);
EditorGUI.LabelField(levelLabelRect, new GUIContent("Level"));
EditorGUI.LabelField(levelValueRect, new GUIContent(displayLevel.ToString("F4")));
EditorGUI.DrawRect(levelProgressBg, viewData._progressBarBackground);
if (negative)
{
EditorGUI.DrawRect(levelProgressFront, negativeColor);
}
else
{
EditorGUI.DrawRect(levelProgressFront, frontColor);
}
}
/// <summary>
/// Fills a list of all the components on the target object
/// </summary>
/// <param name="property"></param>
protected virtual void FillComponentsList(SerializedProperty property, PropertyPickerViewData viewData)
{
viewData._TargetObject = property.FindPropertyRelative("TargetObject").objectReferenceValue as UnityEngine.Object;
viewData._TargetGameObject = property.FindPropertyRelative("TargetObject").objectReferenceValue as GameObject;
viewData._targetIsScriptableObject = false;
if (property.FindPropertyRelative("TargetObject").objectReferenceValue is ScriptableObject)
{
viewData._targetIsScriptableObject = true;
}
if (viewData._TargetGameObject == null)
{
viewData._componentNames = null;
return;
}
// we create a list of components and an array of names
viewData._componentList = new List<Component>();
viewData._componentNames = new string[0];
// we create a temp list to fill our array with
List<string> tempComponentsNameList = new List<string>();
tempComponentsNameList.Add(PropertyPickerViewData._undefinedComponentString);
viewData._componentList.Add(null);
// we add all components to the list
Component[] components = viewData._TargetGameObject.GetComponents(typeof(Component));
foreach (Component component in components)
{
viewData._componentList.Add(component);
tempComponentsNameList.Add(component.GetType().Name);
}
viewData._componentNames = tempComponentsNameList.ToArray();
}
/// <summary>
/// Fills a list of all properties and fields on the target component
/// </summary>
/// <param name="property"></param>
protected virtual void FillPropertyList(SerializedProperty property, PropertyPickerViewData viewData)
{
if (viewData._TargetObject == null)
{
return;
}
if ((property.FindPropertyRelative("TargetComponent").objectReferenceValue == null)
&& !viewData._targetIsScriptableObject)
{
return;
}
// we create a list of components and an array of names
viewData._propertiesNames = Array.Empty<string>();
viewData._propertiesList = new List<string>();
// we create a temp list to fill our array with
List<string> tempPropertiesList = new List<string>();
tempPropertiesList.Add(PropertyPickerViewData._undefinedPropertyString);
viewData._propertiesList.Add("");
if (!viewData._targetIsScriptableObject)
{
// Find all fields
var fieldsList = property.FindPropertyRelative("TargetComponent").objectReferenceValue.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(field =>
(AuthorizedType(viewData._authorizedTypes, field.FieldType))
)
.OrderBy(prop => prop.FieldType.Name).ToList();
foreach (FieldInfo thisFieldInfo in fieldsList)
{
string newEntry = thisFieldInfo.Name + " [Field - " + thisFieldInfo.FieldType.Name + "]";
tempPropertiesList.Add(newEntry);
viewData._propertiesList.Add(thisFieldInfo.Name);
}
// finds all properties
var propertiesList = property.FindPropertyRelative("TargetComponent").objectReferenceValue.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(prop =>
(AuthorizedType(viewData._authorizedTypes, prop.PropertyType))
)
.OrderBy(prop => prop.PropertyType.Name).ToList();
foreach (PropertyInfo foundProperty in propertiesList)
{
string newEntry = foundProperty.Name + " [Property - " + foundProperty.PropertyType.Name + "]";
tempPropertiesList.Add(newEntry);
viewData._propertiesList.Add(foundProperty.Name);
}
}
else
{
// if this is a scriptable object
// finds all fields
var fieldsList = property.FindPropertyRelative("TargetObject").objectReferenceValue.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Instance)
.Where(field =>
(AuthorizedType(viewData._authorizedTypes, field.FieldType))
)
.OrderBy(prop => prop.FieldType.Name).ToList();
foreach (FieldInfo thisFieldInfo in fieldsList)
{
string newEntry = thisFieldInfo.Name + " [Field - " + thisFieldInfo.FieldType.Name + "]";
tempPropertiesList.Add(newEntry);
viewData._propertiesList.Add(thisFieldInfo.Name);
}
// finds all properties
var propertiesList = property.FindPropertyRelative("TargetObject").objectReferenceValue.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(prop =>
(AuthorizedType(viewData._authorizedTypes, prop.PropertyType))
)
.OrderBy(prop => prop.PropertyType.Name).ToList();
foreach (PropertyInfo foundProperty in propertiesList)
{
string newEntry = foundProperty.Name + " [Property - " + foundProperty.PropertyType.Name + "]";
tempPropertiesList.Add(newEntry);
viewData._propertiesList.Add(foundProperty.Name);
}
}
viewData._propertiesNames = tempPropertiesList.ToArray();
}
/// <summary>
/// Sets the target property
/// </summary>
/// <param name="property"></param>
protected virtual void SetTargetProperty(SerializedProperty property, PropertyPickerViewData viewData)
{
if (viewData._selectedPropertyIndex > 0)
{
property.serializedObject.Update();
property.FindPropertyRelative("TargetPropertyName").stringValue = viewData._propertiesList[viewData._selectedPropertyIndex];
property.serializedObject.ApplyModifiedProperties();
viewData._propertyType = GetPropertyType(property, viewData);
}
else
{
property.serializedObject.Update();
property.FindPropertyRelative("TargetPropertyName").stringValue = "";
property.serializedObject.ApplyModifiedProperties();
viewData._selectedPropertyIndex = 0;
viewData._propertyType = null;
}
}
/// <summary>
/// Sets the target component
/// </summary>
/// <param name="property"></param>
protected virtual void SetTargetComponent(SerializedProperty property, PropertyPickerViewData viewData)
{
if (viewData._targetIsScriptableObject)
{
property.serializedObject.Update();
property.FindPropertyRelative("TargetScriptableObject").objectReferenceValue = property.FindPropertyRelative("TargetObject").objectReferenceValue as ScriptableObject;
property.FindPropertyRelative("TargetComponent").objectReferenceValue = null;
property.serializedObject.ApplyModifiedProperties();
return;
}
if (viewData._selectedComponentIndex > 0)
{
property.serializedObject.Update();
property.FindPropertyRelative("TargetComponent").objectReferenceValue = viewData._componentList[viewData._selectedComponentIndex];
property.FindPropertyRelative("TargetScriptableObject").objectReferenceValue = null;
property.serializedObject.ApplyModifiedProperties();
}
else
{
property.serializedObject.Update();
property.FindPropertyRelative("TargetComponent").objectReferenceValue = null;
property.FindPropertyRelative("TargetPropertyName").stringValue = "";
property.FindPropertyRelative("TargetScriptableObject").objectReferenceValue = null;
viewData._selectedComponentIndex = 0;
viewData._selectedPropertyIndex = 0;
property.serializedObject.ApplyModifiedProperties();
}
}
/// <summary>
/// Gets the component index
/// </summary>
/// <param name="property"></param>
protected virtual void GetComponentIndex(SerializedProperty property, PropertyPickerViewData viewData)
{
int index = 0;
bool found = false;
Component targetComponent = property.FindPropertyRelative("TargetComponent").objectReferenceValue as Component;
if ((viewData._componentList == null) || (viewData._componentList.Count == 0))
{
viewData._selectedComponentIndex = 0;
return;
}
foreach (Component component in viewData._componentList)
{
if (component == targetComponent)
{
viewData._selectedComponentIndex = index;
found = true;
}
index++;
}
if (!found)
{
viewData._selectedComponentIndex = 0;
}
}
/// <summary>
/// Gets the property index
/// </summary>
/// <param name="property"></param>
protected virtual void GetPropertyIndex(SerializedProperty property, PropertyPickerViewData viewData)
{
int index = 0;
bool found = false;
Component targetComponent = property.FindPropertyRelative("TargetComponent").objectReferenceValue as Component;
ScriptableObject targetScriptable = property.FindPropertyRelative("TargetScriptableObject").objectReferenceValue as ScriptableObject;
if ((targetComponent == null) && (targetScriptable == null))
{
return;
}
string targetProperty = property.FindPropertyRelative("TargetPropertyName").stringValue;
if ((viewData._propertiesList == null) || (viewData._propertiesList.Count == 0))
{
viewData._selectedPropertyIndex = 0;
return;
}
foreach (string prop in viewData._propertiesList)
{
if (prop == targetProperty)
{
viewData._selectedPropertyIndex = index;
found = true;
}
index++;
}
if (!found)
{
viewData._selectedPropertyIndex = 0;
}
}
protected virtual Type GetPropertyType(SerializedProperty property, PropertyPickerViewData viewData)
{
if (viewData._selectedPropertyIndex == 0)
{
return null;
}
MMProperty tempProperty;
tempProperty = MMProperty.FindProperty(viewData._propertiesList[viewData._selectedPropertyIndex], property.FindPropertyRelative("TargetComponent").objectReferenceValue as Component, null, property.FindPropertyRelative("TargetObject").objectReferenceValue as ScriptableObject);
if (tempProperty != null)
{
return tempProperty.PropertyType;
}
else
{
return null;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e4e9029e392667449a8e7021ac4d66b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,209 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.Reflection;
using System;
using System.Linq;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMPropertyReceiver), true)]
[CanEditMultipleObjects]
public class MMPropertyReceiverDrawer : MMPropertyPickerDrawer
{
protected Color _mmYellow = new Color(1f, 0.7686275f, 0f);
protected Color _mmRed = MMColors.Orangered;
protected override void FillAuthorizedTypes(PropertyPickerViewData viewData)
{
viewData._authorizedTypes = new Type[]
{
typeof(String),
typeof(float),
typeof(Vector2),
typeof(Vector3),
typeof(Vector4),
typeof(Quaternion),
typeof(int),
typeof(bool),
typeof(Color)
};
}
/// <summary>
/// Defines the height of the drawer
/// </summary>
/// <param name="property"></param>
/// <param name="label"></param>
/// <returns></returns>
public override float AdditionalHeight(PropertyPickerViewData viewData)
{
int additionalLines = 0;
if (viewData._TargetObject != null)
{
if ((viewData._selectedPropertyIndex != 0) && (viewData._propertyType != null))
{
additionalLines = 1;
if (viewData._propertyType == typeof(bool))
{
additionalLines = 3;
}
if (viewData._propertyType == typeof(Color))
{
additionalLines = 3;
}
if (viewData._propertyType == typeof(string))
{
additionalLines = 3;
}
if (viewData._propertyType == typeof(float))
{
additionalLines = 3;
}
if (viewData._propertyType == typeof(int))
{
additionalLines = 3;
}
if (viewData._propertyType == typeof(Vector2))
{
additionalLines = 5;
}
if (viewData._propertyType == typeof(Vector3))
{
additionalLines = 6;
}
if (viewData._propertyType == typeof(Vector4))
{
additionalLines = 15;
}
if (viewData._propertyType == typeof(Quaternion))
{
additionalLines = 6;
}
}
if (Application.isPlaying)
{
additionalLines += 1;
}
}
viewData._numberOfLines = viewData._numberOfLines + additionalLines;
return PropertyPickerViewData._lineHeight * additionalLines + PropertyPickerViewData._lineMargin * additionalLines - 1;
}
/// <summary>
/// Draws the inspector
/// </summary>
/// <param name="position"></param>
/// <param name="property"></param>
/// <param name="label"></param>
protected override void DisplayAdditionalProperties(Rect position, SerializedProperty property, GUIContent label, PropertyPickerViewData viewData)
{
float lineHeight = PropertyPickerViewData._lineHeight;
float lineMargin = PropertyPickerViewData._lineMargin;
Rect additional1Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 4, position.width, lineHeight);
Rect additional2Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 5, position.width, lineHeight);
Rect additional3Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 6, position.width, lineHeight);
Rect additional4Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 7, position.width, lineHeight);
Rect additional5Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 8, position.width, lineHeight);
Rect additional6Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 9, position.width, lineHeight);
Rect additional7Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 10, position.width, lineHeight);
Rect additional8Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 11, position.width, lineHeight);
Rect additional9Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 12, position.width, lineHeight);
Rect additional10Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 13, position.width, lineHeight);
// displays the related properties
if ((viewData._selectedPropertyIndex != 0) && (viewData._propertyType != null))
{
if ( (viewData._propertyType != typeof(bool)) && (viewData._propertyType != typeof(string)) )
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("RelativeValue"), new GUIContent("Relative Value"), true);
}
if (viewData._propertyType == typeof(string))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("StringRemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("StringRemapOne"), new GUIContent("Remap One"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("Threshold"), new GUIContent("Zero/One Threshold"), true);
}
if (viewData._propertyType == typeof(bool))
{
EditorGUI.PropertyField(additional1Rect, property.FindPropertyRelative("BoolRemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("BoolRemapOne"), new GUIContent("Remap One"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("Threshold"), new GUIContent("True/False Threshold"), true);
}
if (viewData._propertyType == typeof(float))
{
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("FloatRemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("FloatRemapOne"), new GUIContent("Remap One"), true);
}
if (viewData._propertyType == typeof(Vector2))
{
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("ModifyX"), new GUIContent("Modify x"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ModifyY"), new GUIContent("Modify y"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("Vector2RemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("Vector2RemapOne"), new GUIContent("Remap One"), true);
}
if (viewData._propertyType == typeof(Vector3))
{
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("ModifyX"), new GUIContent("Modify x"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ModifyY"), new GUIContent("Modify y"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ModifyZ"), new GUIContent("Modify z"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("Vector3RemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional6Rect, property.FindPropertyRelative("Vector3RemapOne"), new GUIContent("Remap One"), true);
}
if (viewData._propertyType == typeof(Vector4))
{
Rect additionalVector47Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 9, position.width, lineHeight * 5);
Rect additionalVector48Rect = new Rect(position.x, position.y + (lineHeight + lineMargin) * 10 + lineHeight * 4, position.width, lineHeight * 5);
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("ModifyX"), new GUIContent("Modify x"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ModifyY"), new GUIContent("Modify y"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ModifyZ"), new GUIContent("Modify z"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("ModifyW"), new GUIContent("Modify z"), true);
EditorGUI.PropertyField(additionalVector47Rect, property.FindPropertyRelative("Vector4RemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additionalVector48Rect, property.FindPropertyRelative("Vector4RemapOne"), new GUIContent("Remap One"), true);
}
if (viewData._propertyType == typeof(Quaternion))
{
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("ModifyX"), new GUIContent("Modify x"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ModifyY"), new GUIContent("Modify y"), true);
EditorGUI.PropertyField(additional4Rect, property.FindPropertyRelative("ModifyZ"), new GUIContent("Modify z"), true);
EditorGUI.PropertyField(additional5Rect, property.FindPropertyRelative("QuaternionRemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional6Rect, property.FindPropertyRelative("QuaternionRemapOne"), new GUIContent("Remap One"), true);
}
if (viewData._propertyType == typeof(int))
{
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("IntRemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("IntRemapOne"), new GUIContent("Remap One"), true);
}
if (viewData._propertyType == typeof(Color))
{
EditorGUI.PropertyField(additional2Rect, property.FindPropertyRelative("ColorRemapZero"), new GUIContent("Remap Zero"), true);
EditorGUI.PropertyField(additional3Rect, property.FindPropertyRelative("ColorRemapOne"), new GUIContent("Remap One"), true);
}
}
if ((viewData._TargetObject != null) && (viewData._selectedPropertyIndex != 0) && (viewData._propertyType != null) && (Application.isPlaying))
{
// if the application is playing, we display a progress bar
float level = property.FindPropertyRelative("Level").floatValue;
DrawLevelProgressBar(position, level, _mmYellow, _mmRed, viewData);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50fd27fe4d3854042af8178658492f5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
[CustomEditor(typeof(MMRadioSignal), true)]
[CanEditMultipleObjects]
public class MMRadioSignalEditor : Editor
{
protected MMRadioSignal _radioSignal;
protected float _inspectorWidth;
protected SerializedProperty _duration;
protected SerializedProperty _currentLevel;
public override bool RequiresConstantRepaint()
{
return true;
}
protected virtual void OnEnable()
{
_radioSignal = target as MMRadioSignal;
_duration = serializedObject.FindProperty("Duration");
_currentLevel = serializedObject.FindProperty("CurrentLevel");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
_inspectorWidth = EditorGUIUtility.currentViewWidth - 24;
DrawProperties();
serializedObject.ApplyModifiedProperties();
}
protected virtual void DrawProperties()
{
DrawPropertiesExcluding(serializedObject, "AnimatedPreview", "CurrentLevel");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 61270f15bcfabeb4ba61296fad914dbe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,249 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
[CustomEditor(typeof(MMRadioSignalGenerator), true)]
[CanEditMultipleObjects]
public class MMRadioSignalGeneratorEditor : MMRadioSignalEditor
{
protected MMReorderableList _list;
protected SerializedProperty _globalMultiplier;
protected SerializedProperty _clamp;
protected SerializedProperty _clamps;
protected SerializedProperty _bias;
protected float _spectrumBoxBottomY;
protected Vector2 _spectrumBoxPosition;
protected Vector2 _spectrumBoxSize;
protected float _spectrumMaxColumnHeight;
protected const float _externalMargin = 12f;
protected float _internalMargin = 12f;
protected const int _rawSpectrumBoxHeight = 125;
protected const int _numberOfAxisSpectrum = 4;
protected Vector3 _axisOrigin = Vector3.zero;
protected Vector3 _axisDestination = Vector3.zero;
protected float _spectrumPointsCount = 200;
protected Color _spectrumColor = MMColors.Aqua;
protected Color _spectrumBoxColor = MMColors.AliceBlue;
protected Rect _rect;
protected double _deltaTime = 0f;
protected double _signalTime = 0f;
protected double _lastTime;
protected float _normalizedTime = 0f;
protected Vector2 _pointA;
protected Vector2 _pointB;
protected SerializedProperty _driverTime;
protected SerializedProperty _animatedPreview;
protected override void OnEnable()
{
base.OnEnable();
_globalMultiplier = serializedObject.FindProperty("GlobalMultiplier");
_clamp = serializedObject.FindProperty("Clamp");
_clamps = serializedObject.FindProperty("Clamps");
_bias = serializedObject.FindProperty("Bias");
_list = new MMReorderableList(serializedObject.FindProperty("SignalList"));
_driverTime = serializedObject.FindProperty("DriverTime");
_animatedPreview = serializedObject.FindProperty("AnimatedPreview");
_list.elementNameProperty = "SignalList";
_list.elementDisplayType = MMReorderableList.ElementDisplayType.Expandable;
_list.onAddCallback += OnListAdd;
}
private void OnListAdd(MMReorderableList list)
{
SerializedProperty property = list.AddItem();
property.FindPropertyRelative("Active").boolValue = true;
property.FindPropertyRelative("Frequency").floatValue = 1f;
property.FindPropertyRelative("Amplitude").floatValue = 1f;
property.FindPropertyRelative("Offset").floatValue = 0f;
property.FindPropertyRelative("Phase").floatValue = 0f;
}
protected override void DrawProperties()
{
DrawPropertiesExcluding(serializedObject, "AnimatedPreview", "SignalList", "GlobalMultiplier", "CurrentLevel", "Clamp", "Clamps");
EditorGUILayout.Space(10);
_list.DoLayoutList();
EditorGUILayout.PropertyField(_globalMultiplier);
EditorGUILayout.PropertyField(_clamps);
DrawRawSpectrum();
}
protected virtual void DrawRawSpectrum()
{
_deltaTime = (EditorApplication.timeSinceStartup - _lastTime);
_signalTime += _deltaTime;
if (_signalTime > _duration.floatValue)
{
_signalTime = 0f;
}
_lastTime = EditorApplication.timeSinceStartup;
_normalizedTime = MMMaths.Remap((float)_signalTime, 0f, _duration.floatValue, 0f, 1f);
GUILayout.Space(10);
GUILayout.Label("Preview", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(_animatedPreview);
EditorGUILayout.Space(20);
// box
GUILayout.Box("", GUILayout.Width(_inspectorWidth - _externalMargin), GUILayout.Height(_rawSpectrumBoxHeight));
_spectrumBoxPosition = GUILayoutUtility.GetLastRect().position;
_spectrumBoxSize = GUILayoutUtility.GetLastRect().size;
_spectrumBoxBottomY = _spectrumBoxPosition.y + _spectrumBoxSize.y;
_spectrumMaxColumnHeight = _spectrumBoxSize.y - 2 * _externalMargin;
Handles.BeginGUI();
// horizontal axis
Handles.color = Color.grey;
for (int i = 0; i <= _numberOfAxisSpectrum; i++)
{
_axisOrigin.x = _spectrumBoxPosition.x;
_axisOrigin.y = _spectrumBoxBottomY - i * (_spectrumBoxSize.y / _numberOfAxisSpectrum);
_axisDestination.x = _spectrumBoxPosition.x + _spectrumBoxSize.x;
_axisDestination.y = _axisOrigin.y;
Handles.DrawLine(_axisOrigin, _axisDestination);
}
// y one label
_rect.x = _axisOrigin.x - 12;
_rect.y = _spectrumBoxBottomY - _spectrumBoxSize.y - 20;
_rect.width = 40;
_rect.height = 40;
EditorGUI.LabelField(_rect, "1", EditorStyles.boldLabel);
float minX = _axisOrigin.x - 12;
float maxX = _axisOrigin.x + _spectrumBoxSize.x - 2;
float zeroX = minX;
float oneX = maxX;
if (_animatedPreview.boolValue)
{
float currentTime = (float)EditorApplication.timeSinceStartup;
float normalizedTime = currentTime - Mathf.Floor(currentTime);
zeroX = maxX - MMMaths.Remap(_normalizedTime, 0f, 1f, _spectrumBoxPosition.x + _externalMargin, _spectrumBoxPosition.x + _spectrumBoxSize.x);
oneX = zeroX - 10;
}
// zero label
_rect.x = zeroX;
_rect.y = _spectrumBoxBottomY - 20;
_rect.width = 40;
_rect.height = 40;
EditorGUI.LabelField(_rect, "0", EditorStyles.boldLabel);
// one label
_rect.x = oneX;
_rect.y = _spectrumBoxBottomY - 20;
_rect.width = 40;
_rect.height = 40;
EditorGUI.LabelField(_rect, "1", EditorStyles.boldLabel);
// level
if (Application.isPlaying)
{
_rect.x = _axisOrigin.x + _spectrumBoxSize.x - 40;
_rect.y = _spectrumBoxBottomY - _spectrumBoxSize.y - 40;
_rect.width = 40;
_rect.height = 40;
EditorGUI.LabelField(_rect, _currentLevel.floatValue.ToString("F3"), EditorStyles.boldLabel);
}
// cube
_rect.x = _spectrumBoxPosition.x + _externalMargin / 4;
if (_duration.floatValue > 0f)
{
float boxSpectrumValue;
if (Application.isPlaying)
{
boxSpectrumValue = MMMaths.Remap(_radioSignal.GraphValue(_driverTime.floatValue), 0f, 1f, 0f, _spectrumBoxSize.y);
}
else
{
boxSpectrumValue = MMMaths.Remap(_radioSignal.GraphValue(_normalizedTime), 0f, 1f, 0f, _spectrumBoxSize.y);
}
_rect.y = _spectrumBoxBottomY - boxSpectrumValue - _externalMargin / 4;
}
else
{
_rect.y = _spectrumBoxBottomY;
}
_rect.width = _externalMargin / 2;
_rect.height = _externalMargin / 2;
EditorGUI.DrawRect(_rect, _spectrumBoxColor);
// progress line
if (Application.isPlaying && !_animatedPreview.boolValue)
{
_rect.x = _spectrumBoxPosition.x
+ MMMaths.Remap(_driverTime.floatValue, 0f, 1f, 0f, _spectrumBoxSize.x);
_rect.y = _spectrumBoxBottomY - _spectrumBoxSize.y;
_rect.width = 1;
_rect.height = _spectrumBoxSize.y;
EditorGUI.DrawRect(_rect, _spectrumBoxColor);
}
for (int i = 1; i < _spectrumPointsCount; i++)
{
float xPosition = _spectrumBoxPosition.x + _externalMargin + MMMaths.Remap(i, 0, _spectrumPointsCount, 0f, _spectrumBoxSize.x - _externalMargin * 2);
float deltaBetweenXandXPrevious = (_spectrumBoxSize.x - _externalMargin * 2) / _spectrumPointsCount;
float time = i * (1 / _spectrumPointsCount);
float timePrevious = (i - 1) * (1 / _spectrumPointsCount);
if (_animatedPreview.boolValue)
{
if (Application.isPlaying)
{
time += _driverTime.floatValue;
timePrevious += _driverTime.floatValue;
}
else
{
time += (float)_normalizedTime;
timePrevious += (float)_normalizedTime;
}
if (time > _duration.floatValue)
{
time = 0f;
}
if (timePrevious > _duration.floatValue)
{
timePrevious = 0f;
}
}
float t2 = Mathf.Pow(time, _bias.floatValue);
float spectrumValue = MMMaths.Remap(_radioSignal.GraphValue(time), 0f, 1f, 0f, _spectrumBoxSize.y);
float spectrumValuePrevious = MMMaths.Remap(_radioSignal.GraphValue(timePrevious), 0f, 1f, 0f, _spectrumBoxSize.y);
Handles.color = _spectrumColor;
_axisOrigin.x = xPosition - deltaBetweenXandXPrevious;
_axisOrigin.y = _spectrumBoxBottomY - spectrumValuePrevious;
_axisDestination.x = xPosition;
_axisDestination.y = _spectrumBoxBottomY - spectrumValue;
var p1 = _axisOrigin;
var p2 = _axisDestination;
var thickness = 3;
Handles.DrawBezier(p1, p2, p1, p2, _spectrumColor, null, thickness);
}
EditorGUILayout.Space(50);
Handles.EndGUI();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a2cfef06e5c2aee4dad9fb668eddb176
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: