chore: initial commit

This commit is contained in:
2026-05-08 11:04:00 +08:00
commit f55d2a57c3
6278 changed files with 866081 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 91a094309828a434896d44b4e956b248
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 275abffec231dff4daae967d769cf48b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMBackgroundColorAttribute))]
public class MMBackgroundColorAttributeDrawer : PropertyDrawer
{
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var backgroundColorAttribute = attribute as MMBackgroundColorAttribute;
bool doHighlight = true;
if (doHighlight)
{
var color = GetColor(backgroundColorAttribute.Color);
var padding = EditorGUIUtility.standardVerticalSpacing;
var highlightRect = new Rect(position.x - padding, position.y - padding,
position.width + (padding * 2), position.height + (padding * 2));
EditorGUI.DrawRect(highlightRect, color);
var cc = GUI.contentColor;
GUI.contentColor = Color.black;
EditorGUI.PropertyField(position, property, label);
GUI.contentColor = cc;
}
else
{
EditorGUI.PropertyField(position, property, label);
}
}
#endif
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
private Color GetColor(MMBackgroundAttributeColor color)
{
switch (color)
{
case MMBackgroundAttributeColor.Red:
return new Color32(255, 0, 63, 255);
case MMBackgroundAttributeColor.Pink:
return new Color32(255, 66, 160, 255);
case MMBackgroundAttributeColor.Orange:
return new Color32(255, 128, 0, 255);
case MMBackgroundAttributeColor.Yellow:
return new Color32(255, 211, 0, 255);
case MMBackgroundAttributeColor.Green:
return new Color32(102, 255, 0, 255);
case MMBackgroundAttributeColor.Blue:
return new Color32(0, 135, 189, 255);
case MMBackgroundAttributeColor.Violet:
return new Color32(127, 0, 255, 255);
default:
return Color.white;
}
}
}
}

View File

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

View File

