using System; using UnityEngine; using UnityEngine.Splines; namespace UnityEditor.Splines { /// /// Contains IMGUI controls for editing Spline data. /// public static class SplineGUI { static GUIContent s_TempContent = new GUIContent(); static string[] s_SplineIndexPopupContents = new string[1] { "Spline 0" }; internal static GUIContent TempContent(string label, string tooltip = null, Texture2D image = null) { s_TempContent.text = label; s_TempContent.tooltip = tooltip; s_TempContent.image = image; return s_TempContent; } /// /// Creates a dropdown to select an index between 0 and the count of contained in the /// provided . /// /// A that determines how many splines are available in /// the popup selector. /// The label to use for this property. If null, the property display name is used. /// The rectangle on the screen to use for the field. /// A SerializedProperty that stores an integer value. /// An exception is thrown if is not an integer /// field. /// The type implementing . public static void SplineIndexField(Rect rect, SerializedProperty property, GUIContent label, T container) where T : ISplineContainer { SplineIndexField(rect, property, label, container == null ? 0 : container.Splines.Count); } /// /// Creates a dropdown to select an index between 0 and . /// /// The rectangle on the screen to use for the field. /// A SerializedProperty that stores an integer value. /// The label to use for this property. If null, the property display name is used. /// The number of splines available. In most cases, this is the size of /// /// An exception is thrown if is not an integer /// field. public static void SplineIndexField(Rect rect, SerializedProperty property, GUIContent label, int splineCount) { if (property.propertyType != SerializedPropertyType.Integer) throw new ArgumentException("Spline index property must be of type `int`.", nameof(property)); EditorGUI.showMixedValue = property.hasMultipleDifferentValues; property.intValue = SplineIndexPopup(rect, label == null ? property.displayName : label.text, property.intValue, splineCount); EditorGUI.showMixedValue = false; } /// /// Creates a dropdown to select an index between 0 and . /// /// An optional prefix label. /// The number of splines available. In most cases, this is the size of /// /// The rectangle on the screen to use for the field. /// The current index. /// The selected index. public static int SplineIndexPopup(Rect rect, string label, int index, int splineCount) { if (splineCount != s_SplineIndexPopupContents.Length) { Array.Resize(ref s_SplineIndexPopupContents, splineCount); for (int i = 0; i < splineCount; ++i) s_SplineIndexPopupContents[i] = $"Spline {i}"; } return Math.Min( Math.Max(0, EditorGUI.IntPopup(rect, label, index, s_SplineIndexPopupContents, null)), splineCount-1); } } /// /// Provides IMGUI controls to edit Spline data. /// public static class SplineGUILayout { /// /// Creates a dropdown to select an index between 0 and the count of contained in the /// provided . /// /// A that determines how many splines are available in /// the popup selector. /// A SerializedProperty that stores an integer value. /// An exception is thrown if is not an integer /// field. /// The type implementing . public static void SplineIndexField(SerializedProperty property, T container) where T : ISplineContainer { SplineIndexField(property, container == null ? 0 : container.Splines.Count); } /// /// Creates a dropdown to select an index between 0 and . /// /// A SerializedProperty that stores an integer value. /// The number of splines available. In most cases, this is the size of /// /// An exception is thrown if is not an integer /// field. public static void SplineIndexField(SerializedProperty property, int splineCount) { if (property.propertyType != SerializedPropertyType.Integer) throw new ArgumentException("Spline index property must be of type `int`.", nameof(property)); EditorGUI.showMixedValue = property.hasMultipleDifferentValues; property.intValue = SplineIndexPopup(property.displayName, property.intValue, splineCount); EditorGUI.showMixedValue = false; } /// /// Creates a dropdown to select a spline index relative to . /// /// An optional prefix label. /// The current index. /// A that determines how many splines are available in /// the popup selector. /// The type of . /// The selected index. public static int SplineIndexPopup(string label, int index, T container) where T : ISplineContainer { return SplineIndexPopup(label, index, container == null ? 0 : container.Splines.Count); } /// /// Creates a dropdown to select an index between 0 and . /// /// An optional prefix label. /// The number of splines available. In most cases, this is the size of /// /// The current index. /// The selected index. public static int SplineIndexPopup(string label, int index, int splineCount) { var rect = GUILayoutUtility.GetRect(SplineGUI.TempContent(label), EditorStyles.popup); return SplineGUI.SplineIndexPopup(rect, label, index, splineCount); } /// /// Creates a field for an embedded property. Embedded /// is stored in the class and can be accessed through a string key value. Use this /// function to expose an embedded through the Inspector. /// /// The that holds the target. /// The index of the target in the /// array. /// The type of data stored in the embedded /// /// A string value used to identify and access embedded . /// True if the property has children, is expanded, and includeChildren was set to false. Returns false otherwise. public static bool EmbeddedSplineDataField(SplineContainer container, int index, EmbeddedSplineDataType type, string key) { return EmbeddedSplineDataField(null, container, index, type, key); } /// /// Creates a field for an embedded property. Embedded /// is stored in the class and can be accessed through a string key value. Use this /// function to expose an embedded through the Inspector. /// /// An optional prefix label. /// The that holds the target. /// The index of the target in the /// array. /// The type of data stored in the embedded /// /// A string value used to identify and access embedded . /// True if the property has children, is expanded, and includeChildren was set to false. Returns false otherwise. public static bool EmbeddedSplineDataField(GUIContent label, SplineContainer container, int index, EmbeddedSplineDataType type, string key) { if (container == null || index < 0 || index >= container.Splines.Count) return false; var property = SerializedPropertyUtility.GetEmbeddedSplineDataProperty(container, index, type, key); property.serializedObject.Update(); EditorGUI.BeginChangeCheck(); var ret = EditorGUILayout.PropertyField(property, label); if(EditorGUI.EndChangeCheck()) property.serializedObject.ApplyModifiedProperties(); return ret; } internal static void QuaternionField(Rect rect, GUIContent content, SerializedProperty property) { EditorGUI.BeginChangeCheck(); Quaternion value = SplineGUIUtility.GetQuaternionValue(property); var result = EditorGUI.Vector3Field(rect, content, value.eulerAngles); if (EditorGUI.EndChangeCheck()) SplineGUIUtility.SetQuaternionValue(property, Quaternion.Euler(result)); } } }