将Spline移出Plugin,以调整SplineRenderer的OnWillCameraRender

This commit is contained in:
SoulliesOfficial
2025-03-01 22:58:20 -05:00
parent 860d7393fb
commit 5d775ae687
529 changed files with 237 additions and 119 deletions

View File

@@ -0,0 +1,183 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO;
public class BakeMeshWindow : EditorWindow
{
public bool isStatic = true;
public bool copy = false;
public bool removeComputer = false;
public bool permanent = false;
public bool generateLightmapUVs = false;
MeshFilter filter;
MeshRenderer renderer;
MeshGenerator meshGen;
public enum SaveFormat { MeshAsset, OBJ, Scene }
SaveFormat format = SaveFormat.MeshAsset;
public void Init(MeshGenerator generator)
{
titleContent = new GUIContent("Bake Mesh");
meshGen = generator;
filter = generator.GetComponent<MeshFilter>();
renderer = generator.GetComponent<MeshRenderer>();
if (EditorPrefs.HasKey("BakeWindow_isStatic")) isStatic = EditorPrefs.GetBool("BakeWindow_isStatic");
if (EditorPrefs.HasKey("BakeWindow_generateLightmapUVs")) generateLightmapUVs = EditorPrefs.GetBool("BakeWindow_generateLightmapUVs");
if (EditorPrefs.HasKey("BakeWindow_copy")) copy = EditorPrefs.GetBool("BakeWindow_copy");
if (EditorPrefs.HasKey("BakeWindow_removeComputer")) removeComputer = EditorPrefs.GetBool("BakeWindow_removeComputer");
if (EditorPrefs.HasKey("BakeWindow_permanent")) permanent = EditorPrefs.GetBool("BakeWindow_permanent");
format = (SaveFormat)EditorPrefs.GetInt("BakeWindow_format", 0);
minSize = new Vector2(340, 220);
maxSize = minSize;
}
void OnDestroy()
{
EditorPrefs.SetBool("BakeWindow_isStatic", isStatic);
EditorPrefs.SetBool("BakeWindow_generateLightmapUVs", generateLightmapUVs);
EditorPrefs.SetBool("BakeWindow_copy", copy);
EditorPrefs.SetBool("BakeWindow_removeComputer", removeComputer);
EditorPrefs.SetBool("BakeWindow_permanent", permanent);
EditorPrefs.SetInt("BakeWindow_format", (int)format);
}
void OnGUI() {
format = (SaveFormat)EditorGUILayout.EnumPopup("Save Format", format);
bool saveMesh = format != SaveFormat.Scene;
if (format != SaveFormat.Scene) copy = EditorGUILayout.Toggle("Save without baking", copy);
bool isCopy = format != SaveFormat.Scene && copy;
switch (format)
{
case SaveFormat.Scene: EditorGUILayout.HelpBox("Saves the mesh inside the scene for lightmap", MessageType.Info); break;
case SaveFormat.MeshAsset: EditorGUILayout.HelpBox("Saves the mesh as an .asset file inside the project. This makes using the mesh in prefabs and across scenes possible.", MessageType.Info); break;
case SaveFormat.OBJ: EditorGUILayout.HelpBox("Exports the mesh as an OBJ file which can be imported in a third-party modeling application.", MessageType.Info); break;
}
EditorGUILayout.Space();
if (!isCopy)
{
isStatic = EditorGUILayout.Toggle("Make Static", isStatic);
permanent = EditorGUILayout.Toggle("Permanent", permanent);
generateLightmapUVs = EditorGUILayout.Toggle("Generate Lightmap UVs", generateLightmapUVs);
if (permanent)
{
removeComputer = EditorGUILayout.Toggle("Remove SplineComputer", removeComputer);
if (meshGen.spline.subscriberCount > 1 && !isCopy) EditorGUILayout.HelpBox("WARNING: Removing the SplineComputer from this object will cause other SplineUsers to malfunction!", MessageType.Warning);
}
}
string bakeText = "Bake Mesh";
if (saveMesh) bakeText = "Bake & Save Mesh";
if (isCopy) bakeText = "Save Mesh";
if (GUILayout.Button(bakeText))
{
if (permanent)
{
if (!EditorUtility.DisplayDialog("Permanent bake?", "This operation will remove the Mesh Generator. Are you sure you want to continue?", "Yes", "No")) return;
}
string savePath = "";
if (saveMesh)
{
string ext = "asset";
if (format == SaveFormat.OBJ) ext = "obj";
string meshName = "mesh";
if (filter != null) meshName = filter.sharedMesh.name;
savePath = EditorUtility.SaveFilePanel("Save " + meshName, Application.dataPath, meshName + "." + ext, ext);
if (!Directory.Exists(Path.GetDirectoryName(savePath)) || savePath == "")
{
EditorUtility.DisplayDialog("Save error", "Invalid save path. Please select a valid save path and try again", "OK");
return;
}
if (format == SaveFormat.OBJ && !copy && !savePath.StartsWith(Application.dataPath))
{
EditorUtility.DisplayDialog("Save error", "OBJ files can be saved outside of the project folder only when \"Save without baking\" is selected. Please select a directory inside the project in order to save.", "OK");
return;
}
if (format == SaveFormat.MeshAsset && !savePath.StartsWith(Application.dataPath))
{
EditorUtility.DisplayDialog("Save error", "Asset files cannot be saved outside of the project directory. Please select a path inside the project directory.", "OK");
return;
}
}
Undo.RecordObject(meshGen.gameObject, "Bake mesh");
if (!isCopy) Bake();
else
{
MeshUtility.Optimize(filter.sharedMesh);
Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
}
if (saveMesh)
{
SaveMeshFile(savePath);
}
}
}
void Bake()
{
meshGen.Bake(isStatic, generateLightmapUVs);
EditorUtility.SetDirty(meshGen);
if (permanent && !copy)
{
SplineComputer meshGenComputer = meshGen.spline;
if (permanent)
{
meshGenComputer.Unsubscribe(meshGen);
if (removeComputer && meshGen.transform.IsChildOf(meshGenComputer.transform))
{
DestroyImmediate(meshGenComputer);
}
DestroyImmediate(meshGen);
}
if (removeComputer && meshGenComputer != null)
{
if (meshGenComputer.GetComponents<Component>().Length == 2)
{
DestroyImmediate(meshGenComputer.gameObject);
}
else
{
DestroyImmediate(meshGenComputer);
}
}
}
}
void SaveMeshFile(string savePath)
{
if (format == SaveFormat.Scene) return;
string relativePath = "";
if(savePath.StartsWith(Application.dataPath)) relativePath = "Assets" + savePath.Substring(Application.dataPath.Length);
if (format == SaveFormat.MeshAsset)
{
if (copy)
{
Mesh assetMesh = Dreamteck.MeshUtility.Copy(filter.sharedMesh);
AssetDatabase.CreateAsset(assetMesh, relativePath);
} else AssetDatabase.CreateAsset(filter.sharedMesh, relativePath);
}
if (format == SaveFormat.OBJ)
{
string objString = Dreamteck.MeshUtility.ToOBJString(filter.sharedMesh, renderer.sharedMaterials);
File.WriteAllText(savePath, objString);
if (!copy) DestroyImmediate(filter.sharedMesh);
if (relativePath != "") //Import back the OBJ
{
AssetDatabase.ImportAsset(relativePath, ImportAssetOptions.ForceSynchronousImport);
if (!copy) filter.sharedMesh = AssetDatabase.LoadAssetAtPath<Mesh>(relativePath);
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: befdb339588e28f41aa626b8c6319d06
timeCreated: 1466584092
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(CapsuleColliderGenerator), true)]
[CanEditMultipleObjects]
public class CapsuleColliderGeneratorEditor : SplineUserEditor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
}
protected override void BodyGUI()
{
base.BodyGUI();
CapsuleColliderGenerator generator = (CapsuleColliderGenerator)target;
SerializedProperty directionProperty = serializedObject.FindProperty("_direction");
SerializedProperty heightProperty = serializedObject.FindProperty("_height");
SerializedProperty radiusProperty = serializedObject.FindProperty("_radius");
SerializedProperty overlapCapsProperty = serializedObject.FindProperty("_overlapCaps");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(directionProperty);
CapsuleColliderGenerator.CapsuleColliderZDirection direction = (CapsuleColliderGenerator.CapsuleColliderZDirection)directionProperty.intValue;
if(direction == CapsuleColliderGenerator.CapsuleColliderZDirection.Z)
{
EditorGUILayout.PropertyField(radiusProperty);
EditorGUILayout.PropertyField(overlapCapsProperty);
} else
{
EditorGUILayout.PropertyField(heightProperty);
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3a4dd445293b6d345b9675494ec5e182
timeCreated: 1459595686
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,323 @@
#if UNITY_EDITOR
using Dreamteck.Splines.Editor;
using UnityEditor;
using UnityEngine;
namespace Dreamteck.Splines
{
[CustomEditor(typeof(ComplexSurfaceGenerator), true)]
public class ComplexSurfaceGeneratorEditor : MeshGenEditor
{
private SplineComputer _lastEditedComputer;
private SplineComputer _highlightedComputer;
private int _lastEditedPointIndex = -1;
private bool _positionHandle = false;
private Vector2 _scroll = Vector2.zero;
protected override void Awake()
{
base.Awake();
_positionHandle = EditorPrefs.GetBool(nameof(ComplexSurfaceGeneratorEditor) + ".positionHandles", false);
if (Application.isPlaying) return;
SerializedProperty initProperty = serializedObject.FindProperty("_initializedInEditor");
ComplexSurfaceGenerator gen = (ComplexSurfaceGenerator)target;
if (!initProperty.boolValue)
{
AddSpline(gen);
initProperty.boolValue = true;
serializedObject.ApplyModifiedProperties();
}
SerializedProperty computersProperty = serializedObject.FindProperty("_otherComputers");
ValidateSplines(gen, computersProperty);
}
protected override void OnDestroy()
{
base.OnDestroy();
EditorPrefs.SetBool(nameof(ComplexSurfaceGeneratorEditor) + ".positionHandles", _positionHandle);
}
protected override void BodyGUI()
{
base.BodyGUI();
ComplexSurfaceGenerator gen = (ComplexSurfaceGenerator)target;
EditorGUI.BeginChangeCheck();
gen.separateMaterialIDs = EditorGUILayout.Toggle("Separate Material IDs", gen.separateMaterialIDs);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Paths", EditorStyles.boldLabel);
SerializedProperty computersProperty = serializedObject.FindProperty("_otherComputers");
SerializedProperty subdivisionsProperty = serializedObject.FindProperty("_subdivisions");
SerializedProperty subdivisionModeProperty = serializedObject.FindProperty("_subdivisionMode");
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
EditorGUI.BeginChangeCheck();
bool hasNullSpline = false;
for (int i = 0; i < gen.otherComputers.Length; i++)
{
if (gen.otherComputers[i] == null)
{
hasNullSpline = true;
break;
}
}
if(hasNullSpline)
{
EditorGUILayout.HelpBox("Missing or not enough splines. Please, link at least one splines and remove any missing references.", MessageType.Error);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Splines", EditorStyles.boldLabel);
_positionHandle = EditorGUILayout.Toggle("Toggle Move Handles", _positionHandle);
EditorGUILayout.Space();
EditorGUI.indentLevel++;
_scroll = EditorGUILayout.BeginScrollView(_scroll, GUILayout.Height(Mathf.Min(computersProperty.arraySize * 22, 300)));
for (int i = 0; i < computersProperty.arraySize; i++)
{
SerializedProperty compProperty = computersProperty.GetArrayElementAtIndex(i);
SplineComputer spline = (SplineComputer)compProperty.objectReferenceValue;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(spline.name);
if (GUILayout.Button("Edit", GUILayout.MaxWidth(75)))
{
Selection.activeGameObject = spline.gameObject;
}
if (GUILayout.Button("Highlight", GUILayout.MaxWidth(75)))
{
if(_highlightedComputer == spline)
{
_highlightedComputer = null;
} else
{
_highlightedComputer = spline;
}
}
if (GUILayout.Button("Remove", GUILayout.MaxWidth(75)))
{
if(EditorUtility.DisplayDialog("Delete Spline", "Also remove spline object?", "Yes", "No"))
{
DestroyImmediate(spline.gameObject);
}
computersProperty.DeleteArrayElementAtIndex(i);
i--;
serializedObject.ApplyModifiedProperties();
gen.RebuildImmediate();
}
EditorGUILayout.EndHorizontal();
}
//sEditorGUILayout.PropertyField(computersProperty, new GUIContent("Other Splines"));
if (EditorGUI.EndChangeCheck())
{
ValidateSplines(gen, computersProperty);
serializedObject.ApplyModifiedProperties();
gen.RebuildImmediate();
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Add Spline"))
{
AddSpline(gen);
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Normals", EditorStyles.boldLabel);
gen.automaticNormals = EditorGUILayout.Toggle("Automatic Normals", gen.automaticNormals);
var normalMethods = new string[]
{
MeshGenerator.NormalMethod.Recalculate.ToString(),
MeshGenerator.NormalMethod.SplineNormals.ToString(),
};
if (!gen.automaticNormals) gen.normalMethod = (MeshGenerator.NormalMethod)EditorGUILayout.Popup("Normal Method", (int)gen.normalMethod, normalMethods);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Geometry", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(subdivisionModeProperty);
EditorGUILayout.PropertyField(subdivisionsProperty);
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
UVControls(gen);
}
private void ValidateSplines(ComplexSurfaceGenerator gen, SerializedProperty computersProperty)
{
for (int i = 0; i < computersProperty.arraySize; i++)
{
SerializedProperty compProperty = computersProperty.GetArrayElementAtIndex(i);
SplineComputer spline = (SplineComputer)compProperty.objectReferenceValue;
bool isValid = spline != null;
if (isValid)
{
for (int j = 0; j < i; j++)
{
SerializedProperty compPropertyPrevious = computersProperty.GetArrayElementAtIndex(j);
SplineComputer previousSpline = (SplineComputer)compPropertyPrevious.objectReferenceValue;
if (spline == previousSpline)
{
isValid = false;
break;
}
}
}
if (!isValid)
{
computersProperty.DeleteArrayElementAtIndex(i);
serializedObject.ApplyModifiedProperties();
gen.RebuildImmediate();
i--;
continue;
}
spline.Unsubscribe(gen);
spline.Subscribe(gen);
}
}
private void AddSpline(ComplexSurfaceGenerator gen)
{
SplineComputer reference = gen.spline;
if (gen.otherComputers.Length > 0)
{
for (int i = gen.otherComputers.Length - 1; i >= 0; i--)
{
if (gen.otherComputers[i] != null)
{
reference = gen.otherComputers[i];
break;
}
}
}
SplineComputer spline = Instantiate(reference, gen.transform);
Component[] components = spline.GetComponents<Component>();
for (int i = components.Length-1; i >= 0; i--)
{
if (!(components[i] is SplineComputer || components[i] is Transform))
{
DestroyImmediate(components[i]);
}
}
while(spline.transform.childCount > 0)
{
DestroyImmediate(spline.transform.GetChild(0).gameObject);
}
Undo.RegisterCreatedObjectUndo(spline.gameObject, "Surface Add Spline");
Vector3 direction = Vector3.Slerp(reference.Evaluate(0.0).right, reference.Evaluate(1.0).right, 0.5f);
spline.Subscribe(gen);
spline.transform.position += direction * reference.CalculateLength() / Mathf.Max((reference.pointCount - 1), 1);
SerializedProperty computersProperty = serializedObject.FindProperty("_otherComputers");
computersProperty.arraySize += 1;
computersProperty.GetArrayElementAtIndex(computersProperty.arraySize - 1).objectReferenceValue = spline;
serializedObject.ApplyModifiedProperties();
spline.RebuildImmediate();
gen.RebuildImmediate();
}
public override void OnInspectorGUI()
{
showSize = false;
showRotation = false;
showNormalMethod = false;
showOffset = false;
base.OnInspectorGUI();
}
protected override void DuringSceneGUI(SceneView currentSceneView)
{
ComplexSurfaceGenerator gen = (ComplexSurfaceGenerator)target;
base.DuringSceneGUI(currentSceneView);
for (int i = 0; i < gen.otherComputers.Length; i++)
{
//SplineDrawer.DrawSplineComputer(gen.otherComputers[i]);
}
SplineComputer[] otherSplines = gen.otherComputers;
bool rebuild = false;
for (int i = 0; i < otherSplines.Length; i++)
{
bool markDirty = false;
if (otherSplines[i] == null) continue;
for (int j = 0; j < otherSplines[i].pointCount; j++)
{
if (otherSplines[i].subscriberCount == 1)
{
otherSplines[i].name = "Surface Spline " + (i + 1);
}
Vector3 point = otherSplines[i].GetPointPosition(j);
Vector3 newPos = point;
if (_positionHandle)
{
newPos = Handles.PositionHandle(newPos, Quaternion.identity);
} else
{
Handles.color = Color.clear;
newPos = SplineEditorHandles.FreeMoveRectangle(point, HandleUtility.GetHandleSize(point) * 0.16f);
}
if (Vector3.Distance(point, newPos) > 0.01f)
{
_lastEditedComputer = otherSplines[i];
_lastEditedPointIndex = j;
_highlightedComputer = null;
MainPointModule.HoldInteraction();
markDirty = true;
otherSplines[i].SetPointPosition(j, newPos);
}
bool isSelected = (_lastEditedComputer == otherSplines[i] && _lastEditedPointIndex == j) || (_highlightedComputer == otherSplines[i]);
if (Event.current.type == EventType.Repaint)
{
SplineEditorHandles.DrawPoint(point, isSelected, MainPointModule.isSelecting ? new Color(0.5f, 0.5f, 0.5f, 0.5f) : Color.white);
}
}
if(Event.current.type == EventType.MouseUp && Event.current.button == 0)
{
_lastEditedPointIndex = -1;
_lastEditedComputer = null;
}
if (markDirty)
{
EditorUtility.SetDirty(otherSplines[i]);
rebuild = true;
}
}
if (rebuild)
{
for (int i = 0; i < users.Length; i++)
{
users[i].RebuildImmediate();
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cf0447f608cafa548962ac2c49022f90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,34 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(EdgeColliderGenerator))]
[CanEditMultipleObjects]
public class EdgeColliderGeneratorEditor : SplineUserEditor
{
protected override void BodyGUI()
{
base.BodyGUI();
EdgeColliderGenerator generator = (EdgeColliderGenerator)target;
serializedObject.Update();
SerializedProperty offset = serializedObject.FindProperty("_offset");
SerializedProperty updateRate = serializedObject.FindProperty("updateRate");
EditorGUILayout.Space();
EditorGUILayout.LabelField("Polygon", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(offset, new GUIContent("Offset"));
EditorGUILayout.PropertyField(updateRate);
if (updateRate.floatValue < 0f) updateRate.floatValue = 0f;
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18c6e61192794d34084b29e95d81c0bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(LengthCalculator), true)]
[CanEditMultipleObjects]
public class LengthCalculatorEditor : SplineUserEditor
{
public override void OnInspectorGUI()
{
showAveraging = false;
base.OnInspectorGUI();
}
protected override void BodyGUI()
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Length Calculator", EditorStyles.boldLabel);
base.BodyGUI();
LengthCalculator calculator = (LengthCalculator)target;
for (int i = 0; i < targets.Length; i++)
{
LengthCalculator lengthCalc = (LengthCalculator)targets[i];
if (lengthCalc.spline == null) continue;
EditorGUILayout.HelpBox(lengthCalc.spline.name + " Length: " + lengthCalc.length, MessageType.Info);
}
if (targets.Length > 1) return;
SerializedProperty events = serializedObject.FindProperty("lengthEvents");
EditorGUI.BeginChangeCheck();
for (int i = 0; i < events.arraySize; i++)
{
SerializedProperty eventProperty = events.GetArrayElementAtIndex(i);
SerializedProperty onChange = eventProperty.FindPropertyRelative("onChange");
SerializedProperty enabled = eventProperty.FindPropertyRelative("enabled");
SerializedProperty targetLength = eventProperty.FindPropertyRelative("targetLength");
SerializedProperty type = eventProperty.FindPropertyRelative("type");
EditorGUIUtility.labelWidth = 100;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PropertyField(enabled, new GUIContent(""), GUILayout.Width(20));
EditorGUILayout.PropertyField(targetLength);
EditorGUIUtility.labelWidth = 60;
EditorGUILayout.PropertyField(type);
if (GUILayout.Button("x", GUILayout.Width(20)))
{
Undo.RecordObject(calculator, "Remove Length Event");
ArrayUtility.RemoveAt(ref calculator.lengthEvents, i);
}
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = 0;
EditorGUILayout.PropertyField(onChange);
EditorGUILayout.Space();
}
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
if (GUILayout.Button("Add Length Event"))
{
Undo.RecordObject(calculator, "Add Length Event");
ArrayUtility.Add(ref calculator.lengthEvents, new LengthCalculator.LengthEvent());
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4b0cb98d553738f458280b7a6589f63d
timeCreated: 1459595686
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,229 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(MeshGenerator))]
[CanEditMultipleObjects]
public class MeshGenEditor : SplineUserEditor
{
protected bool showSize = true;
protected bool showColor = true;
protected bool showDoubleSided = true;
protected bool showFlipFaces = true;
protected bool showRotation = true;
protected bool showInfo = false;
protected bool showOffset = true;
protected bool showTangents = true;
protected bool showNormalMethod = true;
private int _framesPassed = 0;
private bool _commonFoldout = false;
MeshGenerator[] generators = new MeshGenerator[0];
BakeMeshWindow bakeWindow = null;
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
MeshGenerator generator = (MeshGenerator)target;
if (Application.isPlaying) return;
_framesPassed++;
if(_framesPassed >= 100)
{
_framesPassed = 0;
if (generator != null && generator.GetComponent<MeshCollider>() != null) generator.UpdateCollider();
}
}
protected override void OnEnable()
{
base.OnEnable();
generators = new MeshGenerator[targets.Length];
for (int i = 0; i < targets.Length; i++)
{
generators[i] = (MeshGenerator)targets[i];
}
MeshGenerator user = (MeshGenerator)target;
}
public override void OnInspectorGUI()
{
MeshGenerator generator = (MeshGenerator)target;
if (generator.baked)
{
SplineEditorGUI.SetHighlightColors(SplinePrefs.highlightColor, SplinePrefs.highlightContentColor);
if (SplineEditorGUI.EditorLayoutSelectableButton(new GUIContent("Revert Bake", "Makes the mesh dynamic again and allows editing"), true, true))
{
for (int i = 0; i < generators.Length; i++)
{
generators[i].Unbake();
EditorUtility.SetDirty(generators[i]);
}
}
return;
}
base.OnInspectorGUI();
}
protected override void BodyGUI()
{
base.BodyGUI();
MeshGenerator generator = (MeshGenerator)target;
serializedObject.Update();
SerializedProperty calculateTangents = serializedObject.FindProperty("_calculateTangents");
SerializedProperty markDynamic = serializedObject.FindProperty("_markDynamic");
SerializedProperty size = serializedObject.FindProperty("_size");
SerializedProperty color = serializedObject.FindProperty("_color");
SerializedProperty normalMethod = serializedObject.FindProperty("_normalMethod");
SerializedProperty useSplineSize = serializedObject.FindProperty("_useSplineSize");
SerializedProperty useSplineColor = serializedObject.FindProperty("_useSplineColor");
SerializedProperty offset = serializedObject.FindProperty("_offset");
SerializedProperty rotation = serializedObject.FindProperty("_rotation");
SerializedProperty flipFaces = serializedObject.FindProperty("_flipFaces");
SerializedProperty doubleSided = serializedObject.FindProperty("_doubleSided");
SerializedProperty meshIndexFormat = serializedObject.FindProperty("_meshIndexFormat");
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
_commonFoldout = EditorGUILayout.Foldout(_commonFoldout, "Common", foldoutHeaderStyle);
if (_commonFoldout)
{
EditorGUI.indentLevel++;
if (showSize) EditorGUILayout.PropertyField(size, new GUIContent("Size"));
if (showColor) EditorGUILayout.PropertyField(color, new GUIContent("Color"));
if (showNormalMethod) EditorGUILayout.PropertyField(normalMethod, new GUIContent("Normal Method"));
if (showOffset) EditorGUILayout.PropertyField(offset, new GUIContent("Offset"));
if (showRotation) EditorGUILayout.PropertyField(rotation, new GUIContent("Rotation"));
if (showTangents) EditorGUILayout.PropertyField(calculateTangents, new GUIContent("Calculate Tangents"));
EditorGUILayout.PropertyField(useSplineSize, new GUIContent("Use Spline Size"));
EditorGUILayout.PropertyField(useSplineColor, new GUIContent("Use Spline Color"));
EditorGUILayout.PropertyField(markDynamic, new GUIContent("Mark Dynamic", "Improves performance in situations where the mesh changes frequently"));
EditorGUILayout.PropertyField(meshIndexFormat, new GUIContent("Index Format", "Format of the mesh index buffer data. Index buffer can either be 16 bit(supports up to 65535 vertices in a mesh), or 32 bit(supports up to 4 billion vertices).Default index format is 16 bit, since that takes less memory and bandwidth."));
if(meshIndexFormat.enumValueIndex > 0)
{
EditorGUILayout.HelpBox("Note that GPU support for 32 bit indices is not guaranteed on all platforms; for example Android devices with Mali-400 GPU do not support them.", MessageType.Warning);
}
EditorGUI.indentLevel--;
}
if (showDoubleSided || showFlipFaces)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Faces", EditorStyles.boldLabel);
if (showDoubleSided) EditorGUILayout.PropertyField(doubleSided, new GUIContent("Double-sided"));
if (!generator.doubleSided && showFlipFaces) EditorGUILayout.PropertyField(flipFaces, new GUIContent("Flip Faces"));
}
if (generator.GetComponent<MeshCollider>() != null)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Mesh Collider", EditorStyles.boldLabel);
generator.colliderUpdateRate = EditorGUILayout.FloatField("Collider Update Iterval", generator.colliderUpdateRate);
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
for (int i = 0; i < generators.Length; i++)
{
generators[i].Rebuild();
}
}
}
protected override void FooterGUI()
{
base.FooterGUI();
showInfo = EditorGUILayout.Foldout(showInfo, "Info & Components");
if (showInfo)
{
MeshGenerator generator = (MeshGenerator)target;
MeshFilter filter = generator.GetComponent<MeshFilter>();
if (filter == null) return;
MeshRenderer renderer = generator.GetComponent<MeshRenderer>();
string str = "";
if (filter.sharedMesh != null) str = "Vertices: " + filter.sharedMesh.vertexCount + "\r\nTriangles: " + (filter.sharedMesh.triangles.Length / 3);
else str = "No info available";
EditorGUILayout.HelpBox(str, MessageType.Info);
bool showFilter = filter.hideFlags == HideFlags.None;
bool last = showFilter;
showFilter = EditorGUILayout.Toggle("Show Mesh Filter", showFilter);
if (last != showFilter)
{
if (showFilter) filter.hideFlags = HideFlags.None;
else filter.hideFlags = HideFlags.HideInInspector;
}
bool showRenderer = renderer.hideFlags == HideFlags.None;
last = showRenderer;
showRenderer = EditorGUILayout.Toggle("Show Mesh Renderer", showRenderer);
if (last != showRenderer)
{
if (showRenderer) renderer.hideFlags = HideFlags.None;
else renderer.hideFlags = HideFlags.HideInInspector;
}
}
if (generators.Length == 1)
{
if (GUILayout.Button("Bake Mesh"))
{
MeshGenerator generator = (MeshGenerator)target;
bakeWindow = EditorWindow.GetWindow<BakeMeshWindow>();
bakeWindow.Init(generator);
}
}
}
protected override void Awake()
{
MeshGenerator generator = (MeshGenerator)target;
MeshRenderer rend = generator.GetComponent<MeshRenderer>();
if (rend == null) return;
base.Awake();
}
protected override void OnDestroy()
{
MeshGenerator generator = (MeshGenerator)target;
base.OnDestroy();
MeshGenerator gen = (MeshGenerator)target;
if (gen == null) return;
if (gen.GetComponent<MeshCollider>() != null) generator.UpdateCollider();
if (bakeWindow != null) bakeWindow.Close();
}
protected override void OnDelete()
{
base.OnDelete();
MeshGenerator generator = (MeshGenerator)target;
if (generator == null) return;
MeshFilter filter = generator.GetComponent<MeshFilter>();
if (filter != null) filter.hideFlags = HideFlags.None;
MeshRenderer renderer = generator.GetComponent<MeshRenderer>();
if (renderer != null) renderer.hideFlags = HideFlags.None;
}
protected virtual void UVControls(MeshGenerator generator)
{
serializedObject.Update();
SerializedProperty uvMode = serializedObject.FindProperty("_uvMode");
SerializedProperty uvOffset = serializedObject.FindProperty("_uvOffset");
SerializedProperty uvRotation = serializedObject.FindProperty("_uvRotation");
SerializedProperty uvScale = serializedObject.FindProperty("_uvScale");
EditorGUILayout.Space();
EditorGUILayout.LabelField("Uv Coordinates", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(uvMode, new GUIContent("UV Mode"));
EditorGUILayout.PropertyField(uvOffset, new GUIContent("UV Offset"));
EditorGUILayout.PropertyField(uvRotation, new GUIContent("UV Rotation"));
EditorGUILayout.PropertyField(uvScale, new GUIContent("UV Scale"));
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 5853c8e53cbbcea4c86f3dfc39e39f47
timeCreated: 1448044279
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,374 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
[CustomEditor(typeof(Node), true)]
[CanEditMultipleObjects]
public class NodeEditor : Editor {
private SplineComputer addComp = null;
private int addPoint = 0;
private Node lastnode = null;
private int[] availablePoints;
bool connectionsOpen = false, settingsOpen = false;
private SerializedProperty transformNormals, transformSize, transformTangents, type;
private Node[] nodes = new Node[0];
private SerializedObject serializedNodes;
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Node node = (Node)target;
if (nodes.Length == 1)
{
if (addComp != null)
{
string[] pointNames = new string[availablePoints.Length];
for (int i = 0; i < pointNames.Length; i++)
{
pointNames[i] = "Point " + (availablePoints[i] + 1);
}
if (availablePoints.Length > 0) addPoint = EditorGUILayout.Popup("Link point", addPoint, pointNames);
else EditorGUILayout.LabelField("No Points Available");
if (GUILayout.Button("Cancel"))
{
addComp = null;
addPoint = 0;
}
if (addPoint >= 0 && availablePoints.Length > addPoint)
{
if (node.HasConnection(addComp, availablePoints[addPoint])) EditorGUILayout.HelpBox("Connection already exists (" + addComp.name + "," + availablePoints[addPoint], MessageType.Error);
else if (GUILayout.Button("Link"))
{
AddConnection(addComp, availablePoints[addPoint]);
}
}
}
else
{
SplineEditorGUI.BeginContainerBox(ref connectionsOpen, "Connections");
if (connectionsOpen)
{
ConnectionsGUI();
}
SplineEditorGUI.EndContainerBox();
Rect rect = GUILayoutUtility.GetLastRect();
SplineComputer[] addComps;
SplineComputer lastComp = addComp;
bool dragged = DreamteckEditorGUI.DropArea<SplineComputer>(rect, out addComps);
if (dragged && addComps.Length > 0)
{
SelectComputer(addComps[0]);
}
if (lastComp != addComp)
{
SceneView.RepaintAll();
}
}
} else
{
EditorGUILayout.HelpBox("Connection UI not available when multiple Nodes are selected.", MessageType.Info);
}
SplineEditorGUI.BeginContainerBox(ref settingsOpen, "Settings");
if (settingsOpen)
{
SettingsGUI();
}
SplineEditorGUI.EndContainerBox();
}
private void SettingsGUI()
{
Node node = (Node)target;
serializedNodes = new SerializedObject(nodes);
transformNormals = serializedNodes.FindProperty("_transformNormals");
transformSize = serializedNodes.FindProperty("_transformSize");
transformTangents = serializedNodes.FindProperty("_transformTangents");
type = serializedNodes.FindProperty("type");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(transformNormals, new GUIContent("Transform Normals"));
EditorGUILayout.PropertyField(transformSize, new GUIContent("Transform Size"));
EditorGUILayout.PropertyField(transformTangents, new GUIContent("Transform Tangents"));
EditorGUILayout.PropertyField(type, new GUIContent("Node Type"));
if (EditorGUI.EndChangeCheck())
{
SceneView.RepaintAll();
serializedNodes.ApplyModifiedProperties();
node.UpdatePoints();
node.UpdateConnectedComputers();
SetDirty(node);
}
EditorGUILayout.BeginHorizontal();
if(GUILayout.Button("Align Tangents X"))
{
AlignTangents(node, 0);
}
if (GUILayout.Button("Align Tangents Y"))
{
AlignTangents(node, 1);
}
if (GUILayout.Button("Align Tangents Z"))
{
AlignTangents(node, 2);
}
EditorGUILayout.EndHorizontal();
}
private void AlignTangents(Node node, int axis)
{
Vector3 axisVector = Vector3.forward;
switch (axis)
{
case 0: axisVector = node.transform.right; break;
case 1: axisVector = node.transform.up; break;
case 2: axisVector = node.transform.forward; break;
}
Undo.RecordObject(node, "Align Tangents");
SplinePoint point = node.GetPoint(0, false);
Vector3 tan1 = point.tangent - point.position;
Vector3 tan2 = point.tangent2 - point.position;
float tan1Dir = Mathf.Sign(Vector3.Dot(tan1, axisVector));
float tan2Dir = Mathf.Sign(Vector3.Dot(tan2, axisVector));
point.tangent = point.position + axisVector * tan1Dir * tan1.magnitude;
point.tangent2 = point.position + axisVector * tan2Dir * tan2.magnitude;
node.SetPoint(0, point, false);
node.UpdateConnectedComputers();
SetDirty(node);
SceneView.RepaintAll();
}
void ConnectionsGUI()
{
Node node = (Node)target;
Node.Connection[] connections = node.GetConnections();
EditorGUILayout.Space();
if (connections.Length > 0)
{
for (int i = 0; i < connections.Length; i++)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(connections[i].spline.name + " at point " + (connections[i].pointIndex+1));
if (GUILayout.Button("Select", GUILayout.Width(70)))
{
Selection.activeGameObject = connections[i].spline.gameObject;
}
SplineEditorGUI.SetHighlightColors(SplinePrefs.highlightColor, SplinePrefs.highlightContentColor);
if (SplineEditorGUI.EditorLayoutSelectableButton(new GUIContent("Swap Tangents"), connections[i].spline.type == Spline.Type.Bezier, connections[i].invertTangents))
{
connections[i].invertTangents = !connections[i].invertTangents;
node.UpdateConnectedComputers();
SetDirty(node);
SceneView.RepaintAll();
}
if (GUILayout.Button("x", GUILayout.Width(20)))
{
Undo.RecordObject(node, "Remove connection");
Undo.RecordObject(connections[i].spline, "Remove node");
connections[i].spline.DisconnectNode(connections[i].pointIndex);
node.RemoveConnection(connections[i].spline, connections[i].pointIndex);
}
EditorGUILayout.EndHorizontal();
}
}
else EditorGUILayout.HelpBox("Drag & Drop SplineComputers here to link their points.", MessageType.Info);
}
void OnEnable()
{
lastnode = (Node)target;
lastnode.EditorMaintainConnections();
connectionsOpen = EditorPrefs.GetBool("Dreamteck.Splines.Editor.NodeEditor.connectionsOpen");
settingsOpen = EditorPrefs.GetBool("Dreamteck.Splines.Editor.NodeEditor.settingsOpen");
nodes = new Node[targets.Length];
for (int i = 0; i < targets.Length; i++)
{
nodes[i] = (Node)targets[i];
}
#if UNITY_2019_1_OR_NEWER
SceneView.duringSceneGui += DuringSceneGUI;
#else
SceneView.onSceneGUIDelegate += DuringSceneGUI;
#endif
}
private void OnDisable()
{
EditorPrefs.SetBool("Dreamteck.Splines.Editor.NodeEditor.connectionsOpen", connectionsOpen);
EditorPrefs.SetBool("Dreamteck.Splines.Editor.NodeEditor.settingsOpen", settingsOpen);
#if UNITY_2019_1_OR_NEWER
SceneView.duringSceneGui -= DuringSceneGUI;
#else
SceneView.onSceneGUIDelegate -= DuringSceneGUI;
#endif
}
void OnDestroy()
{
if (Application.isEditor && !Application.isPlaying)
{
if (((Node)target) == null)
{
Node.Connection[] connections = lastnode.GetConnections();
for(int i = 0; i < connections.Length; i++)
{
if (connections[i].spline == null) continue;
Undo.RecordObject(connections[i].spline, "Delete node connections");
}
lastnode.ClearConnections();
}
}
}
void SelectComputer(SplineComputer comp)
{
addComp = comp;
if (addComp != null) availablePoints = GetAvailablePoints(addComp);
SceneView.RepaintAll();
Repaint();
}
void AddConnection(SplineComputer computer, int pointIndex)
{
Node node = (Node)target;
Node.Connection[] connections = node.GetConnections();
if (EditorUtility.DisplayDialog("Link point?", "Add point " + (pointIndex+1) + " to connections?", "Yes", "No"))
{
Undo.RecordObject(addComp, "Add connection");
Undo.RecordObject(node, "Add Connection");
if (connections.Length == 0)
{
switch (EditorUtility.DisplayDialogComplex("Align node to point?", "This is the first connection for the node, would you like to snap or align the node's Transform the spline point.", "No", "Snap", "Snap and Align"))
{
case 1: SplinePoint point = addComp.GetPoint(pointIndex);
node.transform.position = point.position;
break;
case 2:
SplineSample result = addComp.Evaluate(pointIndex);
node.transform.position = result.position;
node.transform.rotation = result.rotation;
break;
}
}
computer.ConnectNode(node, pointIndex);
addComp = null;
addPoint = 0;
SetDirty(node);
SceneView.RepaintAll();
Repaint();
}
}
int[] GetAvailablePoints(SplineComputer computer)
{
List<int> indices = new List<int>();
for (int i = 0; i < computer.pointCount; i++)
{
if (computer.GetNode(i) != null) continue;
indices.Add(i);
}
return indices.ToArray();
}
protected virtual void DuringSceneGUI(SceneView current)
{
Node node = (Node)target;
Node.Connection[] connections = node.GetConnections();
for (int i = 0; i < connections.Length; i++)
{
DSSplineDrawer.DrawSplineComputer(connections[i].spline, 0.0, 1.0, 0.5f);
}
if (addComp == null)
{
if (connections.Length > 0)
{
bool bezier = false;
for (int i = 0; i < connections.Length; i++)
{
if (connections[i].spline == null) continue;
if (connections[i].spline.type == Spline.Type.Bezier)
{
bezier = true;
continue;
}
}
if (bezier && node.type == Node.Type.Smooth)
{
if (connections[0].spline != null)
{
SplinePoint point = node.GetPoint(0, true);
Handles.DrawDottedLine(node.transform.position, point.tangent, 6f);
Handles.DrawDottedLine(node.transform.position, point.tangent2, 6f);
Vector3 lastPos = point.tangent;
bool setPoint = false;
point.SetTangentPosition(Handles.PositionHandle(point.tangent, node.transform.rotation));
if (lastPos != point.tangent) setPoint = true;
lastPos = point.tangent2;
point.SetTangent2Position(Handles.PositionHandle(point.tangent2, node.transform.rotation));
if (lastPos != point.tangent2) setPoint = true;
if (setPoint)
{
node.SetPoint(0, point, true);
node.UpdateConnectedComputers();
SetDirty(node);
}
}
}
}
return;
}
SplinePoint[] points = addComp.GetPoints();
Transform camTransform = SceneView.currentDrawingSceneView.camera.transform;
DSSplineDrawer.DrawSplineComputer(addComp, 0.0, 1.0, 0.5f);
TextAnchor originalAlignment = GUI.skin.label.alignment;
Color originalColor = GUI.skin.label.normal.textColor;
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
GUI.skin.label.normal.textColor = addComp.editorPathColor;
for (int i = 0; i < availablePoints.Length; i++)
{
if (addComp.isClosed && i == points.Length - 1) break;
Handles.Label(points[i].position + Camera.current.transform.up * HandleUtility.GetHandleSize(points[i].position) * 0.3f, (i + 1).ToString());
if (SplineEditorHandles.CircleButton(points[availablePoints[i]].position, Quaternion.LookRotation(-camTransform.forward, camTransform.up), HandleUtility.GetHandleSize(points[availablePoints[i]].position) * 0.1f, 2f, addComp.editorPathColor))
{
AddConnection(addComp, availablePoints[i]);
break;
}
}
GUI.skin.label.alignment = originalAlignment;
GUI.skin.label.normal.textColor = originalColor;
}
public static void SetDirty(Node node)
{
EditorUtility.SetDirty(node);
Node.Connection[] connections = node.GetConnections();
for (int i = 0; i < connections.Length; i++)
{
EditorUtility.SetDirty(connections[i].spline);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 29b7ad072e04e6341bbda1d04593b91f
timeCreated: 1459107704
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,357 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
[CustomEditor(typeof(ObjectBender), true)]
[CanEditMultipleObjects]
public class ObjectBenderEditor : SplineUserEditor
{
List<int> selected = new List<int>();
Vector2 scroll = Vector2.zero;
bool generatedUvs = false;
protected override void Awake()
{
ObjectBender bender = (ObjectBender)target;
if(!Application.isPlaying) bender.UpdateReferences();
base.Awake();
}
void PropertyEditor(ObjectBender.BendProperty[] properties)
{
if (selected.Count == 0) return;
int applyRotationCount = 0, applyScaleCount = 0, enableCount = 0, bendMeshCount = 0, bendColliderCount = 0, bendSplineCount = 0;
bool showMesh = false, showCollider = false, showSpline = false;
float colliderUpdateRate = 0f;
for(int i = 0; i < selected.Count; i++)
{
ObjectBender.BendProperty property = properties[selected[i]];
if (property.enabled) enableCount++;
if (property.applyRotation) applyRotationCount++;
if (property.applyScale) applyScaleCount++;
if (property.bendMesh) bendMeshCount++;
if (property.bendCollider) bendColliderCount++;
if (property.bendSpline) bendSplineCount++;
if (property.filter != null) showMesh = true;
if (property.collider != null) showCollider = true;
if (property.splineComputer != null) showSpline = true;
colliderUpdateRate += property.colliderUpdateRate;
}
bool enabled = enableCount == selected.Count;
bool applyRotation = applyRotationCount == selected.Count;
bool applyScale = applyScaleCount == selected.Count;
bool bendMesh = bendMeshCount == selected.Count;
bool bendCollider = bendColliderCount == selected.Count;
bool bendSpline = bendSplineCount == selected.Count;
colliderUpdateRate /= selected.Count;
bool lastEnabled = enabled, lastApplyRotation = applyRotation, lastApplyScale = applyScale, lastBendMesh = bendMesh, lastBendCollider = bendCollider, lastBendSpline = bendSpline;
float lastColliderUpdateRate = colliderUpdateRate;
EditorGUIUtility.labelWidth = 90;
EditorGUI.BeginChangeCheck();
GUI.color = Color.white;
EditorGUILayout.BeginVertical(GUI.skin.box, GUILayout.Width(EditorGUIUtility.currentViewWidth - 50));
EditorGUILayout.BeginHorizontal();
enabled = EditorGUILayout.Toggle(enabled, GUILayout.Width(20));
if (selected.Count == 1) EditorGUILayout.LabelField(properties[selected[0]].transform.transform.name);
else EditorGUILayout.LabelField("Multiple objects");
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical();
applyRotation = EditorGUILayout.Toggle("Apply rotation", applyRotation);
applyScale = EditorGUILayout.Toggle("Apply scale", applyScale);
if (showSpline) bendSpline = EditorGUILayout.Toggle("Bend Spline", bendSpline);
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
if (showMesh)
{
bendMesh = EditorGUILayout.Toggle("Bend Mesh", bendMesh);
if (bendMesh)
{
if (showCollider)
{
bendCollider = EditorGUILayout.Toggle("Bend Collider", bendCollider);
if (bendCollider)
{
EditorGUI.indentLevel++;
colliderUpdateRate = EditorGUILayout.FloatField("Update Rate", colliderUpdateRate);
EditorGUI.indentLevel--;
}
}
else GUI.Label(new Rect(EditorGUIUtility.currentViewWidth / 2f - 25, 40, EditorGUIUtility.currentViewWidth / 2f - 30, 22), "No Mesh Colliders Available");
}
}
else EditorGUILayout.LabelField("No Meshes Available");
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
if (EditorGUI.EndChangeCheck())
{
for(int i = 0; i < selected.Count; i++)
{
if (lastEnabled != enabled) properties[selected[i]].enabled = enabled;
if (lastApplyRotation != applyRotation) properties[selected[i]].applyRotation = applyRotation;
if (lastApplyScale != applyScale) properties[selected[i]].applyScale = applyScale;
if (bendMesh != lastBendMesh) properties[selected[i]].bendMesh = bendMesh;
if (bendCollider != lastBendCollider) properties[selected[i]].bendCollider = bendCollider;
if (bendSpline != lastBendSpline) properties[selected[i]].bendSpline = bendSpline;
if (lastColliderUpdateRate != colliderUpdateRate) properties[selected[i]].colliderUpdateRate = colliderUpdateRate;
}
}
}
void GetChildCount(Transform parent, ref int count)
{
foreach(Transform child in parent)
{
count++;
GetChildCount(child, ref count);
}
}
public override void OnInspectorGUI()
{
showAveraging = false;
base.OnInspectorGUI();
}
protected override void BodyGUI()
{
base.BodyGUI();
ObjectBender bender = (ObjectBender)target;
serializedObject.Update();
SerializedProperty axis = serializedObject.FindProperty("_axis");
SerializedProperty normalMode = serializedObject.FindProperty("_normalMode");
SerializedProperty forwardMode = serializedObject.FindProperty("_forwardMode");
for (int i = 0; i < targets.Length; i++)
{
ObjectBender objBender = (ObjectBender)targets[i];
int childCount = 0;
GetChildCount(objBender.transform, ref childCount);
if (objBender.bendProperties.Length - 1 != childCount && !Application.isPlaying) objBender.UpdateReferences();
}
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(axis, new GUIContent("Axis"));
EditorGUILayout.PropertyField(normalMode, new GUIContent("Up Vector"));
if (normalMode.intValue == (int)ObjectBender.NormalMode.Custom)
{
SerializedProperty customNormal = serializedObject.FindProperty("_customNormal");
EditorGUILayout.PropertyField(customNormal, new GUIContent("Custom Up"));
}
EditorGUILayout.PropertyField(forwardMode, new GUIContent("Forward Vector"));
if (forwardMode.intValue == (int)ObjectBender.ForwardMode.Custom)
{
SerializedProperty customForward = serializedObject.FindProperty("_customForward");
EditorGUILayout.PropertyField(customForward, new GUIContent("Custom Forward"));
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
for (int i = 0; i < targets.Length; i++)
{
ObjectBender objBender = (ObjectBender)targets[i];
objBender.Rebuild();
}
}
if (targets.Length > 1)
{
EditorGUILayout.LabelField("Object properties unavailable when multiple benders are selected.", EditorStyles.centeredGreyMiniLabel);
return;
}
if (!bender.bend)
{
float scrollHeight = Mathf.Min(bender.bendProperties.Length, 15) * 22;
scroll = EditorGUILayout.BeginScrollView(scroll, GUILayout.Height(scrollHeight+5));
for (int i = 0; i < bender.bendProperties.Length; i++)
{
bool isSelected = selected.Contains(i);
if (!bender.bendProperties[i].enabled)
{
GUI.color = Color.gray;
if (isSelected) GUI.color = Color.Lerp(Color.gray, SplinePrefs.highlightColor, 0.5f);
}
else
{
if (isSelected) GUI.color = SplinePrefs.highlightColor;
else GUI.color = Color.white;
}
GUILayout.Box(bender.bendProperties[i].transform.transform.name, GUILayout.Height(18), GUILayout.Width(EditorGUIUtility.currentViewWidth - 60));
if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseDown)
{
if (Event.current.control)
{
if (!selected.Contains(i)) selected.Add(i);
}
else if (Event.current.shift && selected.Count > 0)
{
int from = selected[0];
selected.Clear();
if (from < i)
{
for (int n = from; n <= i; n++) selected.Add(n);
}
else
{
for (int n = from; n >= i; n--) selected.Add(n);
}
}
else
{
selected.Clear();
selected.Add(i);
}
Repaint();
SceneView.RepaintAll();
}
GUI.color = Color.white;
}
EditorGUILayout.EndScrollView();
if (selected.Count > 0)
{
PropertyEditor(bender.bendProperties);
}
if (selected.Count > 0)
{
if (Event.current.type == EventType.KeyDown)
{
if (Event.current.keyCode == KeyCode.DownArrow)
{
if (selected.Count > 1)
{
int temp = selected[selected.Count - 1];
selected.Clear();
selected.Add(temp);
}
selected[0]++;
if (selected[0] >= bender.bendProperties.Length) selected[0] = 0;
}
if (Event.current.keyCode == KeyCode.UpArrow)
{
if (selected.Count > 1)
{
int temp = selected[0];
selected.Clear();
selected.Add(temp);
}
selected[0]--;
if (selected[0] < 0) selected[0] = bender.bendProperties.Length - 1;
}
Repaint();
SceneView.RepaintAll();
Event.current.Use();
}
}
}
string editModeText = "Enter Edit Mode";
if (!bender.bend) editModeText = "Bend";
if (GUILayout.Button(editModeText))
{
if (bender.bend) bender.bend = false;
else bender.bend = true;
}
if (bender.bend && !generatedUvs)
{
if (GUILayout.Button("Generate Lightmap UVS"))
{
bender.EditorGenerateLightmapUVs();
generatedUvs = true;
}
}
}
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
ObjectBender bender = (ObjectBender)target;
if (selected.Count > 0)
{
Handles.BeginGUI();
for(int i = 0; i < selected.Count; i++)
{
Vector2 screenPosition = HandleUtility.WorldToGUIPoint(bender.bendProperties[selected[i]].transform.transform.position);
DreamteckEditorGUI.Label(new Rect(screenPosition.x - 120 + bender.bendProperties[selected[i]].transform.transform.name.Length * 4, screenPosition.y, 120, 25), bender.bendProperties[selected[i]].transform.transform.name);
}
Handles.EndGUI();
}
for(int i = 0; i < bender.bendProperties.Length; i++)
{
if(bender.bendProperties[i].bendSpline && bender.bendProperties[i].splineComputer != null)
{
DSSplineDrawer.DrawSplineComputer(bender.bendProperties[i].splineComputer, 0.0, 1.0, 0.2f);
}
}
//Draw bounds
if (bender.bend) return;
TS_Bounds bound = bender.GetBounds();
Vector3 a = bender.transform.TransformPoint(bound.min);
Vector3 b = bender.transform.TransformPoint(new Vector3(bound.max.x, bound.min.y, bound.min.z));
Vector3 c = bender.transform.TransformPoint(new Vector3(bound.max.x, bound.min.y, bound.max.z));
Vector3 d = bender.transform.TransformPoint(new Vector3(bound.min.x, bound.min.y, bound.max.z));
Vector3 e = bender.transform.TransformPoint(new Vector3(bound.min.x, bound.max.y, bound.min.z));
Vector3 f = bender.transform.TransformPoint(new Vector3(bound.max.x, bound.max.y, bound.min.z));
Vector3 g = bender.transform.TransformPoint(new Vector3(bound.max.x, bound.max.y, bound.max.z));
Vector3 h = bender.transform.TransformPoint(new Vector3(bound.min.x, bound.max.y, bound.max.z));
Handles.color = Color.gray;
Handles.DrawLine(a, b);
Handles.DrawLine(b, c);
Handles.DrawLine(c, d);
Handles.DrawLine(d, a);
Handles.DrawLine(e, f);
Handles.DrawLine(f, g);
Handles.DrawLine(g, h);
Handles.DrawLine(h, e);
Handles.DrawLine(a, e);
Handles.DrawLine(b, f);
Handles.DrawLine(c, g);
Handles.DrawLine(d, h);
Vector3 r = bender.transform.right;
Vector3 fr = bender.transform.forward;
switch (bender.axis)
{
case ObjectBender.Axis.Z: Handles.color = Color.blue; Handles.DrawLine(r + b, r + c); break;
case ObjectBender.Axis.X: Handles.color = Color.red; Handles.DrawLine(b - fr, a - fr); break;
case ObjectBender.Axis.Y: Handles.color = Color.green; Handles.DrawLine(b- fr + r, f - fr + r); break;
}
}
protected override void OnDestroy()
{
base.OnDestroy();
SplineUser user = (SplineUser)target;
if (Application.isEditor && !Application.isPlaying)
{
if (user == null) OnDelete(); //The object or the component is being deleted
else if (user.spline != null)
{
if(!generatedUvs) user.Rebuild();
}
}
SplineComputerEditor.hold = false;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 09a7b4cd1afdfcd48b026eef6eef39db
timeCreated: 1463257593
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,264 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
using Dreamteck.Splines;
[CustomEditor(typeof(ObjectController))]
[CanEditMultipleObjects]
public class ObjectControllerEditor : SplineUserEditor
{
protected override void BodyGUI()
{
base.BodyGUI();
ObjectController user = (ObjectController)target;
serializedObject.Update();
SerializedProperty objectMethod = serializedObject.FindProperty("_objectMethod");
SerializedProperty retainPrefabInstancesInEditor = serializedObject.FindProperty("_retainPrefabInstancesInEditor");
SerializedProperty spawnMethod = serializedObject.FindProperty("_spawnMethod");
SerializedProperty spawnCount = serializedObject.FindProperty("_spawnCount");
SerializedProperty delayedSpawn = serializedObject.FindProperty("delayedSpawn");
SerializedProperty spawnDelay = serializedObject.FindProperty("spawnDelay");
SerializedProperty iteration = serializedObject.FindProperty("_iteration");
SerializedProperty applyRotation = serializedObject.FindProperty("_applyRotation");
SerializedProperty minRotation = serializedObject.FindProperty("_minRotation");
SerializedProperty maxRotation = serializedObject.FindProperty("_maxRotation");
SerializedProperty applyScale = serializedObject.FindProperty("_applyScale");
SerializedProperty minScaleMultiplier = serializedObject.FindProperty("_minScaleMultiplier");
SerializedProperty maxScaleMultiplier = serializedObject.FindProperty("_maxScaleMultiplier");
SerializedProperty uniformScaleLerp = serializedObject.FindProperty("_uniformScaleLerp");
SerializedProperty objectPositioning = serializedObject.FindProperty("_objectPositioning");
SerializedProperty evaluateOffset = serializedObject.FindProperty("_evaluateOffset");
SerializedProperty offsetUseWorldCoords = serializedObject.FindProperty("_offsetUseWorldCoords");
SerializedProperty minOffset = serializedObject.FindProperty("_minOffset");
SerializedProperty maxOffset = serializedObject.FindProperty("_maxOffset");
SerializedProperty shellOffset = serializedObject.FindProperty("_shellOffset");
SerializedProperty rotateByOffset = serializedObject.FindProperty("_rotateByOffset");
SerializedProperty randomSeed = serializedObject.FindProperty("_randomSeed");
SerializedProperty useCustomObjectDistance = serializedObject.FindProperty("_useCustomObjectDistance");
SerializedProperty minObjectDistance = serializedObject.FindProperty("_minObjectDistance");
SerializedProperty maxObjectDistance = serializedObject.FindProperty("_maxObjectDistance");
SerializedProperty customOffsetRule = serializedObject.FindProperty("_customOffsetRule");
SerializedProperty customRotationRule = serializedObject.FindProperty("_customRotationRule");
SerializedProperty customScaleRule = serializedObject.FindProperty("_customScaleRule");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(objectMethod, new GUIContent("Object Method"));
if (objectMethod.intValue == (int)ObjectController.ObjectMethod.Instantiate) EditorGUILayout.PropertyField(retainPrefabInstancesInEditor, new GUIContent("Retain Prefab Instances"));
if (objectMethod.intValue == (int)ObjectController.ObjectMethod.Instantiate)
{
bool objectsChanged = false;
bool hasObj = false;
if (users.Length > 1)
{
EditorGUILayout.HelpBox("Editing unavailable when multiple objects are selected", MessageType.Info);
}
else
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Instantiate Objects", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical();
for (int i = 0; i < user.objects.Length; i++)
{
EditorGUILayout.BeginHorizontal();
user.objects[i] = (GameObject)EditorGUILayout.ObjectField(user.objects[i], typeof(GameObject), true);
if (GUILayout.Button("x", GUILayout.Width(20)))
{
GameObject[] newObjects = new GameObject[user.objects.Length - 1];
for (int n = 0; n < user.objects.Length; n++)
{
if (n < i) newObjects[n] = user.objects[n];
else if (n == i) continue;
else newObjects[n - 1] = user.objects[n];
objectsChanged = true;
}
user.objects = newObjects;
}
if (i > 0)
{
if (GUILayout.Button("▲", GUILayout.Width(20)))
{
GameObject temp = user.objects[i - 1];
user.objects[i - 1] = user.objects[i];
user.objects[i] = temp;
objectsChanged = true;
}
}
if (i < user.objects.Length - 1)
{
if (GUILayout.Button("▼", GUILayout.Width(20)))
{
GameObject temp = user.objects[i + 1];
user.objects[i + 1] = user.objects[i];
user.objects[i] = temp;
objectsChanged = true;
}
}
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
GameObject newObj = null;
newObj = (GameObject)EditorGUILayout.ObjectField("Add Object", newObj, typeof(GameObject), true);
if (newObj != null)
{
GameObject[] newObjects = new GameObject[user.objects.Length + 1];
user.objects.CopyTo(newObjects, 0);
newObjects[newObjects.Length - 1] = newObj;
user.objects = newObjects;
objectsChanged = true;
}
for (int i = 0; i < user.objects.Length; i++)
{
if (user.objects[i] != null)
{
hasObj = true;
break;
}
}
}
int lastSpawnMethod = spawnMethod.intValue;
EditorGUILayout.PropertyField(spawnMethod, new GUIContent("Spawn Method"));
if (lastSpawnMethod != spawnMethod.intValue)
{
objectsChanged = true;
}
if (spawnMethod.intValue == (int)ObjectController.SpawnMethod.Count)
{
int lastSpawnCount = spawnCount.intValue;
if (hasObj) EditorGUILayout.PropertyField(spawnCount, new GUIContent("Spawn Count"));
else spawnCount.intValue = 0;
if (lastSpawnCount != spawnCount.intValue) objectsChanged = true;
}
EditorGUILayout.PropertyField(delayedSpawn, new GUIContent("Delayed Spawn"));
if (delayedSpawn.boolValue)
{
EditorGUILayout.PropertyField(spawnDelay, new GUIContent("Spawn Delay"));
}
int lastIteration = iteration.intValue;
EditorGUILayout.PropertyField(iteration, new GUIContent("Iteration"));
if (lastIteration != iteration.intValue)
{
objectsChanged = true;
}
if (objectsChanged)
{
serializedObject.ApplyModifiedProperties();
user.Clear();
user.Spawn();
}
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(useCustomObjectDistance, new GUIContent("Custom Object Distance"));
if (useCustomObjectDistance.boolValue)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(minObjectDistance, new GUIContent("Min. Distance"));
EditorGUILayout.PropertyField(maxObjectDistance, new GUIContent("Max. Distance"));
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Position and Offset");
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(customOffsetRule);
if (customOffsetRule.objectReferenceValue == null)
{
if (offsetUseWorldCoords.boolValue)
{
minOffset.vector3Value = EditorGUILayout.Vector3Field("Min. Offset", minOffset.vector3Value);
maxOffset.vector3Value = EditorGUILayout.Vector3Field("Max. Offset", maxOffset.vector3Value);
}
else
{
minOffset.vector3Value = EditorGUILayout.Vector2Field("Min. Offset", minOffset.vector3Value);
maxOffset.vector3Value = EditorGUILayout.Vector2Field("Max. Offset", maxOffset.vector3Value);
}
} else
{
CustomRuleUI((ObjectControllerCustomRuleBase)customOffsetRule.objectReferenceValue);
}
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.PropertyField(applyRotation, new GUIContent("Apply Rotation"));
if (user.applyRotation)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(customRotationRule);
if (customRotationRule.objectReferenceValue == null)
{
EditorGUILayout.PropertyField(minRotation, new GUIContent("Min. Rotation Offset"));
EditorGUILayout.PropertyField(maxRotation, new GUIContent("Max. Rotation Offset"));
} else
{
CustomRuleUI((ObjectControllerCustomRuleBase)customRotationRule.objectReferenceValue);
}
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUILayout.PropertyField(applyScale, new GUIContent("Apply Scale"));
if (user.applyScale)
{
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(customScaleRule);
if (customScaleRule.objectReferenceValue == null)
{
EditorGUILayout.PropertyField(minScaleMultiplier, new GUIContent("Min. Scale Multiplier"));
EditorGUILayout.PropertyField(maxScaleMultiplier, new GUIContent("Max. Scale Multiplier"));
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(uniformScaleLerp, new GUIContent("Uniform Lerp"));
EditorGUI.indentLevel--;
} else
{
CustomRuleUI((ObjectControllerCustomRuleBase)customScaleRule.objectReferenceValue);
}
EditorGUI.indentLevel--;
}
EditorGUILayout.PropertyField(objectPositioning, new GUIContent("Object Positioning"));
EditorGUILayout.PropertyField(evaluateOffset, new GUIContent("Evaluate Offset"));
EditorGUI.indentLevel++;
EditorGUILayout.PropertyField(offsetUseWorldCoords, new GUIContent("Use World Coords."));
if(minOffset.vector3Value != maxOffset.vector3Value) EditorGUILayout.PropertyField(shellOffset, new GUIContent("Shell"));
EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(rotateByOffset, new GUIContent("Rotate by Offset"));
EditorGUILayout.PropertyField(randomSeed, new GUIContent("Random Seed"));
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
}
private void CustomRuleUI(ObjectControllerCustomRuleBase customRule)
{
SerializedObject serializedRule = new SerializedObject(customRule);
SerializedProperty property = serializedRule.GetIterator();
property.NextVisible(true);
property.NextVisible(false);
EditorGUI.BeginChangeCheck();
do
{
EditorGUILayout.PropertyField(property);
} while (property.NextVisible(false));
if (EditorGUI.EndChangeCheck())
{
serializedRule.ApplyModifiedProperties();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4be170f07c25f6840a0370aab63c89af
timeCreated: 1455911715
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(ParticleController))]
[CanEditMultipleObjects]
public class ParticleControllerEditor : SplineUserEditor
{
protected override void BodyGUI()
{
base.BodyGUI();
ParticleController user = (ParticleController)target;
serializedObject.Update();
SerializedProperty _particleSystem = serializedObject.FindProperty("_particleSystem");
SerializedProperty emitPoint = serializedObject.FindProperty("emitPoint");
SerializedProperty offset = serializedObject.FindProperty("offset");
SerializedProperty volumetric = serializedObject.FindProperty("volumetric");
SerializedProperty pauseWhenNotVisible = serializedObject.FindProperty("pauseWhenNotVisible");
SerializedProperty applyRotation = serializedObject.FindProperty("apply3DRotation");
SerializedProperty emitFromShell = serializedObject.FindProperty("emitFromShell");
SerializedProperty scale = serializedObject.FindProperty("scale");
SerializedProperty motionType = serializedObject.FindProperty("motionType");
SerializedProperty wrapMode = serializedObject.FindProperty("wrapMode");
SerializedProperty minCycles = serializedObject.FindProperty("minCycles");
SerializedProperty maxCycles = serializedObject.FindProperty("maxCycles");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_particleSystem, new GUIContent("Particle System"));
if (_particleSystem.objectReferenceValue == null)
{
EditorGUILayout.HelpBox("No particle system is assigned", MessageType.Error);
return;
}
EditorGUILayout.PropertyField(pauseWhenNotVisible);
EditorGUILayout.PropertyField(emitPoint);
EditorGUILayout.PropertyField(offset);
EditorGUILayout.PropertyField(applyRotation);
EditorGUILayout.PropertyField(volumetric);
if (volumetric.boolValue)
{
EditorGUILayout.PropertyField(emitFromShell);
EditorGUILayout.PropertyField(scale);
}
EditorGUILayout.PropertyField(motionType);
if(motionType.intValue == (int)ParticleController.MotionType.FollowForward || motionType.intValue == (int)ParticleController.MotionType.FollowBackward)
{
EditorGUILayout.PropertyField(wrapMode);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Path cycles (over " + user.particleSystemComponent.main.startLifetime.constantMax + "s.)", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(minCycles, new GUIContent("Min. Cycles"));
if (minCycles.floatValue < 0f) minCycles.floatValue = 0f;
EditorGUILayout.PropertyField(maxCycles, new GUIContent("Max. Cycles"));
if (maxCycles.floatValue < minCycles.floatValue) maxCycles.floatValue = minCycles.floatValue;
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
if (!Application.isPlaying)
{
EditorGUILayout.HelpBox("Particles may not work in the editor preview. Play the game to see the in-game result.", MessageType.Info);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: b2fe6a6d8bb85894c96049081f441293
timeCreated: 1455991724
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(PathGenerator), true)]
[CanEditMultipleObjects]
public class PathGeneratorEditor : MeshGenEditor
{
protected override void BodyGUI()
{
base.BodyGUI();
PathGenerator pathGenerator = (PathGenerator)target;
serializedObject.Update();
SerializedProperty slices = serializedObject.FindProperty("_slices");
SerializedProperty shape = serializedObject.FindProperty("_shape");
SerializedProperty shapeExposure = serializedObject.FindProperty("_shapeExposure");
SerializedProperty useShapeCurve = serializedObject.FindProperty("_useShapeCurve");
SerializedProperty compensateCorners = serializedObject.FindProperty("_compensateCorners");
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Geometry", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(slices, new GUIContent("Slices"));
EditorGUILayout.PropertyField(compensateCorners, new GUIContent("Compensate Corners"));
EditorGUILayout.PropertyField(useShapeCurve, new GUIContent("Use Shape Curve"));
if (useShapeCurve.boolValue)
{
if(shape.animationCurveValue == null || shape.animationCurveValue.keys.Length == 0)
{
shape.animationCurveValue = new AnimationCurve();
shape.animationCurveValue.AddKey(new Keyframe(0, 0));
shape.animationCurveValue.AddKey(new Keyframe(1, 0));
}
if (slices.intValue == 1) EditorGUILayout.HelpBox("Slices are set to 1. The curve shape may not be approximated correctly. You can increase the slices in order to fix that.", MessageType.Warning);
EditorGUILayout.PropertyField(shape, new GUIContent("Shape Curve"));
EditorGUILayout.PropertyField(shapeExposure, new GUIContent("Shape Exposure"));
}
if (slices.intValue < 1) slices.intValue = 1;
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
UVControls(pathGenerator);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: fb780cd10e9c18946bf622bab1d979d9
timeCreated: 1454061509
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(PolygonColliderGenerator))]
[CanEditMultipleObjects]
public class PolygonColliderGenEditor : SplineUserEditor
{
protected override void BodyGUI()
{
base.BodyGUI();
PolygonColliderGenerator generator = (PolygonColliderGenerator)target;
serializedObject.Update();
SerializedProperty type = serializedObject.FindProperty("_type");
SerializedProperty size = serializedObject.FindProperty("_size");
SerializedProperty offset = serializedObject.FindProperty("_offset");
SerializedProperty updateRate = serializedObject.FindProperty("updateRate");
EditorGUILayout.Space();
EditorGUILayout.LabelField("Polygon", EditorStyles.boldLabel);
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(type, new GUIContent("Type"));
if (type.intValue == (int)PolygonColliderGenerator.Type.Path) EditorGUILayout.PropertyField(size, new GUIContent("Size"));
EditorGUILayout.PropertyField(offset, new GUIContent("Offset"));
EditorGUILayout.PropertyField(updateRate);
if (updateRate.floatValue < 0f) updateRate.floatValue = 0f;
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: db08e631e1379c04898db9f7c1414513
timeCreated: 1466252290
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
namespace Dreamteck.Splines.Editor
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class ClipRangeWindow : EditorWindow
{
private float from = 0f;
private float to = 0f;
private System.Action<float, float> rcv;
private float length = 0f;
public void Init(System.Action<float, float> receiver, float fromDistance, float toDistance, float totalLength)
{
rcv = receiver;
length = totalLength;
from = fromDistance;
to = toDistance;
titleContent = new GUIContent("Set Clip Range Distances");
minSize = maxSize = new Vector2(240, 120);
}
private void OnGUI()
{
if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return))
{
rcv(from, to);
Close();
}
from = EditorGUILayout.FloatField("From ", from);
if (from < 0f) from = 0f;
else if (from > length) from = length;
to = EditorGUILayout.FloatField("To ", to);
if (to < 0f) to = 0f;
else if (to > length) to = length;
EditorGUILayout.HelpBox("Enter the distance and press Enter. Current spline length: " + length, MessageType.Info);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db448abaf3c4f914a9fb3ee946340d1c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
namespace Dreamteck.Splines.Editor
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class DistanceWindow : EditorWindow
{
float distance = 0f;
DistanceReceiver rcv;
float length = 0f;
public delegate void DistanceReceiver(float distance);
public void Init(DistanceReceiver receiver, float totalLength)
{
rcv = receiver;
length = totalLength;
titleContent = new GUIContent("Set Distance");
minSize = maxSize = new Vector2(240, 90);
}
private void OnGUI()
{
if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return))
{
rcv(distance);
Close();
}
distance = EditorGUILayout.FloatField("Distance", distance);
if (distance < 0f) distance = 0f;
else if (distance > length) distance = length;
if (distance > 0f)
{
EditorGUILayout.LabelField("Press Enter to set.", EditorStyles.centeredGreyMiniLabel);
}
EditorGUILayout.HelpBox("Enter the distance and press Enter. Current spline length: " + length, MessageType.Info);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 17ee393449811f045b95ade0241f6d05
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,209 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(SplineFollower), true)]
[CanEditMultipleObjects]
public class SplineFollowerEditor : SplineTracerEditor
{
SplineSample result = new SplineSample();
protected SplineFollower[] followers = new SplineFollower[0];
protected FollowerSpeedModifierEditor speedModifierEditor;
void OnSetDistance(float distance)
{
for (int i = 0; i < targets.Length; i++)
{
SplineFollower follower = (SplineFollower)targets[i];
double travel = follower.Travel(0.0, distance, Spline.Direction.Forward);
var startPosition = serializedObject.FindProperty("_startPosition");
startPosition.floatValue = (float)travel;
follower.SetPercent(travel);
EditorUtility.SetDirty(follower);
}
}
protected override void OnEnable()
{
base.OnEnable();
followers = new SplineFollower[users.Length];
for (int i = 0; i < followers.Length; i++)
{
followers[i] = (SplineFollower)users[i];
}
if (followers.Length == 1)
{
speedModifierEditor = new FollowerSpeedModifierEditor(followers[0], this);
}
}
protected override void BodyGUI()
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Following", EditorStyles.boldLabel);
SplineFollower follower = (SplineFollower)target;
SerializedProperty followMode = serializedObject.FindProperty("followMode");
SerializedProperty preserveUniformSpeedWithOffset = serializedObject.FindProperty("preserveUniformSpeedWithOffset");
SerializedProperty wrapMode = serializedObject.FindProperty("wrapMode");
SerializedProperty startPosition = serializedObject.FindProperty("_startPosition");
SerializedProperty autoStartPosition = serializedObject.FindProperty("autoStartPosition");
SerializedProperty follow = serializedObject.FindProperty("_follow");
SerializedProperty direction = serializedObject.FindProperty("_direction");
SerializedProperty unityOnEndReached = serializedObject.FindProperty("_unityOnEndReached");
SerializedProperty unityOnBeginningReached = serializedObject.FindProperty("_unityOnBeginningReached");
EditorGUI.BeginChangeCheck();
bool lastFollow = follow.boolValue;
EditorGUILayout.PropertyField(follow);
if(lastFollow != follow.boolValue)
{
if (follow.boolValue)
{
if (autoStartPosition.boolValue)
{
SplineSample sample = new SplineSample();
followers[0].Project(followers[0].transform.position, ref sample);
if (Application.isPlaying)
{
for (int i = 0; i < followers.Length; i++)
{
followers[i].SetPercent(sample.percent);
}
}
}
}
}
EditorGUILayout.PropertyField(followMode);
if (followMode.intValue == (int)SplineFollower.FollowMode.Uniform)
{
SerializedProperty followSpeed = serializedObject.FindProperty("_followSpeed");
if(followSpeed.floatValue < 0f)
{
direction.intValue = (int)Spline.Direction.Backward;
} else if (followSpeed.floatValue > 0f)
{
direction.intValue = (int)Spline.Direction.Forward;
}
SerializedProperty motion = serializedObject.FindProperty("_motion");
SerializedProperty motionHasOffset = motion.FindPropertyRelative("_hasOffset");
EditorGUILayout.PropertyField(followSpeed, new GUIContent("Follow Speed"));
if (motionHasOffset.boolValue)
{
EditorGUILayout.PropertyField(preserveUniformSpeedWithOffset, new GUIContent("Preserve Uniform Speed With Offset"));
}
if (followers.Length == 1)
{
speedModifierEditor.DrawInspector();
}
}
else
{
follower.followDuration = EditorGUILayout.FloatField("Follow duration", follower.followDuration);
}
EditorGUILayout.PropertyField(wrapMode);
if (follower.motion.applyRotation)
{
follower.applyDirectionRotation = EditorGUILayout.Toggle("Face Direction", follower.applyDirectionRotation);
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Start Position", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(autoStartPosition, new GUIContent("Automatic Start Position"));
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 100f;
if (!follower.autoStartPosition && !Application.isPlaying)
{
float lastStartpos = startPosition.floatValue;
EditorGUILayout.PropertyField(startPosition, new GUIContent("Start Position"));
if (GUILayout.Button("Set Distance", GUILayout.Width(85)))
{
DistanceWindow w = EditorWindow.GetWindow<DistanceWindow>(true);
w.Init(OnSetDistance, follower.CalculateLength());
}
}
else
{
EditorGUILayout.LabelField("Start position", GUILayout.Width(EditorGUIUtility.labelWidth));
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.PropertyField(unityOnBeginningReached);
EditorGUILayout.PropertyField(unityOnEndReached);
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
if (!Application.isPlaying)
{
for (int i = 0; i < followers.Length; i++)
{
if(followers[i].spline.sampleCount > 0)
{
if (!followers[i].autoStartPosition)
{
followers[i].SetPercent(startPosition.floatValue);
if (!followers[i].follow) SceneView.RepaintAll();
}
}
}
}
}
int lastDirection = direction.intValue;
base.BodyGUI();
if(lastDirection != direction.intValue)
{
SerializedProperty followSpeed = serializedObject.FindProperty("_followSpeed");
if(direction.intValue == (int)Spline.Direction.Forward)
{
followSpeed.floatValue = Mathf.Abs(followSpeed.floatValue);
} else
{
followSpeed.floatValue = -Mathf.Abs(followSpeed.floatValue);
}
}
}
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
SplineFollower user = (SplineFollower)target;
if (user == null) return;
if (Application.isPlaying)
{
if (!user.follow) DrawResult(user.result);
return;
}
if (user.spline == null) return;
if (user.autoStartPosition)
{
user.spline.Project(user.transform.position, ref result, user.clipFrom, user.clipTo);
DrawResult(result);
} else if(!user.follow) DrawResult(user.result);
if (followers.Length == 1)
{
speedModifierEditor.DrawScene();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f0ceef9665459454c863f7c9a1de1685
timeCreated: 1454878386
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,479 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(SplineMesh), true)]
[CanEditMultipleObjects]
public class SplineMeshEditor : MeshGenEditor
{
private int selectedChannel = -1;
SplineMesh.Channel renameChannel = null;
MeshDefinitionWindow definitionWindow = null;
MeshScaleModifierEditor scaleModifierEditor;
private Mesh GetMeshFromObject(Object obj)
{
SplineMesh user = (SplineMesh)target;
if (!(obj is GameObject)) return null;
GameObject gameObj = (GameObject)obj;
MeshFilter filter = gameObj.GetComponent<MeshFilter>();
Mesh returnMesh = null;
if (filter != null && filter.sharedMesh != null) returnMesh = filter.sharedMesh;
MeshRenderer rend = user.GetComponent<MeshRenderer>();
if (rend == null) return returnMesh;
MeshRenderer meshRend = gameObj.GetComponent<MeshRenderer>();
if (meshRend == null) return returnMesh;
bool found = false;
for (int i = 0; i < meshRend.sharedMaterials.Length; i++)
{
for (int j = 0; j < rend.sharedMaterials.Length; j++)
{
if(meshRend.sharedMaterials[i] == rend.sharedMaterials[j])
{
found = true;
break;
}
}
}
if (!found)
{
if(EditorUtility.DisplayDialog("New Materials", "The added object has one or more materials which are not refrenced by the renderer. Would you like to add them?", "Yes", "No")) {
if(rend.sharedMaterial == AssetDatabase.GetBuiltinExtraResource<Material>("Default-Diffuse.mat"))
{
if (EditorUtility.DisplayDialog("Replace Material", "The renderer is using the default material. Replace it?", "Yes", "No")) rend.sharedMaterials = new Material[0];
}
for (int i = 0; i < meshRend.sharedMaterials.Length; i++) AddMaterial(rend, meshRend.sharedMaterials[i]);
}
}
return returnMesh;
}
void AddMaterial(MeshRenderer target, Material material)
{
for (int i = 0; i < target.sharedMaterials.Length; i++)
{
if (target.sharedMaterials[i] == material) return;
}
Material[] newMaterials = new Material[target.sharedMaterials.Length + 1];
target.sharedMaterials.CopyTo(newMaterials, 0);
newMaterials[newMaterials.Length - 1] = material;
target.sharedMaterials = newMaterials;
}
void OnDuplicateChannel(object index)
{
SplineMesh extruder = (SplineMesh)target;
SplineMesh.Channel source = extruder.GetChannel((int)index);
SplineMesh.Channel newChannel = extruder.AddChannel(source.name);
source.CopyTo(newChannel);
}
void OnRenameChannel(object index)
{
SplineMesh extruder = (SplineMesh)target;
renameChannel = extruder.GetChannel((int)index);
Repaint();
}
void OnDeleteChannel(object index)
{
SplineMesh extruder = (SplineMesh)target;
extruder.RemoveChannel((int)index);
Repaint();
}
void OnMoveChannelUp(object index)
{
SplineMesh extruder = (SplineMesh)target;
extruder.SwapChannels((int)index, ((int)index)-1);
Repaint();
}
void OnMoveChannelDown(object index)
{
SplineMesh extruder = (SplineMesh)target;
extruder.SwapChannels((int)index, ((int)index) + 1);
Repaint();
}
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
if (scaleModifierEditor != null) scaleModifierEditor.DrawScene();
}
protected override void BodyGUI()
{
showSize = false;
showDoubleSided = false;
showFlipFaces = false;
base.BodyGUI();
SplineMesh user = (SplineMesh)target;
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Uv Coordinates", EditorStyles.boldLabel);
user.uvOffset = EditorGUILayout.Vector2Field("UV Offset", user.uvOffset);
user.uvScale = EditorGUILayout.Vector2Field("UV Scale", user.uvScale);
if (targets.Length > 1)
{
EditorGUILayout.HelpBox("Cannot edit channels when multiple objects are selected", MessageType.Info);
return;
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("Channels", EditorStyles.boldLabel);
for (int i = 0; i < user.GetChannelCount(); i++)
{
if (ChannelPanel(i))
{
if (Event.current.type == EventType.MouseDown)
{
Repaint();
if (Event.current.button == 0)
{
if (selectedChannel == i)
{
selectedChannel = -1;
}
else
{
selectedChannel = i;
scaleModifierEditor = new MeshScaleModifierEditor(user, this, i);
scaleModifierEditor.alwaysOpen = true;
}
}
else if (Event.current.button == 1)
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Rename"), false, OnRenameChannel, i);
menu.AddItem(new GUIContent("Duplicate"), false, OnDuplicateChannel, i);
if (i == 0) menu.AddDisabledItem(new GUIContent("Move Up"));
else menu.AddItem(new GUIContent("Move Up"), false, OnMoveChannelUp, i);
if (i == user.GetChannelCount() - 1) menu.AddDisabledItem(new GUIContent("Move Down"));
else menu.AddItem(new GUIContent("Move Down"), false, OnMoveChannelDown, i);
menu.AddSeparator("");
menu.AddItem(new GUIContent("Delete"), false, OnDeleteChannel, i);
menu.ShowAsContext();
}
}
}
}
if (GUILayout.Button("New Channel")) user.AddChannel("Channel " + (user.GetChannelCount() + 1));
if (EditorGUI.EndChangeCheck()) EditorUtility.SetDirty(user);
}
bool ChannelPanel(int channelIndex)
{
SplineMesh.Channel channel = ((SplineMesh)target).GetChannel(channelIndex);
bool open = selectedChannel == channelIndex;
GUILayout.BeginVertical(EditorStyles.helpBox);
if (renameChannel == channel && Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter))
{
renameChannel = null;
Repaint();
}
if (renameChannel == channel) channel.name = EditorGUILayout.TextField(channel.name);
else EditorGUILayout.LabelField(channel.name, EditorStyles.boldLabel);
if (!open)
{
GUILayout.EndVertical();
return GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition);
}
Rect labelRect = GUILayoutUtility.GetLastRect();
EditorGUI.indentLevel++;
EditorGUILayout.Space();
EditorGUILayout.LabelField("Mesh Objects", EditorStyles.boldLabel);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 100f;
EditorGUILayout.BeginVertical();
for (int i = 0; i < channel.GetMeshCount(); i++) MeshRow(channel, i);
Object obj = null;
obj = EditorGUILayout.ObjectField("Add Mesh", obj, typeof(Object), true);
if (obj != null)
{
if (obj is Mesh) channel.AddMesh((Mesh)obj);
else
{
Mesh m = GetMeshFromObject(obj);
if (m != null) channel.AddMesh(m);
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
channel.type = (SplineMesh.Channel.Type)EditorGUILayout.EnumPopup("Type", channel.type);
if (channel.autoCount) EditorGUILayout.TextField("Auto Count: " + channel.count);
else channel.count = EditorGUILayout.IntField("Count", channel.count);
channel.autoCount = EditorGUILayout.Toggle("Auto Count", channel.autoCount);
channel.randomOrder = EditorGUILayout.Toggle("Random Order", channel.randomOrder);
if (channel.randomOrder) channel.randomSeed = EditorGUILayout.IntField("Seed", channel.randomSeed);
EditorGUILayout.EndVertical();
EditorGUIUtility.labelWidth = 0f;
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
float clipFrom = (float)channel.clipFrom;
float clipTo = (float)channel.clipTo;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.MinMaxSlider(new GUIContent("Clip Range:"), ref clipFrom, ref clipTo, 0f, 1f);
EditorGUIUtility.labelWidth = 0f;
EditorGUILayout.EndHorizontal();
channel.clipFrom = clipFrom;
channel.clipTo = clipTo;
EditorGUILayout.BeginHorizontal(GUILayout.MaxWidth(30));
channel.clipFrom = EditorGUILayout.FloatField((float)channel.clipFrom);
channel.clipTo = EditorGUILayout.FloatField((float)channel.clipTo);
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Geometry", EditorStyles.boldLabel);
if(channel.type != SplineMesh.Channel.Type.Place) channel.spacing = EditorGUILayout.Slider("Spacing", (float)channel.spacing, 0f, 1f);
//Offset
channel.minOffset = EditorGUILayout.Vector2Field(channel.randomOffset ? "Offset Min" : "Offset", channel.minOffset);
if(channel.randomOffset) channel.maxOffset = EditorGUILayout.Vector2Field("Offset Max", channel.maxOffset);
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 130f;
channel.randomOffset = EditorGUILayout.Toggle("Randomize Offset", channel.randomOffset);
if (channel.randomOffset) channel.offsetSeed = EditorGUILayout.IntField("Seed", channel.offsetSeed);
EditorGUIUtility.labelWidth = 0f;
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
//Rotation
if (channel.type == SplineMesh.Channel.Type.Extrude)
{
Vector3 rot = channel.minRotation;
rot.z = EditorGUILayout.FloatField(channel.randomRotation ? "Rotation Min" : "Rotation", rot.z);
channel.minRotation = rot;
if (channel.randomRotation)
{
rot = channel.maxRotation;
rot.z = EditorGUILayout.FloatField("Rotation Max", rot.z);
channel.maxRotation = rot;
}
}
else
{
channel.minRotation = EditorGUILayout.Vector3Field(channel.randomRotation ? "Rotation Min" : "Rotation", channel.minRotation);
if (channel.randomRotation) channel.maxRotation = EditorGUILayout.Vector3Field("Rotation Max", channel.maxRotation);
}
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 130f;
channel.randomRotation = EditorGUILayout.Toggle("Randomize Rotation", channel.randomRotation);
if (channel.randomRotation) channel.rotationSeed = EditorGUILayout.IntField("Seed", channel.rotationSeed);
EditorGUIUtility.labelWidth = 0f;
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
//Scale
if (channel.type == SplineMesh.Channel.Type.Extrude)
{
float lastZ = channel.minScale.z;
Vector3 scale = channel.minScale;
scale = EditorGUILayout.Vector2Field(channel.randomScale ? "Scale Min" : "Scale", scale);
scale += Vector3.forward * lastZ;
channel.minScale = scale;
if (channel.randomScale)
{
lastZ = channel.maxScale.z;
scale = channel.maxScale;
scale = EditorGUILayout.Vector2Field("Scale Max", scale);
scale += Vector3.forward * lastZ;
channel.maxScale = scale;
}
}
else
{
channel.minScale = EditorGUILayout.Vector3Field(channel.randomScale ? "Scale Min" : "Scale", channel.minScale);
if (channel.randomScale) channel.maxScale = EditorGUILayout.Vector3Field("Scale Max", channel.maxScale);
}
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 130f;
channel.randomScale = EditorGUILayout.Toggle("Randomize Scale", channel.randomScale);
if (channel.randomScale) channel.scaleSeed = EditorGUILayout.IntField("Seed", channel.scaleSeed);
EditorGUIUtility.labelWidth = 0f;
EditorGUILayout.EndHorizontal();
if (channel.randomScale)
{
EditorGUI.indentLevel++;
EditorGUIUtility.labelWidth = 120f;
channel.uniformRandomScale = EditorGUILayout.Toggle("Uniform", channel.uniformRandomScale);
EditorGUIUtility.labelWidth = 0f;
EditorGUI.indentLevel--;
}
EditorGUILayout.Space();
EditorGUILayout.LabelField("UV Coordinates", EditorStyles.boldLabel);
channel.uvOffset = EditorGUILayout.Vector2Field("UV Offset", channel.uvOffset);
channel.uvScale = EditorGUILayout.Vector2Field("UV Scale", channel.uvScale);
//Override
EditorGUILayout.Space();
EditorGUILayout.LabelField("Override", EditorStyles.boldLabel);
channel.overrideNormal = EditorGUILayout.Toggle("Normal", channel.overrideNormal);
if(channel.overrideNormal) channel.customNormal = EditorGUILayout.Vector3Field("Normal", channel.customNormal);
if (channel.type == SplineMesh.Channel.Type.Extrude)
{
channel.overrideUVs = (SplineMesh.Channel.UVOverride)EditorGUILayout.EnumPopup("UVs", channel.overrideUVs);
if(channel.overrideUVs != SplineMesh.Channel.UVOverride.None)
{
}
}
channel.overrideMaterialID = EditorGUILayout.Toggle("Material IDs", channel.overrideMaterialID);
if (channel.overrideMaterialID) channel.targetMaterialID = EditorGUILayout.IntField("Target ID", channel.targetMaterialID);
if (scaleModifierEditor != null)
{
EditorGUILayout.LabelField("Scale Regions", EditorStyles.boldLabel);
scaleModifierEditor.DrawInspector();
}
EditorGUI.indentLevel--;
GUILayout.EndVertical();
return labelRect.Contains(Event.current.mousePosition);
}
void OnDuplicateMesh(object mesh)
{
MeshLink link = (MeshLink)mesh;
link.channel.DuplicateMesh(link.index);
}
void OnDeleteMesh(object mesh)
{
MeshLink link = (MeshLink)mesh;
link.channel.RemoveMesh(link.index);
Repaint();
}
void OnMoveMeshUp(object mesh)
{
MeshLink link = (MeshLink)mesh;
link.channel.SwapMeshes(link.index, link.index - 1);
Repaint();
}
void OnMoveMeshDown(object mesh)
{
MeshLink link = (MeshLink)mesh;
link.channel.SwapMeshes(link.index, link.index + 1);
Repaint();
}
void MeshRow(SplineMesh.Channel channel, int index)
{
SplineMesh.Channel.MeshDefinition definition = channel.GetMesh(index);
EditorGUILayout.BeginHorizontal();
GUILayout.Space(15);
if(definition.mesh == null) GUILayout.Box("NULL", EditorStyles.helpBox, GUILayout.MinWidth(200));
else GUILayout.Box(definition.mesh.name, EditorStyles.helpBox, GUILayout.MinWidth(200));
EditorGUILayout.EndHorizontal();
Rect rect = GUILayoutUtility.GetLastRect();
if (Event.current.type == EventType.MouseDown && rect.Contains(Event.current.mousePosition)){
if(Event.current.button == 0)
{
definitionWindow = EditorWindow.GetWindow<MeshDefinitionWindow>(true);
definitionWindow.Init((SplineMesh)target, definition);
}
if(Event.current.button == 1)
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Duplicate"), false, OnDuplicateMesh, new MeshLink(index, channel));
if (index == 0) menu.AddDisabledItem(new GUIContent("Move Up"));
else menu.AddItem(new GUIContent("Move Up"), false, OnMoveMeshUp, new MeshLink(index, channel));
if (index == channel.GetMeshCount() - 1) menu.AddDisabledItem(new GUIContent("Move Down"));
else menu.AddItem(new GUIContent("Move Down"), false, OnMoveMeshDown, new MeshLink(index, channel));
menu.AddSeparator("");
menu.AddItem(new GUIContent("Delete"), false, OnDeleteMesh, new MeshLink(index, channel));
menu.ShowAsContext();
}
}
}
protected override void OnDestroy()
{
base.OnDestroy();
if (definitionWindow != null) definitionWindow.Close();
}
internal class MeshLink
{
internal int index = 0;
internal SplineMesh.Channel channel;
internal MeshLink(int i, SplineMesh.Channel l)
{
index = i;
channel = l;
}
}
public class MeshDefinitionWindow : EditorWindow
{
internal SplineMesh.Channel.MeshDefinition definition = null;
internal SplineMesh extrude = null;
internal void Init(SplineMesh e, SplineMesh.Channel.MeshDefinition d)
{
minSize = new Vector2(482, 180);
extrude = e;
definition = d;
if(definition.mesh != null) titleContent = new GUIContent("Configure " + definition.mesh.name);
else titleContent = new GUIContent("Configure Mesh");
}
private void OnGUI()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("Geometry", EditorStyles.boldLabel);
definition.mesh = (Mesh)EditorGUILayout.ObjectField(definition.mesh, typeof(Mesh), true);
definition.mirror = (SplineMesh.Channel.MeshDefinition.MirrorMethod)EditorGUILayout.EnumPopup("Mirror", definition.mirror);
definition.offset = EditorGUILayout.Vector3Field("Offset", definition.offset);
definition.rotation = EditorGUILayout.Vector3Field("Rotation", definition.rotation);
definition.scale = EditorGUILayout.Vector3Field("Scale", definition.scale);
var spacing = definition.spacing;
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 40;
EditorGUILayout.LabelField("Spacing");
spacing.front = EditorGUILayout.FloatField("Front", spacing.front);
spacing.back = EditorGUILayout.FloatField("Back", spacing.back);
definition.spacing = spacing;
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = 0;
EditorGUILayout.EndVertical();
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("Faces", EditorStyles.boldLabel);
definition.doubleSided = EditorGUILayout.Toggle("Double sided", definition.doubleSided);
if (definition.doubleSided) definition.flipFaces = false;
else definition.flipFaces = EditorGUILayout.Toggle("Flip Faces", definition.flipFaces);
definition.removeInnerFaces = EditorGUILayout.Toggle("Remove Inner Faces", definition.removeInnerFaces);
EditorGUILayout.LabelField("UVs", EditorStyles.boldLabel);
definition.uvOffset = EditorGUILayout.Vector2Field("UV Offset", definition.uvOffset);
definition.uvScale = EditorGUILayout.Vector2Field("UV Scale", definition.uvScale);
definition.uvRotation = EditorGUILayout.Slider("UV Rotation", definition.uvRotation, -180f, 180f);
definition.vertexGroupingMargin = EditorGUILayout.FloatField("Vertex Grouping Margin", definition.vertexGroupingMargin);
EditorGUILayout.EndVertical();
EditorGUILayout.EndHorizontal();
if (GUI.changed) extrude.Rebuild();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 411935f4b3b0d9b428e92c1b65a2fc16
timeCreated: 1454084824
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,175 @@
namespace Dreamteck.Splines.Editor
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(SplineMorph))]
public class SplineMorphEditor : Editor
{
private string addName = "";
bool rename = false;
int selected = -1;
SplineMorph morph;
private void OnEnable()
{
morph = (SplineMorph)target;
GetAddName();
}
void GetAddName()
{
addName = "Channel " + morph.GetChannelCount();
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Undo.RecordObject(morph, "Edit Morph");
morph.spline = (SplineComputer)EditorGUILayout.ObjectField("Spline", morph.spline, typeof(SplineComputer), true);
morph.space = (SplineComputer.Space)EditorGUILayout.EnumPopup("Space", morph.space);
morph.cycle = EditorGUILayout.Toggle("Runtime Cycle", morph.cycle);
if (morph.cycle)
{
EditorGUI.indentLevel++;
morph.cycleMode = (SplineMorph.CycleMode)EditorGUILayout.EnumPopup("Cycle Wrap", morph.cycleMode);
morph.cycleUpdateMode = (SplineMorph.UpdateMode)EditorGUILayout.EnumPopup("Update Mode", morph.cycleUpdateMode);
morph.cycleDuration = EditorGUILayout.FloatField("Cycle Duration", morph.cycleDuration);
EditorGUI.indentLevel--;
}
int channelCount = morph.GetChannelCount();
if (channelCount > 0)
{
if(morph.spline == null)
{
EditorGUILayout.HelpBox("No spline assigned.", MessageType.Error);
return;
}
if (morph.GetSnapshot(0).Length != morph.spline.pointCount)
{
EditorGUILayout.HelpBox("Recorded morphs require the spline to have " + morph.GetSnapshot(0).Length + ". The spline has " + morph.spline.pointCount, MessageType.Error);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Clear morph states"))
{
if (EditorUtility.DisplayDialog("Clear morph states?", "Do you want to clear all morph states?", "Yes", "No"))
{
morph.Clear();
}
}
string str = "Reduce";
if (morph.GetSnapshot(0).Length > morph.spline.pointCount) str = "Increase";
if (GUILayout.Button(str + " spline points"))
{
if (EditorUtility.DisplayDialog(str + " spline points?", "Do you want to " + str + " the spline points?", "Yes", "No"))
{
morph.spline.SetPoints(morph.GetSnapshot(0), SplineComputer.Space.Local);
}
}
if (GUILayout.Button("Update Morph States"))
{
if (EditorUtility.DisplayDialog("Update morph states?", "This will add or delete the needed spline points to all morph states", "Yes", "No"))
{
for (int i = 0; i < morph.GetChannelCount(); i++)
{
var points = morph.GetSnapshot(i);
while (points.Length < morph.spline.pointCount)
{
Dreamteck.ArrayUtility.Add(ref points, new SplinePoint());
}
while (points.Length > morph.spline.pointCount)
{
Dreamteck.ArrayUtility.RemoveAt(ref points, points.Length-1);
}
morph.SetSnapshot(i, points);
}
}
}
EditorGUILayout.EndHorizontal();
return;
}
}
for (int i = 0; i < channelCount; i++) DrawChannel(i);
EditorGUILayout.Space();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("+", GUILayout.Width(40)))
{
morph.AddChannel(addName);
GetAddName();
}
addName = EditorGUILayout.TextField(addName);
EditorGUILayout.EndHorizontal();
if (GUI.changed) SceneView.RepaintAll();
}
void DrawChannel(int index)
{
SplineMorph.Channel channel = morph.GetChannel(index);
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUI.backgroundColor = Color.white;
if (selected == index && rename)
{
if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return) rename = false;
channel.name = EditorGUILayout.TextField(channel.name);
}
else if (index > 0)
{
float weight = morph.GetWeight(index);
float lastWeight = weight;
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(new GUIContent("●", "Capture Snapshot"), GUILayout.Width(22f))) morph.CaptureSnapshot(index);
EditorGUILayout.LabelField(channel.name, GUILayout.Width(EditorGUIUtility.labelWidth));
weight = EditorGUILayout.Slider(weight, 0f, 1f);
EditorGUILayout.EndHorizontal();
if (lastWeight != weight) morph.SetWeight(index, weight);
SplineMorph.Channel.Interpolation lastInterpolation = channel.interpolation;
channel.interpolation = (SplineMorph.Channel.Interpolation)EditorGUILayout.EnumPopup("Interpolation", channel.interpolation);
if (lastInterpolation != channel.interpolation) morph.UpdateMorph();
channel.curve = EditorGUILayout.CurveField("Curve", channel.curve);
}
else
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(new GUIContent("●", "Capture Snapshot"), GUILayout.Width(22f))) morph.CaptureSnapshot(index);
GUILayout.Label(channel.name);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.EndVertical();
Rect last = GUILayoutUtility.GetLastRect();
if (last.Contains(Event.current.mousePosition))
{
if(Event.current.type == EventType.MouseDown)
{
if (Event.current.button == 0)
{
rename = false;
selected = -1;
Repaint();
}
if (Event.current.button == 1)
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Rename"), false, delegate { rename = true; selected = index; });
menu.AddItem(new GUIContent("Delete"), false, delegate
{
morph.SetWeight(index, 0f);
morph.RemoveChannel(index);
selected = -1;
GetAddName();
});
menu.ShowAsContext();
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1be9ae956377fd04384669edabafbd7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,112 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(SplinePositioner), true)]
[CanEditMultipleObjects]
public class SplinePositionerEditor : SplineTracerEditor
{
protected override void BodyGUI()
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Positioning", EditorStyles.boldLabel);
serializedObject.Update();
SerializedProperty mode = serializedObject.FindProperty("_mode");
SerializedProperty position = serializedObject.FindProperty("_position");
SerializedProperty followTarget = serializedObject.FindProperty("_followTarget");
SerializedProperty followLoop = serializedObject.FindProperty("_followLoop");
SerializedProperty followTargetDistance = serializedObject.FindProperty("_followTargetDistance");
SerializedProperty followTargetDirection = serializedObject.FindProperty("_followTargetDirection");
EditorGUI.BeginChangeCheck();
SplinePositioner positioner = (SplinePositioner)target;
if(followTarget.objectReferenceValue == null)
{
EditorGUILayout.PropertyField(mode, new GUIContent("Mode"));
if (positioner.mode == SplinePositioner.Mode.Distance)
{
float lastPos = position.floatValue;
EditorGUILayout.PropertyField(position, new GUIContent("Distance"));
if (lastPos != position.floatValue)
{
positioner.position = position.floatValue;
}
}
else
{
SerializedProperty percent = serializedObject.FindProperty("_result").FindPropertyRelative("percent");
EditorGUILayout.BeginHorizontal();
float pos = position.floatValue;
pos = EditorGUILayout.Slider("Percent", (float)pos, 0f, 1f);
if(pos != position.floatValue)
{
position.floatValue = pos;
serializedObject.ApplyModifiedProperties();
positioner.Rebuild();
}
if (GUILayout.Button("Set Distance", GUILayout.Width(85)))
{
DistanceWindow w = EditorWindow.GetWindow<DistanceWindow>(true);
w.Init(OnSetDistance, positioner.CalculateLength());
}
EditorGUILayout.EndHorizontal();
}
}
EditorGUILayout.PropertyField(followTarget);
if(followTarget.objectReferenceValue != null)
{
EditorGUILayout.PropertyField(followTargetDistance);
EditorGUILayout.PropertyField(followTargetDirection);
EditorGUILayout.PropertyField(followLoop);
}
EditorGUILayout.Space();
SerializedProperty targetObject = serializedObject.FindProperty("_targetObject");
EditorGUILayout.PropertyField(targetObject, new GUIContent("Target Object", "Which object to apply the transformations to."));
if (EditorGUI.EndChangeCheck())
{
positioner.followTarget = followTarget.objectReferenceValue as SplineTracer;
positioner.followTargetDistance = followTargetDistance.floatValue;
positioner.followTargetDirection = (Spline.Direction)followTargetDirection.intValue;
positioner.followLoop = followLoop.boolValue;
serializedObject.ApplyModifiedProperties();
}
base.BodyGUI();
}
void OnSetDistance(float distance)
{
int longest = 0;
float max = 0f;
for (int i = 0; i < users.Length; i++)
{
float length = users[i].CalculateLength();
if (length > max)
{
max = length;
longest = i;
}
}
SerializedProperty position = serializedObject.FindProperty("_position");
SplinePositioner positioner = (SplinePositioner)targets[longest];
double travel = positioner.Travel(0.0, distance, Spline.Direction.Forward);
position.floatValue = (float)travel;
serializedObject.ApplyModifiedProperties();
for (int i = 0; i < targets.Length; i++)
{
positioner = (SplinePositioner)targets[0];
positioner.position = travel;
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 7ac70fff277ab9440b800398df5fb37f
timeCreated: 1467621518
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(SplineProjector), true)]
[CanEditMultipleObjects]
public class SplineProjectorEditor : SplineTracerEditor
{
private bool info = false;
public override void OnInspectorGUI()
{
SplineProjector user = (SplineProjector)target;
if (user.mode == SplineProjector.Mode.Accurate)
{
showAveraging = false;
}
else
{
showAveraging = true;
}
base.OnInspectorGUI();
}
protected override void BodyGUI()
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Projector", EditorStyles.boldLabel);
serializedObject.Update();
SerializedProperty mode = serializedObject.FindProperty("_mode");
SerializedProperty projectTarget = serializedObject.FindProperty("_projectTarget");
SerializedProperty targetObject = serializedObject.FindProperty("_targetObject");
SerializedProperty autoProject = serializedObject.FindProperty("_autoProject");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(mode, new GUIContent("Mode"));
if (mode.intValue == (int)SplineProjector.Mode.Accurate)
{
SerializedProperty subdivide = serializedObject.FindProperty("_subdivide");
EditorGUILayout.PropertyField(subdivide, new GUIContent("Subdivide"));
}
EditorGUILayout.PropertyField(projectTarget, new GUIContent("Project Target"));
EditorGUILayout.PropertyField(targetObject, new GUIContent("Apply Target"));
GUI.color = Color.white;
EditorGUILayout.PropertyField(autoProject, new GUIContent("Auto Project"));
info = EditorGUILayout.Foldout(info, "Info");
SerializedProperty percent = serializedObject.FindProperty("_result").FindPropertyRelative("percent");
if (info) EditorGUILayout.HelpBox("Projection percent: " + percent.floatValue, MessageType.Info);
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
base.BodyGUI();
}
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
for (int i = 0; i < users.Length; i++)
{
SplineProjector user = (SplineProjector)users[i];
if (user.spline == null) return;
if (!user.autoProject) return;
DrawResult(user.result);
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 2d67d75417f347c4ebff4e77014108eb
timeCreated: 1456327392
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(SplineRenderer), true)]
[CanEditMultipleObjects]
public class SplineRendererEditor : MeshGenEditor
{
protected override void BodyGUI()
{
showDoubleSided = false;
showFlipFaces = false;
showRotation = false;
showNormalMethod = false;
serializedObject.Update();
SerializedProperty slices = serializedObject.FindProperty("_slices");
SerializedProperty autoOrient = serializedObject.FindProperty("autoOrient");
SerializedProperty updateFrameInterval = serializedObject.FindProperty("updateFrameInterval");
base.BodyGUI();
EditorGUI.BeginChangeCheck();
SplineRenderer user = (SplineRenderer)target;
EditorGUILayout.Space();
EditorGUILayout.LabelField("Geometry", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(slices);
if (slices.intValue < 1) slices.intValue = 1;
EditorGUILayout.Space();
EditorGUILayout.LabelField("Render", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(autoOrient);
if (user.autoOrient)
{
EditorGUILayout.PropertyField(updateFrameInterval);
if (updateFrameInterval.intValue < 0) updateFrameInterval.intValue = 0;
}
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
UVControls(user);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 50802729861530b4fa1d9c6a58c5530c
timeCreated: 1454771332
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,181 @@
namespace Dreamteck.Splines.Editor
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(SplineTracer), true)]
public class SplineTracerEditor : SplineUserEditor
{
private bool cameraFoldout = false;
private TransformModuleEditor motionEditor;
private RenderTexture rt;
private Texture2D renderCanvas = null;
private Camera cam;
SplineTracer[] tracers = new SplineTracer[0];
public delegate void DistanceReceiver(float distance);
protected override void OnEnable()
{
base.OnEnable();
SplineTracer tracer = (SplineTracer)target;
motionEditor = new TransformModuleEditor(tracer, this, tracer.motion);
tracers = new SplineTracer[targets.Length];
for (int i = 0; i < tracers.Length; i++)
{
tracers[i] = (SplineTracer)targets[i];
}
}
private int GetRTWidth()
{
return Mathf.RoundToInt(EditorGUIUtility.currentViewWidth)-50;
}
private int GetRTHeight()
{
return Mathf.RoundToInt(GetRTWidth()/cam.aspect);
}
private void CreateRT()
{
if(rt != null)
{
DestroyImmediate(rt);
DestroyImmediate(renderCanvas);
}
rt = new RenderTexture(GetRTWidth(), GetRTHeight(), 16, RenderTextureFormat.Default, RenderTextureReadWrite.Default);
renderCanvas = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false);
}
protected override void OnDestroy()
{
base.OnDestroy();
DestroyImmediate(rt);
}
protected override void BodyGUI()
{
base.BodyGUI();
EditorGUILayout.LabelField("Tracing", EditorStyles.boldLabel);
SplineTracer tracer = (SplineTracer)target;
serializedObject.Update();
SerializedProperty useTriggers = serializedObject.FindProperty("useTriggers");
SerializedProperty triggerGroup = serializedObject.FindProperty("triggerGroup");
SerializedProperty direction = serializedObject.FindProperty("_direction");
SerializedProperty physicsMode = serializedObject.FindProperty("_physicsMode");
SerializedProperty dontLerpDirection = serializedObject.FindProperty("_dontLerpDirection");
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(useTriggers);
if (useTriggers.boolValue) EditorGUILayout.PropertyField(triggerGroup);
EditorGUILayout.PropertyField(direction, new GUIContent("Direction"));
EditorGUILayout.PropertyField(dontLerpDirection, new GUIContent("Don't Lerp Direction"));
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(physicsMode, new GUIContent("Physics Mode"));
if (tracer.physicsMode == SplineTracer.PhysicsMode.Rigidbody)
{
Rigidbody rb = tracer.GetComponent<Rigidbody>();
if (rb == null) EditorGUILayout.HelpBox("Assign a Rigidbody component.", MessageType.Error);
else if (rb.interpolation == RigidbodyInterpolation.None && tracer.updateMethod != SplineUser.UpdateMethod.FixedUpdate) EditorGUILayout.HelpBox("Switch to FixedUpdate mode to ensure smooth update for non-interpolated rigidbodies", MessageType.Warning);
}
else if (tracer.physicsMode == SplineTracer.PhysicsMode.Rigidbody2D)
{
Rigidbody2D rb = tracer.GetComponent<Rigidbody2D>();
if (rb == null) EditorGUILayout.HelpBox("Assign a Rigidbody2D component.", MessageType.Error);
else if (rb.interpolation == RigidbodyInterpolation2D.None && tracer.updateMethod != SplineUser.UpdateMethod.FixedUpdate) EditorGUILayout.HelpBox("Switch to FixedUpdate mode to ensure smooth update for non-interpolated rigidbodies", MessageType.Warning);
}
if (tracers.Length == 1)
{
bool mightBe2d = false;
if(tracers[0].spline != null)
{
mightBe2d = tracers[0].spline.is2D;
}
if (!mightBe2d)
{
mightBe2d = physicsMode.intValue == (int)SplineTracer.PhysicsMode.Rigidbody2D;
}
if (!mightBe2d)
{
if(tracer.GetComponentInChildren<SpriteRenderer>() != null)
{
mightBe2d = true;
}
}
motionEditor.DrawInspector();
if (mightBe2d && !tracer.motion.is2D)
{
EditorGUILayout.HelpBox(
"The object is possibly set up for 2D but the rotation is applied in 3D. If the intention is for the object to be 2D, switch to 2D in the Motion panel.",
MessageType.Warning);
}
cameraFoldout = EditorGUILayout.Foldout(cameraFoldout, "Camera preview");
if (cameraFoldout)
{
if (cam == null)
{
cam = tracer.GetComponentInChildren<Camera>();
}
if (cam != null)
{
if (rt == null || rt.width != GetRTWidth() || rt.height != GetRTHeight()) CreateRT();
GUILayout.Box("", GUILayout.Width(rt.width), GUILayout.Height(rt.height));
RenderTexture prevTarget = cam.targetTexture;
RenderTexture prevActive = RenderTexture.active;
CameraClearFlags lastFlags = cam.clearFlags;
Color lastColor = cam.backgroundColor;
cam.targetTexture = rt;
cam.clearFlags = CameraClearFlags.Color;
cam.backgroundColor = Color.black;
cam.Render();
RenderTexture.active = rt;
renderCanvas.SetPixels(new Color[renderCanvas.width * renderCanvas.height]);
renderCanvas.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
renderCanvas.Apply();
RenderTexture.active = prevActive;
cam.targetTexture = prevTarget;
cam.clearFlags = lastFlags;
cam.backgroundColor = lastColor;
GUI.DrawTexture(GUILayoutUtility.GetLastRect(), renderCanvas, ScaleMode.StretchToFill);
}
else EditorGUILayout.HelpBox("There is no camera attached to the selected object or its children.", MessageType.Info);
}
}
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
for (int i = 0; i < tracers.Length; i++) tracers[i].Rebuild();
}
}
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
SplineTracer tracer = (SplineTracer)target;
}
protected void DrawResult(SplineSample result)
{
SplineTracer tracer = (SplineTracer)target;
Handles.color = Color.white;
Handles.DrawLine(tracer.transform.position, result.position);
SplineEditorHandles.DrawSolidSphere(result.position, HandleUtility.GetHandleSize(result.position) * 0.2f);
Handles.color = Color.blue;
Handles.DrawLine(result.position, result.position + result.forward * HandleUtility.GetHandleSize(result.position) * 0.5f);
Handles.color = Color.green;
Handles.DrawLine(result.position, result.position + result.up * HandleUtility.GetHandleSize(result.position) * 0.5f);
Handles.color = Color.red;
Handles.DrawLine(result.position, result.position + result.right * HandleUtility.GetHandleSize(result.position) * 0.5f);
Handles.color = Color.white;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3c6edfe32b7af2542b1eda2ec76580b9
timeCreated: 1495919748
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0895930635ab45148bfcd359f0f2ce19
timeCreated: 1451752176
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
namespace Dreamteck.Splines.Editor
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class SplineUserSubEditor
{
protected string title = "";
protected SplineUser user;
protected SplineUserEditor editor = null;
public bool alwaysOpen = false;
public bool isOpen
{
get { return foldout || alwaysOpen; }
}
bool foldout = false;
public SplineUserSubEditor(SplineUser user, SplineUserEditor editor)
{
this.editor = editor;
this.user = user;
}
public virtual void DrawInspector()
{
if (!alwaysOpen)
{
foldout = EditorGUILayout.Foldout(foldout, title);
}
}
public virtual void DrawScene()
{
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 072866cc5f8b8e94d9ed416f33661a42
timeCreated: 1484136844
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,108 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(SurfaceGenerator))]
[CanEditMultipleObjects]
public class SurfaceGeneratorEditor : MeshGenEditor
{
protected override void DuringSceneGUI(SceneView currentSceneView)
{
base.DuringSceneGUI(currentSceneView);
SurfaceGenerator user = (SurfaceGenerator)target;
if (user.extrudeSpline != null)
{
DSSplineDrawer.DrawSplineComputer(user.extrudeSpline, 0.0, 1.0, 0.5f);
}
}
protected override void BodyGUI()
{
showSize = false;
showRotation = false;
base.BodyGUI();
SurfaceGenerator user = (SurfaceGenerator)target;
serializedObject.Update();
SerializedProperty expand = serializedObject.FindProperty("_expand");
SerializedProperty extrude = serializedObject.FindProperty("_extrude");
SerializedProperty extrudeSpline = serializedObject.FindProperty("_extrudeSpline");
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Shape", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(expand, new GUIContent("Expand"));
if (extrudeSpline.objectReferenceValue == null) EditorGUILayout.PropertyField(extrude, new GUIContent("Extrude"));
var lastExtrudeSpline = extrudeSpline.objectReferenceValue;
EditorGUILayout.PropertyField(extrudeSpline, new GUIContent("Extrude Path"));
if(lastExtrudeSpline != extrudeSpline.objectReferenceValue)
{
if (lastExtrudeSpline != null)
{
for (int i = 0; i < users.Length; i++)
{
((SplineComputer)lastExtrudeSpline).Unsubscribe(users[i]);
}
}
SplineComputer spline = (SplineComputer)extrudeSpline.objectReferenceValue;
if (spline != null)
{
for (int i = 0; i < users.Length; i++)
{
spline.Subscribe(users[i]);
}
}
}
if (extrudeSpline.objectReferenceValue != null)
{
SerializedProperty extrudeClipFrom = serializedObject.FindProperty("_extrudeFrom");
SerializedProperty extrudeClipTo = serializedObject.FindProperty("_extrudeTo");
float clipFrom = extrudeClipFrom.floatValue;
float clipTo = extrudeClipTo.floatValue;
EditorGUILayout.MinMaxSlider(new GUIContent("Extrude Clip Range:"), ref clipFrom, ref clipTo, 0f, 1f);
extrudeClipFrom.floatValue = clipFrom;
extrudeClipTo.floatValue = clipTo;
SerializedProperty extrudeOffset = serializedObject.FindProperty("_extrudeOffset");
EditorGUILayout.PropertyField(extrudeOffset);
}
bool change = false;
if (EditorGUI.EndChangeCheck())
{
change = true;
serializedObject.ApplyModifiedProperties();
}
UVControls(user);
if (extrude.floatValue != 0f || extrudeSpline.objectReferenceValue != null)
{
EditorGUI.BeginChangeCheck();
SerializedProperty sideUvOffset = serializedObject.FindProperty("_sideUvOffset");
SerializedProperty sideUvScale = serializedObject.FindProperty("_sideUvScale");
SerializedProperty sideUVRotation = serializedObject.FindProperty("_sideUvRotation");
SerializedProperty uniformUvs = serializedObject.FindProperty("_uniformUvs");
EditorGUILayout.PropertyField(sideUvOffset, new GUIContent("Side UV Offset"));
EditorGUILayout.PropertyField(sideUVRotation, new GUIContent("Side UV Rotation"));
EditorGUILayout.PropertyField(sideUvScale, new GUIContent("Side UV Scale"));
EditorGUILayout.PropertyField(uniformUvs, new GUIContent("Unform UVs"));
if (EditorGUI.EndChangeCheck())
{
change = true;
serializedObject.ApplyModifiedProperties();
}
}
if (change)
{
for (int i = 0; i < users.Length; i++)
{
users[i].Rebuild();
}
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 09f3755defd393e4d862eb6298748196
timeCreated: 1456760142
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(TubeGenerator))]
[CanEditMultipleObjects]
public class TubeGeneratorEditor : MeshGenEditor
{
protected override void BodyGUI()
{
base.BodyGUI();
TubeGenerator tubeGenerator = (TubeGenerator)target;
serializedObject.Update();
SerializedProperty sides = serializedObject.FindProperty("_sides");
SerializedProperty capMode = serializedObject.FindProperty("_capMode");
SerializedProperty revolve = serializedObject.FindProperty("_revolve");
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Shape", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(sides, new GUIContent("Sides"));
EditorGUILayout.PropertyField(capMode, new GUIContent("Cap"));
EditorGUILayout.PropertyField(revolve, new GUIContent("Revolve"));
if(capMode.intValue == (int)TubeGenerator.CapMethod.Round)
{
SerializedProperty latitude = serializedObject.FindProperty("_roundCapLatitude");
EditorGUILayout.PropertyField(latitude, new GUIContent("Cap Latitude"));
}
if (sides.intValue < 3) sides.intValue = 3;
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
UVControls(tubeGenerator);
SerializedProperty uvTwist = serializedObject.FindProperty("_uvTwist");
EditorGUILayout.PropertyField(uvTwist, new GUIContent("UV Twist"));
if (capMode.intValue != 0)
{
SerializedProperty capUVScale = serializedObject.FindProperty("_capUVScale");
EditorGUILayout.PropertyField(capUVScale, new GUIContent("Cap UV Scale"));
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 79c4f01065705344ab89e0e3534c2e64
timeCreated: 1454003144
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
namespace Dreamteck.Splines.Editor
{
using UnityEngine;
using System.Collections;
using UnityEditor;
[CustomEditor(typeof(WaveformGenerator), true)]
[CanEditMultipleObjects]
public class WaveGeneratorEditor : MeshGenEditor
{
protected override void BodyGUI()
{
showSize = false;
showRotation = false;
base.BodyGUI();
WaveformGenerator user = (WaveformGenerator)target;
serializedObject.Update();
SerializedProperty axis = serializedObject.FindProperty("_axis");
SerializedProperty slices = serializedObject.FindProperty("_slices");
SerializedProperty symmetry = serializedObject.FindProperty("_symmetry");
SerializedProperty uvWrapMode = serializedObject.FindProperty("_uvWrapMode");
SerializedProperty uvOffset = serializedObject.FindProperty("_uvOffset");
SerializedProperty uvScale = serializedObject.FindProperty("_uvScale");
EditorGUI.BeginChangeCheck();
EditorGUILayout.Space();
EditorGUILayout.LabelField("Axis", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(axis, new GUIContent("Axis"));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Shape", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(slices, new GUIContent("Slices"));
if (slices.intValue < 1) slices.intValue = 1;
EditorGUILayout.PropertyField(symmetry, new GUIContent("Use Symmetry"));
EditorGUILayout.Space();
EditorGUILayout.LabelField("Uv Coordinates", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(uvWrapMode, new GUIContent("Wrap Mode"));
EditorGUILayout.PropertyField(uvOffset, new GUIContent("UV Offset"));
EditorGUILayout.PropertyField(uvScale, new GUIContent("UV Scale"));
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();
}
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 988e0370e4dbf5a4e82a4b537aaf96e4
timeCreated: 1456910867
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: