//
// 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
}