Insanely huge initial commit

This commit is contained in:
2026-02-21 17:04:05 -08:00
parent 9cdd36191a
commit 613d75914a
22525 changed files with 4035207 additions and 0 deletions

View File

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

View File

@@ -0,0 +1,84 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(AIAction))]
public class AIActionPropertyInspector : PropertyDrawer
{
const float LineHeight = 16f;
#if UNITY_EDITOR
/// <summary>
/// Draws
/// </summary>
/// <param name="rect"></param>
/// <param name="prop"></param>
/// <param name="label"></param>
public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label)
{
// determines the height of the Action property
var height = Mathf.Max(LineHeight, EditorGUI.GetPropertyHeight(prop));
Rect position = rect;
position.height = height;
// draws the dropdown
DrawSelectionDropdown(position, prop);
// draws the base field
position.y += height;
EditorGUI.PropertyField(position, prop);
}
#endif
/// <summary>
/// Draws a selector letting the user pick any action associated with the AIBrain this action is on
/// </summary>
/// <param name="position"></param>
/// <param name="prop"></param>
protected virtual void DrawSelectionDropdown(Rect position, SerializedProperty prop)
{
AIAction thisAction = prop.objectReferenceValue as AIAction;
AIAction[] actions = (prop.serializedObject.targetObject as AIBrain).GetAttachedActions();
int selected = 0;
int i = 1;
string[] options = new string[actions.Length + 1];
options[0] = "None";
foreach (AIAction action in actions)
{
string name = string.IsNullOrEmpty(action.Label) ? action.GetType().Name : action.Label;
options[i] = i.ToString() + " - " + name;
if (action == thisAction)
{
selected = i;
}
i++;
}
EditorGUI.BeginChangeCheck();
selected = EditorGUI.Popup(position, selected, options);
if (EditorGUI.EndChangeCheck())
{
prop.objectReferenceValue = (selected == 0) ? null : actions[selected - 1];
prop.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(prop.serializedObject.targetObject);
}
}
/// <summary>
/// Returns the height of the full property
/// </summary>
/// <param name="property"></param>
/// <param name="label"></param>
/// <returns></returns>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
var h = Mathf.Max(LineHeight, EditorGUI.GetPropertyHeight(property));
float height = h * 2; // 2 lines, one for the dropdown, one for the property field
return height;
}
}
}

View File

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

View File

@@ -0,0 +1,74 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
[CanEditMultipleObjects]
[CustomEditor(typeof(AIBrain))]
public class AIBrainEditor : Editor
{
protected MMReorderableList _list;
protected SerializedProperty _brainActive;
protected SerializedProperty _resetBrainOnEnable;
protected SerializedProperty _resetBrainOnStart;
protected SerializedProperty _timeInThisState;
protected SerializedProperty _target;
protected SerializedProperty _owner;
protected SerializedProperty _actionsFrequency;
protected SerializedProperty _decisionFrequency;
protected SerializedProperty _randomizeFrequencies;
protected SerializedProperty _randomActionFrequency;
protected SerializedProperty _randomDecisionFrequency;
protected virtual void OnEnable()
{
_list = new MMReorderableList(serializedObject.FindProperty("States"));
_list.elementNameProperty = "States";
_list.elementDisplayType = MMReorderableList.ElementDisplayType.Expandable;
_brainActive = serializedObject.FindProperty("BrainActive");
_resetBrainOnEnable = serializedObject.FindProperty("ResetBrainOnEnable");
_resetBrainOnStart = serializedObject.FindProperty("ResetBrainOnStart");
_timeInThisState = serializedObject.FindProperty("TimeInThisState");
_target = serializedObject.FindProperty("Target");
_owner = serializedObject.FindProperty("Owner");
_actionsFrequency = serializedObject.FindProperty("ActionsFrequency");
_decisionFrequency = serializedObject.FindProperty("DecisionFrequency");
_randomizeFrequencies = serializedObject.FindProperty("RandomizeFrequencies");
_randomActionFrequency = serializedObject.FindProperty("RandomActionFrequency");
_randomDecisionFrequency = serializedObject.FindProperty("RandomDecisionFrequency");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
_list.DoLayoutList();
EditorGUILayout.PropertyField(_timeInThisState);
EditorGUILayout.PropertyField(_owner);
EditorGUILayout.PropertyField(_target);
EditorGUILayout.PropertyField(_brainActive);
EditorGUILayout.PropertyField(_resetBrainOnEnable);
EditorGUILayout.PropertyField(_resetBrainOnStart);
EditorGUILayout.PropertyField(_actionsFrequency);
EditorGUILayout.PropertyField(_decisionFrequency);
EditorGUILayout.PropertyField(_randomizeFrequencies);
if (_randomizeFrequencies.boolValue)
{
EditorGUILayout.PropertyField(_randomActionFrequency);
EditorGUILayout.PropertyField(_randomDecisionFrequency);
}
serializedObject.ApplyModifiedProperties();
AIBrain brain = (AIBrain)target;
if (brain.CurrentState != null)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Current State", brain.CurrentState.StateName);
}
}
}
}

View File

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

View File

