Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JohannesMP/6ca34305208a01688fd09d3a8757368f to your computer and use it in GitHub Desktop.
Save JohannesMP/6ca34305208a01688fd09d3a8757368f to your computer and use it in GitHub Desktop.
Code running pack! two property drawing scripts that make it super easy to trigger code via buttons in the inspector, and get feedback! [TestButton] draws you little buttons that call a method on your MonoBehaviour, and [ProgressBar] give you a great way to show feedback from long running methods. These are *super* helpful for things like proced…
using UnityEngine;
using System.Collections;
public class InspectorButtonsTest : MonoBehaviour
{
[TestButton("Generate world", "DoProcGen", isActiveInEditor = false)]
[TestButton("Clear world", "ClearWorld", 2, isActiveInEditor = false)]
[ProgressBar(hideWhenZero = true, label = "procGenFeedback")]
public float procgenProgress = -1;
[HideInInspector]
public string procGenFeedback;
// Silly little enumerator to test progress bars~
IEnumerator DoProcGen()
{
// lets pretend we have some code here that procedurally generates a map
procGenFeedback = "Initilizing";
procgenProgress = 0.01f;
yield return new WaitForSeconds(0.25f);
procGenFeedback = "Seeding terrain";
procgenProgress = 0.2f;
yield return new WaitForSeconds(0.25f);
procGenFeedback = "Plotting cities";
procgenProgress = 0.4f;
yield return new WaitForSeconds(0.25f);
procGenFeedback = "Drawing roads";
procgenProgress = 0.6f;
yield return new WaitForSeconds(0.25f);
procGenFeedback = "Reticulating splines";
procgenProgress = 0.8f;
yield return new WaitForSeconds(0.25f);
procGenFeedback = "Finalizing";
procgenProgress = 0.9f;
yield return new WaitForSeconds(0.25f);
procGenFeedback = "DONE in 6 seconds";
procgenProgress = 1f;
}
// resets values
void ClearWorld()
{
procgenProgress = 0;
}
}
using UnityEngine;
public class ProgressBarAttribute : PropertyAttribute
{
public bool hideWhenZero;
public string label;
}
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(ProgressBarAttribute))]
public class ProgressBarDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
if (property.propertyType != SerializedPropertyType.Float)
{
GUI.Label(position, "ERROR: can only apply progress bar onto a float");
return;
}
if ((attribute as ProgressBarAttribute).hideWhenZero && property.floatValue <= 0)
return;
var dynamicLabel = property.serializedObject.FindProperty((attribute as ProgressBarAttribute).label);
EditorGUI.ProgressBar(position, property.floatValue/1f, dynamicLabel == null ? property.name : dynamicLabel.stringValue);
}
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if ((attribute as ProgressBarAttribute).hideWhenZero && property.floatValue <= 0)
return 0;
return base.GetPropertyHeight(property, label);
}
}
// NOTE DONT put in an editor folder
using UnityEngine;
using System;
[AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = true)]
public class TestButtonAttribute : PropertyAttribute
{
public string buttonLabel;
public string methodName;
// Set this false to make the button not work whilst in playmode
public bool isActiveAtRuntime = true;
// Set this to false to make the button not work when the game isnt running
public bool isActiveInEditor = true;
public TestButtonAttribute(string buttonLabel, string methodName, int order = 1)
{
this.buttonLabel = buttonLabel;
this.methodName = methodName;
this.order = order; // Defualt the order to 1 so this can draw under headder attribles
}
}
// NOTE put in a Editor folder
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(TestButtonAttribute))]
public class TestButtonDrawer : DecoratorDrawer
{
public override void OnGUI(Rect position)
{
// cast the attribute to make it easier to work with
var buttonAttribute = (attribute as TestButtonAttribute);
// check if the button is supposed to be enabled right now
if (EditorApplication.isPlaying && !buttonAttribute.isActiveAtRuntime)
GUI.enabled = false;
if (!EditorApplication.isPlaying && !buttonAttribute.isActiveInEditor)
GUI.enabled = false;
// figure out where were drawing the button
var pos = new Rect(position.x, position.y, position.width, position.height - EditorGUIUtility.standardVerticalSpacing);
// draw it and if its clicked...
if (GUI.Button(pos, buttonAttribute.buttonLabel))
{
// tell the current game object to find and run the method we asked for!
Selection.activeGameObject.BroadcastMessage(buttonAttribute.methodName);
}
// make sure the GUI is enabled when were done!
GUI.enabled = true;
}
public override float GetHeight()
{
return EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing*2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment