// // Procedural Lightning for Unity // (c) 2015 Digital Ruby, LLC // Source code may be used for personal or commercial projects. // Source code may NOT be redistributed or sold. // using System.Collections.Generic; using UnityEngine; #if UNITY_EDITOR using UnityEditor; using UnityEditor.AnimatedValues; using UnityEditorInternal; #endif namespace DigitalRuby.ThunderAndLightning { /// /// Min and max range of int (inclusive) /// [System.Serializable] public struct RangeOfIntegers { /// Minimum value (inclusive) [Tooltip("Minimum value (inclusive)")] public int Minimum; /// Maximum value (inclusive) [Tooltip("Maximum value (inclusive)")] public int Maximum; /// /// Generate a random value /// /// public int Random() { return UnityEngine.Random.Range(Minimum, Maximum + 1); } /// /// Generate a random value with a random instance /// /// Random /// Random value public int Random(System.Random r) { return r.Next(Minimum, Maximum + 1); } } /// /// Min and max range of floats (inclusive) /// [System.Serializable] public struct RangeOfFloats { /// Minimum value (inclusive) [Tooltip("Minimum value (inclusive)")] public float Minimum; /// Maximum value (inclusive) [Tooltip("Maximum value (inclusive)")] public float Maximum; /// /// Generate a random value /// /// public float Random() { return UnityEngine.Random.Range(Minimum, Maximum); } /// /// Generate a random value with a random instance /// /// Random /// Random value public float Random(System.Random r) { return Minimum + ((float)r.NextDouble() * (Maximum - Minimum)); } } /// /// Apply to a field to make it render in one line /// public class SingleLineAttribute : PropertyAttribute { /// /// Constructor /// /// Tooltip public SingleLineAttribute(string tooltip) { Tooltip = tooltip; } /// /// Tooltip /// public string Tooltip { get; private set; } } /// /// Same as SingleLineAttribute but with clamp /// public class SingleLineClampAttribute : SingleLineAttribute { /// /// Constructor /// /// Tooltip /// Min value /// Max value public SingleLineClampAttribute(string tooltip, double minValue, double maxValue) : base(tooltip) { MinValue = minValue; MaxValue = maxValue; } /// /// Min value /// public double MinValue { get; private set; } /// /// Max value /// public double MaxValue { get; private set; } } #if UNITY_EDITOR /// /// Single line drawer, used on Vector4, RangeOfFloats and RangeOfIntegers /// [CustomPropertyDrawer(typeof(SingleLineAttribute))] [CustomPropertyDrawer(typeof(SingleLineClampAttribute))] public class SingleLineDrawer : PropertyDrawer { private void DrawIntTextField(Rect position, string text, string tooltip, SerializedProperty prop) { EditorGUI.BeginChangeCheck(); int value = EditorGUI.IntField(position, new GUIContent(text, tooltip), prop.intValue); SingleLineClampAttribute clamp = attribute as SingleLineClampAttribute; if (clamp != null) { value = Mathf.Clamp(value, (int)clamp.MinValue, (int)clamp.MaxValue); } if (EditorGUI.EndChangeCheck()) { prop.intValue = value; } } private void DrawFloatTextField(Rect position, string text, string tooltip, SerializedProperty prop) { EditorGUI.BeginChangeCheck(); float value = EditorGUI.FloatField(position, new GUIContent(text, tooltip), prop.floatValue); SingleLineClampAttribute clamp = attribute as SingleLineClampAttribute; if (clamp != null) { value = Mathf.Clamp(value, (float)clamp.MinValue, (float)clamp.MaxValue); } if (EditorGUI.EndChangeCheck()) { prop.floatValue = value; } } private void DrawRangeField(Rect position, SerializedProperty prop, bool floatingPoint) { EditorGUIUtility.labelWidth = 30.0f; EditorGUIUtility.fieldWidth = 40.0f; float width = position.width * 0.49f; float spacing = position.width * 0.02f; position.width = width; if (floatingPoint) { DrawFloatTextField(position, "Min", "Minimum value", prop.FindPropertyRelative("Minimum")); } else { DrawIntTextField(position, "Min", "Minimum value", prop.FindPropertyRelative("Minimum")); } position.x = position.xMax + spacing; position.width = width; if (floatingPoint) { DrawFloatTextField(position, "Max", "Maximum value", prop.FindPropertyRelative("Maximum")); } else { DrawIntTextField(position, "Max", "Maximum value", prop.FindPropertyRelative("Maximum")); } } /// /// OnGUI /// /// Position /// Property /// Label public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label) { EditorGUI.BeginProperty(position, label, prop); int indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0; position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(label.text, (attribute as SingleLineAttribute).Tooltip)); switch (prop.type) { case "RangeOfIntegers": DrawRangeField(position, prop, false); break; case "RangeOfFloats": DrawRangeField(position, prop, true); break; default: EditorGUI.HelpBox(position, "[SingleLineDrawer] doesn't work with type '" + prop.type + "'", MessageType.Error); break; } EditorGUI.indentLevel = indent; EditorGUI.EndProperty(); } } #endif }