@@ -0,0 +1,126 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace MoreMountains.Tools
{
[CustomPropertyDrawer(typeof(AITransition))]
public class AITransitionPropertyInspector : PropertyDrawer
{
const float LineHeight = 16f;
#if UNITY_EDITOR
/// <summary>
/// Draws a Transition inspector, a transition is one or more action(s), one or more decision(s) and associated true/false states
/// </summary>
/// <param name="rect"></param>
/// <param name="prop"></param>
/// <param name="label"></param>
public override void OnGUI(Rect rect, SerializedProperty prop, GUIContent label)
{
Rect position = rect;
foreach (SerializedProperty a in prop)
{
var height = Mathf.Max(LineHeight, EditorGUI.GetPropertyHeight(a));
position.height = height;
if(a.name == "Decision")
{
// draw the decision dropdown
DrawSelectionDropdown(position, prop);
// draw the base decision field
position.y += height;
EditorGUI.PropertyField(position, a, new GUIContent(a.name));
position.y += height;
/*var @object = a.objectReferenceValue;
AIDecision @typedObject = @object as AIDecision;
if (@typedObject != null && !string.IsNullOrEmpty(@typedObject.Label))
{
EditorGUI.LabelField(position, "Label", @typedObject.Label);
position.y += height;
}
else
{
EditorGUIUtility.GetControlID(FocusType.Passive);
}*/
}
else
{
EditorGUI.PropertyField(position, a, new GUIContent(a.name));
position.y += height;
}
}
}
#endif
/// <summary>
/// Draws a selector letting the user pick any decision associated with the AIBrain this transition is on
/// </summary>
/// <param name="position"></param>
/// <param name="prop"></param>
protected virtual void DrawSelectionDropdown(Rect position, SerializedProperty prop)
{
AIDecision thisDecision = prop.objectReferenceValue as AIDecision;
AIDecision[] decisions = (prop.serializedObject.targetObject as AIBrain).GetAttachedDecisions();
int selected = 0;
int i = 1;
string[] options = new string[decisions.Length + 1];
options[0] = "None";
foreach (AIDecision decision in decisions)
{
string name = string.IsNullOrEmpty(decision.Label) ? decision.GetType().Name : decision.Label;
options[i] = i.ToString() + " - " + name;
if (decision == thisDecision)
{
selected = i;
}
i++;
}
EditorGUI.BeginChangeCheck();
selected = EditorGUI.Popup(position, selected, options);
if (EditorGUI.EndChangeCheck())
{
prop.objectReferenceValue = (selected == 0) ? null : decisions[selected - 1];
prop.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(prop.serializedObject.targetObject);
}
}
/// <summary>
/// Determines the height of the transition property
/// </summary>
/// <param name="property"></param>
/// <param name="label"></param>
/// <returns></returns>
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
float height = 0;
foreach (SerializedProperty a in property)
{
var h = Mathf.Max(LineHeight, EditorGUI.GetPropertyHeight(a));
if(a.name == "Decision")
{
height += h * 2;
/*var @object = a.objectReferenceValue;
AIDecision @typedObject = @object as AIDecision;
if (@typedObject != null && !string.IsNullOrEmpty(@typedObject.Label))
{
height += h;
}*/
}
else
{
height += h;
}
}
return height;
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,30 @@
using UnityEngine;
using System.Collections;
using MoreMountains.Tools;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
[CustomEditor(typeof(MMAchievementList),true)]
/// <summary>
/// Custom inspector for the MMAchievementList scriptable object.
/// </summary>
public class MMAchievementListInspector : Editor
{
/// <summary>
/// When drawing the GUI, adds a "Reset Achievements" button, that does exactly what you think it does.
/// </summary>
public override void OnInspectorGUI()
{
DrawDefaultInspector ();
MMAchievementList achievementList = (MMAchievementList)target;
if(GUILayout.Button("Reset Achievements"))
{
achievementList.ResetAchievements();
}
EditorUtility.SetDirty (achievementList);
}
}
}

View File

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

View File

@@ -0,0 +1,19 @@
using UnityEngine;
using System.Collections;
using MoreMountains.Tools;
using UnityEditor;
namespace MoreMountains.Tools
{
public static class MMAchievementMenu
{
[MenuItem("Tools/More Mountains/Reset all achievements", false,21)]
/// <summary>
/// Adds a menu item to enable help
/// </summary>
private static void EnableHelpInInspectors()
{
MMAchievementManager.ResetAllAchievements ();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,108 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
[CustomEditor(typeof(MMTriggerAndCollision), true)]
[CanEditMultipleObjects]
public class MMTriggerAndCollisionEditor : Editor
{
protected SerializedProperty _CollisionLayerMask;
protected SerializedProperty _OnCollisionEnterEvent;
protected SerializedProperty _OnCollisionExitEvent;
protected SerializedProperty _OnCollisionStayEvent;
protected SerializedProperty _TriggerLayerMask;
protected SerializedProperty _OnTriggerEnterEvent;
protected SerializedProperty _OnTriggerExitEvent;
protected SerializedProperty _OnTriggerStayEvent;
protected SerializedProperty _Collision2DLayerMask;
protected SerializedProperty _OnCollision2DEnterEvent;
protected SerializedProperty _OnCollision2DExitEvent;
protected SerializedProperty _OnCollision2DStayEvent;
protected SerializedProperty _Trigger2DLayerMask;
protected SerializedProperty _OnTrigger2DEnterEvent;
protected SerializedProperty _OnTrigger2DExitEvent;
protected SerializedProperty _OnTrigger2DStayEvent;
protected bool OnCollision;
protected bool OnTrigger;
protected bool OnCollision2D;
protected bool OnTrigger2D;
protected virtual void OnEnable()
{
_CollisionLayerMask = serializedObject.FindProperty("CollisionLayerMask");
_OnCollisionEnterEvent = serializedObject.FindProperty("OnCollisionEnterEvent");
_OnCollisionExitEvent = serializedObject.FindProperty("OnCollisionExitEvent");
_OnCollisionStayEvent = serializedObject.FindProperty("OnCollisionStayEvent");
_TriggerLayerMask = serializedObject.FindProperty("TriggerLayerMask");
_OnTriggerEnterEvent = serializedObject.FindProperty("OnTriggerEnterEvent");
_OnTriggerExitEvent = serializedObject.FindProperty("OnTriggerExitEvent");
_OnTriggerStayEvent = serializedObject.FindProperty("OnTriggerStayEvent");
_Collision2DLayerMask = serializedObject.FindProperty("Collision2DLayerMask");
_OnCollision2DEnterEvent = serializedObject.FindProperty("OnCollision2DEnterEvent");
_OnCollision2DExitEvent = serializedObject.FindProperty("OnCollision2DExitEvent");
_OnCollision2DStayEvent = serializedObject.FindProperty("OnCollision2DStayEvent");
_Trigger2DLayerMask = serializedObject.FindProperty("Trigger2DLayerMask");
_OnTrigger2DEnterEvent = serializedObject.FindProperty("OnTrigger2DEnterEvent");
_OnTrigger2DExitEvent = serializedObject.FindProperty("OnTrigger2DExitEvent");
_OnTrigger2DStayEvent = serializedObject.FindProperty("OnTrigger2DStayEvent");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
Undo.RecordObject(target, "Modified MMTriggerAndCollision");
OnCollision = EditorGUILayout.Foldout(OnCollision, "OnCollision");
if (OnCollision)
{
EditorGUILayout.PropertyField(_CollisionLayerMask);
EditorGUILayout.PropertyField(_OnCollisionEnterEvent);
EditorGUILayout.PropertyField(_OnCollisionExitEvent);
EditorGUILayout.PropertyField(_OnCollisionStayEvent);
}
OnTrigger = EditorGUILayout.Foldout(OnTrigger, "OnTrigger");
if (OnTrigger)
{
EditorGUILayout.PropertyField(_TriggerLayerMask);
EditorGUILayout.PropertyField(_OnTriggerEnterEvent);
EditorGUILayout.PropertyField(_OnTriggerExitEvent);
EditorGUILayout.PropertyField(_OnTriggerStayEvent);
}
OnCollision2D = EditorGUILayout.Foldout(OnCollision2D, "OnCollision2D");
if (OnCollision2D)
{
EditorGUILayout.PropertyField(_Collision2DLayerMask);
EditorGUILayout.PropertyField(_OnCollision2DEnterEvent);
EditorGUILayout.PropertyField(_OnCollision2DExitEvent);
EditorGUILayout.PropertyField(_OnCollision2DStayEvent);
}
OnTrigger2D = EditorGUILayout.Foldout(OnTrigger2D, "OnTrigger2D");
if (OnTrigger2D)
{
EditorGUILayout.PropertyField(_Trigger2DLayerMask);
EditorGUILayout.PropertyField(_OnTrigger2DEnterEvent);
EditorGUILayout.PropertyField(_OnTrigger2DExitEvent);
EditorGUILayout.PropertyField(_OnTrigger2DStayEvent);
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 58ec23fbdf517a348851de2bb297888e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
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,71 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
#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,26 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
#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,64 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
#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;
GUI.enabled = enabled;
if (!conditionAttribute.Hidden || enabled)
{
EditorGUI.PropertyField(position, property, label, true);
}
GUI.enabled = previouslyEnabled;
}
#endif
private bool GetConditionAttributeResult(MMConditionAttribute condHAtt, SerializedProperty property)
{
bool enabled = true;
string propertyPath = property.propertyPath;
string conditionPath = propertyPath.Replace(property.name, condHAtt.ConditionBoolean);
SerializedProperty sourcePropertyValue = property.serializedObject.FindProperty(conditionPath);
if (sourcePropertyValue != null)
{
enabled = sourcePropertyValue.boolValue;
}
else
{
Debug.LogWarning("No matching boolean found for ConditionAttribute in object: " + condHAtt.ConditionBoolean);
}
return enabled;
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
MMConditionAttribute conditionAttribute = (MMConditionAttribute)attribute;
bool enabled = GetConditionAttributeResult(conditionAttribute, property);
if (!conditionAttribute.Hidden || enabled)
{
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,26 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
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,268 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Reflection;
using System.Linq;
using System.Collections.Generic;
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();
}
}
/// <summary>
/// A generic drawer for all MMMonoBehaviour, handles both the Group and RequiresConstantRepaint attributes
/// </summary>
[CanEditMultipleObjects]
[CustomEditor(typeof(MMMonoBehaviour), true, isFallback = true)]
public class MMMonoBehaviourDrawer : UnityEditor.Editor
{
public bool DrawerInitialized;
public List<SerializedProperty> PropertiesList = new List<SerializedProperty>();
public Dictionary<string, MMInspectorGroupData> GroupData = new Dictionary<string, MMInspectorGroupData>();
private string[] _mmHiddenPropertiesToHide;
private bool _hasMMHiddenProperties = false;
private bool _requiresConstantRepaint;
protected bool _shouldDrawBase = true;
public override bool RequiresConstantRepaint()
{
return _requiresConstantRepaint;
}
protected virtual void OnEnable()
{
DrawerInitialized = false;
if (!target || !serializedObject.targetObject)
{
return;
}
_requiresConstantRepaint = serializedObject.targetObject.GetType().GetCustomAttribute<MMRequiresConstantRepaintAttribute>() != null;
MMHiddenPropertiesAttribute[] hiddenProperties = (MMHiddenPropertiesAttribute[])target.GetType().GetCustomAttributes(typeof(MMHiddenPropertiesAttribute), false);
if (hiddenProperties != null && hiddenProperties.Length > 0 && hiddenProperties[0].PropertiesNames != null)
{
_mmHiddenPropertiesToHide = hiddenProperties[0].PropertiesNames;
_hasMMHiddenProperties = true;
}
}
protected virtual void OnDisable()
{
if (target == null)
{
return;
}
foreach (KeyValuePair<string, MMInspectorGroupData> groupData in GroupData)
{
EditorPrefs.SetBool(string.Format($"{groupData.Value.GroupAttribute.GroupName}{groupData.Value.PropertiesList[0].name}{target.GetInstanceID()}"), groupData.Value.GroupIsOpen);
groupData.Value.ClearGroup();
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
Initialization();
DrawBase();
DrawScriptBox();
DrawContainer();
DrawContents();
serializedObject.ApplyModifiedProperties();
}
protected virtual void Initialization()
{
if (DrawerInitialized)
{
return;
}
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 groupIsOpen = EditorPrefs.GetBool(string.Format($"{group.GroupName}{fieldInfoList[i].Name}{target.GetInstanceID()}"), false);
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;
}
protected virtual void DrawBase()
{
if (_shouldDrawBase)
{
DrawDefaultInspector();
return;
}
}
protected virtual void DrawScriptBox()
{
if (PropertiesList.Count == 0)
{
return;
}
using (new EditorGUI.DisabledScope("m_Script" == PropertiesList[0].propertyPath))
{
EditorGUILayout.PropertyField(PropertiesList[0], true);
}
}
protected virtual void DrawContainer()
{
if (PropertiesList.Count == 0)
{
return;
}
foreach (KeyValuePair<string, MMInspectorGroupData> pair in GroupData)
{
this.DrawVerticalLayout(() => DrawGroup(pair.Value), MMMonoBehaviourDrawerStyle.ContainerStyle);
EditorGUI.indentLevel = 0;
}
}
protected virtual void DrawContents()
{
if (PropertiesList.Count == 0)
{
return;
}
EditorGUILayout.Space();
for (int i = 1; i < PropertiesList.Count; i++)
{
if (_hasMMHiddenProperties && (!_mmHiddenPropertiesToHide.Contains(PropertiesList[i].name)))
{
EditorGUILayout.PropertyField(PropertiesList[i], true);
}
}
}
protected virtual void DrawGroup(MMInspectorGroupData groupData)
{
Rect verticalGroup = EditorGUILayout.BeginVertical();
var leftBorderRect = new Rect(verticalGroup.xMin + 5, verticalGroup.yMin - 10, 3f, verticalGroup.height + 20);
leftBorderRect.xMin = 15f;
leftBorderRect.xMax = 18f;
EditorGUI.DrawRect(leftBorderRect, groupData.GroupColor);
groupData.GroupIsOpen = EditorGUILayout.Foldout(groupData.GroupIsOpen, groupData.GroupAttribute.GroupName, true, MMMonoBehaviourDrawerStyle.GroupStyle);
if (groupData.GroupIsOpen)
{
EditorGUI.indentLevel = 0;
for (int i = 0; i < groupData.PropertiesList.Count; i++)
{
this.DrawVerticalLayout(() => DrawChild(i), MMMonoBehaviourDrawerStyle.BoxChildStyle);
}
}
EditorGUILayout.EndVertical();
void DrawChild(int i)
{
if ((_hasMMHiddenProperties) && (_mmHiddenPropertiesToHide.Contains(groupData.PropertiesList[i].name)))
{
return;
}
EditorGUILayout.PropertyField(groupData.PropertiesList[i], new GUIContent(ObjectNames.NicifyVariableName(groupData.PropertiesList[i].name), tooltip:groupData.PropertiesList[i].tooltip), 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);
}
}
}
}

View File

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

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
[InitializeOnLoad]
public static class MMMonoBehaviourDrawerHelper
{
public static void DrawButton(this Editor editor, MethodInfo methodInfo)
{
if (GUILayout.Button(methodInfo.Name))
{
methodInfo.Invoke(editor.target, null);
}
}
public static void DrawVerticalLayout(this Editor editor, Action action, GUIStyle style)
{
EditorGUILayout.BeginVertical(style);
action();
EditorGUILayout.EndVertical();
}
}
}

View File

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

View File

@@ -0,0 +1,93 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
static class MMMonoBehaviourDrawerStyle
{
public static GUIStyle ContainerStyle;
public static GUIStyle BoxChildStyle;
public static GUIStyle GroupStyle;
public static GUIStyle TextStyle;
public static bool IsProSkin = EditorGUIUtility.isProSkin;
public static Texture2D GroupClosedTriangle = Resources.Load<Texture2D>("IN foldout focus-6510");
public static Texture2D GroupOpenTriangle = Resources.Load<Texture2D>("IN foldout focus on-5718");
public static Texture2D NoTexture = new Texture2D(0, 0);
static MMMonoBehaviourDrawerStyle()
{
// TEXT STYLE --------------------------------------------------------------------------------------------------------------
TextStyle = new GUIStyle(EditorStyles.largeLabel);
TextStyle.richText = true;
TextStyle.contentOffset = new Vector2(0, 5);
//TextStyle.font = Font.CreateDynamicFontFromOSFont(new[] { "Terminus (TTF) for Windows", "Calibri" }, 14);
// GROUP STYLE --------------------------------------------------------------------------------------------------------------
GroupStyle = new GUIStyle(EditorStyles.foldout);
GroupStyle.active.background = GroupClosedTriangle;
GroupStyle.focused.background = GroupClosedTriangle;
GroupStyle.hover.background = GroupClosedTriangle;
GroupStyle.onActive.background = GroupOpenTriangle;
GroupStyle.onFocused.background = GroupOpenTriangle;
GroupStyle.onHover.background = GroupOpenTriangle;
GroupStyle.fontStyle = FontStyle.Bold;
GroupStyle.overflow = new RectOffset(100, 0, 0, 0);
GroupStyle.padding = new RectOffset(20, 0, 0, 0);
// CONTAINER STYLE --------------------------------------------------------------------------------------------------------------
ContainerStyle = new GUIStyle(GUI.skin.box);
ContainerStyle.padding = new RectOffset(20, 0, 10, 10);
// BOX CHILD STYLE --------------------------------------------------------------------------------------------------------------
BoxChildStyle = new GUIStyle(GUI.skin.box);
/*BoxChildStyle.active.background = GroupClosedTriangle;
BoxChildStyle.focused.background = GroupClosedTriangle;
BoxChildStyle.onActive.background = GroupOpenTriangle;
BoxChildStyle.onFocused.background = GroupOpenTriangle;*/
BoxChildStyle.padding = new RectOffset(0, 0, 0, 0);
BoxChildStyle.margin = new RectOffset(0, 0, 0, 0);
BoxChildStyle.normal.background = NoTexture;
// FOLDOUT STYLE --------------------------------------------------------------------------------------------------------------
/*EditorStyles.foldout.active.background = GroupClosedTriangle;
EditorStyles.foldout.focused.background = GroupClosedTriangle;
EditorStyles.foldout.hover.background = GroupClosedTriangle;
EditorStyles.foldout.onActive.background = GroupOpenTriangle;
EditorStyles.foldout.onFocused.background = GroupOpenTriangle;
EditorStyles.foldout.onHover.background = GroupOpenTriangle;
//EditorStyles.foldout.overflow = new RectOffset(100, 0, 0, 0);
EditorStyles.foldout.padding = new RectOffset(0, 0, 0, 0);
EditorStyles.foldout.overflow = new RectOffset(0, 0, 0, 0);
EditorStyles.foldout.*/
}
static Texture2D MakeTex(int width, int height, Color col)
{
Color[] pix = new Color[width * height];
for (int i = 0; i < pix.Length; ++i)
{
pix[i] = col;
}
Texture2D result = new Texture2D(width, height);
result.SetPixels(pix);
result.Apply();
return result;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 940535a309e9c95418b91f406df57b43
MonoImporter:
externalObjects: {}
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,30 @@
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
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;
using UnityEngine.UI;
using System.Collections;
using System;
#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);
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);
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);
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);
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);
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)
{
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;
}
EditorGUI.LabelField(mainLabelRect, mainLabel);
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))]
[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))]
[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: 07f79b5a8110a854ca5cb1aae7ef890e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,167 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
/// <summary>
/// Custom editor for the MMScreenSafeZones component
/// </summary>
[CustomEditor(typeof(MMAspectRatioSafeZones), true)]
[CanEditMultipleObjects]
public class MMAspectRatioSafeZonesEditor : Editor
{
static MMAspectRatioSafeZones safeZones;
/// <summary>
/// On enable, registers to the OnSceneGUI hook
/// </summary>
void OnEnable()
{
SceneView.duringSceneGui -= OnSceneGUI;
safeZones = (MMAspectRatioSafeZones)target;
SceneView.duringSceneGui += OnSceneGUI;
}
/// <summary>
/// OnSceneGUI, draws center and ratios
/// </summary>
/// <param name="sceneView"></param>
private static void OnSceneGUI(SceneView sceneView)
{
DrawFrameCenter(sceneView);
DrawRatios(sceneView);
}
/// <summary>
/// Draws a rectangle for each ratio
/// </summary>
/// <param name="sceneView"></param>
private static void DrawRatios(SceneView sceneView)
{
if (!safeZones.DrawRatios)
{
return;
}
Vector3 center = sceneView.pivot;
float width = sceneView.position.width;
float height = sceneView.position.height;
Vector3 bottomLeft = new Vector3(center.x - width / 2f, center.y - height / 2f, 0f);
Vector3 topRight = new Vector3(center.x + width / 2f, center.y + height / 2f, 0f);
Vector3 topLeft = bottomLeft;
topLeft.y = topRight.y;
Vector3 bottomRight = topRight;
bottomRight.y = bottomLeft.y;
float size = safeZones.CameraSize;
// dotted lines
float spacing = 2f;
Color dottedLineColor = Color.white;
dottedLineColor.a = 0.4f;
Handles.color = dottedLineColor;
// top
Handles.DrawDottedLine(new Vector3(topLeft.x, center.y + size, 0f), new Vector3(topRight.x, center.y + size, 0f), spacing);
// bottom
Handles.DrawDottedLine(new Vector3(topLeft.x, center.y - size, 0f), new Vector3(topRight.x, center.y - size, 0f), spacing);
foreach (Ratio ratio in safeZones.Ratios)
{
if (ratio.DrawRatio)
{
float aspectRatio = ratio.Size.x / ratio.Size.y;
Handles.color = ratio.RatioColor;
// aspect ratio positions
Vector3 ratioTopLeft = new Vector3(center.x - size * aspectRatio, center.y + size, 0f);
Vector3 ratioTopRight = new Vector3(center.x + size * aspectRatio, center.y + size, 0f);
Vector3 ratioBottomLeft = new Vector3(center.x - size * aspectRatio, center.y - size, 0f);
Vector3 ratioBottomRight = new Vector3(center.x + size * aspectRatio, center.y - size, 0f);
Vector3 ratioLabelPosition = ratioBottomLeft + 0.1f * Vector3.down + 0.1f * Vector3.right;
// draws a label under the rectangle
GUIStyle style = new GUIStyle();
style.normal.textColor = ratio.RatioColor;
style.fontSize = 8;
Handles.Label(ratioLabelPosition, ratio.Size.x + ":" + ratio.Size.y, style);
// draws a rectangle around the aspect ratio
Vector3[] verts = new Vector3[] { ratioTopLeft, ratioTopRight, ratioBottomRight, ratioBottomLeft };
Handles.DrawSolidRectangleWithOutline(verts, new Color(0, 0, 0, 0), ratio.RatioColor);
// draws the dead zone of that ratio
Color zoneColor = ratio.RatioColor;
zoneColor.a = zoneColor.a * safeZones.UnsafeZonesOpacity;
// top rectangle
verts = new Vector3[] { topLeft, topRight, new Vector3(topLeft.x, ratioTopLeft.y, 0f), new Vector3(topRight.x, ratioTopRight.y, 0f) };
Handles.DrawSolidRectangleWithOutline(verts, zoneColor, new Color(0, 0, 0, 0));
// bottom rectangle
verts = new Vector3[] { bottomLeft, new Vector3(topLeft.x, ratioBottomLeft.y, 0f), new Vector3(topRight.x, ratioBottomRight.y, 0f), bottomRight };
Handles.DrawSolidRectangleWithOutline(verts, zoneColor, new Color(0, 0, 0, 0));
// left rectangle
verts = new Vector3[] { new Vector3(topLeft.x, ratioTopLeft.y, 0f), ratioTopLeft, ratioBottomLeft, new Vector3(bottomLeft.x, ratioBottomLeft.y, 0f) };
Handles.DrawSolidRectangleWithOutline(verts, zoneColor, new Color(0, 0, 0, 0));
// right rectangle
verts = new Vector3[] { new Vector3(topRight.x, ratioTopRight.y, 0f), new Vector3(bottomRight.x, ratioBottomRight.y, 0f), ratioBottomRight, ratioTopRight};
Handles.DrawSolidRectangleWithOutline(verts, zoneColor, new Color(0, 0, 0, 0));
// dotted line left
Handles.DrawDottedLine(new Vector3(ratioBottomLeft.x, topLeft.y, 0f), new Vector3(ratioTopLeft.x, bottomLeft.y, 0f), spacing);
// dotted line right
Handles.DrawDottedLine(new Vector3(ratioBottomRight.x, topLeft.y, 0f), new Vector3(ratioBottomRight.x, bottomLeft.y, 0f), spacing);
}
}
}
/// <summary>
/// Draws a crosshair at the center
/// </summary>
/// <param name="sceneView"></param>
private static void DrawFrameCenter(SceneView sceneView)
{
if (!safeZones.DrawCenterCrosshair)
{
return;
}
Vector3 center = sceneView.pivot;
float crossHairSize = safeZones.CenterCrosshairSize;
float reticleSize = crossHairSize / 10f;
Handles.color = safeZones.CenterCrosshairColor;
Vector3 crosshairTopLeft = new Vector3(center.x - crossHairSize / 2f, center.y + crossHairSize / 2f, 0f);
Vector3 crosshairTopRight = new Vector3(center.x + crossHairSize / 2f, center.y + crossHairSize / 2f, 0f);
Vector3 crosshairBottomLeft = new Vector3(center.x - crossHairSize / 2f, center.y - crossHairSize / 2f, 0f);
Vector3 crosshairBottomRight = new Vector3(center.x + crossHairSize / 2f, center.y - crossHairSize / 2f, 0f);
// cross
Handles.DrawLine(new Vector3(center.x, center.y + crossHairSize / 2f, 0f), new Vector3(center.x, center.y - crossHairSize / 2f, 0f));
Handles.DrawLine(new Vector3(center.x - crossHairSize / 2f, center.y, 0f), new Vector3(center.x + crossHairSize / 2f, center.y, 0f));
// top left
Handles.DrawLine(crosshairTopLeft, new Vector3(crosshairTopLeft.x + reticleSize, crosshairTopLeft.y, 0f));
Handles.DrawLine(crosshairTopLeft, new Vector3(crosshairTopLeft.x, crosshairTopLeft.y - reticleSize, 0f));
// top right
Handles.DrawLine(crosshairTopRight, new Vector3(crosshairTopRight.x - reticleSize, crosshairTopRight.y, 0f));
Handles.DrawLine(crosshairTopRight, new Vector3(crosshairTopRight.x, crosshairTopRight.y - reticleSize, 0f));
// bottom left
Handles.DrawLine(crosshairBottomLeft, new Vector3(crosshairBottomLeft.x + reticleSize, crosshairBottomLeft.y, 0f));
Handles.DrawLine(crosshairBottomLeft, new Vector3(crosshairBottomLeft.x, crosshairBottomLeft.y + reticleSize, 0f));
// bottom right
Handles.DrawLine(crosshairBottomRight, new Vector3(crosshairBottomRight.x - reticleSize, crosshairBottomRight.y, 0f));
Handles.DrawLine(crosshairBottomRight, new Vector3(crosshairBottomRight.x, crosshairBottomRight.y + reticleSize, 0f));
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,134 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// A class that lets you create polygon collider 2D out of mesh filters
/// </summary>
public class MMMeshToPolygonCollider2D : MonoBehaviour
{
/// <summary>
/// Generates a PolygonCollider2D out of a meshfilter
/// </summary>
/// <param name="meshFilter"></param>
private static void GeneratePolygonCollider2D(MeshFilter meshFilter)
{
// we validate our mesh
if (!ValidateMesh(meshFilter))
{
return;
}
// we grab or create our PolygonCollider2D
PolygonCollider2D polygonCollider2D = InitializePolygonCollider2D(meshFilter);
if (polygonCollider2D == null)
{
return;
}
Vector3[] vectors = MeshFilterToVectors(meshFilter);
Vector2[] newPoints = VectorsToPoints(vectors);
EditorUtility.SetDirty(polygonCollider2D);
polygonCollider2D.SetPath(0, newPoints);
}
/// <summary>
/// Takes an array of vectors and outputs points
/// </summary>
/// <param name="vectors"></param>
/// <returns></returns>
private static Vector2[] VectorsToPoints(Vector3[] vectors)
{
List<Vector2> newColliderVertices = new List<Vector2>();
for (int i = 0; i < vectors.Length; i++)
{
newColliderVertices.Add(new Vector2(vectors[i].x, vectors[i].y));
}
Vector2[] newPoints = newColliderVertices.Distinct().ToArray();
return newPoints;
}
/// <summary>
/// Turns a meshfilter into an array of vectors
/// </summary>
/// <param name="meshFilter"></param>
/// <returns></returns>
private static Vector3[] MeshFilterToVectors(MeshFilter meshFilter)
{
List<Vector3> vertices = new List<Vector3>();
meshFilter.sharedMesh.GetVertices(vertices);
List<MMGeometry.MMEdge> boundaryPath = MMGeometry.GetEdges(meshFilter.sharedMesh.triangles).FindBoundary().SortEdges();
Vector3[] vectors = new Vector3[boundaryPath.Count];
for (int i = 0; i < boundaryPath.Count; i++)
{
vectors[i] = vertices[boundaryPath[i].Vertice1];
}
return vectors;
}
/// <summary>
/// Grabs or creates a polygon collider 2D
/// </summary>
/// <param name="meshFilter"></param>
/// <returns></returns>
private static PolygonCollider2D InitializePolygonCollider2D(MeshFilter meshFilter)
{
PolygonCollider2D polygonCollider2D = meshFilter.GetComponent<PolygonCollider2D>();
if (polygonCollider2D == null)
{
polygonCollider2D = meshFilter.gameObject.AddComponent<PolygonCollider2D>();
}
polygonCollider2D.pathCount = 1;
return polygonCollider2D;
}
/// <summary>
/// Makes sure that
/// </summary>
/// <param name="meshFilter"></param>
/// <returns></returns>
private static bool ValidateMesh(MeshFilter meshFilter)
{
if (meshFilter.sharedMesh == null)
{
Debug.LogWarning("[MMMeshToPolygonCollider2D] "
+ meshFilter.gameObject.name
+ " needs to have at least a mesh set on its mesh filter component.");
return false;
}
return true;
}
/// <summary>
/// A method meant to be called via the Tools menu, that will go through all mesh colliders on an object and generate a polygon collider2D out of it
/// </summary>
[MenuItem("Tools/More Mountains/Collisions/Generate PolygonCollider2D", false, 601)]
public static void GeneratePolygonCollider2DMenu()
{
Transform activeTransform = Selection.activeTransform;
if (activeTransform == null)
{
Debug.LogWarning("[MMMeshToPolygonCollider2D] You need to select a gameobject first.");
return;
}
EditorSceneManager.MarkSceneDirty(activeTransform.gameObject.scene);
MeshFilter[] meshFilters = activeTransform.GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter meshFilter in meshFilters)
{
GeneratePolygonCollider2D(meshFilter);
}
}
}
}

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f9bd36e0fdcb17346bb804d148559eb2
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d7ae097ceef007248a49d4df212cceb7
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// A custom editor displaying a foldable list of MMFeedbacks, a dropdown to add more, as well as test buttons to test your feedbacks at runtime
/// </summary>
[CanEditMultipleObjects]
[CustomEditor(typeof(MMPlotter))]
public class MMPlotterEditor : Editor
{
protected string[] _typeDisplays;
protected string[] _excludedProperties = new string[] { "TweenMethod", "m_Script" };
protected MMPlotter _mmPlotter;
protected virtual void OnEnable()
{
_mmPlotter = target as MMPlotter;
_typeDisplays = _mmPlotter.GetMethodsList();
}
public override void OnInspectorGUI()
{
serializedObject.Update();
Undo.RecordObject(target, "Modified Plotter");
EditorGUILayout.Space();
EditorGUILayout.LabelField("Tween Method", EditorStyles.boldLabel);
_mmPlotter.TweenMethodIndex = EditorGUILayout.Popup("Tween Method", _mmPlotter.TweenMethodIndex, _typeDisplays, EditorStyles.popup);
//int newItem = EditorGUILayout.Popup(0, _typeDisplays) - 1;
//DrawDefaultInspector();
DrawPropertiesExcluding(serializedObject, _excludedProperties);
if (GUILayout.Button("Draw Graph"))
{
_mmPlotter.DrawGraph();
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,45 @@
using System;
using UnityEngine;
using MoreMountains.Tools;
using UnityEditor;
using UnityEngine.UI;
namespace MoreMountains.Tools
{
[CanEditMultipleObjects]
[CustomEditor(typeof(MMHealthBar),true)]
/// <summary>
/// Custom editor for health bars (mostly a switch for prefab based / drawn bars
/// </summary>
public class HealthBarEditor : Editor
{
public MMHealthBar HealthBarTarget
{
get
{
return (MMHealthBar)target;
}
}
public override void OnInspectorGUI()
{
serializedObject.Update();
switch (HealthBarTarget.HealthBarType)
{
case MMHealthBar.HealthBarTypes.Prefab:
Editor.DrawPropertiesExcluding(serializedObject, new string[] {"TargetProgressBar", "NestDrawnHealthBar", "Billboard", "FollowTargetMode", "Size","BackgroundPadding", "SortingLayerName", "InitialRotationAngles", "ForegroundColor", "DelayedColor", "BorderColor", "BackgroundColor", "Delay", "LerpFrontBar", "LerpFrontBarSpeed", "LerpDelayedBar", "LerpDelayedBarSpeed", "BumpScaleOnChange", "BumpDuration", "BumpAnimationCurve" });
break;
case MMHealthBar.HealthBarTypes.Drawn:
Editor.DrawPropertiesExcluding(serializedObject, new string[] {"TargetProgressBar", "HealthBarPrefab" });
break;
case MMHealthBar.HealthBarTypes.Existing:
Editor.DrawPropertiesExcluding(serializedObject, new string[] {"HealthBarPrefab", "NestDrawnHealthBar", "Billboard", "FollowTargetMode", "Size","BackgroundPadding", "SortingLayerName", "InitialRotationAngles", "ForegroundColor", "DelayedColor", "BorderColor", "BackgroundColor", "Delay", "LerpFrontBar", "LerpFrontBarSpeed", "LerpDelayedBar", "LerpDelayedBarSpeed", "BumpScaleOnChange", "BumpDuration", "BumpAnimationCurve" });
break;
}
serializedObject.ApplyModifiedProperties();
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,384 @@
using UnityEditor;
using UnityEditor.ShortcutManagement;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// a custom editor for the MMGizmo component
/// </summary>
[CustomEditor(typeof(MMGizmo), true)]
[CanEditMultipleObjects]
public class MMGizmoEditor : Editor
{
/// <summary>
/// Lets you press G when in scene view to toggle gizmos on or off
/// </summary>
[Shortcut("Toggle Gizmos", typeof(SceneView), KeyCode.G, displayName = "ToggleGizmos")]
public static void ToggleGizmos()
{
SceneView.lastActiveSceneView.drawGizmos = !SceneView.lastActiveSceneView.drawGizmos;
}
/// <summary>
/// When the target object is selected, we draw our gizmos
/// </summary>
/// <param name="mmGizmo"></param>
/// <param name="gizmoType"></param>
[DrawGizmo(GizmoType.Selected)]
private static void DrawGizmoSelected(MMGizmo mmGizmo, GizmoType gizmoType)
{
if (!mmGizmo.DisplayGizmo)
{
return;
}
DrawGizmos(mmGizmo);
}
/// <summary>
/// When the target object is not selected, we draw our gizmos if needed
/// </summary>
/// <param name="mmGizmo"></param>
/// <param name="gizmoType"></param>
[DrawGizmo(GizmoType.NonSelected)]
private static void DrawGizmoNonSelected(MMGizmo mmGizmo, GizmoType gizmoType)
{
if (!mmGizmo.DisplayGizmo)
{
return;
}
if (mmGizmo.DisplayMode != MMGizmo.DisplayModes.Always)
{
return;
}
DrawGizmos(mmGizmo);
}
/// <summary>
/// Draws gizmos and text
/// </summary>
/// <param name="mmGizmo"></param>
private static void DrawGizmos(MMGizmo mmGizmo)
{
if (!mmGizmo.Initialized)
{
Initialization(mmGizmo);
}
if (TestDistance(mmGizmo, mmGizmo.ViewDistance))
{
Gizmos.color = mmGizmo.GizmoColor;
Gizmos.matrix = mmGizmo.transform.localToWorldMatrix;
switch (mmGizmo.GizmoType)
{
case MMGizmo.GizmoTypes.Collider:
DrawColliderGizmo(mmGizmo);
break;
case MMGizmo.GizmoTypes.Position:
DrawPositionGizmo(mmGizmo);
break;
}
}
DrawText(mmGizmo);
}
/// <summary>
/// Tests whether or not gizmos should be drawn based on distance to the scene camera
/// </summary>
/// <param name="mmGizmo"></param>
/// <param name="viewDistance"></param>
/// <returns></returns>
private static bool TestDistance(MMGizmo mmGizmo, float viewDistance)
{
float distanceToCamera = 0f;
if (SceneView.currentDrawingSceneView == null)
{
distanceToCamera = Vector3.Distance(mmGizmo.transform.position, Camera.main.transform.position);
return (distanceToCamera < viewDistance);
}
else
{
distanceToCamera = Vector3.Distance(mmGizmo.transform.position, SceneView.currentDrawingSceneView.camera.transform.position);
return (distanceToCamera < viewDistance);
}
}
/// <summary>
/// On Enable we initialize our gizmo
/// </summary>
protected virtual void OnEnable()
{
Initialization(target as MMGizmo);
}
/// <summary>
/// On validate we initialize our gizmo
/// </summary>
protected void OnValidate()
{
Initialization(target as MMGizmo);
}
/// <summary>
/// Initializes the gizmo, caching components, values, and inits the GUIStyle
/// </summary>
/// <param name="mmGizmo"></param>
private static void Initialization(MMGizmo mmGizmo)
{
mmGizmo._sphereCollider = mmGizmo.gameObject.GetComponent<SphereCollider>();
mmGizmo._boxCollider = mmGizmo.gameObject.GetComponent<BoxCollider>();
mmGizmo._meshCollider = mmGizmo.gameObject.GetComponent<MeshCollider>();
mmGizmo._circleCollider2D = mmGizmo.gameObject.GetComponent<CircleCollider2D>();
mmGizmo._boxCollider2D = mmGizmo.gameObject.GetComponent<BoxCollider2D>();
mmGizmo._sphereColliderNotNull = (mmGizmo._sphereCollider != null);
mmGizmo._boxColliderNotNull = (mmGizmo._boxCollider != null);
mmGizmo._meshColliderNotNull = (mmGizmo._meshCollider != null);
mmGizmo._circleCollider2DNotNull = (mmGizmo._circleCollider2D != null);
mmGizmo._boxCollider2DNotNull = (mmGizmo._boxCollider2D != null);
mmGizmo._vector3Zero = Vector3.zero;
mmGizmo._textureRect = new Rect(0f, 0f, mmGizmo.TextureSize.x, mmGizmo.TextureSize.y);
mmGizmo._positionTextureNotNull = (mmGizmo.PositionTexture != null);
mmGizmo._textGUIStyle = new GUIStyle();
mmGizmo._textGUIStyle.normal.textColor = mmGizmo.TextColor;
mmGizmo._textGUIStyle.fontSize = mmGizmo.TextSize;
mmGizmo._textGUIStyle.fontStyle = mmGizmo.TextFontStyle;
mmGizmo._textGUIStyle.padding = new RectOffset((int)mmGizmo.TextPadding.x, (int)mmGizmo.TextPadding.y, (int)mmGizmo.TextPadding.z, (int)mmGizmo.TextPadding.w);
mmGizmo._textGUIStyle.normal.background = MMGUI.MakeTex(600, 100, mmGizmo.TextBackgroundColor);
mmGizmo.Initialized = true;
}
/// <summary>
/// Draws a gizmo for the associated collider
/// </summary>
/// <param name="mmGizmo"></param>
private static void DrawColliderGizmo(MMGizmo mmGizmo)
{
if (mmGizmo._sphereColliderNotNull)
{
if (mmGizmo.ColliderRenderType == MMGizmo.ColliderRenderTypes.Full)
{
Gizmos.DrawSphere(ComputeGizmoPosition(mmGizmo, mmGizmo._sphereCollider.center), mmGizmo._sphereCollider.radius);
}
else
{
Gizmos.DrawWireSphere(ComputeGizmoPosition(mmGizmo, mmGizmo._sphereCollider.center), mmGizmo._sphereCollider.radius);
}
}
if (mmGizmo._boxColliderNotNull)
{
if (mmGizmo.ColliderRenderType == MMGizmo.ColliderRenderTypes.Full)
{
Gizmos.DrawCube(ComputeGizmoPosition(mmGizmo, mmGizmo._boxCollider.center), mmGizmo._boxCollider.size);
}
else
{
Gizmos.DrawWireCube(ComputeGizmoPosition(mmGizmo, mmGizmo._boxCollider.center), mmGizmo._boxCollider.size);
}
}
if (mmGizmo._circleCollider2DNotNull)
{
if (mmGizmo.ColliderRenderType == MMGizmo.ColliderRenderTypes.Full)
{
Gizmos.DrawSphere((Vector3)ComputeGizmoPosition(mmGizmo, mmGizmo._circleCollider2D.offset), mmGizmo._circleCollider2D.radius);
}
else
{
Gizmos.DrawWireSphere((Vector3)ComputeGizmoPosition(mmGizmo, mmGizmo._circleCollider2D.offset), mmGizmo._circleCollider2D.radius);
}
}
if (mmGizmo._boxCollider2DNotNull)
{
Vector3 gizmoSize = new Vector3();
gizmoSize.x = mmGizmo._boxCollider2D.size.x ;
gizmoSize.y = mmGizmo._boxCollider2D.size.y ;
gizmoSize.z = 0.1f;
if (mmGizmo.ColliderRenderType == MMGizmo.ColliderRenderTypes.Full)
{
Gizmos.DrawCube(ComputeGizmoPosition(mmGizmo, mmGizmo._boxCollider2D.offset), gizmoSize);
}
else
{
Gizmos.DrawWireCube(ComputeGizmoPosition(mmGizmo, mmGizmo._boxCollider2D.offset), gizmoSize);
}
}
if (mmGizmo._meshColliderNotNull)
{
if (mmGizmo.ColliderRenderType == MMGizmo.ColliderRenderTypes.Full)
{
Gizmos.DrawMesh(mmGizmo._meshCollider.sharedMesh);
}
else
{
Gizmos.DrawWireMesh(mmGizmo._meshCollider.sharedMesh);
}
}
}
/// <summary>
/// Draws a position gizmo
/// </summary>
/// <param name="mmGizmo"></param>
private static void DrawPositionGizmo(MMGizmo mmGizmo)
{
switch (mmGizmo.PositionMode)
{
case MMGizmo.PositionModes.Point:
MMDebug.DrawGizmoPoint(ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero), mmGizmo.GizmoColor, mmGizmo.PositionSize);
break;
case MMGizmo.PositionModes.Cube:
Gizmos.DrawCube(ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero), Vector3.one * mmGizmo.PositionSize);
break;
case MMGizmo.PositionModes.Sphere:
Gizmos.DrawSphere(ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero), mmGizmo.PositionSize);
break;
case MMGizmo.PositionModes.WireCube:
Gizmos.DrawWireCube(ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero), Vector3.one * mmGizmo.PositionSize);
break;
case MMGizmo.PositionModes.WireSphere:
Gizmos.DrawWireSphere(ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero), mmGizmo.PositionSize);
break;
case MMGizmo.PositionModes.Texture:
if (mmGizmo._positionTextureNotNull)
{
Handles.BeginGUI();
mmGizmo._worldToGUIPosition = HandleUtility.WorldToGUIPoint(ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false));
mmGizmo._textureRect = new Rect(mmGizmo._worldToGUIPosition.x - mmGizmo.TextureSize.x/2f, mmGizmo._worldToGUIPosition.y - mmGizmo.TextureSize.y/2f, mmGizmo.TextureSize.x, mmGizmo.TextureSize.y);
GUI.Label(mmGizmo._textureRect, mmGizmo.PositionTexture);
Handles.EndGUI();
}
break;
case MMGizmo.PositionModes.Arrows:
Handles.color = Handles.xAxisColor;
Handles.ArrowHandleCap(0, ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false),
Quaternion.LookRotation(mmGizmo.transform.right, mmGizmo.transform.up), mmGizmo.PositionSize, EventType.Repaint);
Handles.color = Handles.yAxisColor;
Handles.ArrowHandleCap(0, ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false),
Quaternion.LookRotation(mmGizmo.transform.up, mmGizmo.transform.up), mmGizmo.PositionSize, EventType.Repaint);
Handles.color = Handles.zAxisColor;
Handles.ArrowHandleCap(0, ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false),
Quaternion.LookRotation(mmGizmo.transform.forward, mmGizmo.transform.up), mmGizmo.PositionSize, EventType.Repaint);
break;
case MMGizmo.PositionModes.RightArrow:
Handles.color = mmGizmo.GizmoColor;
Handles.ArrowHandleCap(0, ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false),
Quaternion.LookRotation(mmGizmo.transform.right, mmGizmo.transform.up), mmGizmo.PositionSize, EventType.Repaint);
break;
case MMGizmo.PositionModes.UpArrow:
Handles.color = mmGizmo.GizmoColor;
Handles.ArrowHandleCap(0, ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false),
Quaternion.LookRotation(mmGizmo.transform.up, mmGizmo.transform.up), mmGizmo.PositionSize, EventType.Repaint);
break;
case MMGizmo.PositionModes.ForwardArrow:
Handles.color = mmGizmo.GizmoColor;
Handles.ArrowHandleCap(0, ComputeGizmoPosition(mmGizmo, mmGizmo.transform.position, false),
Quaternion.LookRotation(mmGizmo.transform.forward, mmGizmo.transform.up), mmGizmo.PositionSize, EventType.Repaint);
break;
case MMGizmo.PositionModes.Lines:
Vector3 origin = ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero);
Vector3 destination = origin + Vector3.right * mmGizmo.PositionSize;
Gizmos.DrawLine(origin, destination);
destination = origin + Vector3.up * mmGizmo.PositionSize;
Gizmos.DrawLine(origin, destination);
destination = origin + Vector3.forward * mmGizmo.PositionSize;
Gizmos.DrawLine(origin, destination);
break;
case MMGizmo.PositionModes.RightLine:
Vector3 rightOrigin = ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero);
Vector3 rightDestination = rightOrigin + Vector3.right * mmGizmo.PositionSize;
Gizmos.DrawLine(rightOrigin, rightDestination);
break;
case MMGizmo.PositionModes.UpLine:
Vector3 upOrigin = ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero);
Vector3 upDestination = upOrigin + Vector3.up * mmGizmo.PositionSize;
Gizmos.DrawLine(upOrigin, upDestination);
break;
case MMGizmo.PositionModes.ForwardLine:
Vector3 fwdOrigin = ComputeGizmoPosition(mmGizmo, mmGizmo._vector3Zero);
Vector3 fwdDestination = fwdOrigin + Vector3.forward * mmGizmo.PositionSize;
Gizmos.DrawLine(fwdOrigin, fwdDestination);
break;
}
}
/// <summary>
/// Draws our gizmo text
/// </summary>
/// <param name="mmGizmo"></param>
private static void DrawText(MMGizmo mmGizmo)
{
if (!mmGizmo.DisplayText)
{
return;
}
if (!TestDistance(mmGizmo, mmGizmo.TextMaxDistance))
{
return;
}
switch (mmGizmo.TextMode)
{
case MMGizmo.TextModes.GameObjectName:
mmGizmo._textToDisplay = mmGizmo.gameObject.name;
break;
case MMGizmo.TextModes.CustomText:
mmGizmo._textToDisplay = mmGizmo.TextToDisplay;
break;
case MMGizmo.TextModes.Position:
mmGizmo._textToDisplay = mmGizmo.transform.position.ToString();
break;
case MMGizmo.TextModes.Rotation:
mmGizmo._textToDisplay = mmGizmo.transform.rotation.ToString();
break;
case MMGizmo.TextModes.Scale:
mmGizmo._textToDisplay = mmGizmo.transform.localScale.ToString();
break;
case MMGizmo.TextModes.Property:
if (mmGizmo.TargetProperty.PropertyFound)
{
mmGizmo._textToDisplay = mmGizmo.TargetProperty.GetRawValue().ToString();
}
break;
}
if (mmGizmo._textToDisplay != "")
{
Handles.Label(mmGizmo.transform.position + mmGizmo.TextOffset, mmGizmo._textToDisplay, mmGizmo._textGUIStyle);
}
}
/// <summary>
/// Computes the position at which to draw the gizmo
/// </summary>
/// <param name="mmGizmo"></param>
/// <param name="position"></param>
/// <param name="relativeLock"></param>
/// <returns></returns>
private static Vector3 ComputeGizmoPosition(MMGizmo mmGizmo, Vector3 position, bool relativeLock = true)
{
mmGizmo._newPosition = position + mmGizmo.GizmoOffset;
if (mmGizmo.LockX || mmGizmo.LockY || mmGizmo.LockZ)
{
Vector3 mmGizmoNewPosition = mmGizmo._newPosition;
if (mmGizmo.LockX) { mmGizmoNewPosition.x = relativeLock ? - mmGizmo.transform.position.x + mmGizmo.LockedX : mmGizmo.LockedX; }
if (mmGizmo.LockY) { mmGizmoNewPosition.y = relativeLock ? - mmGizmo.transform.position.y + mmGizmo.LockedY : mmGizmo.LockedY; }
if (mmGizmo.LockZ) { mmGizmoNewPosition.z = relativeLock ? - mmGizmo.transform.position.z + mmGizmo.LockedZ : mmGizmo.LockedZ; }
mmGizmo._newPosition = mmGizmoNewPosition;
}
return mmGizmo._newPosition;
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,66 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using System.IO;
using System.Text;
using System.Linq;
using System;
namespace MoreMountains.Tools
{
/// <summary>
/// A maintenance class that removes all empty directories from a project via a menu item
/// </summary>
public class MMCleanEmptyFolders : MonoBehaviour
{
static string _consoleLog = "";
static List<DirectoryInfo> _listOfEmptyDirectories = new List<DirectoryInfo>();
/// <summary>
/// Parses the project for empty directories and removes them, as well as their associated meta file
/// </summary>
[MenuItem("Tools/More Mountains/Cleanup empty folders", false, 504)]
protected static void CleanupMissingScripts()
{
_listOfEmptyDirectories.Clear();
var assetsDir = Application.dataPath + Path.DirectorySeparatorChar;
GetEmptyDirectories(new DirectoryInfo(assetsDir), _listOfEmptyDirectories);
if (0 < _listOfEmptyDirectories.Count)
{
_consoleLog = "[MMCleanEmptyFolders] Removed "+ _listOfEmptyDirectories.Count + " empty directories:\n";
foreach (var d in _listOfEmptyDirectories)
{
_consoleLog += "· "+ d.FullName.Replace(assetsDir, "") + "\n";
FileUtil.DeleteFileOrDirectory(d.FullName);
FileUtil.DeleteFileOrDirectory(d.FullName+".meta");
}
Debug.Log(_consoleLog);
_consoleLog = "";
AssetDatabase.Refresh();
}
}
/// <summary>
/// Returns true if a directory is empty and updates a list of empty directories
/// </summary>
/// <param name="directory"></param>
/// <param name="listOfEmptyDirectories"></param>
/// <returns></returns>
static bool GetEmptyDirectories(DirectoryInfo directory, List<DirectoryInfo> listOfEmptyDirectories)
{
bool directoryIsEmpty = true;
directoryIsEmpty = (directory.GetDirectories().Count(x => !GetEmptyDirectories(x, listOfEmptyDirectories)) == 0) && (directory.GetFiles("*.*").All(x => x.Extension == ".meta"));
if (directoryIsEmpty)
{
listOfEmptyDirectories.Add(directory);
}
return directoryIsEmpty;
}
}
}

View File

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

View File

@@ -0,0 +1,39 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// This class lets you clean all missing scripts on a selection of gameobjects
/// </summary>
public class MMCleanupMissingScripts : MonoBehaviour
{
/// <summary>
/// Processes the cleaning of gameobjects for all missing scripts on them
/// </summary>
[MenuItem("Tools/More Mountains/Cleanup missing scripts on selected GameObjects", false, 504)]
protected static void CleanupMissingScripts()
{
Object[] collectedDeepHierarchy = EditorUtility.CollectDeepHierarchy(Selection.gameObjects);
int removedComponentsCounter = 0;
int gameobjectsAffectedCounter = 0;
foreach (Object targetObject in collectedDeepHierarchy)
{
if (targetObject is GameObject gameObject)
{
int amountOfMissingScripts = GameObjectUtility.GetMonoBehavioursWithMissingScriptCount(gameObject);
if (amountOfMissingScripts > 0)
{
Undo.RegisterCompleteObjectUndo(gameObject, "Removing missing scripts");
GameObjectUtility.RemoveMonoBehavioursWithMissingScript(gameObject);
removedComponentsCounter += amountOfMissingScripts;
gameobjectsAffectedCounter++;
}
}
}
Debug.Log("[MMCleanupMissingScripts] Removed " + removedComponentsCounter + " missing scripts from " + gameobjectsAffectedCounter + " GameObjects");
}
}
}

