1
This commit is contained in:
420
Assets/Dreamteck/Splines/Editor/Components/SplineUserEditor.cs
Normal file
420
Assets/Dreamteck/Splines/Editor/Components/SplineUserEditor.cs
Normal file
@@ -0,0 +1,420 @@
|
||||
namespace Dreamteck.Splines.Editor
|
||||
{
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(SplineUser), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class SplineUserEditor : Editor
|
||||
{
|
||||
protected bool showClip = true;
|
||||
protected bool showAveraging = true;
|
||||
protected bool showUpdateMethod = true;
|
||||
protected bool showMultithreading = true;
|
||||
private bool settingsFoldout = false;
|
||||
protected RotationModifierEditor rotationModifierEditor;
|
||||
protected OffsetModifierEditor offsetModifierEditor;
|
||||
protected ColorModifierEditor colorModifierEditor;
|
||||
protected SizeModifierEditor sizeModifierEditor;
|
||||
protected SplineUser[] users = new SplineUser[0];
|
||||
SerializedProperty multithreadedProperty, updateMethodProperty, buildOnAwakeProperty, buildOnEnableProperty, autoUpdateProperty, loopSamplesProperty, clipFromProperty, clipToProperty;
|
||||
protected GUIStyle foldoutHeaderStyle;
|
||||
|
||||
bool doRebuild = false;
|
||||
protected SerializedProperty spline;
|
||||
|
||||
public int editIndex
|
||||
{
|
||||
get { return _editIndex; }
|
||||
set
|
||||
{
|
||||
if(value == 0)
|
||||
{
|
||||
Debug.LogError("Cannot set edit index to 0. 0 is reserved.");
|
||||
return;
|
||||
}
|
||||
if (value < -1) value = -1;
|
||||
_editIndex = value;
|
||||
}
|
||||
}
|
||||
private int _editIndex = -1; //0 is reserved for editing clip values
|
||||
|
||||
protected GUIContent editButtonContent = new GUIContent("Edit", "Enable edit mode in scene view");
|
||||
|
||||
protected virtual void HeaderGUI()
|
||||
{
|
||||
SplineUser user = (SplineUser)target;
|
||||
Undo.RecordObject(user, "Inspector Change");
|
||||
SplineComputer lastSpline = (SplineComputer)spline.objectReferenceValue;
|
||||
EditorGUILayout.PropertyField(spline);
|
||||
SplineComputer newSpline = (SplineComputer)spline.objectReferenceValue;
|
||||
if (lastSpline != (SplineComputer)spline.objectReferenceValue)
|
||||
{
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
if (lastSpline != null) lastSpline.Unsubscribe(users[i]);
|
||||
if (newSpline != null) newSpline.Subscribe(users[i]);
|
||||
}
|
||||
user.Rebuild();
|
||||
}
|
||||
|
||||
|
||||
if (user.spline == null) EditorGUILayout.HelpBox("No SplineComputer is referenced. Link a SplineComputer to make this SplineUser work.", MessageType.Error);
|
||||
|
||||
settingsFoldout = EditorGUILayout.Foldout(settingsFoldout, "User Configuration", foldoutHeaderStyle);
|
||||
if (settingsFoldout)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (showClip) InspectorClipEdit();
|
||||
if (showUpdateMethod) EditorGUILayout.PropertyField(updateMethodProperty);
|
||||
EditorGUILayout.PropertyField(autoUpdateProperty, new GUIContent("Auto Rebuild"));
|
||||
if (showMultithreading) EditorGUILayout.PropertyField(multithreadedProperty);
|
||||
EditorGUILayout.PropertyField(buildOnAwakeProperty);
|
||||
EditorGUILayout.PropertyField(buildOnEnableProperty);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
private void InspectorClipEdit()
|
||||
{
|
||||
bool isClosed = true;
|
||||
bool loopSamples = true;
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
if (users[i].spline == null) isClosed = false;
|
||||
else if (!users[i].spline.isClosed) isClosed = false;
|
||||
else if (!users[i].loopSamples) loopSamples = false;
|
||||
}
|
||||
|
||||
float clipFrom = clipFromProperty.floatValue;
|
||||
float clipTo = clipToProperty.floatValue;
|
||||
|
||||
if (isClosed && loopSamples)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (EditButton(_editIndex == 0))
|
||||
{
|
||||
if (_editIndex == 0) _editIndex = -1;
|
||||
else _editIndex = 0;
|
||||
}
|
||||
EditorGUILayout.BeginVertical();
|
||||
clipFrom = EditorGUILayout.Slider("Clip From", clipFrom, 0f, 1f);
|
||||
clipTo = EditorGUILayout.Slider("Clip To", clipTo, 0f, 1f);
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (EditButton(_editIndex == 0))
|
||||
{
|
||||
if (_editIndex == 0) _editIndex = -1;
|
||||
else _editIndex = 0;
|
||||
}
|
||||
if (GUILayout.Button("Set Distance", GUILayout.Width(85)))
|
||||
{
|
||||
ClipRangeWindow w = EditorWindow.GetWindow<ClipRangeWindow>(true);
|
||||
float length = 0f;
|
||||
if(users.Length == 1)
|
||||
{
|
||||
length = users[0].spline.CalculateLength();
|
||||
}
|
||||
float fromDist = 0f;
|
||||
float toDist = 0f;
|
||||
int divide = 0;
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
if(users[i].spline != null)
|
||||
{
|
||||
fromDist += users[i].spline.CalculateLength(0.0, users[i].clipFrom);
|
||||
toDist += users[i].spline.CalculateLength(0.0, users[i].clipTo);
|
||||
divide++;
|
||||
}
|
||||
}
|
||||
|
||||
if(divide > 0)
|
||||
{
|
||||
fromDist /= divide;
|
||||
toDist /= divide;
|
||||
}
|
||||
w.Init(OnSetClipRangeDistance, fromDist, toDist, length);
|
||||
|
||||
}
|
||||
EditorGUIUtility.labelWidth = 80f;
|
||||
EditorGUILayout.MinMaxSlider(new GUIContent("Clip Range "), ref clipFrom, ref clipTo, 0f, 1f);
|
||||
EditorGUIUtility.labelWidth = 0f;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(30));
|
||||
clipFrom = EditorGUILayout.FloatField(clipFrom);
|
||||
clipTo = EditorGUILayout.FloatField(clipTo);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
}
|
||||
clipFromProperty.floatValue = clipFrom;
|
||||
clipToProperty.floatValue = clipTo;
|
||||
SplineComputerEditor.hold = _editIndex >= 0;
|
||||
|
||||
if (isClosed) EditorGUILayout.PropertyField(loopSamplesProperty, new GUIContent("Loop Samples"));
|
||||
if (!loopSamplesProperty.boolValue || !isClosed)
|
||||
{
|
||||
if (clipFromProperty.floatValue > clipToProperty.floatValue)
|
||||
{
|
||||
float temp = clipToProperty.floatValue;
|
||||
clipToProperty.floatValue = clipFromProperty.floatValue;
|
||||
clipFromProperty.floatValue = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnSetClipRangeDistance(float from, float to)
|
||||
{
|
||||
int longest = 0;
|
||||
float max = 0f;
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
if (users[i].spline == null) continue;
|
||||
float length = users[i].CalculateLength();
|
||||
if(length > max)
|
||||
{
|
||||
max = length;
|
||||
longest = i;
|
||||
}
|
||||
}
|
||||
clipFromProperty = serializedObject.FindProperty("_clipFrom");
|
||||
clipToProperty = serializedObject.FindProperty("_clipTo");
|
||||
serializedObject.Update();
|
||||
clipFromProperty.floatValue = (float)users[longest].spline.Travel(0.0, from);
|
||||
clipToProperty.floatValue = (float)users[longest].spline.Travel(0.0, to);
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
if (users[i].spline == null) continue;
|
||||
users[i].clipFrom = clipFromProperty.floatValue;
|
||||
users[i].clipTo = clipToProperty.floatValue;
|
||||
users[i].RebuildImmediate();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void BodyGUI()
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
protected virtual void FooterGUI()
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Sample Modifiers", EditorStyles.boldLabel);
|
||||
if (users.Length == 1)
|
||||
{
|
||||
if (offsetModifierEditor != null) offsetModifierEditor.DrawInspector();
|
||||
if (rotationModifierEditor != null) rotationModifierEditor.DrawInspector();
|
||||
if (colorModifierEditor != null) colorModifierEditor.DrawInspector();
|
||||
if (sizeModifierEditor != null) sizeModifierEditor.DrawInspector();
|
||||
}
|
||||
else EditorGUILayout.LabelField("Modifiers not available when multiple Spline Users are selected.", EditorStyles.centeredGreyMiniLabel);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
protected virtual void DuringSceneGUI(SceneView currentSceneView)
|
||||
{
|
||||
if (doRebuild)
|
||||
{
|
||||
DoRebuild();
|
||||
}
|
||||
SplineUser user = (SplineUser)target;
|
||||
if (user == null) return;
|
||||
if (user.spline != null)
|
||||
{
|
||||
SplineComputer rootComputer = user.GetComponent<SplineComputer>();
|
||||
List<SplineComputer> allComputers = user.spline.GetConnectedComputers();
|
||||
for (int i = 0; i < allComputers.Count; i++)
|
||||
{
|
||||
if (allComputers[i] == rootComputer && _editIndex == -1) continue;
|
||||
if (allComputers[i].editorAlwaysDraw) continue;
|
||||
DSSplineDrawer.DrawSplineComputer(allComputers[i], 0.0, 1.0, 0.4f);
|
||||
}
|
||||
DSSplineDrawer.DrawSplineComputer(user.spline);
|
||||
}
|
||||
if (_editIndex == 0) SceneClipEdit();
|
||||
if (offsetModifierEditor != null) offsetModifierEditor.DrawScene();
|
||||
if (rotationModifierEditor != null) rotationModifierEditor.DrawScene();
|
||||
if (colorModifierEditor != null) colorModifierEditor.DrawScene();
|
||||
if (sizeModifierEditor != null) sizeModifierEditor.DrawScene();
|
||||
}
|
||||
|
||||
void SceneClipEdit()
|
||||
{
|
||||
if (users.Length > 1) return;
|
||||
SplineUser user = (SplineUser)target;
|
||||
if (user.spline == null) return;
|
||||
Color col = user.spline.editorPathColor;
|
||||
Undo.RecordObject(user, "Edit Clip Range");
|
||||
double val = user.clipFrom;
|
||||
SplineComputerEditorHandles.Slider(user.spline, ref val, col, "Clip From", SplineComputerEditorHandles.SplineSliderGizmo.ForwardTriangle);
|
||||
if (val != user.clipFrom) user.clipFrom = val;
|
||||
val = user.clipTo;
|
||||
SplineComputerEditorHandles.Slider(user.spline, ref val, col, "Clip To", SplineComputerEditorHandles.SplineSliderGizmo.BackwardTriangle);
|
||||
if (val != user.clipTo) user.clipTo = val;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
if (doRebuild) DoRebuild();
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
HeaderGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
ApplyAndRebuild();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
BodyGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
ApplyAndRebuild();
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
FooterGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
ApplyAndRebuild();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyAndRebuild()
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
DoRebuild();
|
||||
}
|
||||
|
||||
private void DoRebuild()
|
||||
{
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
if (users[i] && users[i].isActiveAndEnabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
users[i].Rebuild();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.Log(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
doRebuild = false;
|
||||
}
|
||||
|
||||
protected virtual void OnDestroy()
|
||||
{
|
||||
if (Application.isEditor && !Application.isPlaying)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
OnDelete(); //The object or the component is being deleted
|
||||
}
|
||||
else
|
||||
{
|
||||
DoRebuild();
|
||||
}
|
||||
}
|
||||
SplineComputerEditor.hold = false;
|
||||
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
SceneView.duringSceneGui -= DuringSceneGUI;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected virtual void OnDelete()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
foldoutHeaderStyle = EditorStyles.foldout;
|
||||
#if UNITY_2019_1_OR_NEWER
|
||||
SceneView.duringSceneGui += DuringSceneGUI;
|
||||
#endif
|
||||
SplineUser user = (SplineUser)target;
|
||||
user.EditorAwake();
|
||||
}
|
||||
|
||||
#if !UNITY_2019_1_OR_NEWER
|
||||
protected void OnSceneGUI()
|
||||
{
|
||||
DuringSceneGUI(SceneView.currentDrawingSceneView);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
SplineUser user = (SplineUser)target;
|
||||
|
||||
settingsFoldout = EditorPrefs.GetBool("Dreamteck.Splines.Editor.SplineUserEditor.settingsFoldout", false);
|
||||
rotationModifierEditor = new RotationModifierEditor(user, this);
|
||||
offsetModifierEditor = new OffsetModifierEditor(user, this);
|
||||
colorModifierEditor = new ColorModifierEditor(user, this);
|
||||
sizeModifierEditor = new SizeModifierEditor(user, this);
|
||||
|
||||
updateMethodProperty = serializedObject.FindProperty("updateMethod");
|
||||
buildOnAwakeProperty = serializedObject.FindProperty("buildOnAwake");
|
||||
buildOnEnableProperty = serializedObject.FindProperty("buildOnEnable");
|
||||
multithreadedProperty = serializedObject.FindProperty("multithreaded");
|
||||
autoUpdateProperty = serializedObject.FindProperty("_autoUpdate");
|
||||
loopSamplesProperty = serializedObject.FindProperty("_loopSamples");
|
||||
clipFromProperty = serializedObject.FindProperty("_clipFrom");
|
||||
clipToProperty = serializedObject.FindProperty("_clipTo");
|
||||
spline = serializedObject.FindProperty("_spline");
|
||||
|
||||
users = new SplineUser[targets.Length];
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
users[i] = (SplineUser)targets[i];
|
||||
}
|
||||
Undo.undoRedoPerformed += OnUndoRedo;
|
||||
}
|
||||
|
||||
|
||||
protected virtual void OnDisable()
|
||||
{
|
||||
EditorPrefs.SetBool("Dreamteck.Splines.Editor.SplineUserEditor.settingsFoldout", settingsFoldout);
|
||||
Undo.undoRedoPerformed -= OnUndoRedo;
|
||||
}
|
||||
|
||||
protected virtual void OnUndoRedo()
|
||||
{
|
||||
doRebuild = true;
|
||||
}
|
||||
|
||||
public bool EditButton(bool selected)
|
||||
{
|
||||
float width = 40f;
|
||||
editButtonContent.image = ResourceUtility.EditorLoadTexture("Splines/Editor/Icons", "edit_cursor");
|
||||
if (editButtonContent.image != null)
|
||||
{
|
||||
editButtonContent.text = "";
|
||||
width = 25f;
|
||||
}
|
||||
SplineEditorGUI.SetHighlightColors(SplinePrefs.highlightColor, SplinePrefs.highlightContentColor);
|
||||
if (SplineEditorGUI.EditorLayoutSelectableButton(editButtonContent, true, selected, GUILayout.Width(width)))
|
||||
{
|
||||
SceneView.RepaintAll();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user