LightningEditorUtilities.cs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. //
  2. // Procedural Lightning for Unity
  3. // (c) 2015 Digital Ruby, LLC
  4. // Source code may be used for personal or commercial projects.
  5. // Source code may NOT be redistributed or sold.
  6. //
  7. using System.Collections.Generic;
  8. using UnityEngine;
  9. #if UNITY_EDITOR
  10. using UnityEditor;
  11. using UnityEditor.AnimatedValues;
  12. using UnityEditorInternal;
  13. #endif
  14. namespace DigitalRuby.ThunderAndLightning
  15. {
  16. /// <summary>
  17. /// Min and max range of int (inclusive)
  18. /// </summary>
  19. [System.Serializable]
  20. public struct RangeOfIntegers
  21. {
  22. /// <summary>Minimum value (inclusive)</summary>
  23. [Tooltip("Minimum value (inclusive)")]
  24. public int Minimum;
  25. /// <summary>Maximum value (inclusive)</summary>
  26. [Tooltip("Maximum value (inclusive)")]
  27. public int Maximum;
  28. /// <summary>
  29. /// Generate a random value
  30. /// </summary>
  31. /// <returns></returns>
  32. public int Random() { return UnityEngine.Random.Range(Minimum, Maximum + 1); }
  33. /// <summary>
  34. /// Generate a random value with a random instance
  35. /// </summary>
  36. /// <param name="r">Random</param>
  37. /// <returns>Random value</returns>
  38. public int Random(System.Random r) { return r.Next(Minimum, Maximum + 1); }
  39. }
  40. /// <summary>
  41. /// Min and max range of floats (inclusive)
  42. /// </summary>
  43. [System.Serializable]
  44. public struct RangeOfFloats
  45. {
  46. /// <summary>Minimum value (inclusive)</summary>
  47. [Tooltip("Minimum value (inclusive)")]
  48. public float Minimum;
  49. /// <summary>Maximum value (inclusive)</summary>
  50. [Tooltip("Maximum value (inclusive)")]
  51. public float Maximum;
  52. /// <summary>
  53. /// Generate a random value
  54. /// </summary>
  55. /// <returns></returns>
  56. public float Random() { return UnityEngine.Random.Range(Minimum, Maximum); }
  57. /// <summary>
  58. /// Generate a random value with a random instance
  59. /// </summary>
  60. /// <param name="r">Random</param>
  61. /// <returns>Random value</returns>
  62. public float Random(System.Random r) { return Minimum + ((float)r.NextDouble() * (Maximum - Minimum)); }
  63. }
  64. /// <summary>
  65. /// Apply to a field to make it render in one line
  66. /// </summary>
  67. public class SingleLineAttribute : PropertyAttribute
  68. {
  69. /// <summary>
  70. /// Constructor
  71. /// </summary>
  72. /// <param name="tooltip">Tooltip</param>
  73. public SingleLineAttribute(string tooltip) { Tooltip = tooltip; }
  74. /// <summary>
  75. /// Tooltip
  76. /// </summary>
  77. public string Tooltip { get; private set; }
  78. }
  79. /// <summary>
  80. /// Same as SingleLineAttribute but with clamp
  81. /// </summary>
  82. public class SingleLineClampAttribute : SingleLineAttribute
  83. {
  84. /// <summary>
  85. /// Constructor
  86. /// </summary>
  87. /// <param name="tooltip">Tooltip</param>
  88. /// <param name="minValue">Min value</param>
  89. /// <param name="maxValue">Max value</param>
  90. public SingleLineClampAttribute(string tooltip, double minValue, double maxValue) : base(tooltip)
  91. {
  92. MinValue = minValue;
  93. MaxValue = maxValue;
  94. }
  95. /// <summary>
  96. /// Min value
  97. /// </summary>
  98. public double MinValue { get; private set; }
  99. /// <summary>
  100. /// Max value
  101. /// </summary>
  102. public double MaxValue { get; private set; }
  103. }
  104. #if UNITY_EDITOR
  105. /// <summary>
  106. /// Single line drawer, used on Vector4, RangeOfFloats and RangeOfIntegers
  107. /// </summary>
  108. [CustomPropertyDrawer(typeof(SingleLineAttribute))]
  109. [CustomPropertyDrawer(typeof(SingleLineClampAttribute))]
  110. public class SingleLineDrawer : PropertyDrawer
  111. {
  112. private void DrawIntTextField(Rect position, string text, string tooltip, SerializedProperty prop)
  113. {
  114. EditorGUI.BeginChangeCheck();
  115. int value = EditorGUI.IntField(position, new GUIContent(text, tooltip), prop.intValue);
  116. SingleLineClampAttribute clamp = attribute as SingleLineClampAttribute;
  117. if (clamp != null)
  118. {
  119. value = Mathf.Clamp(value, (int)clamp.MinValue, (int)clamp.MaxValue);
  120. }
  121. if (EditorGUI.EndChangeCheck())
  122. {
  123. prop.intValue = value;
  124. }
  125. }
  126. private void DrawFloatTextField(Rect position, string text, string tooltip, SerializedProperty prop)
  127. {
  128. EditorGUI.BeginChangeCheck();
  129. float value = EditorGUI.FloatField(position, new GUIContent(text, tooltip), prop.floatValue);
  130. SingleLineClampAttribute clamp = attribute as SingleLineClampAttribute;
  131. if (clamp != null)
  132. {
  133. value = Mathf.Clamp(value, (float)clamp.MinValue, (float)clamp.MaxValue);
  134. }
  135. if (EditorGUI.EndChangeCheck())
  136. {
  137. prop.floatValue = value;
  138. }
  139. }
  140. private void DrawRangeField(Rect position, SerializedProperty prop, bool floatingPoint)
  141. {
  142. EditorGUIUtility.labelWidth = 30.0f;
  143. EditorGUIUtility.fieldWidth = 40.0f;
  144. float width = position.width * 0.49f;
  145. float spacing = position.width * 0.02f;
  146. position.width = width;
  147. if (floatingPoint)
  148. {
  149. DrawFloatTextField(position, "Min", "Minimum value", prop.FindPropertyRelative("Minimum"));
  150. }
  151. else
  152. {
  153. DrawIntTextField(position, "Min", "Minimum value", prop.FindPropertyRelative("Minimum"));
  154. }
  155. position.x = position.xMax + spacing;
  156. position.width = width;
  157. if (floatingPoint)
  158. {
  159. DrawFloatTextField(position, "Max", "Maximum value", prop.FindPropertyRelative("Maximum"));
  160. }
  161. else
  162. {
  163. DrawIntTextField(position, "Max", "Maximum value", prop.FindPropertyRelative("Maximum"));
  164. }
  165. }
  166. /// <summary>
  167. /// OnGUI
  168. /// </summary>
  169. /// <param name="position">Position</param>
  170. /// <param name="prop">Property</param>
  171. /// <param name="label">Label</param>
  172. public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
  173. {
  174. EditorGUI.BeginProperty(position, label, prop);
  175. int indent = EditorGUI.indentLevel;
  176. EditorGUI.indentLevel = 0;
  177. position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), new GUIContent(label.text, (attribute as SingleLineAttribute).Tooltip));
  178. switch (prop.type)
  179. {
  180. case "RangeOfIntegers":
  181. DrawRangeField(position, prop, false);
  182. break;
  183. case "RangeOfFloats":
  184. DrawRangeField(position, prop, true);
  185. break;
  186. default:
  187. EditorGUI.HelpBox(position, "[SingleLineDrawer] doesn't work with type '" + prop.type + "'", MessageType.Error);
  188. break;
  189. }
  190. EditorGUI.indentLevel = indent;
  191. EditorGUI.EndProperty();
  192. }
  193. }
  194. #endif
  195. }