@@ -0,0 +1,23 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMColorAttribute))]
public class MMColorAttributeDrawer : PropertyDrawer
{
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Color color = (attribute as MMColorAttribute).color;
Color prev = GUI.color;
GUI.color = color;
EditorGUI.PropertyField(position, property, label, true);
GUI.color = prev;
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,72 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
// original implementation by http://www.brechtos.com/hiding-or-disabling-inspector-properties-using-propertydrawers-within-unity-5/
[CustomPropertyDrawer(typeof(MMConditionAttribute))]
public class MMConditionAttributeDrawer : PropertyDrawer
{
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
MMConditionAttribute conditionAttribute = (MMConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(conditionAttribute, property);
bool previouslyEnabled = GUI.enabled;
bool shouldDisplay = ShouldDisplay(conditionAttribute, enabled);
if (shouldDisplay)
{
GUI.enabled = enabled;
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = previouslyEnabled;
}
}
#endif
private bool GetConditionAttributeResult(MMConditionAttribute conditionAttribute, SerializedProperty property)
{
bool enabled = true;
string propertyPath = property.propertyPath;
string conditionPath = propertyPath.Replace(property.name, conditionAttribute.ConditionBoolean);
SerializedProperty sourcePropertyValue = property.serializedObject.FindProperty(conditionPath);
if (sourcePropertyValue != null)
{
enabled = sourcePropertyValue.boolValue;
}
else
{
Debug.LogWarning("No matching boolean found for ConditionAttribute in object: " + conditionAttribute.ConditionBoolean);
}
if (conditionAttribute.Negative)
{
enabled = !enabled;
}
return enabled;
}
private bool ShouldDisplay(MMConditionAttribute conditionAttribute, bool result)
{
bool shouldDisplay = !conditionAttribute.Hidden || result;
return shouldDisplay;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
MMConditionAttribute conditionAttribute = (MMConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(conditionAttribute, property);
bool shouldDisplay = ShouldDisplay(conditionAttribute, enabled);
if (shouldDisplay)
{
return EditorGUI.GetPropertyHeight(property, label);
}
else
{
return -EditorGUIUtility.standardVerticalSpacing;
}
}
}
}

View File

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

View File

@@ -0,0 +1,91 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMDropdownAttribute))]
public class MMDropdownAttributeDrawer : PropertyDrawer
{
protected MMDropdownAttribute _dropdownAttribute;
protected string[] _dropdownValues;
protected int _selectedDropdownValueIndex = -1;
protected Type _propertyType;
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (_dropdownAttribute == null)
{
_dropdownAttribute = (MMDropdownAttribute)attribute;
if (_dropdownAttribute.DropdownValues == null || _dropdownAttribute.DropdownValues.Length == 0)
{
return;
}
_propertyType = _dropdownAttribute.DropdownValues[0].GetType();
_dropdownValues = new string[_dropdownAttribute.DropdownValues.Length];
for (int i = 0; i < _dropdownAttribute.DropdownValues.Length; i++)
{
_dropdownValues[i] = _dropdownAttribute.DropdownValues[i].ToString();
}
bool found = false;
for (var i = 0; i < _dropdownValues.Length; i++)
{
if ((_propertyType == typeof(string)) && property.stringValue == _dropdownValues[i])
{
_selectedDropdownValueIndex = i;
found = true;
break;
}
if ((_propertyType == typeof(int)) && property.intValue == Convert.ToInt32(_dropdownValues[i]))
{
_selectedDropdownValueIndex = i;
found = true;
break;
}
if ((_propertyType == typeof(float)) && Mathf.Approximately(property.floatValue, Convert.ToSingle(_dropdownValues[i])))
{
_selectedDropdownValueIndex = i;
found = true;
break;
}
}
if (!found)
{
_selectedDropdownValueIndex = 0;
}
}
if ((_dropdownValues == null) || (_dropdownValues.Length == 0) || (_selectedDropdownValueIndex < 0))
{
EditorGUI.PropertyField(position, property, label);
return;
}
EditorGUI.BeginChangeCheck();
_selectedDropdownValueIndex = EditorGUI.Popup(position, label.text, _selectedDropdownValueIndex, _dropdownValues);
if (EditorGUI.EndChangeCheck())
{
if (_propertyType == typeof(string))
{
property.stringValue = _dropdownValues[_selectedDropdownValueIndex];
}
else if (_propertyType == typeof(int))
{
property.intValue = Convert.ToInt32(_dropdownValues[_selectedDropdownValueIndex]);
}
else if (_propertyType == typeof(float))
{
property.floatValue = Convert.ToSingle(_dropdownValues[_selectedDropdownValueIndex]);
}
property.serializedObject.ApplyModifiedProperties();
}
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,74 @@
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
// original implementation by http://www.brechtos.com/hiding-or-disabling-inspector-properties-using-propertydrawers-within-unity-5/
[CustomPropertyDrawer(typeof(MMEnumConditionAttribute))]
public class MMEnumConditionAttributeDrawer : PropertyDrawer
{
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
MMEnumConditionAttribute enumConditionAttribute = (MMEnumConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(enumConditionAttribute, property);
bool previouslyEnabled = GUI.enabled;
GUI.enabled = enabled;
if (!enumConditionAttribute.Hidden || enabled)
{
EditorGUI.PropertyField(position, property, label, true);
}
GUI.enabled = previouslyEnabled;
}
#endif
private static Dictionary<string, string> cachedPaths = new Dictionary<string, string>();
private bool GetConditionAttributeResult(MMEnumConditionAttribute enumConditionAttribute, SerializedProperty property)
{
bool enabled = true;
SerializedProperty enumProp;
string enumPropPath = string.Empty;
string propertyPath = property.propertyPath;
if (!cachedPaths.TryGetValue(propertyPath, out enumPropPath))
{
enumPropPath = propertyPath.Replace(property.name, enumConditionAttribute.ConditionEnum);
cachedPaths.Add(propertyPath, enumPropPath);
}
enumProp = property.serializedObject.FindProperty(enumPropPath);
if (enumProp != null)
{
int currentEnum = enumProp.enumValueIndex;
enabled = enumConditionAttribute.ContainsBitFlag(currentEnum);
}
else
{
Debug.LogWarning("No matching boolean found for ConditionAttribute in object: " + enumConditionAttribute.ConditionEnum);
}
return enabled;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
MMEnumConditionAttribute enumConditionAttribute = (MMEnumConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(enumConditionAttribute, property);
if (!enumConditionAttribute.Hidden || enabled)
{
return EditorGUI.GetPropertyHeight(property, label);
}
else
{
return -EditorGUIUtility.standardVerticalSpacing;
}
}
}
}

View File

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

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMHiddenAttribute))]
public class MMHiddenAttributeDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return 0f;
}
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ac53bf83e8327014bbc73944dfec5ff8
timeCreated: 1456270265
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,118 @@
#if UNITY_EDITOR
using System;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Reflection;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer (typeof(MMInformationAttribute))]
/// <summary>
/// This class allows the display of a message box (warning, info, error...) next to a property (before or after)
/// </summary>
public class MMInformationAttributeDrawer : PropertyDrawer
{
// determines the space after the help box, the space before the text box, and the width of the help box icon
const int spaceBeforeTheTextBox = 5;
const int spaceAfterTheTextBox = 10;
const int iconWidth = 55;
MMInformationAttribute informationAttribute { get { return ((MMInformationAttribute)attribute); } }
#if UNITY_EDITOR
/// <summary>
/// OnGUI, displays the property and the textbox in the specified order
/// </summary>
/// <param name="rect">Rect.</param>
/// <param name="prop">Property.</param>
/// <param name="label">Label.</param>
public override void OnGUI (Rect rect, SerializedProperty prop, GUIContent label)
{
if (HelpEnabled())
{
EditorStyles.helpBox.richText=true ;
if (!informationAttribute.MessageAfterProperty)
{
// we position the message before the property
rect.height = DetermineTextboxHeight(informationAttribute.Message);
EditorGUI.HelpBox (rect, informationAttribute.Message, informationAttribute.Type);
rect.y += rect.height + spaceBeforeTheTextBox;
EditorGUI.PropertyField(rect, prop, label, true);
}
else
{
// we position the property first, then the message
rect.height = GetPropertyHeight(prop,label);
EditorGUI.PropertyField(rect, prop, label, true);
rect.height = DetermineTextboxHeight(informationAttribute.Message);
// we add the complete property height (property + helpbox, as overridden in this very script), and substract both to get just the property
rect.y += GetPropertyHeight(prop,label) - DetermineTextboxHeight(informationAttribute.Message) - spaceAfterTheTextBox;
EditorGUI.HelpBox (rect, informationAttribute.Message, informationAttribute.Type);
}
}
else
{
EditorGUI.PropertyField(rect, prop, label, true);
}
}
#endif
/// <summary>
/// Returns the complete height of the whole block (property + help text)
/// </summary>
/// <returns>The block height.</returns>
/// <param name="property">Property.</param>
/// <param name="label">Label.</param>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (HelpEnabled())
{
return EditorGUI.GetPropertyHeight(property) + DetermineTextboxHeight(informationAttribute.Message) + spaceAfterTheTextBox + spaceBeforeTheTextBox;
}
else
{
return EditorGUI.GetPropertyHeight(property);
}
}
/// <summary>
/// Checks the editor prefs to see if help is enabled or not
/// </summary>
/// <returns><c>true</c>, if enabled was helped, <c>false</c> otherwise.</returns>
protected virtual bool HelpEnabled()
{
bool helpEnabled = false;
if (EditorPrefs.HasKey("MMShowHelpInInspectors"))
{
if (EditorPrefs.GetBool("MMShowHelpInInspectors"))
{
helpEnabled = true;
}
}
return helpEnabled;
}
/// <summary>
/// Determines the height of the textbox.
/// </summary>
/// <returns>The textbox height.</returns>
/// <param name="message">Message.</param>
protected virtual float DetermineTextboxHeight(string message)
{
GUIStyle style = new GUIStyle(EditorStyles.helpBox);
style.richText=true;
float newHeight = style.CalcHeight(new GUIContent(message),EditorGUIUtility.currentViewWidth - iconWidth);
return newHeight;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 45b7f6ca773ad4e81ad2ed6d93158953
timeCreated: 1459517598
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,77 @@
using UnityEngine;
using System.Collections;
using MoreMountains.Tools;
using UnityEditor;
namespace MoreMountains.Tools
{
/// <summary>
/// This class adds a MoreMountains entry in Unity's top menu, allowing to enable/disable the help texts from the engine's inspectors
/// </summary>
public static class MMMenuHelp
{
[MenuItem("Tools/More Mountains/Enable Help in Inspectors", false,0)]
/// <summary>
/// Adds a menu item to enable help
/// </summary>
private static void EnableHelpInInspectors()
{
SetHelpEnabled(true);
}
[MenuItem("Tools/More Mountains/Enable Help in Inspectors", true)]
/// <summary>
/// Conditional method to determine if the "enable help" entry should be greyed or not
/// </summary>
private static bool EnableHelpInInspectorsValidation()
{
return !HelpEnabled();
}
[MenuItem("Tools/More Mountains/Disable Help in Inspectors", false,1)]
/// <summary>
/// Adds a menu item to disable help
/// </summary>
private static void DisableHelpInInspectors()
{
SetHelpEnabled(false);
}
[MenuItem("Tools/More Mountains/Disable Help in Inspectors", true)]
/// <summary>
/// Conditional method to determine if the "disable help" entry should be greyed or not
/// </summary>
private static bool DisableHelpInInspectorsValidation()
{
return HelpEnabled();
}
/// <summary>
/// Checks editor prefs to see if help is enabled or not
/// </summary>
/// <returns><c>true</c>, if enabled was helped, <c>false</c> otherwise.</returns>
private static bool HelpEnabled()
{
if (EditorPrefs.HasKey("MMShowHelpInInspectors"))
{
return EditorPrefs.GetBool("MMShowHelpInInspectors");
}
else
{
EditorPrefs.SetBool("MMShowHelpInInspectors",true);
return true;
}
}
/// <summary>
/// Sets the help enabled editor pref.
/// </summary>
/// <param name="status">If set to <c>true</c> status.</param>
private static void SetHelpEnabled(bool status)
{
EditorPrefs.SetBool("MMShowHelpInInspectors",status);
SceneView.RepaintAll();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 28fbd4d56656345f4ba40f7e4d786fb1
timeCreated: 1477393124
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace MoreMountains.Tools
{
static class MMMonoBehaviourFieldInfo
{
public static Dictionary<int, List<FieldInfo>> FieldInfoList = new Dictionary<int, List<FieldInfo>>();
public static int GetFieldInfo(Object target, out List<FieldInfo> fieldInfoList)
{
Type targetType = target.GetType();
int targetTypeHashCode = targetType.GetHashCode();
if (!FieldInfoList.TryGetValue(targetTypeHashCode, out fieldInfoList))
{
IList<Type> typeTree = targetType.GetBaseTypes();
fieldInfoList = target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.NonPublic)
.OrderByDescending(x => typeTree.IndexOf(x.DeclaringType))
.ToList();
FieldInfoList.Add(targetTypeHashCode, fieldInfoList);
}
return fieldInfoList.Count;
}
public static IList<Type> GetBaseTypes(this Type t)
{
var types = new List<Type>();
while (t.BaseType != null)
{
types.Add(t);
t = t.BaseType;
}
return types;
}
}
}

View File

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

View File

@@ -0,0 +1,236 @@
using System;
using System.Collections.Generic;
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UIElements;
#endif
using UnityEngine;
using System.Linq;
using UnityEngine.UIElements;
namespace MoreMountains.Tools
{
public class MMInspectorGroupData
{
public bool GroupIsOpen;
public MMInspectorGroupAttribute GroupAttribute;
public List<SerializedProperty> PropertiesList = new List<SerializedProperty>();
public HashSet<string> GroupHashSet = new HashSet<string>();
public Color GroupColor;
public void ClearGroup()
{
GroupAttribute = null;
GroupHashSet.Clear();
PropertiesList.Clear();
}
}
[CanEditMultipleObjects]
[CustomEditor(typeof(MMMonoBehaviour), true)]
public class MMMonoBehaviourUITKEditor : Editor
{
public StyleSheet EditorStyleSheet;
public bool DrawerInitialized;
public Dictionary<string, MMInspectorGroupData> GroupData ;
public List<SerializedProperty> PropertiesList;
private bool _requiresConstantRepaint;
private bool _requiresConstantRepaintOnlyWhenPlaying;
private MMMonoBehaviour _targetMonoBehaviourGameObject;
private bool _targetMonoBehaviourIsNotNull;
protected bool _shouldDrawBase = true;
protected string _targetTypeName;
public override bool RequiresConstantRepaint()
{
if (_requiresConstantRepaintOnlyWhenPlaying)
{
return Application.isPlaying && _targetMonoBehaviourIsNotNull && _targetMonoBehaviourGameObject.enabled;
}
else
{
return _requiresConstantRepaint;
}
}
private string[] _mmHiddenPropertiesToHide;
private bool _hasMMHiddenProperties = false;
protected virtual void Initialization()
{
if (DrawerInitialized && PropertiesList != null)
{
return;
}
_shouldDrawBase = true;
GroupData = new Dictionary<string, MMInspectorGroupData>();
PropertiesList = new List<SerializedProperty>();
_targetTypeName = target.GetType().Name;
_targetMonoBehaviourGameObject = (MMMonoBehaviour)target;
if (_targetMonoBehaviourGameObject != null)
{
_targetMonoBehaviourIsNotNull = true;
}
_requiresConstantRepaint = serializedObject.targetObject.GetType().GetCustomAttribute<MMRequiresConstantRepaintAttribute>() != null;
_requiresConstantRepaintOnlyWhenPlaying = serializedObject.targetObject.GetType().GetCustomAttribute<MMRequiresConstantRepaintOnlyWhenPlayingAttribute>() != null;
List<FieldInfo> fieldInfoList;
MMInspectorGroupAttribute previousGroupAttribute = default;
int fieldInfoLength = MMMonoBehaviourFieldInfo.GetFieldInfo(target, out fieldInfoList);
for (int i = 0; i < fieldInfoLength; i++)
{
MMInspectorGroupAttribute group = Attribute.GetCustomAttribute(fieldInfoList[i], typeof(MMInspectorGroupAttribute)) as MMInspectorGroupAttribute;
MMInspectorGroupData groupData;
if (group == null)
{
if (previousGroupAttribute != null && previousGroupAttribute.GroupAllFieldsUntilNextGroupAttribute)
{
_shouldDrawBase = false;
if (!GroupData.TryGetValue(previousGroupAttribute.GroupName, out groupData))
{
GroupData.Add(previousGroupAttribute.GroupName, new MMInspectorGroupData
{
GroupAttribute = previousGroupAttribute,
GroupHashSet = new HashSet<string> { fieldInfoList[i].Name },
GroupColor = MMColors.GetColorAt(previousGroupAttribute.GroupColorIndex)
});
}
else
{
groupData.GroupColor = MMColors.GetColorAt(previousGroupAttribute.GroupColorIndex);
groupData.GroupHashSet.Add(fieldInfoList[i].Name);
}
}
continue;
}
previousGroupAttribute = group;
if (!GroupData.TryGetValue(group.GroupName, out groupData))
{
bool fallbackOpenState = true;
if (group.ClosedByDefault) { fallbackOpenState = false; }
bool groupIsOpen = EditorPrefs.GetBool(string.Format($"{group.GroupName}{fieldInfoList[i].Name}{target.GetInstanceID()}"), fallbackOpenState);
GroupData.Add(group.GroupName, new MMInspectorGroupData
{
GroupAttribute = group,
GroupColor = MMColors.GetColorAt(previousGroupAttribute.GroupColorIndex),
GroupHashSet = new HashSet<string> { fieldInfoList[i].Name }, GroupIsOpen = groupIsOpen });
}
else
{
groupData.GroupHashSet.Add(fieldInfoList[i].Name);
groupData.GroupColor = MMColors.GetColorAt(previousGroupAttribute.GroupColorIndex);
}
}
SerializedProperty iterator = serializedObject.GetIterator();
if (iterator.NextVisible(true))
{
do
{
FillPropertiesList(iterator);
} while (iterator.NextVisible(false));
}
DrawerInitialized = true;
}
public void FillPropertiesList(SerializedProperty serializedProperty)
{
bool shouldClose = false;
foreach (KeyValuePair<string, MMInspectorGroupData> pair in GroupData)
{
if (pair.Value.GroupHashSet.Contains(serializedProperty.name))
{
SerializedProperty property = serializedProperty.Copy();
shouldClose = true;
pair.Value.PropertiesList.Add(property);
break;
}
}
if (!shouldClose)
{
SerializedProperty property = serializedProperty.Copy();
PropertiesList.Add(property);
}
}
public override VisualElement CreateInspectorGUI()
{
Initialization();
VisualElement root = new VisualElement();
root.styleSheets.Add(EditorStyleSheet);
// Draw the script field
SerializedProperty scriptProperty = serializedObject.FindProperty("m_Script");
if (PropertiesList.Count == 0)
{
return root;
}
if (_shouldDrawBase)
{
VisualElement defaultInspector = new VisualElement();
InspectorElement.FillDefaultInspector(defaultInspector, serializedObject, this);
root.Add(defaultInspector);
return root;
}
PropertyField scriptField = new PropertyField(scriptProperty);
scriptField.SetEnabled(false);
root.Add(scriptField);
foreach (KeyValuePair<string, MMInspectorGroupData> pair in GroupData)
{
DrawGroup(pair.Value, root);
}
serializedObject.ApplyModifiedProperties();
return root;
}
protected virtual void DrawGroup(MMInspectorGroupData groupData, VisualElement root)
{
Foldout foldout = new Foldout();
foldout.text = groupData.GroupAttribute.GroupName;
foldout.value = groupData.GroupIsOpen;
foldout.AddToClassList("mm-foldout");
foldout.style.borderLeftColor = groupData.GroupColor;
foldout.viewDataKey = target.name + "-" + _targetTypeName + groupData.GroupAttribute.GroupName;
root.Add(foldout);
var toggleElement = foldout.Q<Toggle>();
toggleElement.AddToClassList("mm-foldout-toggle");
for (int i = 0; i < groupData.PropertiesList.Count; i++)
{
DrawChild(i, foldout, root);
}
void DrawChild(int i, Foldout foldout, VisualElement root)
{
if ((_hasMMHiddenProperties) && (_mmHiddenPropertiesToHide.Contains(groupData.PropertiesList[i].name)))
{
return;
}
PropertyField field = new PropertyField(groupData.PropertiesList[i]);
field.label = ObjectNames.NicifyVariableName(groupData.PropertiesList[i].name);
field.tooltip = groupData.PropertiesList[i].tooltip;
foldout.Add(field);
}
}
}
}

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 117d5758fb780a14d91b570328c048da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- EditorStyleSheet: {fileID: 7433441132597879392, guid: 9da245a6982a71d45b143036ec3684bd,
type: 3}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,113 @@
/* Foldout */
.mm-foldout {
background-color: rgba(0, 0, 0, 0.12);
margin-top: 5px;
margin-bottom: 5px;
border-left-color: black;
border-left-width: 3px;
padding-right: 10px;
padding-left: 0;
padding-bottom: 0;
padding-top: 0;
}
/* Foldout header bar */
.mm-foldout Toggle.mm-foldout-toggle {
background-color: rgba(0, 0, 0, 0.12);
padding-top: 5px;
padding-left: 10px;
margin-left: 0;
padding-bottom: 5px;
margin-bottom: 0;
-unity-font-style: bold;
}
/* Foldout contents */
.mm-foldout #unity-content {
padding-top: 5px;
margin-top: 0;
margin-left: 10px;
padding-left: 10px;
padding-bottom: 10px;
}
/* [Header] attributes */
.mm-foldout .unity-header-drawer__label {
margin-top: 10px;
padding-bottom: 5px;
padding-top: 5px;
margin-left: -20px;
padding-left: 20px;
-unity-font-style: bold;
background-color: rgba(255, 255, 255, 0.04);
}
/* Button toolbars */
.mm-toolbar {
margin-top: 5px;
border-width: 0px;
}
.mm-toolbar ToolbarButton {
border-width: 1px;
-unity-text-align: middle-center;
}
.mm-toolbar ToolbarButton.main-call-to-action {
background-color: rgba(30, 94, 88, 1);
color: white;
-unity-text-align: middle-center;
}
.mm-fixed-width-floatfield FloatInput TextElement
{
width: 50px;
}
.mm-fixed-width-floatfield Label
{
min-width: 50px;
}
/* Spring */
.mm-spring-debug-track-background
{
margin-top: 5px;
background-color: rgba(0, 0, 0, 0.5);
height: 20px;
width: 100%;
flex-direction: row;
justify-content: flex-start;
}
.mm-spring-debug-track-foreground
{
background-color: rgba(255, 196, 0, 1);
height: 20px;
width: 10px;
margin-top: -20px;
}
.mm-spring-debug-track-foreground-container-left
{
background-color: green;
height: 20px;
width: 50%;
left: 0px;
margin-top: -20px;
display: flex;
justify-content: flex-end;
}
.mm-spring-debug-track-foreground-container-right
{
background-color: blue;
height: 20px;
width: 50%;
left: 50%;
margin-top: -20px;
display: flex;
justify-content: flex-end;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9da245a6982a71d45b143036ec3684bd
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0}
disableValidation: 0

View File

@@ -0,0 +1,32 @@
#if UNITY_EDITOR
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMNavMeshAreaMaskAttribute))]
public class MMNavMeshAreaMaskAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty serializedProperty, GUIContent label)
{
string[] navMeshAreaNames = GameObjectUtility.GetNavMeshAreaNames();
float positionWidth = position.width;
int maskValue = serializedProperty.intValue;
position.width = EditorGUIUtility.labelWidth;
EditorGUI.PrefixLabel(position, label);
position.x += EditorGUIUtility.labelWidth;
position.width = positionWidth - EditorGUIUtility.labelWidth;
EditorGUI.BeginChangeCheck();
maskValue = EditorGUI.MaskField(position, maskValue, navMeshAreaNames);
if (EditorGUI.EndChangeCheck())
{
serializedProperty.intValue = maskValue;
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,27 @@
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMReadOnlyAttribute))]
public class MMReadOnlyAttributeDrawer : PropertyDrawer
{
// Necessary since some properties tend to collapse smaller than their content
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUI.GetPropertyHeight(property, label, true);
}
#if UNITY_EDITOR
// Draw a disabled property field
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
GUI.enabled = false; // Disable fields
EditorGUI.PropertyField(position, property, label, true);
GUI.enabled = true; // Enable fields
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 8bc90960c2aea754a8ff74069babfa0b
timeCreated: 1456269803
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,102 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMVectorAttribute))]
public class MMVectorLabelsAttributeDrawer : PropertyDrawer
{
protected static readonly GUIContent[] originalLabels = new GUIContent[] { new GUIContent("X"), new GUIContent("Y"), new GUIContent("Z"), new GUIContent("W") };
protected const int padding = 375;
public override float GetPropertyHeight(SerializedProperty property, GUIContent guiContent)
{
int ratio = (padding > Screen.width) ? 2 : 1;
return ratio * base.GetPropertyHeight(property, guiContent);
}
#if UNITY_EDITOR
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent guiContent)
{
MMVectorAttribute vector = (MMVectorAttribute)attribute;
if (property.propertyType == SerializedPropertyType.Vector2)
{
float[] fieldArray = new float[] { property.vector2Value.x, property.vector2Value.y };
fieldArray = DrawFields(rect, fieldArray, ObjectNames.NicifyVariableName(property.name), EditorGUI.FloatField, vector, guiContent);
property.vector2Value = new Vector2(fieldArray[0], fieldArray[1]);
}
else if (property.propertyType == SerializedPropertyType.Vector3)
{
float[] fieldArray = new float[] { property.vector3Value.x, property.vector3Value.y, property.vector3Value.z };
fieldArray = DrawFields(rect, fieldArray, ObjectNames.NicifyVariableName(property.name), EditorGUI.FloatField, vector, guiContent);
property.vector3Value = new Vector3(fieldArray[0], fieldArray[1], fieldArray[2]);
}
else if (property.propertyType == SerializedPropertyType.Vector4)
{
float[] fieldArray = new float[] { property.vector4Value.x, property.vector4Value.y, property.vector4Value.z, property.vector4Value.w };
fieldArray = DrawFields(rect, fieldArray, ObjectNames.NicifyVariableName(property.name), EditorGUI.FloatField, vector, guiContent);
property.vector4Value = new Vector4(fieldArray[0], fieldArray[1], fieldArray[2]);
}
else if (property.propertyType == SerializedPropertyType.Vector2Int)
{
int[] fieldArray = new int[] { property.vector2IntValue.x, property.vector2IntValue.y };
fieldArray = DrawFields(rect, fieldArray, ObjectNames.NicifyVariableName(property.name), EditorGUI.IntField, vector, guiContent);
property.vector2IntValue = new Vector2Int(fieldArray[0], fieldArray[1]);
}
else if (property.propertyType == SerializedPropertyType.Vector3Int)
{
int[] array = new int[] { property.vector3IntValue.x, property.vector3IntValue.y, property.vector3IntValue.z };
array = DrawFields(rect, array, ObjectNames.NicifyVariableName(property.name), EditorGUI.IntField, vector, guiContent);
property.vector3IntValue = new Vector3Int(array[0], array[1], array[2]);
}
}
#endif
protected T[] DrawFields<T>(Rect rect, T[] vector, string mainLabel, System.Func<Rect, GUIContent, T, T> fieldDrawer, MMVectorAttribute vectors, GUIContent originalGuiContent)
{
T[] result = vector;
bool shortSpace = (Screen.width < padding);
Rect mainLabelRect = rect;
mainLabelRect.width = EditorGUIUtility.labelWidth;
if (shortSpace)
{
mainLabelRect.height *= 0.5f;
}
Rect fieldRect = rect;
if (shortSpace)
{
fieldRect.height *= 0.5f;
fieldRect.y += fieldRect.height;
fieldRect.width = rect.width / vector.Length;
}
else
{
fieldRect.x += mainLabelRect.width;
fieldRect.width = (rect.width - mainLabelRect.width) / vector.Length;
}
GUIContent mainLabelContent = new GUIContent();
mainLabelContent.text = mainLabel;
mainLabelContent.tooltip = originalGuiContent.tooltip;
EditorGUI.LabelField(mainLabelRect, mainLabelContent);
for (int i = 0; i < vector.Length; i++)
{
GUIContent label = vectors.Labels.Length > i ? new GUIContent(vectors.Labels[i]) : originalLabels[i];
Vector2 labelSize = EditorStyles.label.CalcSize(label);
EditorGUIUtility.labelWidth = Mathf.Max(labelSize.x + 5, 0.3f * fieldRect.width);
result[i] = fieldDrawer(fieldRect, label, vector[i]);
fieldRect.x += fieldRect.width;
}
EditorGUIUtility.labelWidth = 0;
return result;
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 691b9da9cdfd29744bccf9b73c08711e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 16c45ec4926adef408a0bca043df116f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,677 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
#if UNITY_EDITOR
[CustomEditor(typeof(MMAudioAnalyzer), true)]
[CanEditMultipleObjects]
public class MMAudioAnalyzerEditor : Editor
{
public bool Active;
public SerializedProperty BandLevels;
public SerializedProperty BufferedBandLevels;
public SerializedProperty NormalizedBandLevels;
public SerializedProperty NormalizedBufferedBandLevels;
public SerializedProperty BandPeaks;
public SerializedProperty LastPeaksAt;
public SerializedProperty RawSpectrum;
public SerializedProperty Amplitude;
public SerializedProperty NormalizedAmplitude;
public SerializedProperty BufferedAmplitude;
public SerializedProperty NormalizedBufferedAmplitude;
public SerializedProperty PeaksPasted;
public SerializedProperty Beats;
// inspector
protected float _inspectorWidth;
protected int _numberOfBands;
protected Color _barColor;
protected Color _inactiveColor = new Color(0f, 0f, 0f, 0.4f);
protected Color _bufferedBarColor = new Color(0f, 0f, 0f, 0.3f);
protected Color _normalBarColor = MMColors.Orange;
protected Color _normalNormalizedBarColor = MMColors.Aqua;
protected Color _peakColor = MMColors.Yellow;
protected Color _activePeakColor = Color.white;
protected Color _amplitudeColor = MMColors.DarkOrange;
protected Color _normalizedAmplitudeColor = MMColors.Aquamarine;
protected Color _spectrumColor = MMColors.HotPink;
protected Color _beatColor;
protected bool _bandValuesFoldout = false;
protected float _peakShowDuration = 0.5f;
// box
protected Vector2 _boxPosition;
protected Vector2 _boxSize;
protected const float _externalMargin = 12f;
protected float _internalMargin = 12f;
protected const float _lineHeight = 15f;
protected const int _numberOfAxis = 5;
protected const int _numberOfAxisSpectrum = 4;
protected const int _bandsValuesBoxHeight = 150;
protected const int _rawSpectrumBoxHeight = 75;
// coordinates
protected float _topY;
protected float _boxBottomY;
protected float _positionX;
protected float _positionY;
// column
protected float _columnWidth;
protected float _columnHeight;
protected float _maxColumnHeight;
// spectrum
protected float _spectrumBoxBottomY;
protected Vector2 _spectrumBoxPosition;
protected Vector2 _spectrumBoxSize;
protected float _spectrumMaxColumnHeight;
// axis
protected Vector3 _axisOrigin = Vector3.zero;
protected Vector3 _axisDestination = Vector3.zero;
// styles
protected GUIStyle _redLabel = new GUIStyle();
protected Color _normalLabelColor;
protected Rect _rect;
protected virtual void OnEnable()
{
Active = serializedObject.FindProperty("Active").boolValue;
BandLevels = serializedObject.FindProperty("BandLevels");
BufferedBandLevels = serializedObject.FindProperty("BufferedBandLevels");
NormalizedBandLevels = serializedObject.FindProperty("NormalizedBandLevels");
NormalizedBufferedBandLevels = serializedObject.FindProperty("NormalizedBufferedBandLevels");
BandPeaks = serializedObject.FindProperty("BandPeaks");
LastPeaksAt = serializedObject.FindProperty("LastPeaksAt");
RawSpectrum = serializedObject.FindProperty("RawSpectrum");
_numberOfBands = serializedObject.FindProperty("NumberOfBands").intValue;
Amplitude = serializedObject.FindProperty("Amplitude");
NormalizedAmplitude = serializedObject.FindProperty("NormalizedAmplitude");
BufferedAmplitude = serializedObject.FindProperty("BufferedAmplitude");
NormalizedBufferedAmplitude = serializedObject.FindProperty("NormalizedBufferedAmplitude");
PeaksPasted = serializedObject.FindProperty("PeaksPasted");
Beats = serializedObject.FindProperty("Beats");
_redLabel.normal.textColor = Color.red;
_rect = new Rect();
}
/// <summary>
/// Forces constant repaint of the inspector, making for much faster display of the bands bars.
/// </summary>
/// <returns></returns>
public override bool RequiresConstantRepaint()
{
return true;
}
public override void OnInspectorGUI()
{
serializedObject.Update();
UpdateNumberOfBandsIfNeeded();
DrawDefaultInspector();
_inspectorWidth = EditorGUIUtility.currentViewWidth - 24;
DrawBandTable();
DrawBeats();
DrawBandVisualization();
DrawBandVisualizationNormalized();
DrawRawSpectrum();
PreProcessingButtons();
serializedObject.ApplyModifiedProperties();
}
protected virtual void UpdateNumberOfBandsIfNeeded()
{
if (!Application.isPlaying)
{
_numberOfBands = serializedObject.FindProperty("NumberOfBands").intValue;
}
}
protected virtual void DrawBandTable()
{
GUILayout.Space(10);
GUILayout.Label("Band values", EditorStyles.boldLabel);
_bandValuesFoldout = EditorGUILayout.Foldout(_bandValuesFoldout, "Levels");
if (!Active)
{
if (_bandValuesFoldout)
{
GUILayout.Label("Values are only displayed when the game is running.");
}
return;
}
if (BandPeaks.arraySize == 0)
{
return;
}
if (_bandValuesFoldout)
{
float win = Screen.width;
float w1 = win * 0.15f;
float w2 = win * 0.2f;
float w3 = win * 0.2f;
float w4 = win * 0.2f;
float w5 = win * 0.2f;
float wA = win * 0.5f;
float wB = win * 0.5f;
GUILayout.BeginHorizontal();
GUILayout.Label("Amplitude :", GUILayout.Width(wA));
GUILayout.Label(Amplitude.floatValue.ToString(), GUILayout.Width(wB));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Normalized Amplitude :", GUILayout.Width(wA));
GUILayout.Label(NormalizedAmplitude.floatValue.ToString(), GUILayout.Width(wB));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Buffered Amplitude :", GUILayout.Width(wA));
GUILayout.Label(BufferedAmplitude.floatValue.ToString(), GUILayout.Width(wB));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Normalized Buffered Amplitude :", GUILayout.Width(wA));
GUILayout.Label(NormalizedBufferedAmplitude.floatValue.ToString(), GUILayout.Width(wB));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Band", EditorStyles.boldLabel, GUILayout.Width(w1));
GUILayout.Label("Value", EditorStyles.boldLabel, GUILayout.Width(w2));
GUILayout.Label("Peak", EditorStyles.boldLabel, GUILayout.Width(w3));
GUILayout.Label("Normalized", EditorStyles.boldLabel, GUILayout.Width(w4));
GUILayout.Label("Norm. Buffered", EditorStyles.boldLabel, GUILayout.Width(w5));
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
for (int i = 0; i < _numberOfBands; i++)
{
GUILayout.BeginHorizontal();
GUILayout.Label(i.ToString(), EditorStyles.boldLabel, GUILayout.Width(w1));
GUILayout.Label(BandLevels.GetArrayElementAtIndex(i).floatValue.ToString(), GUILayout.Width(w2));
if (Time.time - LastPeaksAt.GetArrayElementAtIndex(i).floatValue < _peakShowDuration)
{
_normalLabelColor = GUI.skin.label.normal.textColor;
GUI.skin.label.normal.textColor = _peakColor;
GUILayout.Label(BandPeaks.GetArrayElementAtIndex(i).floatValue.ToString(), GUILayout.Width(w3));
GUI.skin.label.normal.textColor = _normalLabelColor;
}
else
{
GUILayout.Label(BandPeaks.GetArrayElementAtIndex(i).floatValue.ToString(), GUILayout.Width(w3));
}
GUILayout.Label(NormalizedBandLevels.GetArrayElementAtIndex(i).floatValue.ToString(), GUILayout.Width(w4));
GUILayout.Label(NormalizedBufferedBandLevels.GetArrayElementAtIndex(i).floatValue.ToString(), GUILayout.Width(w5));
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
}
protected const int _beatsBoxHeight = 40;
protected virtual void DrawBeats()
{
if ((Beats == null) || (target as MMAudioAnalyzer).Beats == null)
{
return;
}
float length = (target as MMAudioAnalyzer).Beats.Length;
if (length <= 0)
{
return;
}
float margin = _beatsBoxHeight / 10;
float beatsBoxSquareSize = _beatsBoxHeight - (2 * margin);
int boxesPerLine = (int)Mathf.Round((_inspectorWidth - margin - 3*_externalMargin) / (beatsBoxSquareSize + margin)) ;
int numberOfLines = (int)(length / boxesPerLine) + 1;
float boxHeight = (_beatsBoxHeight) * numberOfLines - margin * (numberOfLines - 1);
GUILayout.Space(10);
GUILayout.Label("Beats Visualization", EditorStyles.boldLabel);
GUILayout.Box("", GUILayout.Width(_inspectorWidth - _externalMargin), GUILayout.Height(boxHeight));
_boxPosition = GUILayoutUtility.GetLastRect().position;
_boxSize = GUILayoutUtility.GetLastRect().size;
_boxBottomY = _boxPosition.y + _beatsBoxHeight - _externalMargin - _lineHeight;
int counter = 0;
int lineCounter = 0;
for (int i = 0; i < length; i++)
{
if (counter > boxesPerLine - 1)
{
counter = 0;
lineCounter++;
}
float boxX = _boxPosition.x + margin + counter * (beatsBoxSquareSize + margin);
float boxY = _boxPosition.y + margin + lineCounter * (beatsBoxSquareSize + margin);
// draw bg bar
_rect.x = boxX;
_rect.y = boxY;
_rect.width = beatsBoxSquareSize;
_rect.height = beatsBoxSquareSize;
EditorGUI.DrawRect(_rect, _inactiveColor);
if (Active)
{
// draw front bar
_beatColor = (target as MMAudioAnalyzer).Beats[i].BeatColor;
_beatColor.a = (target as MMAudioAnalyzer).Beats[i].CurrentValue;
_rect.x = boxX;
_rect.y = boxY;
_rect.width = beatsBoxSquareSize;
_rect.height = beatsBoxSquareSize;
EditorGUI.DrawRect(_rect, _beatColor);
}
// draw number
float labelX = (i > 9) ? boxX + beatsBoxSquareSize / 4 - 2 : boxX + beatsBoxSquareSize / 4 + 2;
_rect.x = labelX;
_rect.y = boxY + beatsBoxSquareSize / 4;
_rect.width = beatsBoxSquareSize;
_rect.height = beatsBoxSquareSize;
EditorGUI.LabelField(_rect, i.ToString(), EditorStyles.boldLabel);
counter++;
}
}
protected virtual void DrawBandVisualization()
{
GUILayout.Space(10);
GUILayout.Label("Raw Visualization", EditorStyles.boldLabel);
_internalMargin = (_numberOfBands > 8) ? 6f : _externalMargin;
// box
GUILayout.Box("", GUILayout.Width(_inspectorWidth - _externalMargin), GUILayout.Height(_bandsValuesBoxHeight));
_boxPosition = GUILayoutUtility.GetLastRect().position;
_boxSize = GUILayoutUtility.GetLastRect().size;
_boxBottomY = _boxPosition.y + _boxSize.y - _externalMargin - _lineHeight;
_columnWidth = (_boxSize.x - (_numberOfBands + 1) * _internalMargin) / _numberOfBands;
_maxColumnHeight = _boxSize.y - 2 * _externalMargin - _lineHeight - 5;
// lines
Handles.BeginGUI();
// horizontal axis
Handles.color = Color.grey;
for (int i = 0; i < _numberOfAxis; i++)
{
_axisOrigin.x = _boxPosition.x;
_axisOrigin.y = _boxBottomY + _lineHeight / _numberOfAxis - i * (_boxSize.y / _numberOfAxis);
_axisDestination.x = _boxPosition.x + _boxSize.x;
_axisDestination.y = _axisOrigin.y;
Handles.DrawLine(_axisOrigin, _axisDestination);
}
// peaks
if ((BandPeaks != null) && (BandPeaks.arraySize == _numberOfBands))
{
for (int i = 0; i < _numberOfBands; i++)
{
float peak = BandPeaks.GetArrayElementAtIndex(i).floatValue;
if (Active)
{
if (Time.time - LastPeaksAt.GetArrayElementAtIndex(i).floatValue < _peakShowDuration)
{
Handles.color = _activePeakColor;
}
else
{
Handles.color = _peakColor;
}
}
else
{
Handles.color = _peakColor;
}
_axisOrigin.x = _boxPosition.x + _internalMargin * (i + 1) + _columnWidth * i;
_axisOrigin.y = _boxBottomY - MMMaths.Remap(peak, 0f, 1f, 0f, _maxColumnHeight);
_axisDestination.x = _axisOrigin.x + _columnWidth;
_axisDestination.y = _axisOrigin.y;
Handles.DrawLine(_axisOrigin, _axisDestination);
}
}
Handles.EndGUI();
// amplitude cursors
_columnHeight = MMMaths.Remap(Amplitude.floatValue, 0f, 1f, 0f, _maxColumnHeight);
_positionX = _boxPosition.x - _externalMargin/4 ;
_positionY = _boxBottomY - _columnHeight;
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _externalMargin / 2;
_rect.height = _externalMargin / 2;
EditorGUI.DrawRect(_rect, _amplitudeColor);
_columnHeight = MMMaths.Remap(BufferedAmplitude.floatValue, 0f, 1f, 0f, _maxColumnHeight);
_positionX = _boxPosition.x + _boxSize.x - _externalMargin / 4;
_positionY = _boxBottomY - _columnHeight;
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _externalMargin / 2;
_rect.height = _externalMargin / 2;
EditorGUI.DrawRect(_rect, _amplitudeColor);
// buffered bars
for (int i = 0; i < _numberOfBands; i++)
{
if (Active)
{
float bandLevel = BufferedBandLevels.GetArrayElementAtIndex(i).floatValue;
_columnHeight = MMMaths.Remap(bandLevel, 0f, 1f, 0f, _maxColumnHeight);
_barColor = (Time.time - LastPeaksAt.GetArrayElementAtIndex(i).floatValue < _peakShowDuration/3f) ? _activePeakColor : _bufferedBarColor;
_positionX = _boxPosition.x + _internalMargin * (i + 1) + _columnWidth * i;
_positionY = _boxBottomY;
// bar rectangle
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _columnWidth;
_rect.height = -_columnHeight;
EditorGUI.DrawRect(_rect, _barColor);
}
}
// bars
for (int i = 0; i < _numberOfBands; i++)
{
if (Active)
{
float bandLevel = BandLevels.GetArrayElementAtIndex(i).floatValue;
_columnHeight = MMMaths.Remap(bandLevel, 0f, 1f, 0f, _maxColumnHeight);
_barColor = (Time.time - LastPeaksAt.GetArrayElementAtIndex(i).floatValue < _peakShowDuration) ? _peakColor : _normalBarColor;
}
else
{
_barColor = _inactiveColor;
_columnHeight = (i + 1) * (_maxColumnHeight / (_numberOfBands + 1));
}
_positionX = _boxPosition.x + _internalMargin * (i + 1) + _columnWidth * i;
_positionY = _boxBottomY;
// bar rectangle
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _columnWidth;
_rect.height = -_columnHeight;
EditorGUI.DrawRect(_rect, _barColor);
// bar number label
float labelCorrection = (i > 9) ? -5f : 0f;
_rect.x = _positionX + _columnWidth / 2 - 5 + labelCorrection;
_rect.y = _boxBottomY + _lineHeight / 4;
_rect.width = _columnWidth;
_rect.height = _lineHeight;
EditorGUI.LabelField(_rect, i.ToString(), EditorStyles.boldLabel);
}
}
protected virtual void DrawBandVisualizationNormalized()
{
GUILayout.Space(10);
GUILayout.Label("Normalized Visualization", EditorStyles.boldLabel);
// box
GUILayout.Box("", GUILayout.Width(_inspectorWidth - _externalMargin), GUILayout.Height(_bandsValuesBoxHeight));
_boxPosition = GUILayoutUtility.GetLastRect().position;
_boxSize = GUILayoutUtility.GetLastRect().size;
_boxBottomY = _boxPosition.y + _boxSize.y - _externalMargin - _lineHeight;
_columnWidth = (_boxSize.x - (_numberOfBands + 1) * _internalMargin) / _numberOfBands;
_maxColumnHeight = _boxSize.y - 2 * _externalMargin - _lineHeight;
// lines
Handles.BeginGUI();
// horizontal axis
Handles.color = Color.grey;
for (int i = 0; i < _numberOfAxis; i++)
{
_axisOrigin.x = _boxPosition.x;
_axisOrigin.y = _boxBottomY + _lineHeight / _numberOfAxis - i * (_boxSize.y / _numberOfAxis);
_axisDestination.x = _boxPosition.x + _boxSize.x;
_axisDestination.y = _axisOrigin.y;
Handles.DrawLine(_axisOrigin, _axisDestination);
}
Handles.EndGUI();
// amplitude cursors
_columnHeight = MMMaths.Remap(NormalizedAmplitude.floatValue, 0f, 1f, 0f, _maxColumnHeight);
_positionX = _boxPosition.x - _externalMargin / 4;
_positionY = _boxBottomY - _columnHeight;
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _externalMargin / 2;
_rect.height = _externalMargin / 2;
EditorGUI.DrawRect(_rect, _normalizedAmplitudeColor);
_columnHeight = MMMaths.Remap(NormalizedBufferedAmplitude.floatValue, 0f, 1f, 0f, _maxColumnHeight);
_positionX = _boxPosition.x + _boxSize.x - _externalMargin / 4;
_positionY = _boxBottomY - _columnHeight;
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _externalMargin / 2;
_rect.height = _externalMargin / 2;
EditorGUI.DrawRect(_rect, _normalizedAmplitudeColor);
// buffered bars
for (int i = 0; i < _numberOfBands; i++)
{
if (Active)
{
float bandLevel = NormalizedBufferedBandLevels.GetArrayElementAtIndex(i).floatValue;
_columnHeight = MMMaths.Remap(bandLevel, 0f, 1f, 0f, _maxColumnHeight);
_barColor = (Time.time - LastPeaksAt.GetArrayElementAtIndex(i).floatValue < _peakShowDuration / 3f) ? _activePeakColor : _bufferedBarColor;
_positionX = _boxPosition.x + _internalMargin * (i + 1) + _columnWidth * i;
_positionY = _boxBottomY;
// bar rectangle
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _columnWidth;
_rect.height = -_columnHeight;
EditorGUI.DrawRect(_rect, _barColor);
}
}
// bars
for (int i = 0; i < _numberOfBands; i++)
{
if (Active)
{
float bandLevel = NormalizedBandLevels.GetArrayElementAtIndex(i).floatValue;
_columnHeight = MMMaths.Remap(bandLevel, 0f, 1f, 0f, _maxColumnHeight);
_barColor = (Time.time - LastPeaksAt.GetArrayElementAtIndex(i).floatValue < _peakShowDuration) ? _peakColor : _normalNormalizedBarColor;
}
else
{
_barColor = _inactiveColor;
_columnHeight = (i + 1) * (_maxColumnHeight / (_numberOfBands + 1));
}
_positionX = _boxPosition.x + _internalMargin * (i + 1) + _columnWidth * i;
_positionY = _boxBottomY;
// bar rectangle
_rect.x = _positionX;
_rect.y = _positionY;
_rect.width = _columnWidth;
_rect.height = -_columnHeight;
EditorGUI.DrawRect(_rect, _barColor);
// bar number label
float labelCorrection = (i > 9) ? -5f : 0f;
_rect.x = _positionX + _columnWidth / 2 - 5 + labelCorrection;
_rect.y = _boxBottomY + _lineHeight / 4;
_rect.width = _columnWidth;
_rect.height = _lineHeight;
EditorGUI.LabelField(_rect, i.ToString(), EditorStyles.boldLabel);
}
}
protected virtual void DrawRawSpectrum()
{
GUILayout.Space(10);
GUILayout.Label("Raw Spectrum", EditorStyles.boldLabel);
// 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);
}
if (Active)
{
// spectrum
for (int i = 1; i < RawSpectrum.arraySize - 1; i++)
{
float xPosition = _spectrumBoxPosition.x + _externalMargin + MMMaths.Remap(i, 0, RawSpectrum.arraySize, 0f, _spectrumBoxSize.x - _externalMargin * 2);
float yPosition = _spectrumBoxPosition.y + _spectrumBoxSize.y / 2 ;
float deltaX = (_spectrumBoxSize.x - _externalMargin * 2) / RawSpectrum.arraySize;
float spectrumValue = RawSpectrum.GetArrayElementAtIndex(i).floatValue;
float spectrumValuePrevious = RawSpectrum.GetArrayElementAtIndex(i - 1).floatValue;
float factor = _spectrumBoxSize.y/2;
spectrumValue = - (1 / Mathf.Log(spectrumValue)) * factor; ;
spectrumValuePrevious = - (1 / Mathf.Log(spectrumValuePrevious)) * factor;
spectrumValue = Mathf.Clamp(spectrumValue, 0f, _spectrumBoxSize.y / 2f);
spectrumValuePrevious = Mathf.Clamp(spectrumValuePrevious, 0f, _spectrumBoxSize.y / 2f);
Handles.color = _spectrumColor;
_axisOrigin.x = xPosition - deltaX;
_axisOrigin.y = yPosition + spectrumValuePrevious;
_axisDestination.x = xPosition;
_axisDestination.y = (i % 2 == 0) ? yPosition + spectrumValue : yPosition - spectrumValue;
Handles.DrawLine(_axisOrigin, _axisDestination);
}
}
else
{
int points = 100;
for (int i = 1; i < points - 1; i++)
{
float xPosition = _spectrumBoxPosition.x + _externalMargin + MMMaths.Remap(i, 0, points, 0f, _spectrumBoxSize.x - _externalMargin * 2);
float yPosition = _spectrumBoxPosition.y + _spectrumBoxSize.y / 2;
float deltaBetweenXandXPrevious = (_spectrumBoxSize.x - _externalMargin * 2) / points;
float spectrumValue = Foobar(i);
float spectrumValuePrevious = Foobar(i-1);
float factor = _spectrumBoxSize.y / 2;
Handles.color = _inactiveColor;
_axisOrigin.x = xPosition - deltaBetweenXandXPrevious;
_axisOrigin.y = yPosition + spectrumValuePrevious;
_axisDestination.x = xPosition;
_axisDestination.y = yPosition + spectrumValue ;
var p1 = _axisOrigin;
var p2 = _axisDestination;
var thickness = 3;
Handles.DrawBezier(p1, p2, p1, p2, _spectrumColor, null, thickness);
}
}
Handles.EndGUI();
}
protected virtual float Foobar(float x)
{
return 25f * Mathf.Sin(x * 0.5f);
}
protected virtual void PreProcessingButtons()
{
if ((target as MMAudioAnalyzer).Mode != MMAudioAnalyzer.Modes.AudioSource)
{
return;
}
GUILayout.Space(10);
GUILayout.Label("Peaks preprocessing", EditorStyles.boldLabel);
if (!PeaksPasted.boolValue)
{
if ((PeaksSaver.Peaks == null) || (PeaksSaver.Peaks.Length == 0))
{
EditorGUILayout.HelpBox("You haven't preprocessed peaks for this track yet. It's recommended to do so, by pressing play, " +
"then the Find Peaks button below. Then, exit play, and press the 'Paste Peaks' button.", MessageType.Warning);
if (GUILayout.Button("Find Peaks"))
{
(target as MMAudioAnalyzer).FindPeaks();
}
}
else
{
EditorGUILayout.HelpBox("Exit Play Mode first, then paste your saved peaks using the 'Paste Peaks' button below.", MessageType.Warning);
if (!Application.isPlaying)
{
if (GUILayout.Button("Paste Peaks"))
{
(target as MMAudioAnalyzer).PastePeaks();
}
}
}
}
if (GUILayout.Button("Clear Peaks"))
{
(target as MMAudioAnalyzer).ClearPeaks();
}
}
}
#endif
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1329772f40e2ebb419ba950b49ca5557
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,260 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// Custom editor for the MMSoundManager, used to display custom track controls
/// </summary>
#if UNITY_EDITOR
[CustomEditor(typeof(MMSoundManager), true)]
[CanEditMultipleObjects]
public class MMSoundManagerEditor : Editor
{
public override bool RequiresConstantRepaint()
{
return true;
}
protected MMSoundManagerSettingsSO _settingsSO;
protected MMSoundManager _mmSoundManager;
private static float _masterVolume, _musicVolume, _sfxVolume, _uiVolume;
protected Color _originalBackgroundColor;
protected Color _saveButtonColor = new Color32(80, 80, 80, 255);
protected Color _loadButtonColor = new Color32(107, 107, 107, 255);
protected Color _resetButtonColor = new Color32(120, 120, 120, 255);
protected Color _baseColor = new Color32(150, 150, 150, 255);
protected Color _masterColorBase = MMColors.ReunoYellow;
protected Color _masterColorMute;
protected Color _masterColorUnmute;
protected Color _masterColorPause;
protected Color _masterColorStop;
protected Color _masterColorPlay;
protected Color _masterColorFree;
protected Color _musicColorBase = MMColors.Aquamarine;
protected Color _musicColorMute;
protected Color _musicColorUnmute;
protected Color _musicColorPause;
protected Color _musicColorStop;
protected Color _musicColorPlay;
protected Color _musicColorFree;
protected Color _sfxColorBase = MMColors.Coral;
protected Color _sfxColorMute;
protected Color _sfxColorUnmute;
protected Color _sfxColorPause;
protected Color _sfxColorStop;
protected Color _sfxColorPlay;
protected Color _sfxColorFree;
protected Color _uiColorBase = MMColors.SteelBlue;
protected Color _uiColorMute;
protected Color _uiColorUnmute;
protected Color _uiColorPause;
protected Color _uiColorStop;
protected Color _uiColorPlay;
protected Color _uiColorFree;
protected MMColors.ColoringMode _coloringMode = MMColors.ColoringMode.Add;
/// <summary>
/// On Enable, we initialize our button colors. Why? Because we can.
/// </summary>
protected virtual void OnEnable()
{
_masterColorMute = MMColors.MMColorize(_baseColor, _masterColorBase, _coloringMode, 1f);
_masterColorUnmute = MMColors.MMColorize(_baseColor, _masterColorBase, _coloringMode, 0.9f);
_masterColorPause = MMColors.MMColorize(_baseColor, _masterColorBase, _coloringMode, 0.8f);
_masterColorStop = MMColors.MMColorize(_baseColor, _masterColorBase, _coloringMode, 0.7f);
_masterColorPlay = MMColors.MMColorize(_baseColor, _masterColorBase, _coloringMode, 0.5f);
_masterColorFree = MMColors.MMColorize(_baseColor, _masterColorBase, _coloringMode, 0.4f);
_musicColorMute = MMColors.MMColorize(_baseColor, _musicColorBase, _coloringMode, 1f);
_musicColorUnmute = MMColors.MMColorize(_baseColor, _musicColorBase, _coloringMode, 0.9f);
_musicColorPause = MMColors.MMColorize(_baseColor, _musicColorBase, _coloringMode, 0.8f);
_musicColorStop = MMColors.MMColorize(_baseColor, _musicColorBase, _coloringMode, 0.7f);
_musicColorPlay = MMColors.MMColorize(_baseColor, _musicColorBase, _coloringMode, 0.5f);
_musicColorFree = MMColors.MMColorize(_baseColor, _musicColorBase, _coloringMode, 0.4f);
_sfxColorMute = MMColors.MMColorize(_baseColor, _sfxColorBase, _coloringMode, 1f);
_sfxColorUnmute = MMColors.MMColorize(_baseColor, _sfxColorBase, _coloringMode, 0.9f);
_sfxColorPause = MMColors.MMColorize(_baseColor, _sfxColorBase, _coloringMode, 0.8f);
_sfxColorStop = MMColors.MMColorize(_baseColor, _sfxColorBase, _coloringMode, 0.7f);
_sfxColorPlay = MMColors.MMColorize(_baseColor, _sfxColorBase, _coloringMode, 0.5f);
_sfxColorFree = MMColors.MMColorize(_baseColor, _sfxColorBase, _coloringMode, 0.4f);
_uiColorMute = MMColors.MMColorize(_baseColor, _uiColorBase, _coloringMode, 1f);
_uiColorUnmute = MMColors.MMColorize(_baseColor, _uiColorBase, _coloringMode, 0.9f);
_uiColorPause = MMColors.MMColorize(_baseColor, _uiColorBase, _coloringMode, 0.8f);
_uiColorStop = MMColors.MMColorize(_baseColor, _uiColorBase, _coloringMode, 0.7f);
_uiColorPlay = MMColors.MMColorize(_baseColor, _uiColorBase, _coloringMode, 0.5f);
_uiColorFree = MMColors.MMColorize(_baseColor, _uiColorBase, _coloringMode, 0.4f);
}
/// <summary>
/// On GUI, draws the base inspector and track controls
/// </summary>
public override void OnInspectorGUI()
{
_settingsSO = (target as MMSoundManager).settingsSo;
_mmSoundManager = target as MMSoundManager;
if (_settingsSO != null)
{
_masterVolume = _settingsSO.GetTrackVolume(MMSoundManager.MMSoundManagerTracks.Master);
_musicVolume = _settingsSO.GetTrackVolume(MMSoundManager.MMSoundManagerTracks.Music);
_sfxVolume = _settingsSO.GetTrackVolume(MMSoundManager.MMSoundManagerTracks.Sfx);
_uiVolume = _settingsSO.GetTrackVolume(MMSoundManager.MMSoundManagerTracks.UI);
}
serializedObject.Update();
DrawDefaultInspector();
serializedObject.ApplyModifiedProperties();
if ( ((_settingsSO != null) && _mmSoundManager.gameObject.activeInHierarchy))
{
DrawTrack("Master Track", _mmSoundManager.settingsSo.Settings.MasterOn, MMSoundManager.MMSoundManagerTracks.Master, _masterColorMute, _masterColorUnmute, _masterColorPause, _masterColorStop, _masterColorPlay, _masterColorFree);
DrawTrack("Music Track", _mmSoundManager.settingsSo.Settings.MusicOn, MMSoundManager.MMSoundManagerTracks.Music, _musicColorMute, _musicColorUnmute, _musicColorPause, _musicColorStop, _musicColorPlay, _musicColorFree);
DrawTrack("SFX Track", _mmSoundManager.settingsSo.Settings.SfxOn, MMSoundManager.MMSoundManagerTracks.Sfx, _sfxColorMute, _sfxColorUnmute, _sfxColorPause, _sfxColorStop, _sfxColorPlay, _sfxColorFree);
DrawTrack("UI Track", _mmSoundManager.settingsSo.Settings.UIOn, MMSoundManager.MMSoundManagerTracks.UI, _uiColorMute, _uiColorUnmute, _uiColorPause, _uiColorStop, _uiColorPlay, _uiColorFree);
DrawSaveLoadButtons();
}
}
/// <summary>
/// Draws track controls for the specified track
/// </summary>
/// <param name="title"></param>
/// <param name="mute"></param>
/// <param name="track"></param>
/// <param name="muteColor"></param>
/// <param name="unmuteColor"></param>
/// <param name="pauseColor"></param>
/// <param name="stopColor"></param>
/// <param name="playColor"></param>
/// <param name="freeColor"></param>
protected virtual void DrawTrack(string title, bool mute, MMSoundManager.MMSoundManagerTracks track, Color muteColor, Color unmuteColor, Color pauseColor, Color stopColor, Color playColor, Color freeColor)
{
GUILayout.Space(10);
GUILayout.Label(title, EditorStyles.boldLabel);
EditorGUI.BeginDisabledGroup(!Application.isPlaying);
// we draw the volume slider
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Volume");
float newVolume = 0;
switch (track)
{
case MMSoundManager.MMSoundManagerTracks.Master:
newVolume = EditorGUILayout.Slider(_masterVolume, MMSoundManagerSettings._minimalVolume, MMSoundManagerSettings._maxVolume);
if (newVolume != _masterVolume) { _mmSoundManager.settingsSo.SetTrackVolume(MMSoundManager.MMSoundManagerTracks.Master, newVolume); }
break;
case MMSoundManager.MMSoundManagerTracks.Music:
newVolume = EditorGUILayout.Slider(_musicVolume, MMSoundManagerSettings._minimalVolume, MMSoundManagerSettings._maxVolume);
if (newVolume != _musicVolume) { _mmSoundManager.settingsSo.SetTrackVolume(MMSoundManager.MMSoundManagerTracks.Music, newVolume); }
break;
case MMSoundManager.MMSoundManagerTracks.Sfx:
newVolume = EditorGUILayout.Slider(_sfxVolume, MMSoundManagerSettings._minimalVolume, MMSoundManagerSettings._maxVolume);
if (newVolume != _sfxVolume) { _mmSoundManager.settingsSo.SetTrackVolume(MMSoundManager.MMSoundManagerTracks.Sfx, newVolume); }
break;
case MMSoundManager.MMSoundManagerTracks.UI:
newVolume = EditorGUILayout.Slider(_uiVolume, MMSoundManagerSettings._minimalVolume, MMSoundManagerSettings._maxVolume);
if (newVolume != _uiVolume) { _mmSoundManager.settingsSo.SetTrackVolume(MMSoundManager.MMSoundManagerTracks.UI, newVolume); }
break;
}
EditorGUILayout.EndHorizontal();
// we draw the buttons
EditorGUILayout.BeginHorizontal();
{
if (mute)
{
DrawColoredButton("Mute", muteColor, track, _mmSoundManager.MuteTrack, EditorStyles.miniButtonLeft);
}
else
{
DrawColoredButton("Unmute", unmuteColor, track, _mmSoundManager.UnmuteTrack, EditorStyles.miniButtonMid);
}
DrawColoredButton("Pause", pauseColor, track, _mmSoundManager.PauseTrack, EditorStyles.miniButtonMid);
DrawColoredButton("Stop", stopColor, track, _mmSoundManager.StopTrack, EditorStyles.miniButtonMid);
DrawColoredButton("Play", playColor, track, _mmSoundManager.PlayTrack, EditorStyles.miniButtonMid);
DrawColoredButton("Free", freeColor, track, _mmSoundManager.FreeTrack, EditorStyles.miniButtonRight);
}
EditorGUILayout.EndHorizontal();
EditorGUI.EndDisabledGroup();
}
/// <summary>
/// Draws save related buttons
/// </summary>
protected virtual void DrawSaveLoadButtons()
{
EditorGUI.BeginDisabledGroup(!Application.isPlaying);
GUILayout.Space(10);
GUILayout.Label("Settings", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
DrawColoredButton("Save", _saveButtonColor, _settingsSO.SaveSoundSettings, EditorStyles.miniButtonLeft);
DrawColoredButton("Load", _loadButtonColor, _settingsSO.LoadSoundSettings, EditorStyles.miniButtonMid);
DrawColoredButton("Reset", _resetButtonColor, _settingsSO.ResetSoundSettings, EditorStyles.miniButtonRight);
EditorGUILayout.EndHorizontal();
EditorGUI.EndDisabledGroup();
}
/// <summary>
/// Draws a button
/// </summary>
/// <param name="buttonLabel"></param>
/// <param name="buttonColor"></param>
/// <param name="track"></param>
/// <param name="action"></param>
/// <param name="styles"></param>
public virtual void DrawColoredButton(string buttonLabel, Color buttonColor, MMSoundManager.MMSoundManagerTracks track, System.Action<MMSoundManager.MMSoundManagerTracks> action, GUIStyle styles)
{
_originalBackgroundColor = GUI.backgroundColor;
GUI.backgroundColor = buttonColor;
if (GUILayout.Button(buttonLabel, styles))
{
action.Invoke(track);
}
GUI.backgroundColor = _originalBackgroundColor;
}
/// <summary>
/// Draws a button
/// </summary>
/// <param name="buttonLabel"></param>
/// <param name="buttonColor"></param>
/// <param name="action"></param>
/// <param name="styles"></param>
protected virtual void DrawColoredButton(string buttonLabel, Color buttonColor, Action action, GUIStyle styles)
{
_originalBackgroundColor = GUI.backgroundColor;
GUI.backgroundColor = buttonColor;
if (GUILayout.Button(buttonLabel, styles))
{
action.Invoke();
}
GUI.backgroundColor = _originalBackgroundColor;
}
}
#endif
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ba48426db14159040b651a2a7735761f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using UnityEngine;
using System.Collections;
using UnityEditor;
using MoreMountains.Tools;
namespace MoreMountains.Tools
{
[CustomEditor(typeof(MMObjectBounds),true)]
public class ObjectBoundsEditor : Editor
{
protected MMObjectBounds _objectBounds;
public override void OnInspectorGUI()
{
_objectBounds = (MMObjectBounds)target;
DrawDefaultInspector();
if (_objectBounds.GetComponent<Renderer>()==null && _objectBounds.BoundsBasedOn==MMObjectBounds.WaysToDetermineBounds.Renderer)
{
EditorGUILayout.HelpBox("You've defined this object as having Renderer defined bounds, but no renderer is attached to the object. Add a Renderer, or switch to collider based bounds. The bounds are the dimensions that will be used when spawning your object and to determine when it should be recycled.",MessageType.Warning);
}
if (_objectBounds.GetComponent<Collider>()==null && _objectBounds.BoundsBasedOn==MMObjectBounds.WaysToDetermineBounds.Collider)
{
EditorGUILayout.HelpBox("You've defined this object as having Collider defined bounds, but no Collider is attached to the object. Add a Collider, or switch to renderer based bounds. The bounds are the dimensions that will be used when spawning your object and to determine when it should be recycled.",MessageType.Warning);
}
if (_objectBounds.GetComponent<Collider2D>()==null && _objectBounds.BoundsBasedOn==MMObjectBounds.WaysToDetermineBounds.Collider2D)
{
EditorGUILayout.HelpBox("You've defined this object as having Collider2D defined bounds, but no Collider2D is attached to the object. Add a Collider2D, or switch to renderer based bounds. The bounds are the dimensions that will be used when spawning your object and to determine when it should be recycled.",MessageType.Warning);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: bada8c222727b4fe49b6a90f1dddad8e
timeCreated: 1456407699
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 392fd774dc5df3648b20341bd79a31af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,323 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
/// <summary>
/// Custom editor for the FloatController, conditional hiding and dropdown fill
/// </summary>
[CustomEditor(typeof(FloatController), true)]
[CanEditMultipleObjects]
public class FloatControllerEditor : Editor
{
protected SerializedProperty _TargetObject;
protected SerializedProperty _Curve;
protected SerializedProperty _MinValue;
protected SerializedProperty _MaxValue;
protected SerializedProperty _Duration;
protected SerializedProperty _PingPongPauseDuration;
protected SerializedProperty _Amplitude;
protected SerializedProperty _Frequency;
protected SerializedProperty _Shift;
protected SerializedProperty _RemapNoiseValues;
protected SerializedProperty _RemapNoiseZero;
protected SerializedProperty _RemapNoiseOne;
protected SerializedProperty _OneTimeDuration;
protected SerializedProperty _OneTimeAmplitude;
protected SerializedProperty _OneTimeRemapMin;
protected SerializedProperty _OneTimeRemapMax;
protected SerializedProperty _OneTimeCurve;
protected SerializedProperty _DisableAfterOneTime;
protected SerializedProperty _DisableGameObjectAfterOneTime;
protected SerializedProperty _OneTimeButton;
protected SerializedProperty _DrivenLevel;
protected SerializedProperty _ToDestinationValue;
protected SerializedProperty _ToDestinationDuration;
protected SerializedProperty _ToDestinationCurve;
protected SerializedProperty _DisableAfterToDestination;
protected SerializedProperty _ToDestinationButton;
protected SerializedProperty _InitialValue;
protected SerializedProperty _CurrentValue;
protected SerializedProperty _CurrentValueNormalized;
protected SerializedProperty _ChoiceIndex;
protected SerializedProperty _PropertyName;
protected SerializedProperty _AudioAnalyzer;
protected SerializedProperty _BeatID;
protected SerializedProperty _AudioAnalyzerMode;
protected SerializedProperty _NormalizedLevelID;
protected SerializedProperty _AudioAnalyzerMultiplier;
public override bool RequiresConstantRepaint()
{
return true;
}
/// <summary>
/// On enable, grabs our serialized properties
/// </summary>
protected virtual void OnEnable()
{
FloatController myTarget = (FloatController)target;
_TargetObject = serializedObject.FindProperty("TargetObject");
_Curve = serializedObject.FindProperty("Curve");
_MinValue = serializedObject.FindProperty("MinValue");
_MaxValue = serializedObject.FindProperty("MaxValue");
_Duration = serializedObject.FindProperty("Duration");
_PingPongPauseDuration = serializedObject.FindProperty("PingPongPauseDuration");
_Amplitude = serializedObject.FindProperty("Amplitude");
_Frequency = serializedObject.FindProperty("Frequency");
_Shift = serializedObject.FindProperty("Shift");
_RemapNoiseValues = serializedObject.FindProperty("RemapNoiseValues");
_RemapNoiseZero = serializedObject.FindProperty("RemapNoiseZero");
_RemapNoiseOne = serializedObject.FindProperty("RemapNoiseOne");
_OneTimeDuration = serializedObject.FindProperty("OneTimeDuration");
_OneTimeAmplitude = serializedObject.FindProperty("OneTimeAmplitude");
_OneTimeRemapMin = serializedObject.FindProperty("OneTimeRemapMin");
_OneTimeRemapMax = serializedObject.FindProperty("OneTimeRemapMax");
_OneTimeCurve = serializedObject.FindProperty("OneTimeCurve");
_DisableAfterOneTime = serializedObject.FindProperty("DisableAfterOneTime");
_DisableGameObjectAfterOneTime = serializedObject.FindProperty("DisableGameObjectAfterOneTime");
_OneTimeButton = serializedObject.FindProperty("OneTimeButton");
_DrivenLevel = serializedObject.FindProperty("DrivenLevel");
_ToDestinationValue = serializedObject.FindProperty("ToDestinationValue");
_ToDestinationDuration = serializedObject.FindProperty("ToDestinationDuration");
_ToDestinationCurve = serializedObject.FindProperty("ToDestinationCurve");
_DisableAfterToDestination = serializedObject.FindProperty("DisableAfterToDestination");
_ToDestinationButton = serializedObject.FindProperty("ToDestinationButton");
_InitialValue = serializedObject.FindProperty("InitialValue");
_CurrentValue = serializedObject.FindProperty("CurrentValue");
_CurrentValueNormalized = serializedObject.FindProperty("CurrentValueNormalized");
_ChoiceIndex = serializedObject.FindProperty("ChoiceIndex");
_PropertyName = serializedObject.FindProperty("PropertyName");
_AudioAnalyzer = serializedObject.FindProperty("AudioAnalyzer");
_AudioAnalyzerMode = serializedObject.FindProperty("AudioAnalyzerMode");
_NormalizedLevelID = serializedObject.FindProperty("NormalizedLevelID");
_BeatID = serializedObject.FindProperty("BeatID");
_AudioAnalyzerMultiplier = serializedObject.FindProperty("AudioAnalyzerMultiplier");
VerifyChosenIndex();
AssemblyReloadEvents.afterAssemblyReload += OnAfterAssemblyReload;
}
protected virtual void OnDisable()
{
//BindPropertyName();
AssemblyReloadEvents.afterAssemblyReload -= OnAfterAssemblyReload;
}
protected virtual void BindPropertyName()
{
FloatController myTarget = (FloatController)target;
if (myTarget.ChoiceIndex > myTarget.AttributeNames.Length - 1)
{
_ChoiceIndex.intValue = 0;
_PropertyName.stringValue = FloatController._undefinedString;
}
else
{
_PropertyName.stringValue = myTarget.AttributeNames[myTarget.ChoiceIndex];
serializedObject.ApplyModifiedProperties();
}
}
protected virtual void VerifyChosenIndex()
{
FloatController myTarget = (FloatController)target;
// determine choice index
int index = 0;
bool found = false;
foreach (string attName in myTarget.AttributeNames)
{
if (attName == myTarget.PropertyName)
{
_ChoiceIndex.intValue = index;
found = true;
}
index++;
}
if (!found)
{
_ChoiceIndex.intValue = 0;
_PropertyName.stringValue = FloatController._undefinedString;
}
serializedObject.ApplyModifiedProperties();
}
protected virtual void OnAfterAssemblyReload()
{
FloatController myTarget = (FloatController)target;
myTarget.FillDropDownList();
VerifyChosenIndex();
serializedObject.ApplyModifiedProperties();
}
/// <summary>
/// Draws a custom conditional inspector
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
Undo.RecordObject(target, "Modified FloatController");
FloatController myTarget = (FloatController)target;
EditorGUILayout.PropertyField(_TargetObject);
if (myTarget.AttributeNames != null)
{
if (myTarget.AttributeNames.Length > 0)
{
// draws a dropdown with all our properties
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("Property");
_ChoiceIndex.intValue = EditorGUILayout.Popup(myTarget.ChoiceIndex, myTarget.AttributeNames);
BindPropertyName();
EditorGUILayout.EndHorizontal();
Editor.DrawPropertiesExcluding(serializedObject, new string[] { "m_Script", "TargetObject", "Curve", "MinValue", "MaxValue", "Duration", "Amplitude",
"RemapNoiseValues","RemapNoiseZero","RemapNoiseOne",
"Frequency", "Shift", "InitialValue", "CurrentValue", "CurrentValueNormalized", "PingPongPauseDuration",
"OneTimeDuration", "OneTimeAmplitude", "OneTimeRemapMin", "OneTimeRemapMax",
"OneTimeCurve", "OneTimeButton", "DisableAfterOneTime", "DisableGameObjectAfterOneTime",
"AudioAnalyzer","AudioAnalyzerMode", "BeatID", "NormalizedLevelID", "AudioAnalyzerMultiplier",
"DisableAfterToDestination", "DrivenLevel",
"ToDestinationDuration", "ToDestinationValue", "ToDestinationCurve", "ToDestinationButton"});
if (myTarget.ControlMode == FloatController.ControlModes.PingPong)
{
EditorGUILayout.PropertyField(_Curve);
EditorGUILayout.PropertyField(_MinValue);
EditorGUILayout.PropertyField(_MaxValue);
EditorGUILayout.PropertyField(_Duration);
EditorGUILayout.PropertyField(_PingPongPauseDuration);
}
else if (myTarget.ControlMode == FloatController.ControlModes.Random)
{
EditorGUILayout.PropertyField(_Amplitude);
EditorGUILayout.PropertyField(_Frequency);
EditorGUILayout.PropertyField(_Shift);
EditorGUILayout.PropertyField(_RemapNoiseValues);
EditorGUILayout.PropertyField(_RemapNoiseZero);
EditorGUILayout.PropertyField(_RemapNoiseOne);
}
else if (myTarget.ControlMode == FloatController.ControlModes.Driven)
{
EditorGUILayout.PropertyField(_DrivenLevel);
}
else if (myTarget.ControlMode == FloatController.ControlModes.OneTime)
{
EditorGUILayout.PropertyField(_OneTimeDuration);
EditorGUILayout.PropertyField(_OneTimeAmplitude);
EditorGUILayout.PropertyField(_OneTimeRemapMin);
EditorGUILayout.PropertyField(_OneTimeRemapMax);
EditorGUILayout.PropertyField(_OneTimeCurve);
EditorGUILayout.PropertyField(_DisableAfterOneTime);
EditorGUILayout.PropertyField(_DisableGameObjectAfterOneTime);
EditorGUILayout.PropertyField(_OneTimeButton);
}
else if (myTarget.ControlMode == FloatController.ControlModes.AudioAnalyzer)
{
EditorGUILayout.PropertyField(_AudioAnalyzer);
EditorGUILayout.PropertyField(_AudioAnalyzerMode);
if (myTarget.AudioAnalyzerMode == FloatController.AudioAnalyzerModes.Beat)
{
EditorGUILayout.PropertyField(_BeatID);
}
else
{
EditorGUILayout.PropertyField(_NormalizedLevelID);
}
EditorGUILayout.PropertyField(_AudioAnalyzerMultiplier);
}
else if (myTarget.ControlMode == FloatController.ControlModes.ToDestination)
{
EditorGUILayout.PropertyField(_ToDestinationDuration);
EditorGUILayout.PropertyField(_ToDestinationValue);
EditorGUILayout.PropertyField(_ToDestinationCurve);
EditorGUILayout.PropertyField(_DisableAfterToDestination);
EditorGUILayout.PropertyField(_ToDestinationButton);
}
EditorGUILayout.PropertyField(_InitialValue);
EditorGUILayout.PropertyField(_CurrentValue);
EditorGUILayout.PropertyField(_CurrentValueNormalized);
}
}
serializedObject.ApplyModifiedProperties();
if (Application.isPlaying)
{
_barRect = EditorGUILayout.GetControlRect();
DrawLevelProgressBar(_barRect, myTarget.CurrentValueNormalized, _mmYellow, _mmRed);
}
}
protected Rect _barRect;
protected Color _mmYellow = new Color(1f, 0.7686275f, 0f);
protected Color _mmRed = MMColors.Orangered;
protected const int _lineHeight = 20;
protected const int _lineMargin = 2;
protected const int _numberOfLines = 1;
protected Color _progressBarBackground = new Color(0, 0, 0, 0.5f);
protected virtual void DrawLevelProgressBar(Rect position, float level, Color frontColor, Color negativeColor)
{
Rect levelLabelRect = new Rect(position.x, position.y + (_lineHeight + _lineMargin) * (_numberOfLines - 1), position.width, _lineHeight);
Rect levelValueRect = new Rect(position.x - 15 + EditorGUIUtility.labelWidth + 4, position.y + (_lineHeight + _lineMargin) * (_numberOfLines - 1), position.width, _lineHeight);
float progressX = position.x - 5 + EditorGUIUtility.labelWidth + 60;
float progressY = position.y + (_lineHeight + _lineMargin) * (_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, _progressBarBackground);
if (negative)
{
EditorGUI.DrawRect(levelProgressFront, negativeColor);
}
else
{
EditorGUI.DrawRect(levelProgressFront, frontColor);
}
}
}
}

View File

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

View File

@@ -0,0 +1,280 @@
using UnityEngine;
using UnityEditor;
#if MM_UI
namespace MoreMountains.Tools
{
/// <summary>
/// Custom editor for the ShaderController, conditional hiding
/// </summary>
[CustomEditor(typeof(ShaderController), true)]
[CanEditMultipleObjects]
public class ShaderControllerEditor : Editor
{
protected SerializedProperty _TargetRenderer;
protected SerializedProperty _Curve;
protected SerializedProperty _MinValue;
protected SerializedProperty _MaxValue;
protected SerializedProperty _Duration;
protected SerializedProperty _PingPongPauseDuration;
protected SerializedProperty _Amplitude;
protected SerializedProperty _Frequency;
protected SerializedProperty _Shift;
protected SerializedProperty _RemapNoiseValues;
protected SerializedProperty _RemapNoiseZero;
protected SerializedProperty _RemapNoiseOne;
protected SerializedProperty _OneTimeDuration;
protected SerializedProperty _OneTimeAmplitude;
protected SerializedProperty _OneTimeRemapMin;
protected SerializedProperty _OneTimeRemapMax;
protected SerializedProperty _OneTimeCurve;
protected SerializedProperty _OneTimeButton;
protected SerializedProperty _DisableAfterOneTime;
protected SerializedProperty _DisableGameObjectAfterOneTime;
protected SerializedProperty _DrivenLevel;
protected SerializedProperty _AudioAnalyzer;
protected SerializedProperty _BeatID;
protected SerializedProperty _AudioAnalyzerMultiplier;
protected SerializedProperty _AudioAnalyzerOffset;
protected SerializedProperty _AudioAnalyzerLerp;
protected SerializedProperty _ToDestinationValue;
protected SerializedProperty _ToDestinationDuration;
protected SerializedProperty _ToDestinationCurve;
protected SerializedProperty _ToDestinationButton;
protected SerializedProperty _DisableAfterToDestination;
protected SerializedProperty _InitialValue;
protected SerializedProperty _CurrentValue;
protected SerializedProperty _CurrentValueNormalized;
protected SerializedProperty _InitialColor;
protected SerializedProperty _ColorMode;
protected SerializedProperty _ColorRamp;
protected SerializedProperty _PropertyID;
protected SerializedProperty _PropertyFound;
protected SerializedProperty _TargetMaterial;
protected SerializedProperty _FromColor;
protected SerializedProperty _ToColor;
protected SerializedProperty _LoopCurve;
protected SerializedProperty _LoopStartValue;
protected SerializedProperty _LoopEndValue;
protected SerializedProperty _LoopDuration;
protected SerializedProperty _LoopPauseDuration;
protected SerializedProperty _SpriteRendererTextureProperty;
public override bool RequiresConstantRepaint()
{
return true;
}
/// <summary>
/// On enable we grab our properties
/// </summary>
protected virtual void OnEnable()
{
ShaderController myTarget = (ShaderController)target;
_TargetRenderer = serializedObject.FindProperty("TargetRenderer");
_Curve = serializedObject.FindProperty("Curve");
_MinValue = serializedObject.FindProperty("MinValue");
_MaxValue = serializedObject.FindProperty("MaxValue");
_Duration = serializedObject.FindProperty("Duration");
_PingPongPauseDuration = serializedObject.FindProperty("PingPongPauseDuration");
_Amplitude = serializedObject.FindProperty("Amplitude");
_Frequency = serializedObject.FindProperty("Frequency");
_Shift = serializedObject.FindProperty("Shift");
_RemapNoiseValues = serializedObject.FindProperty("RemapNoiseValues");
_RemapNoiseZero = serializedObject.FindProperty("RemapNoiseZero");
_RemapNoiseOne = serializedObject.FindProperty("RemapNoiseOne");
_OneTimeDuration = serializedObject.FindProperty("OneTimeDuration");
_OneTimeAmplitude = serializedObject.FindProperty("OneTimeAmplitude");
_OneTimeRemapMin = serializedObject.FindProperty("OneTimeRemapMin");
_OneTimeRemapMax = serializedObject.FindProperty("OneTimeRemapMax");
_OneTimeCurve = serializedObject.FindProperty("OneTimeCurve");
_DisableAfterOneTime = serializedObject.FindProperty("DisableAfterOneTime");
_DisableGameObjectAfterOneTime = serializedObject.FindProperty("DisableGameObjectAfterOneTime");
_OneTimeButton = serializedObject.FindProperty("OneTimeButton");
_AudioAnalyzer = serializedObject.FindProperty("AudioAnalyzer");
_BeatID = serializedObject.FindProperty("BeatID");
_AudioAnalyzerMultiplier = serializedObject.FindProperty("AudioAnalyzerMultiplier");
_AudioAnalyzerOffset = serializedObject.FindProperty("AudioAnalyzerOffset");
_AudioAnalyzerLerp = serializedObject.FindProperty("AudioAnalyzerLerp");
_ToDestinationValue = serializedObject.FindProperty("ToDestinationValue");
_ToDestinationDuration = serializedObject.FindProperty("ToDestinationDuration");
_ToDestinationCurve = serializedObject.FindProperty("ToDestinationCurve");
_DisableAfterToDestination = serializedObject.FindProperty("DisableAfterToDestination");
_ToDestinationButton = serializedObject.FindProperty("ToDestinationButton");
_InitialValue = serializedObject.FindProperty("InitialValue");
_CurrentValue = serializedObject.FindProperty("CurrentValue");
_CurrentValueNormalized = serializedObject.FindProperty("CurrentValueNormalized");
_InitialColor = serializedObject.FindProperty("InitialColor");
_ColorMode = serializedObject.FindProperty("ColorMode");
_ColorRamp = serializedObject.FindProperty("ColorRamp");
_PropertyID = serializedObject.FindProperty("PropertyID");
_PropertyFound = serializedObject.FindProperty("PropertyFound");
_TargetMaterial = serializedObject.FindProperty("TargetMaterial");
_DrivenLevel = serializedObject.FindProperty("DrivenLevel");
_FromColor = serializedObject.FindProperty("FromColor");
_ToColor = serializedObject.FindProperty("ToColor");
_LoopCurve = serializedObject.FindProperty("LoopCurve");
_LoopStartValue = serializedObject.FindProperty("LoopStartValue");
_LoopEndValue = serializedObject.FindProperty("LoopEndValue");
_LoopDuration = serializedObject.FindProperty("LoopDuration");
_LoopPauseDuration = serializedObject.FindProperty("LoopPauseDuration");
_SpriteRendererTextureProperty = serializedObject.FindProperty("SpriteRendererTextureProperty");
}
/// <summary>
/// Draws a conditional inspector
/// </summary>
public override void OnInspectorGUI()
{
serializedObject.Update();
Undo.RecordObject(target, "Modified ShaderController");
ShaderController myTarget = (ShaderController)target;
Editor.DrawPropertiesExcluding(serializedObject, new string[] { "m_Script", "Curve", "MinValue", "MaxValue", "Duration", "PingPongPauseDuration",
"Amplitude", "Frequency", "Shift", "OneTimeDuration", "OneTimeAmplitude", "OneTimeRemapMin",
"OneTimeRemapMax", "OneTimeCurve", "DisableAfterOneTime", "DisableGameObjectAfterOneTime", "OneTimeButton", "AudioAnalyzer",
"BeatID", "AudioAnalyzerMultiplier", "AudioAnalyzerOffset",
"AudioAnalyzerLerp", "ToDestinationValue", "RemapNoiseValues","RemapNoiseZero","RemapNoiseOne", "ColorMode", "ColorRamp",
"ToDestinationDuration", "ToDestinationCurve", "DisableAfterToDestination", "ToDestinationButton", "DrivenLevel", "FromColor", "ToColor",
"LoopCurve", "LoopStartValue", "LoopEndValue", "LoopDuration", "LoopPauseDuration",
"InitialValue","CurrentValue", "CurrentValueNormalized","InitialColor","PropertyID","PropertyFound","TargetMaterial"});
if (myTarget.PropertyType == ShaderController.PropertyTypes.Color)
{
EditorGUILayout.PropertyField(_ColorMode);
if (myTarget.ColorMode == ShaderController.ColorModes.TwoColors)
{
if (myTarget.ControlMode != ShaderController.ControlModes.ToDestination)
{
EditorGUILayout.PropertyField(_FromColor);
}
EditorGUILayout.PropertyField(_ToColor);
}
else
{
EditorGUILayout.PropertyField(_ColorRamp);
}
}
if (myTarget.ControlMode == ShaderController.ControlModes.PingPong)
{
EditorGUILayout.PropertyField(_Curve);
EditorGUILayout.PropertyField(_MinValue);
EditorGUILayout.PropertyField(_MaxValue);
EditorGUILayout.PropertyField(_Duration);
EditorGUILayout.PropertyField(_PingPongPauseDuration);
}
if (myTarget.ControlMode == ShaderController.ControlModes.Loop)
{
EditorGUILayout.PropertyField(_LoopCurve);
EditorGUILayout.PropertyField(_LoopStartValue);
EditorGUILayout.PropertyField(_LoopEndValue);
EditorGUILayout.PropertyField(_LoopDuration);
EditorGUILayout.PropertyField(_LoopPauseDuration);
}
else if (myTarget.ControlMode == ShaderController.ControlModes.Random)
{
EditorGUILayout.PropertyField(_Amplitude);
EditorGUILayout.PropertyField(_Frequency);
EditorGUILayout.PropertyField(_Shift);
EditorGUILayout.PropertyField(_RemapNoiseValues);
EditorGUILayout.PropertyField(_RemapNoiseZero);
EditorGUILayout.PropertyField(_RemapNoiseOne);
}
else if (myTarget.ControlMode == ShaderController.ControlModes.OneTime)
{
EditorGUILayout.PropertyField(_OneTimeDuration);
EditorGUILayout.PropertyField(_OneTimeAmplitude);
EditorGUILayout.PropertyField(_OneTimeRemapMin);
EditorGUILayout.PropertyField(_OneTimeRemapMax);
EditorGUILayout.PropertyField(_OneTimeCurve);
EditorGUILayout.PropertyField(_DisableAfterOneTime);
EditorGUILayout.PropertyField(_DisableGameObjectAfterOneTime);
EditorGUILayout.PropertyField(_OneTimeButton);
}
else if (myTarget.ControlMode == ShaderController.ControlModes.AudioAnalyzer)
{
EditorGUILayout.PropertyField(_AudioAnalyzer);
EditorGUILayout.PropertyField(_BeatID);
EditorGUILayout.PropertyField(_AudioAnalyzerMultiplier);
EditorGUILayout.PropertyField(_AudioAnalyzerOffset);
EditorGUILayout.PropertyField(_AudioAnalyzerLerp);
}
else if (myTarget.ControlMode == ShaderController.ControlModes.Driven)
{
EditorGUILayout.PropertyField(_DrivenLevel);
}
else if (myTarget.ControlMode == ShaderController.ControlModes.ToDestination)
{
EditorGUILayout.PropertyField(_ToDestinationValue);
EditorGUILayout.PropertyField(_ToDestinationDuration);
EditorGUILayout.PropertyField(_ToDestinationCurve);
EditorGUILayout.PropertyField(_DisableAfterToDestination);
EditorGUILayout.PropertyField(_ToDestinationButton);
}
EditorGUILayout.PropertyField(_InitialValue);
EditorGUILayout.PropertyField(_CurrentValue);
EditorGUILayout.PropertyField(_CurrentValueNormalized);
EditorGUILayout.PropertyField(_InitialColor);
EditorGUILayout.PropertyField(_PropertyID);
EditorGUILayout.PropertyField(_PropertyFound);
EditorGUILayout.PropertyField(_TargetMaterial);
serializedObject.ApplyModifiedProperties();
if (Application.isPlaying)
{
_barRect = EditorGUILayout.GetControlRect();
DrawLevelProgressBar(_barRect, myTarget.CurrentValueNormalized, _mmYellow, _mmRed);
}
}
protected Rect _barRect;
protected Color _mmYellow = new Color(1f, 0.7686275f, 0f);
protected Color _mmRed = MMColors.Orangered;
protected const int _lineHeight = 20;
protected const int _lineMargin = 2;
protected const int _numberOfLines = 1;
protected Color _progressBarBackground = new Color(0, 0, 0, 0.5f);
protected virtual void DrawLevelProgressBar(Rect position, float level, Color frontColor, Color negativeColor)
{
Rect levelLabelRect = new Rect(position.x, position.y + (_lineHeight + _lineMargin) * (_numberOfLines - 1), position.width, _lineHeight);
Rect levelValueRect = new Rect(position.x - 15 + EditorGUIUtility.labelWidth + 4, position.y + (_lineHeight + _lineMargin) * (_numberOfLines - 1), position.width, _lineHeight);
float progressX = position.x - 5 + EditorGUIUtility.labelWidth + 60;
float progressY = position.y + (_lineHeight + _lineMargin) * (_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, _progressBarBackground);
if (negative)
{
EditorGUI.DrawRect(levelProgressFront, negativeColor);
}
else
{
EditorGUI.DrawRect(levelProgressFront, frontColor);
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1f3f8a0f0ac6c3e48adfc0e94029a3af
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

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));
for(int i = 0; i < components.Length; i++)
{
viewData._componentList.Add(components[i]);
tempComponentsNameList.Add(i + ". " + components[i].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:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6f909c63670744543afced64613357cb
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7524a33cc4881484f94d10e60833382b
timeCreated: 1434688391
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,101 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMReorderableAttributeAttribute))]
public class ReorderableDrawer : PropertyDrawer {
private static Dictionary<int, MMReorderableList> lists = new Dictionary<int, MMReorderableList>();
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
MMReorderableList list = GetList(property, attribute as MMReorderableAttributeAttribute);
return list != null ? list.GetHeight() : EditorGUIUtility.singleLineHeight;
}
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
MMReorderableList list = GetList(property, attribute as MMReorderableAttributeAttribute);
if (list != null) {
list.DoList(EditorGUI.IndentedRect(position), label);
}
else {
GUI.Label(position, "Array must extend from ReorderableArray", EditorStyles.label);
}
}
#endif
public static int GetListId(SerializedProperty property) {
if (property != null) {
int h1 = property.serializedObject.targetObject.GetHashCode();
int h2 = property.propertyPath.GetHashCode();
return (((h1 << 5) + h1) ^ h2);
}
return 0;
}
public static MMReorderableList GetList(SerializedProperty property) {
return GetList(property, null, GetListId(property));
}
public static MMReorderableList GetList(SerializedProperty property, MMReorderableAttributeAttribute attrib) {
return GetList(property, attrib, GetListId(property));
}
public static MMReorderableList GetList(SerializedProperty property, int id) {
return GetList(property, null, id);
}
public static MMReorderableList GetList(SerializedProperty property, MMReorderableAttributeAttribute attrib, int id) {
if (property == null) {
return null;
}
MMReorderableList list = null;
SerializedProperty array = property.FindPropertyRelative("array");
if (array != null && array.isArray) {
if (!lists.TryGetValue(id, out list)) {
if (attrib != null) {
Texture icon = !string.IsNullOrEmpty(attrib.elementIconPath) ? AssetDatabase.GetCachedIcon(attrib.elementIconPath) : null;
MMReorderableList.ElementDisplayType displayType = attrib.singleLine ? MMReorderableList.ElementDisplayType.SingleLine : MMReorderableList.ElementDisplayType.Auto;
list = new MMReorderableList(array, attrib.add, attrib.remove, attrib.draggable, displayType, attrib.elementNameProperty, attrib.elementNameOverride, icon);
}
else {
list = new MMReorderableList(array, true, true, true);
}
lists.Add(id, list);
}
else {
list.List = array;
}
}
return list;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3b5cb2f0917b1f34f8aceb725a71bfe7
timeCreated: 1491846866
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5e08c956b4cc7924ea038522f941bb9b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,23 @@
using UnityEngine;
using System.Collections;
using MoreMountains.Tools;
using UnityEditor;
namespace MoreMountains.Tools
{
/// <summary>
/// Adds a dedicated Tools menu into the top bar More Mountains entry to delete all saved data
/// </summary>
public static class MMSaveLoadMenu
{
[MenuItem("Tools/More Mountains/Delete all saved data",false,31)]
/// <summary>
/// Adds a menu item to reset all data saved by the MMSaveLoadManager. No turning back.
/// </summary>
private static void ResetAllSavedInventories()
{
MMSaveLoadManager.DeleteAllSaveFiles();
Debug.LogFormat ("All Save Files Deleted");
}
}
}

View File

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

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c261684060cd13546bb14fd96acb5bb7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.UIElements;
#endif
using UnityEngine;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(MMTweenType))]
public class MMTweenTypeDrawer : PropertyDrawer
{
protected const int _lineHeight = 20;
protected const int _lineMargin = 2;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return _lineHeight * 2 + _lineMargin;
}
#if UNITY_EDITOR
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
var type = property.FindPropertyRelative("MMTweenDefinitionType");
EditorGUI.BeginProperty(position, label, property);
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
var definitionTypeRect = new Rect(position.x, position.y, position.width, _lineHeight);
var curveRect = new Rect(position.x, position.y + _lineHeight + _lineMargin, position.width, _lineHeight);
EditorGUI.PropertyField(definitionTypeRect, property.FindPropertyRelative("MMTweenDefinitionType"), GUIContent.none);
if (type.enumValueIndex == 0)
{
EditorGUI.PropertyField(curveRect, property.FindPropertyRelative("MMTweenCurve"), GUIContent.none);
}
if (type.enumValueIndex == 1)
{
EditorGUI.PropertyField(curveRect, property.FindPropertyRelative("Curve"), GUIContent.none);
}
EditorGUI.EndProperty();
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,16 @@
{
"name": "MoreMountains.Tools.Editor",
"references": [
"GUID:4a1cb1490dc4df8409b2580d6b44e75e"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d9dbf313afb206f458581847ac758375
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 35da110902fbc43f79f283baf2a738c6
folderAsset: yes
timeCreated: 1459528287
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,26 @@
using UnityEngine;
namespace MoreMountains.Tools
{
public enum MMBackgroundAttributeColor
{
Red,
Pink,
Orange,
Yellow,
Green,
Blue,
Violet,
White
}
public class MMBackgroundColorAttribute : PropertyAttribute
{
public MMBackgroundAttributeColor Color;
public MMBackgroundColorAttribute(MMBackgroundAttributeColor color = MMBackgroundAttributeColor.Yellow)
{
this.Color = color;
}
}
}

View File

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

View File

@@ -0,0 +1,14 @@
using UnityEngine;
namespace MoreMountains.Tools
{
public class MMColorAttribute : PropertyAttribute
{
public Color color;
public MMColorAttribute(float red = 1, float green = 0, float blue = 0)
{
this.color = new Color(red, green, blue, 1);
}
}
}

View File

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

View File

@@ -0,0 +1,37 @@
using UnityEngine;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct, Inherited = true)]
public class MMConditionAttribute : PropertyAttribute
{
public string ConditionBoolean = "";
public bool Hidden = false;
public bool Negative = false;
public MMConditionAttribute(string conditionBoolean)
{
this.ConditionBoolean = conditionBoolean;
this.Hidden = false;
}
public MMConditionAttribute(string conditionBoolean, bool hideInInspector)
{
this.ConditionBoolean = conditionBoolean;
this.Hidden = hideInInspector;
this.Negative = false;
}
public MMConditionAttribute(string conditionBoolean, bool hideInInspector, bool negative)
{
this.ConditionBoolean = conditionBoolean;
this.Hidden = hideInInspector;
this.Negative = negative;
}
}
}

View File

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

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// An attribute to add to static methods to they can be called via the MMDebugMenu's command line
/// </summary>
[AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false)]
public class MMDebugLogCommandArgumentCountAttribute : System.Attribute
{
public readonly int ArgumentCount;
public MMDebugLogCommandArgumentCountAttribute(int argumentCount)
{
this.ArgumentCount = argumentCount;
}
}
}

View File

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

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// An attribute to add to static methods to they can be called via the MMDebugMenu's command line
/// </summary>
[AttributeUsage(System.AttributeTargets.Method, AllowMultiple = false)]
public class MMDebugLogCommandAttribute : System.Attribute { }
}