View File

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

View File

@@ -0,0 +1,72 @@
// Original FindMissingScriptsRecursively script by SimTex and Clement
// http://wiki.unity3d.com/index.php?title=FindMissingScripts
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
public class MMFindMissingScriptsRecursively : EditorWindow
{
static int go_count = 0, components_count = 0, missing_count = 0;
[MenuItem("Tools/More Mountains/Find missing scripts recursively", false, 505)]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(MMFindMissingScriptsRecursively));
}
#if UNITY_EDITOR
public void OnGUI()
{
if (GUILayout.Button("Find Missing Scripts in selected GameObjects"))
{
FindInSelected();
}
}
#endif
private static void FindInSelected()
{
GameObject[] go = Selection.gameObjects;
go_count = 0;
components_count = 0;
missing_count = 0;
foreach (GameObject g in go)
{
FindInGO(g);
}
Debug.Log(string.Format("Searched {0} GameObjects, {1} components, found {2} missing", go_count, components_count, missing_count));
}
private static void FindInGO(GameObject g)
{
go_count++;
Component[] components = g.GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
components_count++;
if (components[i] == null)
{
missing_count++;
string s = g.name;
Transform t = g.transform;
while (t.parent != null)
{
s = t.parent.name +"/"+s;
t = t.parent;
}
Debug.Log (s + " has an empty script attached in position: " + i, g);
}
}
// Now recurse through each child GO (if there are any):
foreach (Transform childT in g.transform)
{
FindInGO(childT.gameObject);
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,283 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
namespace MoreMountains.Tools
{
/// <summary>
/// As static class that lets you look for missing scripts on any prefab in your project, or for prefabs equipped with a certain type of MonoBehaviour
/// </summary>
public class MMFindPrefabsByMono : EditorWindow
{
protected Vector2 _scrollView;
protected string[] _tabs = new string[] { "Find prefabs with missing components", "Find prefabs by MonoBehaviour" };
protected int _selectedTab;
protected int _lastSelectedTab = -1;
protected MonoScript _searchedMonoBehaviour;
protected MonoScript _lastSearchedMonoBehaviour;
protected string _searchedMonoBehaviourName = "";
protected List<string> _resultsList;
static GUIStyle _padded;
static GUIStyle _horizontalPadded;
static int _horizontalPadding = 20;
static int _verticalPadding = 20;
static RectOffset _padding;
static RectOffset _horizontalPaddingOnly;
/// <summary>
/// Menu bound method
/// </summary>
[MenuItem("Tools/More Mountains/Prefab Finder", false, 504)]
public static void MenuAction()
{
OpenWindow();
}
/// <summary>
/// Opens and resizes the window
/// </summary>
public static void OpenWindow()
{
InitializePaddingAndStyles();
MMFindPrefabsByMono window = (MMFindPrefabsByMono)EditorWindow.GetWindow(typeof(MMFindPrefabsByMono));
window.position = new Rect(400, 400, 800, 600);
window.titleContent = new GUIContent("MM Prefabs Finder");
window.Show();
}
/// <summary>
/// Initializes padding variables and GUI styles
/// </summary>
static void InitializePaddingAndStyles()
{
if (_padding == null)
{
_padding = new RectOffset(_horizontalPadding, _horizontalPadding, _verticalPadding, _verticalPadding);
_horizontalPaddingOnly = new RectOffset(_horizontalPadding, _horizontalPadding, 0, 0);
_padded = new GUIStyle
{
name = "padded",
padding = _padding
};
_horizontalPadded = new GUIStyle
{
name = "horizontalPadded",
padding = _horizontalPaddingOnly
};
}
}
/// <summary>
/// Draws tab buttons
/// </summary>
protected virtual void DrawTabs()
{
GUI.skin.box.padding = _padding;
GUILayout.BeginHorizontal("box");
GUILayout.Space(10);
_selectedTab = GUILayout.Toolbar(_selectedTab, _tabs);
GUILayout.EndHorizontal();
}
/// <summary>
/// Detects changes in tabs selection
/// </summary>
protected virtual void HandleTabsChange()
{
if (_lastSelectedTab != _selectedTab)
{
_lastSelectedTab = _selectedTab;
_resultsList = new List<string>();
_searchedMonoBehaviourName = _searchedMonoBehaviour == null ? "" : _searchedMonoBehaviour.name;
_lastSearchedMonoBehaviour = null;
}
}
/// <summary>
/// Draws the content of the selected tab
/// </summary>
protected virtual void DrawSelectedTab()
{
switch (_selectedTab)
{
case 0:
DrawSearchMissing();
break;
case 1:
DrawSearchByMonoBehaviour();
break;
}
}
/// <summary>
/// Draws the search by mono form
/// </summary>
protected virtual void DrawSearchByMonoBehaviour()
{
GUILayout.BeginHorizontal("box");
GUILayout.Space(20);
GUILayout.BeginVertical();
GUILayout.Label("Select a MonoBehaviour to search for:");
_searchedMonoBehaviour = (MonoScript)EditorGUILayout.ObjectField(_searchedMonoBehaviour, typeof(MonoScript), false);
GUILayout.EndVertical();
GUILayout.Space(10);
if (_searchedMonoBehaviour != _lastSearchedMonoBehaviour)
{
string[] allPrefabsInProject = GetAllPrefabsInProject();
_lastSearchedMonoBehaviour = _searchedMonoBehaviour;
_searchedMonoBehaviourName = _searchedMonoBehaviour.name;
AssetDatabase.SaveAssets();
string searchedMonoBehaviourPath = AssetDatabase.GetAssetPath(_searchedMonoBehaviour);
_resultsList = new List<string>();
foreach (string prefab in allPrefabsInProject)
{
string[] pathName = new string[] { prefab };
string[] monoDependenciesPaths = AssetDatabase.GetDependencies(pathName, false);
foreach (string monoDependencyPath in monoDependenciesPaths)
{
if (monoDependencyPath == searchedMonoBehaviourPath)
{
_resultsList.Add(prefab);
}
}
}
}
GUILayout.EndHorizontal();
}
/// <summary>
/// Draws the search missing form
/// </summary>
protected virtual void DrawSearchMissing()
{
GUILayout.BeginHorizontal("box");
GUILayout.Space(20);
if (GUILayout.Button("Search the project for prefabs with missing scripts"))
{
string[] allPrefabs = GetAllPrefabsInProject();
_resultsList = new List<string>();
foreach (string prefab in allPrefabs)
{
UnityEngine.Object asset = AssetDatabase.LoadMainAssetAtPath(prefab);
GameObject assetGameObject;
try
{
assetGameObject = (GameObject)asset;
Component[] components = assetGameObject.GetComponentsInChildren<Component>(true);
foreach (Component component in components)
{
if (component == null)
{
_resultsList.Add(prefab);
}
}
}
catch
{
Debug.Log("An error occured with prefab " + prefab);
}
}
}
GUILayout.EndHorizontal();
}
/// <summary>
/// Draws the result list
/// </summary>
protected virtual void DrawResultsList()
{
GUILayout.BeginHorizontal(_padded);
if (_resultsList != null)
{
if (_resultsList.Count == 0)
{
switch (_selectedTab)
{
case 0:
GUILayout.Label("No prefabs have missing components.", EditorStyles.boldLabel);
break;
case 1:
if (!string.IsNullOrEmpty(_searchedMonoBehaviourName))
{
GUILayout.Label("No prefabs use component " + _searchedMonoBehaviourName, EditorStyles.boldLabel);
}
break;
}
GUILayout.EndHorizontal(); // end padded
}
else
{
switch (_selectedTab)
{
case 0:
GUILayout.Label("These prefabs have missing components :", EditorStyles.boldLabel);
break;
case 1:
GUILayout.Label("MonoBehaviour " + _searchedMonoBehaviourName + " was found in these prefabs :", EditorStyles.boldLabel);
break;
}
GUILayout.EndHorizontal(); // end padded
GUILayout.BeginHorizontal();
GUI.skin.scrollView.padding = _padding;
_scrollView = GUILayout.BeginScrollView(_scrollView);
foreach (string s in _resultsList)
{
GUILayout.BeginHorizontal(_horizontalPadded);
GUILayout.Label(s, GUILayout.Width(4 * (position.width - 4 * _horizontalPadding) / 5));
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
if (GUILayout.Button("Select prefab", GUILayout.Width((position.width - 4 * _horizontalPadding) / 5 - 20)))
{
Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(s);
}
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
GUILayout.EndHorizontal();
}
}
}
#if UNITY_EDITOR
/// <summary>
/// On GUI we draw our window's contents
/// </summary>
protected virtual void OnGUI()
{
InitializePaddingAndStyles();
DrawTabs();
HandleTabsChange();
DrawSelectedTab();
DrawResultsList();
}
#endif
/// <summary>
/// Gets all prefabs and sorts them alphabetically
/// </summary>
/// <returns></returns>
public static string[] GetAllPrefabsInProject()
{
string[] assetPaths = AssetDatabase.GetAllAssetPaths();
List<string> results = new List<string>();
foreach (string assetPath in assetPaths)
{
if (assetPath.Contains(".prefab"))
{
results.Add(assetPath);
}
}
results.Sort();
return results.ToArray();
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
/// <summary>
/// A class used to add a menu item and a shortcut to group objects together under a parent game object
/// </summary>
public class MMGroupSelection
{
/// <summary>
/// Creates a parent object and puts all selected transforms under it
/// </summary>
[MenuItem("Tools/More Mountains/Group Selection %g")]
public static void GroupSelection()
{
if (!Selection.activeTransform)
{
return;
}
GameObject groupObject = new GameObject();
groupObject.name = "Group";
Undo.RegisterCreatedObjectUndo(groupObject, "Group Selection");
groupObject.transform.SetParent(Selection.activeTransform.parent, false);
foreach (Transform selectedTransform in Selection.transforms)
{
Undo.SetTransformParent(selectedTransform, groupObject.transform, "Group Selection");
}
Selection.activeGameObject = groupObject;
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
using System;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace MoreMountains.Tools
{
/// <summary>
/// A simple class that lets you lock the current inspector by pressing ctrl (or cmd) + L
/// Pressing the same shortcut again unlocks the
/// </summary>
public class MMLockInspector : MonoBehaviour
{
[MenuItem("Tools/More Mountains/Lock Inspector %l")]
static public void LockInspector()
{
Type inspectorType = typeof(Editor).Assembly.GetType("UnityEditor.InspectorWindow");
EditorWindow inspectorWindow = EditorWindow.GetWindow(inspectorType);
PropertyInfo isLockedPropertyInfo = inspectorType.GetProperty("isLocked", BindingFlags.Public | BindingFlags.Instance);
bool state = (bool)isLockedPropertyInfo.GetGetMethod().Invoke(inspectorWindow, new object[] { });
isLockedPropertyInfo.GetSetMethod().Invoke(inspectorWindow, new object[] { !state });
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,67 @@
using UnityEngine;
using UnityEditor;
namespace MoreMountains.Tools
{
/// <summary>
/// Custom editor for the MMAutoRotate component
/// </summary>
[CustomEditor(typeof(MMAutoRotate), true)]
[CanEditMultipleObjects]
public class MMAutoRotateEditor : Editor
{
/// <summary>
///
/// </summary>
/// <param name="autoRotate"></param>
/// <param name="gizmoType"></param>
[DrawGizmo(GizmoType.InSelectionHierarchy)]
static void DrawHandles(MMAutoRotate autoRotate, GizmoType gizmoType)
{
MMAutoRotate myTarget = autoRotate;
// only draw gizmos if orbiting and gizmos enabled
if (!myTarget.Orbiting || !myTarget.DrawGizmos)
{
return;
};
// if we're not playing, we compute our center/axis
if (!Application.isPlaying)
{
if (myTarget.OrbitCenterTransform != null)
{
myTarget._orbitCenter = myTarget.OrbitCenterTransform.transform.position + myTarget.OrbitCenterOffset;
myTarget._worldRotationAxis = myTarget.OrbitCenterTransform.TransformDirection(myTarget.OrbitRotationAxis);
myTarget._rotationPlane.SetNormalAndPosition(myTarget._worldRotationAxis.normalized, myTarget._orbitCenter);
myTarget._snappedPosition = myTarget._rotationPlane.ClosestPointOnPlane(myTarget.transform.position);
myTarget._radius = myTarget.OrbitRadius * Vector3.Normalize(myTarget._snappedPosition - myTarget._orbitCenter);
}
}
// draws a plane disc
Handles.color = myTarget.OrbitPlaneColor;
Handles.DrawSolidDisc(myTarget._orbitCenter, myTarget._rotationPlane.normal, myTarget.OrbitRadius + 0.5f);
// draws a circle to mark the orbit
Handles.color = myTarget.OrbitLineColor;
Handles.DrawWireArc(myTarget._orbitCenter, myTarget._rotationPlane.normal, Vector3.ProjectOnPlane(myTarget._orbitCenter + Vector3.forward, myTarget._rotationPlane.normal), 360f, myTarget.OrbitRadius);
// draws an arrow to mark the direction
Quaternion newRotation = Quaternion.AngleAxis(1f, myTarget._worldRotationAxis);
Vector3 origin = myTarget._orbitCenter + newRotation * myTarget._radius;
newRotation = Quaternion.AngleAxis(15f, myTarget._worldRotationAxis);
Vector3 direction = Vector3.zero;
if (myTarget.OrbitRotationSpeed > 0f)
{
direction = (myTarget._orbitCenter + newRotation * myTarget._radius) - origin;
}
else
{
direction = origin - (myTarget._orbitCenter + newRotation * myTarget._radius);
}
MMDebug.DebugDrawArrow(origin, direction, myTarget.OrbitLineColor);
}
}
}

View File

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

View File

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

View File

@@ -0,0 +1,88 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace MoreMountains.Tools
{
/// <summary>
/// This class adds names for each LevelMapPathElement next to it on the scene view, for easier setup
/// </summary>
[CustomEditor(typeof(MMPath),true)]
[InitializeOnLoad]
public class MMPathEditor : Editor
{
public MMPath pathTarget
{
get
{
return (MMPath)target;
}
}
/// <summary>
/// OnSceneGUI, draws repositionable handles at every point in the path, for easier setup
/// </summary>
protected virtual void OnSceneGUI()
{
Handles.color=Color.green;
MMPath t = (target as MMPath);
if (t.GetOriginalTransformPositionStatus() == false)
{
return;
}
for (int i=0;i<t.PathElements.Count;i++)
{
EditorGUI.BeginChangeCheck();
Vector3 oldPoint = t.GetOriginalTransformPosition()+t.PathElements[i].PathElementPosition;
GUIStyle style = new GUIStyle();
// draws the path item number
style.normal.textColor = Color.yellow;
Handles.Label(t.GetOriginalTransformPosition()+t.PathElements[i].PathElementPosition+(Vector3.down*0.4f)+(Vector3.right*0.4f), ""+i,style);
// draws a movable handle
Vector3 newPoint = Handles.FreeMoveHandle(oldPoint, Quaternion.identity,.5f,new Vector3(.25f,.25f,.25f),Handles.CircleHandleCap);
newPoint = ApplyAxisLock(oldPoint, newPoint);
// records changes
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Free Move Handle");
t.PathElements[i].PathElementPosition = newPoint - t.GetOriginalTransformPosition();
}
}
}
/// <summary>
/// Locks handles movement on x, y, or z axis
/// </summary>
/// <param name="oldPoint"></param>
/// <param name="newPoint"></param>
/// <returns></returns>
protected virtual Vector3 ApplyAxisLock(Vector3 oldPoint, Vector3 newPoint)
{
MMPath t = (target as MMPath);
if (t.LockHandlesOnXAxis)
{
newPoint.x = oldPoint.x;
}
if (t.LockHandlesOnYAxis)
{
newPoint.y = oldPoint.y;
}
if (t.LockHandlesOnZAxis)
{
newPoint.z = oldPoint.z;
}
return newPoint;
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,78 @@
#if UNITY_EDITOR
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace MoreMountains.Tools
{
/// <summary>
/// This class adds names for each LevelMapPathElement next to it on the scene view, for easier setup
/// </summary>
[CustomEditor(typeof(MMPathMovement),true)]
[InitializeOnLoad]
public class MMPathMovementEditor : Editor
{
public MMPathMovement pathMovementTarget
{
get
{
return (MMPathMovement)target;
}
}
public override void OnInspectorGUI()
{
serializedObject.Update ();
if (pathMovementTarget.AccelerationType == MMPathMovement.PossibleAccelerationType.AnimationCurve)
{
DrawDefaultInspector ();
}
else
{
Editor.DrawPropertiesExcluding (serializedObject, new string [] { "Acceleration" });
}
serializedObject.ApplyModifiedProperties ();
}
/// <summary>
/// OnSceneGUI, draws repositionable handles at every point in the path, for easier setup
/// </summary>
protected virtual void OnSceneGUI()
{
Handles.color = Color.green;
MMPathMovement t = (target as MMPathMovement);
if (t.GetOriginalTransformPositionStatus() == false)
{
return;
}
for (int i=0;i<t.PathElements.Count;i++)
{
EditorGUI.BeginChangeCheck();
Vector3 oldPoint = t.PointPosition(i);
GUIStyle style = new GUIStyle();
// draws the path item number
style.normal.textColor = Color.yellow;
Handles.Label(t.PointPosition(i) + (Vector3.down*0.4f) + (Vector3.right*0.4f), ""+i,style);
// draws a movable handle
Vector3 newPoint = Handles.FreeMoveHandle(oldPoint, Quaternion.identity,.5f,new Vector3(.25f,.25f,.25f),Handles.CircleHandleCap);
// records changes
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(target, "Free Move Handle");
t.PathElements[i].PathElementPosition = newPoint - t.GetOriginalTransformPosition();
}
}
}
}
}
#endif

View File

@@ -0,0 +1,13 @@
fileFormatVersion: 2
guid: 80063623289ee3e49b584d00f3a90a32
timeCreated: 1523894192
licenseType: Store
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: c3bceac71c8f2d64196c4fa6c935b200
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,62 @@
using System;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Reflection;
namespace MoreMountains.Tools
{
[CanEditMultipleObjects()]
[CustomEditor(typeof(MMRendererSortingLayer))]
public class MMRendererLayerEditor : Editor
{
int popupMenuIndex;
string[] sortingLayerNames;
protected MMRendererSortingLayer _mmRendererSortingLayer;
protected Renderer _renderer;
void OnEnable()
{
sortingLayerNames = GetSortingLayerNames();
_mmRendererSortingLayer = (MMRendererSortingLayer)target;
_renderer = _mmRendererSortingLayer.GetComponent<Renderer> ();
for (int i = 0; i<sortingLayerNames.Length;i++) //here we initialize our popupMenuIndex with the current Sort Layer Name
{
if (sortingLayerNames[i] == _renderer.sortingLayerName)
popupMenuIndex = i;
}
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (_renderer == null)
{
return;
}
popupMenuIndex = EditorGUILayout.Popup("Sorting Layer", popupMenuIndex, sortingLayerNames);
int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", _renderer.sortingOrder);
if (sortingLayerNames[popupMenuIndex] != _renderer.sortingLayerName
|| newSortingLayerOrder != _renderer.sortingOrder)
{
Undo.RecordObject(_renderer, "Change Particle System Renderer Order");
_renderer.sortingLayerName = sortingLayerNames[popupMenuIndex];
_renderer.sortingOrder = newSortingLayerOrder;
EditorUtility.SetDirty(_renderer);
}
}
public string[] GetSortingLayerNames()
{
Type internalEditorUtilityType = typeof(InternalEditorUtility);
PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
return (string[])sortingLayersProperty.GetValue(null, new object[0]);
}
}
}

View File

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

View File

@@ -0,0 +1,62 @@
using System;
using UnityEngine;
using UnityEditor;
using UnityEditorInternal;
using System.Reflection;
namespace MoreMountains.Tools
{
[CanEditMultipleObjects()]
[CustomEditor(typeof(MMTrailRendererSortingLayer))]
public class MMTrailRendererLayerEditor : Editor
{
int popupMenuIndex;
string[] sortingLayerNames;
protected MMTrailRendererSortingLayer _mmTrailRendererSortingLayer;
protected TrailRenderer _trailRenderer;
void OnEnable()
{
sortingLayerNames = GetSortingLayerNames();
_mmTrailRendererSortingLayer = (MMTrailRendererSortingLayer)target;
_trailRenderer = _mmTrailRendererSortingLayer.GetComponent<TrailRenderer> ();
for (int i = 0; i<sortingLayerNames.Length;i++) //here we initialize our popupMenuIndex with the current Sort Layer Name
{
if (sortingLayerNames[i] == _trailRenderer.sortingLayerName)
popupMenuIndex = i;
}
}
public override void OnInspectorGUI()
{
DrawDefaultInspector();
if (_trailRenderer == null)
{
return;
}
popupMenuIndex = EditorGUILayout.Popup("Sorting Layer", popupMenuIndex, sortingLayerNames);
int newSortingLayerOrder = EditorGUILayout.IntField("Order in Layer", _trailRenderer.sortingOrder);
if (sortingLayerNames[popupMenuIndex] != _trailRenderer.sortingLayerName
|| newSortingLayerOrder != _trailRenderer.sortingOrder)
{
Undo.RecordObject(_trailRenderer, "Change Particle System Renderer Order");
_trailRenderer.sortingLayerName = sortingLayerNames[popupMenuIndex];
_trailRenderer.sortingOrder = newSortingLayerOrder;
EditorUtility.SetDirty(_trailRenderer);
}
}
public string[] GetSortingLayerNames()
{
Type internalEditorUtilityType = typeof(InternalEditorUtility);
PropertyInfo sortingLayersProperty = internalEditorUtilityType.GetProperty("sortingLayerNames", BindingFlags.Static | BindingFlags.NonPublic);
return (string[])sortingLayersProperty.GetValue(null, new object[0]);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f767333d7f0eaf24892e4778169d0d37
timeCreated: 1491156263
licenseType: Store
MonoImporter:
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