View File

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

View File

@@ -0,0 +1,16 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
public class MMDropdownAttribute : PropertyAttribute
{
public readonly object[] DropdownValues;
public MMDropdownAttribute(params object[] dropdownValues)
{
DropdownValues = dropdownValues;
}
}
}

View File

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

View File

@@ -0,0 +1,37 @@
using UnityEngine;
using System.Collections;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
/// <summary>
/// An attribute to conditionnally hide fields based on the current selection in an enum.
/// Usage : [MMEnumCondition("rotationMode", (int)RotationMode.LookAtTarget, (int)RotationMode.RotateToAngles)]
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct, Inherited = true)]
public class MMEnumConditionAttribute : PropertyAttribute
{
public string ConditionEnum = "";
public bool Hidden = false;
BitArray bitArray = new BitArray(32);
public bool ContainsBitFlag(int enumValue)
{
return bitArray.Get(enumValue);
}
public MMEnumConditionAttribute(string conditionBoolean, params int[] enumValues)
{
this.ConditionEnum = conditionBoolean;
this.Hidden = true;
for (int i = 0; i < enumValues.Length; i++)
{
bitArray.Set(enumValues[i], true);
}
}
}
}

View File

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

View File

@@ -0,0 +1,157 @@
using UnityEngine;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
/// <summary>
/// Add this attribute to a class and its Execution Order will be changed to the value specified in parameters
/// Usage : [ExecutionOrder(66)]
/// </summary>
public class MMExecutionOrderAttribute : Attribute
{
#if UNITY_EDITOR
/// the execution order you want for the class this attribute is applied to
public int ExecutionOrder = 0;
protected static Dictionary<MonoScript, MMExecutionOrderAttribute> _monoScripts;
protected static Type _executionOrderAttributeType;
protected static Assembly _typeAssembly;
protected static Type[] _assemblyTypes;
/// <summary>
/// Attribute method
/// </summary>
/// <param name="newExecutionOrder"></param>
public MMExecutionOrderAttribute(int newExecutionOrder)
{
ExecutionOrder = newExecutionOrder;
}
/// <summary>
/// When Unity loads, modifies the execution orders of monos with an ExecutionOrder attribute, if needed
/// </summary>
[InitializeOnLoadMethod]
protected static void ModifyExecutionOrder()
{
Initialization();
FindExecutionOrderAttributes();
if (ExecutionOrderHasChanged())
{
UpdateExecutionOrders();
}
}
/// <summary>
/// Initialization method
/// </summary>
protected static void Initialization()
{
_monoScripts = new Dictionary<MonoScript, MMExecutionOrderAttribute>();
_executionOrderAttributeType = typeof(MMExecutionOrderAttribute);
_typeAssembly = _executionOrderAttributeType.Assembly;
_assemblyTypes = _typeAssembly.GetTypes();
}
/// <summary>
/// Goes through all assembly types and stores execution order attributes when found
/// </summary>
protected static void FindExecutionOrderAttributes()
{
foreach (Type assemblyType in _assemblyTypes)
{
if (!HasExecutionOrderAttribute(assemblyType))
{
continue;
}
object[] attributes = assemblyType.GetCustomAttributes(_executionOrderAttributeType, false);
MMExecutionOrderAttribute attribute = attributes[0] as MMExecutionOrderAttribute;
string asset = "";
string[] guids = AssetDatabase.FindAssets(assemblyType.Name + " t:script");
if (guids.Length != 0)
{
foreach (string guid in guids)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
string filename = Path.GetFileNameWithoutExtension(assetPath);
if (filename == assemblyType.Name)
{
asset = guid;
break;
}
}
}
else
{
Debug.LogError("MMTools' ExecutionOrderAttribute : Can't change "+ assemblyType.Name + "'s execution order");
return;
}
MonoScript monoScript = AssetDatabase.LoadAssetAtPath<MonoScript>(AssetDatabase.GUIDToAssetPath(asset));
_monoScripts.Add(monoScript, attribute);
}
}
/// <summary>
/// Returns true if the class in parameters has the ExecutionOrder attribute, false otherwise
/// </summary>
/// <param name="assemblyType"></param>
/// <returns></returns>
protected static bool HasExecutionOrderAttribute(Type assemblyType)
{
object[] attributes = assemblyType.GetCustomAttributes(_executionOrderAttributeType, false);
return (attributes.Length == 1);
}
/// <summary>
/// Returns true if the execution order has changed since last time
/// </summary>
/// <returns></returns>
protected static bool ExecutionOrderHasChanged()
{
bool executionOrderHasChanged = false;
foreach (KeyValuePair<MonoScript, MMExecutionOrderAttribute> monoScript in _monoScripts)
{
if (monoScript.Key != null)
{
if (MonoImporter.GetExecutionOrder(monoScript.Key) != monoScript.Value.ExecutionOrder)
{
executionOrderHasChanged = true;
break;
}
}
}
return executionOrderHasChanged;
}
/// <summary>
/// Updates the execution orders for all pairs found by FindExecutionOrderAttributes()
/// </summary>
protected static void UpdateExecutionOrders()
{
foreach (KeyValuePair<MonoScript, MMExecutionOrderAttribute> monoScript in _monoScripts)
{
if (monoScript.Key != null)
{
if (MonoImporter.GetExecutionOrder(monoScript.Key) != monoScript.Value.ExecutionOrder)
{
MonoImporter.SetExecutionOrder(monoScript.Key, monoScript.Value.ExecutionOrder);
}
}
}
}
#endif
}
}

View File

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

View File

@@ -0,0 +1,9 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
public class MMHiddenAttribute : PropertyAttribute { }
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 171bddfe1b8d24a049ab93c4b4d2323d
timeCreated: 1456675987
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class MMHiddenPropertiesAttribute : Attribute
{
public string[] PropertiesNames;
public MMHiddenPropertiesAttribute(params string[] propertiesNames)
{
PropertiesNames = propertiesNames;
}
}
}

View File

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

View File

@@ -0,0 +1,34 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace MoreMountains.Tools
{
public class MMInformationAttribute : PropertyAttribute
{
public enum InformationType { Error, Info, None, Warning }
#if UNITY_EDITOR
public string Message;
public MessageType Type;
public bool MessageAfterProperty;
public MMInformationAttribute(string message, InformationType type, bool messageAfterProperty)
{
this.Message = message;
if (type==InformationType.Error) { this.Type = UnityEditor.MessageType.Error;}
if (type==InformationType.Info) { this.Type = UnityEditor.MessageType.Info;}
if (type==InformationType.Warning) { this.Type = UnityEditor.MessageType.Warning;}
if (type==InformationType.None) { this.Type = UnityEditor.MessageType.None;}
this.MessageAfterProperty = messageAfterProperty;
}
#else
public MMInformationAttribute(string message, InformationType type, bool messageAfterProperty)
{
}
#endif
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: a083e52b3b6964a0d88af5b74900af5e
timeCreated: 1459528299
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System.Reflection;
namespace MoreMountains.Tools
{
[System.AttributeUsage(System.AttributeTargets.Field)]
public class MMInspectorButtonAttribute : PropertyAttribute
{
public readonly string MethodName;
public MMInspectorButtonAttribute(string MethodName)
{
this.MethodName = MethodName;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(MMInspectorButtonAttribute))]
public class InspectorButtonPropertyDrawer : PropertyDrawer
{
private MethodInfo _eventMethodInfo = null;
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
{
MMInspectorButtonAttribute inspectorButtonAttribute = (MMInspectorButtonAttribute)attribute;
float buttonLength = position.width;
Rect buttonRect = new Rect(position.x, position.y, buttonLength, position.height);
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
if (GUI.Button(buttonRect, inspectorButtonAttribute.MethodName))
{
System.Type eventOwnerType = prop.serializedObject.targetObject.GetType();
string eventName = inspectorButtonAttribute.MethodName;
if (_eventMethodInfo == null)
{
_eventMethodInfo = eventOwnerType.GetMethod(eventName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_eventMethodInfo != null)
{
_eventMethodInfo.Invoke(prop.serializedObject.targetObject, null);
}
else
{
Debug.LogWarning(string.Format("InspectorButton: Unable to find method {0} in {1}", eventName, eventOwnerType));
}
}
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 325b5ef7494cead4fbd33a7e9c22c44d
timeCreated: 1490625668
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor.UIElements;
using UnityEditor;
#endif
using System.Reflection;
using UnityEngine.UIElements;
namespace MoreMountains.Tools
{
[System.AttributeUsage(System.AttributeTargets.Field)]
public class MMInspectorButtonBarAttribute : PropertyAttribute
{
public string[] Labels { get; set; }
public string[] Methods{ get; set; }
public bool[] OnlyWhenPlaying{ get; set; }
public string[] UssClass{ get; set; }
public MMInspectorButtonBarAttribute(string[] labels, string[] methods, bool[] onlyWhenPlaying, string[] ussClass)
{
this.Labels = labels;
this.Methods = methods;
this.OnlyWhenPlaying = onlyWhenPlaying;
this.UssClass = ussClass;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(MMInspectorButtonBarAttribute))]
public class MMInspectorButtonBarPropertyDrawer : PropertyDrawer
{
private MethodInfo[] _eventMethodInfos = null;
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
MMInspectorButtonBarAttribute inspectorButtonBarAttribute = (MMInspectorButtonBarAttribute)attribute;
System.Type eventOwnerType = property.serializedObject.targetObject.GetType();
// add our root
var root = new VisualElement();
// add toolbar
Toolbar moveToControls = new Toolbar();
moveToControls.AddToClassList("mm-toolbar");
if (_eventMethodInfos == null)
{
_eventMethodInfos = new MethodInfo[inspectorButtonBarAttribute.Methods.Length];
}
// add each button
for (var i = 0; i < inspectorButtonBarAttribute.Labels.Length; i++)
{
var newButton = new ToolbarButton();
newButton.text = inspectorButtonBarAttribute.Labels[i];
newButton.style.flexGrow = 1;
if (inspectorButtonBarAttribute.UssClass[i] != "")
{
newButton.AddToClassList(inspectorButtonBarAttribute.UssClass[i]);
}
if (_eventMethodInfos[i] == null)
{
_eventMethodInfos[i] = eventOwnerType.GetMethod(inspectorButtonBarAttribute.Methods[i], BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_eventMethodInfos[i] != null)
{
var i1 = i;
newButton.clicked += () => _eventMethodInfos[i1].Invoke(property.serializedObject.targetObject, null);
}
else
{
Debug.LogWarning(string.Format("InspectorButton: Unable to find method {0} in {1}", inspectorButtonBarAttribute.Methods[i], eventOwnerType));
}
if (inspectorButtonBarAttribute.OnlyWhenPlaying[i] && !Application.isPlaying)
{
newButton.SetEnabled(false);
}
moveToControls.Add(newButton);
}
root.Add(moveToControls);
return root;
/*
if (GUI.Button(buttonRect, inspectorButtonBarAttribute.MethodName))
{
System.Type eventOwnerType = prop.serializedObject.targetObject.GetType();
string eventName = inspectorButtonBarAttribute.MethodName;
if (_eventMethodInfo == null)
{
_eventMethodInfo = eventOwnerType.GetMethod(eventName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
}
if (_eventMethodInfo != null)
{
_eventMethodInfo.Invoke(prop.serializedObject.targetObject, null);
}
else
{
Debug.LogWarning(string.Format("InspectorButton: Unable to find method {0} in {1}", eventName, eventOwnerType));
}
}*/
}
}
#endif
}

View File

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

View File

@@ -0,0 +1,28 @@
using System;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// An attribute used to group inspector fields under common dropdowns
/// Implementation inspired by Rodrigo Prinheiro's work, available at https://github.com/RodrigoPrinheiro/unityFoldoutAttribute
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct, Inherited = true)]
public class MMInspectorGroupAttribute : PropertyAttribute
{
public string GroupName;
public bool GroupAllFieldsUntilNextGroupAttribute;
public int GroupColorIndex;
public bool ClosedByDefault;
public MMInspectorGroupAttribute(string groupName, bool groupAllFieldsUntilNextGroupAttribute = false, int groupColorIndex = 24, bool closedByDefault = false)
{
if (groupColorIndex > 139) { groupColorIndex = 139; }
this.GroupName = groupName;
this.GroupAllFieldsUntilNextGroupAttribute = groupAllFieldsUntilNextGroupAttribute;
this.GroupColorIndex = groupColorIndex;
this.ClosedByDefault = closedByDefault;
}
}
}

View File

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

View File

@@ -0,0 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MoreMountains.Tools
{
public class MMMonoBehaviour : MonoBehaviour
{
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More