init
9
Assets/Dreamteck/Splines.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5221f4094c07ce47ad35201e769a812
|
||||
folderAsset: yes
|
||||
timeCreated: 1455392304
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Dreamteck/Splines/Components.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 829f5091cc4fe8941a75b10d0468e04d
|
||||
folderAsset: yes
|
||||
timeCreated: 1447174501
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
45
Assets/Dreamteck/Splines/Components/BlankUser.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
//This is a blank SplineUser-derived class which you can use to build your custom SplineUser
|
||||
//You can safely delete any functions that you won't use
|
||||
//DO NOT ADD Update, LateUpdate or FixedUpdate, use Run, it is automatically called through one of these methods
|
||||
public class BlankUser : SplineUser
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public override void EditorAwake()
|
||||
{
|
||||
base.EditorAwake();
|
||||
//Editor initialization
|
||||
}
|
||||
#endif
|
||||
|
||||
void Start()
|
||||
{
|
||||
//Write initialization code here
|
||||
}
|
||||
|
||||
protected override void LateRun()
|
||||
{
|
||||
base.LateRun();
|
||||
//Code to run every Update/FixedUpdate/LateUpdate
|
||||
}
|
||||
|
||||
protected override void Build()
|
||||
{
|
||||
base.Build();
|
||||
//Build is called after the spline has been sampled.
|
||||
//Use it for calculations (example: generate mesh geometry, calculate object positions)
|
||||
}
|
||||
|
||||
protected override void PostBuild()
|
||||
{
|
||||
base.PostBuild();
|
||||
//Called on the main thread after Build has finished
|
||||
//Use it to apply the calculations from Build to GameObjects, Transforms, Meshes, etc.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
12
Assets/Dreamteck/Splines/Components/BlankUser.cs.meta
Normal file
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 740f49ddb7ee0984b83bd6ab7514b564
|
||||
timeCreated: 1459692700
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
130
Assets/Dreamteck/Splines/Components/EdgeColliderGenerator.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
[AddComponentMenu("Dreamteck/Splines/Edge Collider Generator")]
|
||||
[RequireComponent(typeof(EdgeCollider2D))]
|
||||
public class EdgeColliderGenerator : SplineUser
|
||||
{
|
||||
public float offset
|
||||
{
|
||||
get { return _offset; }
|
||||
set
|
||||
{
|
||||
if (value != _offset)
|
||||
{
|
||||
_offset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private float _offset = 0f;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected EdgeCollider2D edgeCollider;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Vector2[] vertices = new Vector2[0];
|
||||
|
||||
[HideInInspector]
|
||||
public float updateRate = 0.1f;
|
||||
protected float lastUpdateTime = 0f;
|
||||
|
||||
private bool updateCollider = false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override void EditorAwake()
|
||||
{
|
||||
base.EditorAwake();
|
||||
edgeCollider = GetComponent<EdgeCollider2D>();
|
||||
Awake();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
edgeCollider = GetComponent<EdgeCollider2D>();
|
||||
}
|
||||
|
||||
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
protected override void LateRun()
|
||||
{
|
||||
base.LateRun();
|
||||
if (updateCollider)
|
||||
{
|
||||
if (edgeCollider != null)
|
||||
{
|
||||
if (Time.time - lastUpdateTime >= updateRate)
|
||||
{
|
||||
lastUpdateTime = Time.time;
|
||||
updateCollider = false;
|
||||
edgeCollider.points = vertices;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Build()
|
||||
{
|
||||
base.Build();
|
||||
if (sampleCount == 0) return;
|
||||
if (vertices.Length != sampleCount) vertices = new Vector2[sampleCount];
|
||||
bool hasOffset = offset != 0f;
|
||||
for (int i = 0; i < sampleCount; i++)
|
||||
{
|
||||
GetSample(i, evalResult);
|
||||
vertices[i] = evalResult.position;
|
||||
if (hasOffset)
|
||||
{
|
||||
Vector2 right = new Vector2(-evalResult.forward.y, evalResult.forward.x).normalized * evalResult.size;
|
||||
vertices[i] += right * offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostBuild()
|
||||
{
|
||||
base.PostBuild();
|
||||
if (edgeCollider == null) return;
|
||||
for(int i = 0; i < vertices.Length; i++) vertices[i] = transform.InverseTransformPoint(vertices[i]);
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying || updateRate <= 0f)
|
||||
{
|
||||
edgeCollider.points = vertices;
|
||||
} else updateCollider = true;
|
||||
#else
|
||||
if(updateRate == 0f) edgeCollider.points = vertices;
|
||||
else updateCollider = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d28d465ca9ef341488ba836962159676
|
||||
timeCreated: 1523272688
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 7417baf45051d9e4b974d45e69811efd, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Dreamteck/Splines/Components/Editor.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f9ed0f2ef3d38c49b2f48303506a43f
|
||||
folderAsset: yes
|
||||
timeCreated: 1448044180
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
166
Assets/Dreamteck/Splines/Components/Editor/BakeMeshWindow.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
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;
|
||||
MeshGenerator meshGen;
|
||||
public enum SaveFormat { MeshAsset, OBJ, None }
|
||||
SaveFormat format = SaveFormat.MeshAsset;
|
||||
|
||||
public void Init(MeshGenerator generator)
|
||||
{
|
||||
titleContent = new GUIContent("Bake Mesh");
|
||||
meshGen = generator;
|
||||
filter = generator.GetComponent<MeshFilter>();
|
||||
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.None;
|
||||
|
||||
if (format != SaveFormat.None) copy = EditorGUILayout.Toggle("Save without baking", copy);
|
||||
bool isCopy = format != SaveFormat.None && copy;
|
||||
switch (format)
|
||||
{
|
||||
case SaveFormat.None: 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
|
||||
{
|
||||
UnityEditor.MeshUtility.Optimize(filter.sharedMesh);
|
||||
Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
|
||||
}
|
||||
if (saveMesh) SaveMeshFile(savePath);
|
||||
}
|
||||
}
|
||||
|
||||
void Bake()
|
||||
{
|
||||
meshGen.Bake(isStatic, generateLightmapUVs);
|
||||
if (permanent && !copy)
|
||||
{
|
||||
SplineComputer meshGenComputer = meshGen.spline;
|
||||
if (permanent)
|
||||
{
|
||||
meshGenComputer.Unsubscribe(meshGen);
|
||||
DestroyImmediate(meshGen);
|
||||
}
|
||||
if (removeComputer)
|
||||
{
|
||||
if(meshGenComputer.GetComponents<Component>().Length == 2) DestroyImmediate(meshGenComputer.gameObject);
|
||||
else DestroyImmediate(meshGenComputer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveMeshFile(string savePath)
|
||||
{
|
||||
if (format == SaveFormat.None) 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)
|
||||
{
|
||||
MeshRenderer renderer = meshGen.GetComponent<MeshRenderer>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: befdb339588e28f41aa626b8c6319d06
|
||||
timeCreated: 1466584092
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b0cb98d553738f458280b7a6589f63d
|
||||
timeCreated: 1459595686
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
208
Assets/Dreamteck/Splines/Components/Editor/MeshGenEditor.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
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;
|
||||
|
||||
MeshGenerator[] generators = new MeshGenerator[0];
|
||||
|
||||
BakeMeshWindow bakeWindow = null;
|
||||
|
||||
protected override void OnSceneGUI()
|
||||
{
|
||||
base.OnSceneGUI();
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
MeshGenerator generator = (MeshGenerator)target;
|
||||
if (generator.baked)
|
||||
{
|
||||
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 size = serializedObject.FindProperty("_size");
|
||||
SerializedProperty color = serializedObject.FindProperty("_color");
|
||||
SerializedProperty normalMethod = serializedObject.FindProperty("_normalMethod");
|
||||
SerializedProperty offset = serializedObject.FindProperty("_offset");
|
||||
SerializedProperty rotation = serializedObject.FindProperty("_rotation");
|
||||
SerializedProperty flipFaces = serializedObject.FindProperty("_flipFaces");
|
||||
SerializedProperty doubleSided = serializedObject.FindProperty("_doubleSided");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (showTangents)
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Mesh", EditorStyles.boldLabel);
|
||||
if (showTangents) EditorGUILayout.PropertyField(calculateTangents, new GUIContent("Calculate Tangents"));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Vertices", EditorStyles.boldLabel);
|
||||
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 (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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5853c8e53cbbcea4c86f3dfc39e39f47
|
||||
timeCreated: 1448044279
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
288
Assets/Dreamteck/Splines/Components/Editor/NodeEditor.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
namespace Dreamteck.Splines.Editor
|
||||
{
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[CustomEditor(typeof(Node), true)]
|
||||
public class NodeEditor : Editor {
|
||||
private SplineComputer addComp = null;
|
||||
private int addPoint = 0;
|
||||
private Node lastnode = null;
|
||||
private Vector3 position, scale;
|
||||
private Quaternion rotation;
|
||||
private int[] availablePoints;
|
||||
bool connectionsOpen = false, settingsOpen = false;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
Node node = (Node)target;
|
||||
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();
|
||||
|
||||
|
||||
SplineEditorGUI.BeginContainerBox(ref settingsOpen, "Settings");
|
||||
if (settingsOpen) SettingsGUI();
|
||||
SplineEditorGUI.EndContainerBox();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsGUI()
|
||||
{
|
||||
Node node = (Node)target;
|
||||
node.transformNormals = EditorGUILayout.Toggle("Transform Normals", node.transformNormals);
|
||||
node.transformSize = EditorGUILayout.Toggle("Transform Size", node.transformSize);
|
||||
node.transformTangents = EditorGUILayout.Toggle("Transform Tangents", node.transformTangents);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
node.type = (Node.Type)EditorGUILayout.EnumPopup("Node type", node.type);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
SceneView.RepaintAll();
|
||||
node.UpdateConnectedComputers();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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();
|
||||
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");
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
EditorPrefs.SetBool("Dreamteck.Splines.Editor.NodeEditor.connectionsOpen", connectionsOpen);
|
||||
EditorPrefs.SetBool("Dreamteck.Splines.Editor.NodeEditor.settingsOpen", settingsOpen);
|
||||
}
|
||||
|
||||
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;
|
||||
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 OnSceneGUI()
|
||||
{
|
||||
Node node = (Node)target;
|
||||
Node.Connection[] connections = node.GetConnections();
|
||||
#if DREAMTECK_SPLINES
|
||||
for (int i = 0; i < connections.Length; i++) SplineDrawer.DrawSplineComputer(connections[i].spline, 0.0, 1.0, 0.5f);
|
||||
#endif
|
||||
bool update = false;
|
||||
if (position != node.transform.position)
|
||||
{
|
||||
position = node.transform.position;
|
||||
update = true;
|
||||
}
|
||||
if(scale != node.transform.localScale){
|
||||
scale = node.transform.localScale;
|
||||
update = true;
|
||||
}
|
||||
if (rotation != node.transform.rotation)
|
||||
{
|
||||
rotation = node.transform.rotation;
|
||||
update = true;
|
||||
}
|
||||
if(update) node.UpdateConnectedComputers();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
SplinePoint[] points = addComp.GetPoints();
|
||||
Transform camTransform = SceneView.currentDrawingSceneView.camera.transform;
|
||||
#if DREAMTECK_SPLINES
|
||||
SplineDrawer.DrawSplineComputer(addComp, 0.0, 1.0, 0.5f);
|
||||
#endif
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 29b7ad072e04e6341bbda1d04593b91f
|
||||
timeCreated: 1459107704
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
356
Assets/Dreamteck/Splines/Components/Editor/ObjectBenderEditor.cs
Normal file
@@ -0,0 +1,356 @@
|
||||
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 OnSceneGUI()
|
||||
{
|
||||
base.OnSceneGUI();
|
||||
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)
|
||||
{
|
||||
SplineDrawer.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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09a7b4cd1afdfcd48b026eef6eef39db
|
||||
timeCreated: 1463257593
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,183 @@
|
||||
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 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 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");
|
||||
|
||||
|
||||
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 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.LabelField("Transform", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(applyRotation, new GUIContent("Apply Rotation"));
|
||||
if (user.applyRotation)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(minRotation, new GUIContent("Min. Rotation Offset"));
|
||||
EditorGUILayout.PropertyField(maxRotation, new GUIContent("Max. Rotation Offset"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
EditorGUILayout.PropertyField(applyScale, new GUIContent("Apply Scale"));
|
||||
if (user.applyScale)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(minScaleMultiplier, new GUIContent("Min. Scale Multiplier"));
|
||||
EditorGUILayout.PropertyField(maxScaleMultiplier, new GUIContent("Max. Scale Multiplier"));
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(objectPositioning, new GUIContent("Object Positioning"));
|
||||
EditorGUILayout.PropertyField(evaluateOffset, new GUIContent("Evaluate Offset"));
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4be170f07c25f6840a0370aab63c89af
|
||||
timeCreated: 1455911715
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
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 volumetric = serializedObject.FindProperty("volumetric");
|
||||
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(emitPoint);
|
||||
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._particleSystem.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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2fe6a6d8bb85894c96049081f441293
|
||||
timeCreated: 1455991724
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
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");
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Geometry", EditorStyles.boldLabel);
|
||||
EditorGUILayout.PropertyField(slices, new GUIContent("Slices"));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb780cd10e9c18946bf622bab1d979d9
|
||||
timeCreated: 1454061509
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db08e631e1379c04898db9f7c1414513
|
||||
timeCreated: 1466252290
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17ee393449811f045b95ade0241f6d05
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,106 @@
|
||||
namespace Dreamteck.Splines.Editor
|
||||
{
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(SplineFollower), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class SplineFollowerEditor : SplineTracerEditor
|
||||
{
|
||||
SplineSample result = new SplineSample();
|
||||
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);
|
||||
follower.startPosition = travel;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void BodyGUI()
|
||||
{
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("Following", EditorStyles.boldLabel);
|
||||
SplineFollower follower = (SplineFollower)target;
|
||||
|
||||
serializedObject.Update();
|
||||
SerializedProperty followMode = serializedObject.FindProperty("followMode");
|
||||
SerializedProperty wrapMode = serializedObject.FindProperty("wrapMode");
|
||||
SerializedProperty startPosition = serializedObject.FindProperty("_startPosition");
|
||||
SerializedProperty autoStartPosition = serializedObject.FindProperty("autoStartPosition");
|
||||
SerializedProperty follow = serializedObject.FindProperty("follow");
|
||||
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUILayout.PropertyField(follow);
|
||||
EditorGUILayout.PropertyField(followMode);
|
||||
if (followMode.intValue == (int)SplineFollower.FollowMode.Uniform)
|
||||
{
|
||||
SerializedProperty followSpeed = serializedObject.FindProperty("_followSpeed");
|
||||
EditorGUILayout.PropertyField(followSpeed, new GUIContent("Follow Speed"));
|
||||
if (followSpeed.floatValue < 0f) followSpeed.floatValue = 0f;
|
||||
}
|
||||
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("Project"));
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUIUtility.labelWidth = 100f;
|
||||
if (!follower.autoStartPosition && !Application.isPlaying)
|
||||
{
|
||||
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();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (!Application.isPlaying && follower.spline.sampleCount > 0)
|
||||
{
|
||||
if (!follower.autoStartPosition)
|
||||
{
|
||||
follower.SetPercent(startPosition.floatValue);
|
||||
if (!follower.follow) SceneView.RepaintAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
base.BodyGUI();
|
||||
}
|
||||
|
||||
|
||||
protected override void OnSceneGUI()
|
||||
{
|
||||
base.OnSceneGUI();
|
||||
SplineFollower user = (SplineFollower)target;
|
||||
if (user == null) return;
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
if (!user.follow) DrawResult(user.modifiedResult);
|
||||
return;
|
||||
}
|
||||
if (user.spline == null) return;
|
||||
if (user.autoStartPosition)
|
||||
{
|
||||
user.spline.Project(result, user.transform.position, user.clipFrom, user.clipTo);
|
||||
DrawResult(result);
|
||||
} else if(!user.follow) DrawResult(user.result);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0ceef9665459454c863f7c9a1de1685
|
||||
timeCreated: 1454878386
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
446
Assets/Dreamteck/Splines/Components/Editor/SplineMeshEditor.cs
Normal file
@@ -0,0 +1,446 @@
|
||||
namespace Dreamteck.Splines.Editor
|
||||
{
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(SplineMesh), true)]
|
||||
[CanEditMultipleObjects]
|
||||
public class SplineMeshEditor : MeshGenEditor
|
||||
{
|
||||
int selected = -1;
|
||||
SplineMesh.Channel renameChannel = null;
|
||||
MeshDefinitionWindow definitionWindow = null;
|
||||
|
||||
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 BodyGUI()
|
||||
{
|
||||
showSize = false;
|
||||
showColor = 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(user.GetChannel(i), selected == i))
|
||||
{
|
||||
if (Event.current.type == EventType.MouseDown)
|
||||
{
|
||||
Repaint();
|
||||
if (Event.current.button == 0)
|
||||
{
|
||||
if (selected == i) selected = -1;
|
||||
else selected = i;
|
||||
}
|
||||
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(SplineMesh.Channel channel, bool open)
|
||||
{
|
||||
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 = 120f;
|
||||
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);
|
||||
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.Vector2Field("Offset", definition.offset);
|
||||
definition.rotation = EditorGUILayout.Vector3Field("Rotation", definition.rotation);
|
||||
definition.scale = EditorGUILayout.Vector3Field("Scale", definition.scale);
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 411935f4b3b0d9b428e92c1b65a2fc16
|
||||
timeCreated: 1454084824
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
153
Assets/Dreamteck/Splines/Components/Editor/SplineMorphEditor.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1be9ae956377fd04384669edabafbd7f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,57 @@
|
||||
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");
|
||||
EditorGUI.BeginChangeCheck();
|
||||
SplinePositioner positioner = (SplinePositioner)target;
|
||||
EditorGUILayout.PropertyField(mode, new GUIContent("Mode"));
|
||||
if (positioner.mode == SplinePositioner.Mode.Distance) positioner.position = EditorGUILayout.FloatField("Distance", (float)positioner.position);
|
||||
else
|
||||
{
|
||||
SerializedProperty percent = serializedObject.FindProperty("_result").FindPropertyRelative("percent");
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
SerializedProperty position = serializedObject.FindProperty("_position");
|
||||
double pos = positioner.ClipPercent(percent.floatValue);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
pos = EditorGUILayout.Slider("Percent", (float)pos, 0f, 1f);
|
||||
if (EditorGUI.EndChangeCheck()) position.floatValue = (float)pos;
|
||||
if (GUILayout.Button("Set Distance", GUILayout.Width(85)))
|
||||
{
|
||||
DistanceWindow w = EditorWindow.GetWindow<DistanceWindow>(true);
|
||||
w.Init(OnSetDistance, positioner.CalculateLength());
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
|
||||
}
|
||||
SerializedProperty targetObject = serializedObject.FindProperty("_targetObject");
|
||||
EditorGUILayout.PropertyField(targetObject, new GUIContent("Target Object"));
|
||||
if (EditorGUI.EndChangeCheck()) serializedObject.ApplyModifiedProperties();
|
||||
base.BodyGUI();
|
||||
}
|
||||
|
||||
void OnSetDistance(float distance)
|
||||
{
|
||||
for (int i = 0; i < targets.Length; i++)
|
||||
{
|
||||
SplinePositioner positioner = (SplinePositioner)targets[i];
|
||||
double travel = positioner.Travel(0.0, distance, Spline.Direction.Forward);
|
||||
positioner.position = travel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ac70fff277ab9440b800398df5fb37f
|
||||
timeCreated: 1467621518
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 OnSceneGUI()
|
||||
{
|
||||
base.OnSceneGUI();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d67d75417f347c4ebff4e77014108eb
|
||||
timeCreated: 1456327392
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50802729861530b4fa1d9c6a58c5530c
|
||||
timeCreated: 1454771332
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
156
Assets/Dreamteck/Splines/Components/Editor/SplineTracerEditor.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
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");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(useTriggers);
|
||||
if (useTriggers.boolValue) EditorGUILayout.PropertyField(triggerGroup);
|
||||
EditorGUILayout.PropertyField(direction, new GUIContent("Direction"));
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(physicsMode, new GUIContent("Physics Mode"));
|
||||
if(EditorGUI.EndChangeCheck())
|
||||
{
|
||||
for (int i = 0; i < tracers.Length; i++) tracers[i].EditorAwake();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
motionEditor.DrawInspector();
|
||||
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 OnSceneGUI()
|
||||
{
|
||||
base.OnSceneGUI();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c6edfe32b7af2542b1eda2ec76580b9
|
||||
timeCreated: 1495919748
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
340
Assets/Dreamteck/Splines/Components/Editor/SplineUserEditor.cs
Normal file
@@ -0,0 +1,340 @@
|
||||
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;
|
||||
bool settings = false;
|
||||
protected RotationModifierEditor rotationModifierEditor;
|
||||
protected OffsetModifierEditor offsetModifierEditor;
|
||||
protected ColorModifierEditor colorModifierEditor;
|
||||
protected SizeModifierEditor sizeModifierEditor;
|
||||
protected SplineUser[] users = new SplineUser[0];
|
||||
protected SerializedObject serializedUsers;
|
||||
SerializedProperty multithreaded, updateMethod, buildOnAwake, buildOnEnable, autoUpdate, loopSamples, clipFrom, clipTo;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 (GUI.changed) serializedObject.ApplyModifiedProperties();
|
||||
|
||||
|
||||
if (user.spline == null) EditorGUILayout.HelpBox("No SplineComputer is referenced. Link a SplineComputer to make this SplineUser work.", MessageType.Error);
|
||||
|
||||
if (showClip)
|
||||
{
|
||||
float clipFrom = 0f, clipTo = 1f;
|
||||
clipFrom = this.clipFrom.floatValue;
|
||||
clipTo = this.clipTo.floatValue;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
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;
|
||||
}
|
||||
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();
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
this.clipFrom.floatValue = clipFrom;
|
||||
this.clipTo.floatValue = clipTo;
|
||||
}
|
||||
SplineComputerEditor.hold = _editIndex >= 0;
|
||||
|
||||
if (isClosed) EditorGUILayout.PropertyField(this.loopSamples, new GUIContent("Loop Samples"));
|
||||
if (!this.loopSamples.boolValue || !isClosed)
|
||||
{
|
||||
if (this.clipFrom.floatValue > this.clipTo.floatValue)
|
||||
{
|
||||
float temp = this.clipTo.floatValue;
|
||||
this.clipTo.floatValue = this.clipFrom.floatValue;
|
||||
this.clipFrom.floatValue = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
settings = EditorGUILayout.Foldout(settings, "Settings");
|
||||
if (settings)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
if (showUpdateMethod) EditorGUILayout.PropertyField(updateMethod);
|
||||
EditorGUILayout.PropertyField(autoUpdate, new GUIContent("Auto Rebuild"));
|
||||
if (showMultithreading) EditorGUILayout.PropertyField(multithreaded);
|
||||
EditorGUILayout.PropertyField(buildOnAwake);
|
||||
EditorGUILayout.PropertyField(buildOnEnable);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
|
||||
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 OnSceneGUI()
|
||||
{
|
||||
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].alwaysDraw) continue;
|
||||
SplineDrawer.DrawSplineComputer(allComputers[i], 0.0, 1.0, 0.4f);
|
||||
}
|
||||
SplineDrawer.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;
|
||||
SplineEditorHandles.Slider(user.spline, ref val, col, "Clip From", SplineEditorHandles.SplineSliderGizmo.ForwardTriangle);
|
||||
if (val != user.clipFrom) user.clipFrom = val;
|
||||
val = user.clipTo;
|
||||
SplineEditorHandles.Slider(user.spline, ref val, col, "Clip To", SplineEditorHandles.SplineSliderGizmo.BackwardTriangle);
|
||||
if (val != user.clipTo) user.clipTo = val;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
if (doRebuild) DoRebuild();
|
||||
serializedUsers = new SerializedObject(users);
|
||||
updateMethod = serializedUsers.FindProperty("updateMethod");
|
||||
buildOnAwake = serializedUsers.FindProperty("buildOnAwake");
|
||||
buildOnEnable = serializedUsers.FindProperty("buildOnEnable");
|
||||
multithreaded = serializedUsers.FindProperty("multithreaded");
|
||||
autoUpdate = serializedUsers.FindProperty("_autoUpdate");
|
||||
SerializedProperty sampleCollection = serializedUsers.FindProperty("sampleCollection");
|
||||
loopSamples = sampleCollection.FindPropertyRelative("loopSamples");
|
||||
clipFrom = sampleCollection.FindPropertyRelative("clipFrom");
|
||||
clipTo = sampleCollection.FindPropertyRelative("clipTo"); ;
|
||||
spline = serializedUsers.FindProperty("_spline");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
HeaderGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedUsers.ApplyModifiedProperties();
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
EditorUtility.SetDirty(users[i]);
|
||||
users[i].Rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
BodyGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedUsers.ApplyModifiedProperties();
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
EditorUtility.SetDirty(users[i]);
|
||||
users[i].Rebuild();
|
||||
} catch (System.Exception ex)
|
||||
{
|
||||
Debug.Log(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
FooterGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
serializedUsers.ApplyModifiedProperties();
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
EditorUtility.SetDirty(users[i]);
|
||||
users[i].Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoRebuild()
|
||||
{
|
||||
for (int i = 0; i < users.Length; i++) users[i].Rebuild();
|
||||
doRebuild = false;
|
||||
}
|
||||
|
||||
protected virtual void 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) user.Rebuild();
|
||||
}
|
||||
SplineComputerEditor.hold = false;
|
||||
}
|
||||
|
||||
protected virtual void OnDelete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void OnEnable()
|
||||
{
|
||||
SplineUser user = (SplineUser)target;
|
||||
user.EditorAwake();
|
||||
|
||||
rotationModifierEditor = new RotationModifierEditor(user, this, user.rotationModifier);
|
||||
offsetModifierEditor = new OffsetModifierEditor(user, this, user.offsetModifier);
|
||||
colorModifierEditor = new ColorModifierEditor(user, this, user.colorModifier);
|
||||
sizeModifierEditor = new SizeModifierEditor(user, this, user.sizeModifier);
|
||||
|
||||
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()
|
||||
{
|
||||
Undo.undoRedoPerformed += OnUndoRedo;
|
||||
}
|
||||
|
||||
protected virtual void OnUndoRedo()
|
||||
{
|
||||
doRebuild = true;
|
||||
}
|
||||
|
||||
public bool EditButton(bool selected)
|
||||
{
|
||||
float width = 40f;
|
||||
editButtonContent.image = ImageDB.GetImage("edit_cursor.png", "Splines/Editor/Icons");
|
||||
if (editButtonContent.image != null)
|
||||
{
|
||||
editButtonContent.text = "";
|
||||
width = 25f;
|
||||
}
|
||||
if (SplineEditorGUI.EditorLayoutSelectableButton(editButtonContent, true, selected, GUILayout.Width(width)))
|
||||
{
|
||||
SceneView.RepaintAll();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0895930635ab45148bfcd359f0f2ce19
|
||||
timeCreated: 1451752176
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
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 isOpen
|
||||
{
|
||||
get { return foldout; }
|
||||
}
|
||||
bool foldout = false;
|
||||
|
||||
public SplineUserSubEditor(SplineUser user, SplineUserEditor editor)
|
||||
{
|
||||
this.editor = editor;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public virtual void DrawInspector()
|
||||
{
|
||||
foldout = EditorGUILayout.Foldout(foldout, title);
|
||||
}
|
||||
|
||||
public virtual void DrawScene()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 072866cc5f8b8e94d9ed416f33661a42
|
||||
timeCreated: 1484136844
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,69 @@
|
||||
namespace Dreamteck.Splines.Editor
|
||||
{
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using UnityEditor;
|
||||
|
||||
[CustomEditor(typeof(SurfaceGenerator))]
|
||||
[CanEditMultipleObjects]
|
||||
public class SurfaceGeneratorEditor : MeshGenEditor
|
||||
{
|
||||
protected override void OnSceneGUI()
|
||||
{
|
||||
base.OnSceneGUI();
|
||||
SurfaceGenerator user = (SurfaceGenerator)target;
|
||||
if(user.extrudeSpline != null)
|
||||
SplineDrawer.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"));
|
||||
EditorGUILayout.PropertyField(extrudeSpline, new GUIContent("Extrude Path"));
|
||||
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;
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
for (int i = 0; i < users.Length; i++)
|
||||
{
|
||||
users[i].Rebuild();
|
||||
}
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
UVControls(user);
|
||||
|
||||
if (extrude.floatValue != 0f || extrudeSpline.objectReferenceValue != null)
|
||||
{
|
||||
SerializedProperty sideUvOffset = serializedObject.FindProperty("_sideUvOffset");
|
||||
SerializedProperty sideUvScale = serializedObject.FindProperty("_sideUvScale");
|
||||
SerializedProperty uniformUvs = serializedObject.FindProperty("_uniformUvs");
|
||||
|
||||
EditorGUILayout.PropertyField(sideUvOffset, new GUIContent("Side UV Offset"));
|
||||
EditorGUILayout.PropertyField(sideUvScale, new GUIContent("Side UV Scale"));
|
||||
EditorGUILayout.PropertyField(uniformUvs, new GUIContent("Unform UVs"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09f3755defd393e4d862eb6298748196
|
||||
timeCreated: 1456760142
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
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);
|
||||
if(capMode.intValue != 0)
|
||||
{
|
||||
SerializedProperty capUVScale = serializedObject.FindProperty("_capUVScale");
|
||||
EditorGUILayout.PropertyField(capUVScale, new GUIContent("Cap UV Scale"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79c4f01065705344ab89e0e3534c2e64
|
||||
timeCreated: 1454003144
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 988e0370e4dbf5a4e82a4b537aaf96e4
|
||||
timeCreated: 1456910867
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Dreamteck/Splines/Components/Icons.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e8f7791e2385f7946a593cd84b580025
|
||||
folderAsset: yes
|
||||
timeCreated: 1457811249
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7417baf45051d9e4b974d45e69811efd
|
||||
timeCreated: 1523272668
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/LengthCalculator.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4b069b14ffccf146b40c7aae7c4818f
|
||||
timeCreated: 1497441467
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/NodeIcon.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
107
Assets/Dreamteck/Splines/Components/Icons/NodeIcon.png.meta
Normal file
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09a5be8542799294ab31f6b97c88471b
|
||||
timeCreated: 1459172591
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/ObjectBender.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
107
Assets/Dreamteck/Splines/Components/Icons/ObjectBender.png.meta
Normal file
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71feaa5f5395f3640a94b1ba649bc941
|
||||
timeCreated: 1472464036
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/ObjectController.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 809d29b9ca1b74947aca02225d2ec233
|
||||
timeCreated: 1497441486
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/ParticleController.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c78150f2237d29247b0f01c770f06979
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/PathGenerator.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
107
Assets/Dreamteck/Splines/Components/Icons/PathGenerator.png.meta
Normal file
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71dadc4e471c37945ba62bf068cf1468
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5fad78752ebca1541a3321d08d1cd041
|
||||
timeCreated: 1497441504
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineComputer.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,117 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c4c2926f013fcf498c19b14b90050c5
|
||||
timeCreated: 1484825827
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: iPhone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineFollower.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14d9ee407d8622249bb457e71b4400d1
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineMesh.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
107
Assets/Dreamteck/Splines/Components/Icons/SplineMesh.png.meta
Normal file
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 832e3a79eca687941a031a046045c8cc
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineMorph.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
112
Assets/Dreamteck/Splines/Components/Icons/SplineMorph.png.meta
Normal file
@@ -0,0 +1,112 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a7f65ad6116cff448644595264d0ae4
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 2
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- serializedVersion: 2
|
||||
buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplinePositioner.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7445cc27708caa049a4b4ef14d9a5eef
|
||||
timeCreated: 1467623533
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineProjector.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9dbfb387ba852e34299827107f06d528
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineRenderer.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02f78a9ec76d40f49bfac78c64a754d1
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SplineUser.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
107
Assets/Dreamteck/Splines/Components/Icons/SplineUser.png.meta
Normal file
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9bbaac8eb7021d44b9864113856c00fa
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/SurfaceGenerator.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf90d545cbe8b2a4197b471709a5e579
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/TubeGenerator.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
107
Assets/Dreamteck/Splines/Components/Icons/TubeGenerator.png.meta
Normal file
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4e3f1d75c0b07f4890e7acab6fd1a15
|
||||
timeCreated: 1457811264
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Dreamteck/Splines/Components/Icons/WaveformGenerator.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,107 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 608905f522fa0644398876606b832e68
|
||||
timeCreated: 1497441532
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: -1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: 1
|
||||
mipBias: -1
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
89
Assets/Dreamteck/Splines/Components/LengthCalculator.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Reflection;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
[AddComponentMenu("Dreamteck/Splines/Length Calculator")]
|
||||
public class LengthCalculator : SplineUser
|
||||
{
|
||||
[System.Serializable]
|
||||
public class LengthEvent
|
||||
{
|
||||
public bool enabled = true;
|
||||
public float targetLength = 0f;
|
||||
public UnityEvent onChange = new UnityEvent();
|
||||
public enum Type { Growing, Shrinking, Both}
|
||||
public Type type = Type.Both;
|
||||
|
||||
public LengthEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public LengthEvent(Type t)
|
||||
{
|
||||
type = t;
|
||||
}
|
||||
|
||||
public void Check(float fromLength, float toLength)
|
||||
{
|
||||
if (!enabled) return;
|
||||
bool condition = false;
|
||||
switch (type)
|
||||
{
|
||||
case Type.Growing: condition = toLength >= targetLength && fromLength < targetLength; break;
|
||||
case Type.Shrinking: condition = toLength <= targetLength && fromLength > targetLength; break;
|
||||
case Type.Both: condition = toLength >= targetLength && fromLength < targetLength || toLength <= targetLength && fromLength > targetLength; break;
|
||||
}
|
||||
if (condition) onChange.Invoke();
|
||||
}
|
||||
}
|
||||
[HideInInspector]
|
||||
public LengthEvent[] lengthEvents = new LengthEvent[0];
|
||||
[HideInInspector]
|
||||
public float idealLength = 1f;
|
||||
private float _length = 0f;
|
||||
private float lastLength = 0f;
|
||||
public float length
|
||||
{
|
||||
get {
|
||||
return _length;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
_length = CalculateLength();
|
||||
lastLength = _length;
|
||||
for (int i = 0; i < lengthEvents.Length; i++)
|
||||
{
|
||||
if (lengthEvents[i].targetLength == _length) lengthEvents[i].onChange.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Build()
|
||||
{
|
||||
base.Build();
|
||||
_length = CalculateLength();
|
||||
if (lastLength != _length)
|
||||
{
|
||||
for (int i = 0; i < lengthEvents.Length; i++)
|
||||
{
|
||||
lengthEvents[i].Check(lastLength, _length);
|
||||
}
|
||||
lastLength = _length;
|
||||
}
|
||||
}
|
||||
|
||||
private void AddEvent(LengthEvent lengthEvent)
|
||||
{
|
||||
LengthEvent[] newEvents = new LengthEvent[lengthEvents.Length + 1];
|
||||
lengthEvents.CopyTo(newEvents, 0);
|
||||
newEvents[newEvents.Length - 1] = lengthEvent;
|
||||
lengthEvents = newEvents;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Dreamteck/Splines/Components/LengthCalculator.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 995701723b428a94c9305a2abf319ad6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: b4b069b14ffccf146b40c7aae7c4818f, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
440
Assets/Dreamteck/Splines/Components/MeshGenerator.cs
Normal file
@@ -0,0 +1,440 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
public class MeshGenerator : SplineUser
|
||||
{
|
||||
public float size
|
||||
{
|
||||
get { return _size; }
|
||||
set
|
||||
{
|
||||
if (value != _size)
|
||||
{
|
||||
_size = value;
|
||||
Rebuild();
|
||||
} else _size = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Color color
|
||||
{
|
||||
get { return _color; }
|
||||
set
|
||||
{
|
||||
if (value != _color)
|
||||
{
|
||||
_color = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 offset
|
||||
{
|
||||
get { return _offset; }
|
||||
set
|
||||
{
|
||||
if (value != _offset)
|
||||
{
|
||||
_offset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NormalMethod normalMethod
|
||||
{
|
||||
get { return _normalMethod; }
|
||||
set
|
||||
{
|
||||
if (value != _normalMethod)
|
||||
{
|
||||
_normalMethod = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool calculateTangents
|
||||
{
|
||||
get { return _calculateTangents; }
|
||||
set
|
||||
{
|
||||
if (value != _calculateTangents)
|
||||
{
|
||||
_calculateTangents = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float rotation
|
||||
{
|
||||
get { return _rotation; }
|
||||
set
|
||||
{
|
||||
if (value != _rotation)
|
||||
{
|
||||
_rotation = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool flipFaces
|
||||
{
|
||||
get { return _flipFaces; }
|
||||
set
|
||||
{
|
||||
if (value != _flipFaces)
|
||||
{
|
||||
_flipFaces = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool doubleSided
|
||||
{
|
||||
get { return _doubleSided; }
|
||||
set
|
||||
{
|
||||
if (value != _doubleSided)
|
||||
{
|
||||
_doubleSided = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UVMode uvMode
|
||||
{
|
||||
get { return _uvMode; }
|
||||
set
|
||||
{
|
||||
if (value != _uvMode)
|
||||
{
|
||||
_uvMode = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 uvScale
|
||||
{
|
||||
get { return _uvScale; }
|
||||
set
|
||||
{
|
||||
if (value != _uvScale)
|
||||
{
|
||||
_uvScale = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 uvOffset
|
||||
{
|
||||
get { return _uvOffset; }
|
||||
set
|
||||
{
|
||||
if (value != _uvOffset)
|
||||
{
|
||||
_uvOffset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float uvRotation
|
||||
{
|
||||
get { return _uvRotation; }
|
||||
set
|
||||
{
|
||||
if (value != _uvRotation)
|
||||
{
|
||||
_uvRotation = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool baked
|
||||
{
|
||||
get
|
||||
{
|
||||
return _baked;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum UVMode { Clip, UniformClip, Clamp, UniformClamp }
|
||||
public enum NormalMethod { Recalculate, SplineNormals }
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _baked = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private float _size = 1f;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Color _color = Color.white;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _offset = Vector3.zero;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private NormalMethod _normalMethod = NormalMethod.SplineNormals;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _calculateTangents = true;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[Range(-360f, 360f)]
|
||||
private float _rotation = 0f;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _flipFaces = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _doubleSided = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private UVMode _uvMode = UVMode.Clip;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector2 _uvScale = Vector2.one;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector2 _uvOffset = Vector2.zero;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private float _uvRotation = 0f;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected MeshCollider meshCollider;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected MeshFilter filter;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected MeshRenderer meshRenderer;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected TS_Mesh tsMesh = new TS_Mesh();
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Mesh mesh;
|
||||
[HideInInspector]
|
||||
public float colliderUpdateRate = 0.2f;
|
||||
protected bool updateCollider = false;
|
||||
protected float lastUpdateTime = 0f;
|
||||
|
||||
private float vDist = 0f;
|
||||
protected static Vector2 uvs = Vector2.zero;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public override void EditorAwake()
|
||||
{
|
||||
base.EditorAwake();
|
||||
CloneMesh();
|
||||
Awake();
|
||||
}
|
||||
|
||||
public void Bake(bool makeStatic, bool lightmapUV)
|
||||
{
|
||||
if (mesh == null) return;
|
||||
gameObject.isStatic = false;
|
||||
UnityEditor.MeshUtility.Optimize(mesh);
|
||||
if(spline != null) spline.Unsubscribe(this);
|
||||
filter = GetComponent<MeshFilter>();
|
||||
meshRenderer = GetComponent<MeshRenderer>();
|
||||
filter.hideFlags = meshRenderer.hideFlags = HideFlags.None;
|
||||
filter.sharedMesh = mesh;
|
||||
if (lightmapUV) Unwrapping.GenerateSecondaryUVSet(filter.sharedMesh);
|
||||
if (makeStatic) gameObject.isStatic = true;
|
||||
_baked = true;
|
||||
}
|
||||
|
||||
public void Unbake()
|
||||
{
|
||||
gameObject.isStatic = false;
|
||||
_baked = false;
|
||||
spline.Subscribe(this);
|
||||
Rebuild();
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
if (mesh == null) mesh = new Mesh();
|
||||
base.Awake();
|
||||
filter = GetComponent<MeshFilter>();
|
||||
meshRenderer = GetComponent<MeshRenderer>();
|
||||
meshCollider = GetComponent<MeshCollider>();
|
||||
}
|
||||
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
#if UNITY_EDITOR
|
||||
MeshRenderer rend = GetComponent<MeshRenderer>();
|
||||
bool materialFound = false;
|
||||
for (int i = 0; i < rend.sharedMaterials.Length; i++)
|
||||
{
|
||||
if (rend.sharedMaterials[i] != null)
|
||||
{
|
||||
materialFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!materialFound) rend.sharedMaterial = AssetDatabase.GetBuiltinExtraResource<Material>("Default-Diffuse.mat");
|
||||
#endif
|
||||
}
|
||||
|
||||
public void CloneMesh()
|
||||
{
|
||||
if (tsMesh != null) tsMesh = TS_Mesh.Copy(tsMesh);
|
||||
else tsMesh = new TS_Mesh();
|
||||
if (mesh != null) mesh = (Mesh)Instantiate(mesh);
|
||||
else mesh = new Mesh();
|
||||
}
|
||||
|
||||
public override void Rebuild()
|
||||
{
|
||||
if (_baked) return;
|
||||
base.Rebuild();
|
||||
}
|
||||
|
||||
public override void RebuildImmediate()
|
||||
{
|
||||
if (_baked) return;
|
||||
base.RebuildImmediate();
|
||||
}
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
}
|
||||
|
||||
protected override void OnDisable()
|
||||
{
|
||||
base.OnDisable();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
MeshFilter filter = GetComponent<MeshFilter>();
|
||||
MeshRenderer rend = GetComponent<MeshRenderer>();
|
||||
if (filter != null) filter.hideFlags = HideFlags.None;
|
||||
if (rend != null) rend.hideFlags = HideFlags.None;
|
||||
}
|
||||
|
||||
|
||||
public void UpdateCollider()
|
||||
{
|
||||
meshCollider = GetComponent<MeshCollider>();
|
||||
if (meshCollider == null) meshCollider = gameObject.AddComponent<MeshCollider>();
|
||||
meshCollider.sharedMesh = filter.sharedMesh;
|
||||
}
|
||||
|
||||
protected override void LateRun()
|
||||
{
|
||||
if (_baked) return;
|
||||
base.LateRun();
|
||||
if (updateCollider)
|
||||
{
|
||||
if (meshCollider != null)
|
||||
{
|
||||
if (Time.time - lastUpdateTime >= colliderUpdateRate)
|
||||
{
|
||||
lastUpdateTime = Time.time;
|
||||
updateCollider = false;
|
||||
meshCollider.sharedMesh = filter.sharedMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Build()
|
||||
{
|
||||
base.Build();
|
||||
if (sampleCount > 0) BuildMesh();
|
||||
}
|
||||
|
||||
protected override void PostBuild()
|
||||
{
|
||||
base.PostBuild();
|
||||
WriteMesh();
|
||||
}
|
||||
|
||||
protected virtual void BuildMesh()
|
||||
{
|
||||
//Logic for mesh generation, automatically called in the Build method
|
||||
}
|
||||
|
||||
protected virtual void WriteMesh()
|
||||
{
|
||||
MeshUtility.InverseTransformMesh(tsMesh, trs);
|
||||
if (_doubleSided) MeshUtility.MakeDoublesidedHalf(tsMesh);
|
||||
else if(_flipFaces) MeshUtility.FlipFaces(tsMesh);
|
||||
if (_calculateTangents) MeshUtility.CalculateTangents(tsMesh);
|
||||
if(tsMesh.vertexCount > 64000) Debug.LogError("WARNING: The generated mesh for " + name + " has " + tsMesh.vertexCount + " vertices. The maximum vertex count for meshes in Unity is 64000. The mesh will not be updated.");
|
||||
tsMesh.WriteMesh(ref mesh);
|
||||
if (_normalMethod == 0) mesh.RecalculateNormals();
|
||||
if (filter != null) filter.sharedMesh = mesh;
|
||||
updateCollider = true;
|
||||
}
|
||||
|
||||
protected virtual void AllocateMesh(int vertexCount, int trisCount)
|
||||
{
|
||||
if (_doubleSided)
|
||||
{
|
||||
vertexCount *= 2;
|
||||
trisCount *= 2;
|
||||
}
|
||||
if (tsMesh.vertexCount != vertexCount)
|
||||
{
|
||||
tsMesh.vertices = new Vector3[vertexCount];
|
||||
tsMesh.normals = new Vector3[vertexCount];
|
||||
tsMesh.tangents = new Vector4[vertexCount];
|
||||
tsMesh.colors = new Color[vertexCount];
|
||||
tsMesh.uv = new Vector2[vertexCount];
|
||||
}
|
||||
if (tsMesh.triangles.Length != trisCount) tsMesh.triangles = new int[trisCount];
|
||||
}
|
||||
|
||||
protected void ResetUVDistance()
|
||||
{
|
||||
vDist = 0f;
|
||||
if (uvMode == UVMode.UniformClip) vDist = spline.CalculateLength(0.0, GetSampleRaw(0).percent);
|
||||
}
|
||||
|
||||
protected void AddUVDistance(int sampleIndex)
|
||||
{
|
||||
if (sampleIndex == 0) return;
|
||||
vDist += Vector3.Distance(GetSampleRaw(sampleIndex).position, GetSampleRaw(sampleIndex - 1).position);
|
||||
}
|
||||
|
||||
protected void CalculateUVs(double percent, float u)
|
||||
{
|
||||
uvs.x = u * _uvScale.x - _uvOffset.x;
|
||||
switch (uvMode)
|
||||
{
|
||||
case UVMode.Clip: uvs.y = (float)percent * _uvScale.y - _uvOffset.y; break;
|
||||
case UVMode.Clamp: uvs.y = (float)DMath.InverseLerp(clipFrom, clipTo, percent) * _uvScale.y - _uvOffset.y; break;
|
||||
case UVMode.UniformClamp: uvs.y = vDist * _uvScale.y / (float)span - _uvOffset.y; break;
|
||||
default: uvs.y = vDist * _uvScale.y - _uvOffset.y; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
11
Assets/Dreamteck/Splines/Components/MeshGenerator.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49c9228d9868e1747b4763bc4cb1d86f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 9bbaac8eb7021d44b9864113856c00fa, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
372
Assets/Dreamteck/Splines/Components/Node.cs
Normal file
@@ -0,0 +1,372 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
[ExecuteInEditMode]
|
||||
public class Node : MonoBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Connection
|
||||
{
|
||||
public SplineComputer spline
|
||||
{
|
||||
get { return _computer; }
|
||||
}
|
||||
|
||||
public int pointIndex
|
||||
{
|
||||
get { return _pointIndex; }
|
||||
}
|
||||
|
||||
public bool invertTangents = false;
|
||||
|
||||
[SerializeField]
|
||||
private int _pointIndex = 0;
|
||||
[SerializeField]
|
||||
private SplineComputer _computer = null;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
internal SplinePoint point;
|
||||
|
||||
internal bool isValid
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_computer == null) return false;
|
||||
if (_pointIndex >= _computer.pointCount) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal Connection(SplineComputer comp, int index, SplinePoint inputPoint)
|
||||
{
|
||||
_pointIndex = index;
|
||||
_computer = comp;
|
||||
point = inputPoint;
|
||||
}
|
||||
}
|
||||
public enum Type { Smooth, Free }
|
||||
[HideInInspector]
|
||||
public Type type = Type.Smooth;
|
||||
|
||||
public bool transformNormals
|
||||
{
|
||||
get { return _transformNormals; }
|
||||
set
|
||||
{
|
||||
if (value != _transformNormals)
|
||||
{
|
||||
_transformNormals = value;
|
||||
UpdatePoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool transformSize
|
||||
{
|
||||
get { return _transformSize; }
|
||||
set
|
||||
{
|
||||
if (value != _transformSize)
|
||||
{
|
||||
_transformSize = value;
|
||||
UpdatePoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool transformTangents
|
||||
{
|
||||
get { return _transformTangents; }
|
||||
set
|
||||
{
|
||||
if (value != _transformTangents)
|
||||
{
|
||||
_transformTangents = value;
|
||||
UpdatePoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
protected Connection[] connections = new Connection[0];
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _transformSize = true;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _transformNormals = true;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _transformTangents = true;
|
||||
|
||||
private Vector3 lastPosition, lastScale;
|
||||
private Quaternion lastRotation;
|
||||
Transform trs;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
trs = transform;
|
||||
SampleTransform();
|
||||
}
|
||||
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
Run();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
Run();
|
||||
}
|
||||
|
||||
bool TransformChanged()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if(trs == null) return lastPosition != transform.position || lastRotation != transform.rotation || lastScale != transform.lossyScale;
|
||||
#endif
|
||||
return lastPosition != trs.position || lastRotation != trs.rotation || lastScale != trs.lossyScale;
|
||||
}
|
||||
|
||||
void SampleTransform() {
|
||||
#if UNITY_EDITOR
|
||||
lastPosition = transform.position;
|
||||
lastScale = transform.lossyScale;
|
||||
lastRotation = transform.rotation;
|
||||
return;
|
||||
#else
|
||||
lastPosition = trs.position;
|
||||
lastScale = trs.lossyScale;
|
||||
lastRotation = trs.rotation;
|
||||
#endif
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
if (TransformChanged())
|
||||
{
|
||||
UpdateConnectedComputers();
|
||||
SampleTransform();
|
||||
}
|
||||
}
|
||||
|
||||
public SplinePoint GetPoint(int connectionIndex, bool swapTangents)
|
||||
{
|
||||
SplinePoint point = PointToWorld(connections[connectionIndex].point);
|
||||
if (connections[connectionIndex].invertTangents && swapTangents)
|
||||
{
|
||||
Vector3 tempTan = point.tangent;
|
||||
point.tangent = point.tangent2;
|
||||
point.tangent2 = tempTan;
|
||||
}
|
||||
return point;
|
||||
}
|
||||
|
||||
public void SetPoint(int connectionIndex, SplinePoint worldPoint, bool swappedTangents)
|
||||
{
|
||||
Connection connection = connections[connectionIndex];
|
||||
connection.point = PointToLocal(worldPoint);
|
||||
if (connection.invertTangents && swappedTangents)
|
||||
{
|
||||
Vector3 tempTan = connection.point.tangent;
|
||||
connection.point.tangent = connection.point.tangent2;
|
||||
connection.point.tangent2 = tempTan;
|
||||
}
|
||||
if (type == Type.Smooth)
|
||||
{
|
||||
if (connection.point.type == SplinePoint.Type.SmoothFree)
|
||||
{
|
||||
for (int i = 0; i < connections.Length; i++)
|
||||
{
|
||||
if (i == connectionIndex) continue;
|
||||
Vector3 tanDir = (connection.point.tangent - connection.point.position).normalized;
|
||||
if (tanDir == Vector3.zero) tanDir = -(connection.point.tangent2 - connection.point.position).normalized;
|
||||
float tan1Length = (connections[i].point.tangent - connections[i].point.position).magnitude;
|
||||
float tan2Length = (connections[i].point.tangent2 - connections[i].point.position).magnitude;
|
||||
connections[i].point = connection.point;
|
||||
connections[i].point.tangent = connections[i].point.position + tanDir * tan1Length;
|
||||
connections[i].point.tangent2 = connections[i].point.position - tanDir * tan2Length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < connections.Length; i++)
|
||||
{
|
||||
if (i == connectionIndex) continue;
|
||||
connections[i].point = connection.point;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
ClearConnections();
|
||||
}
|
||||
|
||||
public void ClearConnections()
|
||||
{
|
||||
for (int i = connections.Length-1; i >= 0; i--)
|
||||
{
|
||||
if (connections[i].spline != null) connections[i].spline.DisconnectNode(connections[i].pointIndex);
|
||||
}
|
||||
connections = new Connection[0];
|
||||
}
|
||||
|
||||
public void UpdateConnectedComputers(SplineComputer excludeComputer = null)
|
||||
{
|
||||
for (int i = connections.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (!connections[i].isValid)
|
||||
{
|
||||
RemoveConnection(i);
|
||||
continue;
|
||||
}
|
||||
if (connections[i].spline == excludeComputer) continue;
|
||||
if (type == Type.Smooth && i != 0) SetPoint(i, GetPoint(0, false), false);
|
||||
SplinePoint point = GetPoint(i, true);
|
||||
if (!transformNormals) point.normal = connections[i].spline.GetPointNormal(connections[i].pointIndex);
|
||||
if (!transformTangents)
|
||||
{
|
||||
point.tangent = connections[i].spline.GetPointTangent(connections[i].pointIndex);
|
||||
point.tangent2 = connections[i].spline.GetPointTangent2(connections[i].pointIndex);
|
||||
}
|
||||
if(!transformSize) point.size = connections[i].spline.GetPointSize(connections[i].pointIndex);
|
||||
connections[i].spline.SetPoint(connections[i].pointIndex, point);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdatePoint(SplineComputer computer, int pointIndex, SplinePoint point, bool updatePosition = true)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) transform.position = point.position;
|
||||
else trs.position = point.position;
|
||||
#else
|
||||
trs.position = point.position;
|
||||
#endif
|
||||
for (int i = 0; i < connections.Length; i++)
|
||||
{
|
||||
if (connections[i].spline == computer && connections[i].pointIndex == pointIndex) SetPoint(i, point, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdatePoints()
|
||||
{
|
||||
for (int i = connections.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (!connections[i].isValid)
|
||||
{
|
||||
RemoveConnection(i);
|
||||
continue;
|
||||
}
|
||||
SplinePoint point = connections[i].spline.GetPoint(connections[i].pointIndex);
|
||||
point.SetPosition(transform.position);
|
||||
SetPoint(i, point, true);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
//Use this to maintain the connections between computers in the editor
|
||||
public void EditorMaintainConnections()
|
||||
{
|
||||
RemoveInvalidConnections();
|
||||
}
|
||||
#endif
|
||||
//Remove invalid connections
|
||||
protected void RemoveInvalidConnections()
|
||||
{
|
||||
for (int i = connections.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (connections[i] == null || !connections[i].isValid) RemoveConnection(i);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddConnection(SplineComputer computer, int pointIndex)
|
||||
{
|
||||
RemoveInvalidConnections();
|
||||
Node connected = computer.GetNode(pointIndex);
|
||||
if (connected != null)
|
||||
{
|
||||
Debug.LogError(computer.name + " is already connected to node " + connected.name + " at point " + pointIndex);
|
||||
return;
|
||||
}
|
||||
SplinePoint point = computer.GetPoint(pointIndex);
|
||||
point.SetPosition(transform.position);
|
||||
ArrayUtility.Add(ref connections, new Connection(computer, pointIndex, PointToLocal(point)));
|
||||
if(connections.Length == 1) SetPoint(connections.Length - 1, point, true);
|
||||
UpdateConnectedComputers();
|
||||
}
|
||||
|
||||
protected SplinePoint PointToLocal(SplinePoint worldPoint)
|
||||
{
|
||||
worldPoint.position = Vector3.zero;
|
||||
worldPoint.tangent = transform.InverseTransformPoint(worldPoint.tangent);
|
||||
worldPoint.tangent2 = transform.InverseTransformPoint(worldPoint.tangent2);
|
||||
worldPoint.normal = transform.InverseTransformDirection(worldPoint.normal);
|
||||
worldPoint.size /= (transform.localScale.x + transform.localScale.y + transform.localScale.z)/ 3f;
|
||||
return worldPoint;
|
||||
}
|
||||
|
||||
protected SplinePoint PointToWorld(SplinePoint localPoint)
|
||||
{
|
||||
localPoint.position = transform.position;
|
||||
localPoint.tangent = transform.TransformPoint(localPoint.tangent);
|
||||
localPoint.tangent2 = transform.TransformPoint(localPoint.tangent2);
|
||||
localPoint.normal = transform.TransformDirection(localPoint.normal);
|
||||
localPoint.size *= (transform.localScale.x + transform.localScale.y + transform.localScale.z) / 3f;
|
||||
return localPoint;
|
||||
}
|
||||
|
||||
public virtual void RemoveConnection(SplineComputer computer, int pointIndex)
|
||||
{
|
||||
int index = -1;
|
||||
for (int i = 0; i < connections.Length; i++)
|
||||
{
|
||||
if (connections[i].pointIndex == pointIndex && connections[i].spline == computer)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index < 0) return;
|
||||
RemoveConnection(index);
|
||||
}
|
||||
|
||||
private void RemoveConnection(int index)
|
||||
{
|
||||
Connection[] newConnections = new Connection[connections.Length - 1];
|
||||
SplineComputer computer = connections[index].spline;
|
||||
int pointIndex = connections[index].pointIndex;
|
||||
for (int i = 0; i < connections.Length; i++)
|
||||
{
|
||||
if (i < index) newConnections[i] = connections[i];
|
||||
else if (i == index) continue;
|
||||
else newConnections[i - 1] = connections[i];
|
||||
}
|
||||
connections = newConnections;
|
||||
}
|
||||
|
||||
public virtual bool HasConnection(SplineComputer computer, int pointIndex)
|
||||
{
|
||||
for (int i = connections.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (!connections[i].isValid)
|
||||
{
|
||||
RemoveConnection(i);
|
||||
continue;
|
||||
}
|
||||
if (connections[i].spline == computer && connections[i].pointIndex == pointIndex) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Connection[] GetConnections()
|
||||
{
|
||||
return connections;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Dreamteck/Splines/Components/Node.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a212c074803b6824cae48ffa7abb84cf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: -50
|
||||
icon: {fileID: 2800000, guid: 09a5be8542799294ab31f6b97c88471b, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
803
Assets/Dreamteck/Splines/Components/ObjectBender.cs
Normal file
@@ -0,0 +1,803 @@
|
||||
using UnityEngine;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
[AddComponentMenu("Dreamteck/Splines/Object Bender")]
|
||||
public class ObjectBender : SplineUser
|
||||
{
|
||||
public enum Axis { X, Y, Z }
|
||||
public enum NormalMode { Spline, Auto, Custom }
|
||||
public enum ForwardMode { Spline, Custom }
|
||||
public bool bend
|
||||
{
|
||||
get { return _bend; }
|
||||
set
|
||||
{
|
||||
if(_bend != value)
|
||||
{
|
||||
_bend = value;
|
||||
if (value)
|
||||
{
|
||||
UpdateReferences();
|
||||
Rebuild();
|
||||
} else Revert();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _bend = false;
|
||||
public Axis axis
|
||||
{
|
||||
get { return _axis; }
|
||||
set
|
||||
{
|
||||
if (spline != null && value != _axis)
|
||||
{
|
||||
_axis = value;
|
||||
UpdateReferences();
|
||||
Rebuild();
|
||||
}
|
||||
else _axis = value;
|
||||
}
|
||||
}
|
||||
|
||||
public NormalMode upMode
|
||||
{
|
||||
get { return _normalMode; }
|
||||
set
|
||||
{
|
||||
if (spline != null && value != _normalMode)
|
||||
{
|
||||
_normalMode = value;
|
||||
Rebuild();
|
||||
} else _normalMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 customNormal
|
||||
{
|
||||
get { return _customNormal; }
|
||||
set
|
||||
{
|
||||
if (spline != null && value != _customNormal)
|
||||
{
|
||||
_customNormal = value;
|
||||
Rebuild();
|
||||
}
|
||||
else _customNormal = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ForwardMode forwardMode
|
||||
{
|
||||
get { return _forwardMode; }
|
||||
set
|
||||
{
|
||||
if (spline != null && value != _forwardMode)
|
||||
{
|
||||
_forwardMode = value;
|
||||
Rebuild();
|
||||
} else _forwardMode = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 customForward
|
||||
{
|
||||
get { return _customForward; }
|
||||
set
|
||||
{
|
||||
if (spline != null && value != _customForward)
|
||||
{
|
||||
_customForward = value;
|
||||
Rebuild();
|
||||
}
|
||||
else _customForward = value;
|
||||
}
|
||||
}
|
||||
[HideInInspector]
|
||||
public BendProperty[] bendProperties = new BendProperty[0];
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private TS_Bounds bounds = null;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Axis _axis = Axis.Z;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private NormalMode _normalMode = NormalMode.Auto;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private ForwardMode _forwardMode = ForwardMode.Spline;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
[UnityEngine.Serialization.FormerlySerializedAs("_upVector")]
|
||||
private Vector3 _customNormal = Vector3.up;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _customForward = Vector3.forward;
|
||||
Matrix4x4 normalMatrix = new Matrix4x4();
|
||||
Quaternion bendRotation = Quaternion.identity;
|
||||
|
||||
private void GetTransformsRecursively(Transform current, ref List<Transform> transformList)
|
||||
{
|
||||
transformList.Add(current);
|
||||
foreach (Transform child in current)
|
||||
{
|
||||
GetTransformsRecursively(child, ref transformList);
|
||||
}
|
||||
}
|
||||
|
||||
private void GetObjects()
|
||||
{
|
||||
List<Transform> found = new List<Transform>();
|
||||
GetTransformsRecursively(transform, ref found);
|
||||
BendProperty[] newProperties = new BendProperty[found.Count];
|
||||
for (int i = 0; i < found.Count; i++)
|
||||
{
|
||||
CreateProperty(ref newProperties[i], found[i]);
|
||||
}
|
||||
bendProperties = newProperties;
|
||||
}
|
||||
|
||||
public TS_Bounds GetBounds()
|
||||
{
|
||||
return new TS_Bounds(bounds.min, bounds.max, bounds.center);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public void EditorGenerateLightmapUVs()
|
||||
{
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
if (bendProperties[i].bendMesh)
|
||||
{
|
||||
if (bendProperties[i].filter == null) continue;
|
||||
if (bendProperties[i].filter.sharedMesh == null) continue;
|
||||
EditorUtility.DisplayProgressBar("Generating Lightmap UVS", bendProperties[i].filter.sharedMesh.name, (float)i / (bendProperties.Length - 1));
|
||||
Unwrapping.GenerateSecondaryUVSet(bendProperties[i].filter.sharedMesh);
|
||||
}
|
||||
}
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
#endif
|
||||
|
||||
private void CreateProperty(ref BendProperty property, Transform t)
|
||||
{
|
||||
property = new BendProperty(t, t == trs); //Create a new bend property for each child
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
//Search for properties that have the same trasform and copy their settings
|
||||
if (bendProperties[i].transform.transform == t)
|
||||
{
|
||||
property.enabled = bendProperties[i].enabled;
|
||||
property.applyRotation = bendProperties[i].applyRotation;
|
||||
property.applyScale = bendProperties[i].applyScale;
|
||||
property.bendMesh = bendProperties[i].bendMesh;
|
||||
property.bendCollider = bendProperties[i].bendCollider;
|
||||
property.generateLightmapUVs = bendProperties[i].generateLightmapUVs;
|
||||
property.colliderUpdateRate = bendProperties[i].colliderUpdateRate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (t.transform != trs)
|
||||
{
|
||||
property.originalPosition = trs.InverseTransformPoint(t.position);
|
||||
property.originalRotation = Quaternion.Inverse(trs.rotation) * t.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateBounds()
|
||||
{
|
||||
if (bounds == null) bounds = new TS_Bounds(Vector3.zero, Vector3.zero);
|
||||
bounds.min = bounds.max = Vector3.zero;
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
CalculatePropertyBounds(ref bendProperties[i]);
|
||||
}
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
CalculatePercents(bendProperties[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculatePropertyBounds(ref BendProperty property)
|
||||
{
|
||||
if (property.transform.transform == trs)
|
||||
{
|
||||
if (0f < bounds.min.x) bounds.min.x = 0f;
|
||||
if (0f < bounds.min.y) bounds.min.y = 0f;
|
||||
if (0f < bounds.min.z) bounds.min.z = 0f;
|
||||
if (0f > bounds.max.x) bounds.max.x = 0f;
|
||||
if (0f > bounds.max.y) bounds.max.y = 0f;
|
||||
if (0f > bounds.max.z) bounds.max.z = 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (property.originalPosition.x < bounds.min.x) bounds.min.x = property.originalPosition.x;
|
||||
if (property.originalPosition.y < bounds.min.y) bounds.min.y = property.originalPosition.y;
|
||||
if (property.originalPosition.z < bounds.min.z) bounds.min.z = property.originalPosition.z;
|
||||
if (property.originalPosition.x > bounds.max.x) bounds.max.x = property.originalPosition.x;
|
||||
if (property.originalPosition.y > bounds.max.y) bounds.max.y = property.originalPosition.y;
|
||||
if (property.originalPosition.z > bounds.max.z) bounds.max.z = property.originalPosition.z;
|
||||
}
|
||||
if (property.editMesh != null)
|
||||
{
|
||||
for (int n = 0; n < property.editMesh.vertices.Length; n++)
|
||||
{
|
||||
Vector3 localPos = property.transform.TransformPoint(property.editMesh.vertices[n]);
|
||||
localPos = trs.InverseTransformPoint(localPos);
|
||||
if (localPos.x < bounds.min.x) bounds.min.x = localPos.x;
|
||||
if (localPos.y < bounds.min.y) bounds.min.y = localPos.y;
|
||||
if (localPos.z < bounds.min.z) bounds.min.z = localPos.z;
|
||||
if (localPos.x > bounds.max.x) bounds.max.x = localPos.x;
|
||||
if (localPos.y > bounds.max.y) bounds.max.y = localPos.y;
|
||||
if (localPos.z > bounds.max.z) bounds.max.z = localPos.z;
|
||||
}
|
||||
}
|
||||
|
||||
if (property.editColliderMesh != null)
|
||||
{
|
||||
for (int n = 0; n < property.editColliderMesh.vertices.Length; n++)
|
||||
{
|
||||
Vector3 localPos = property.transform.TransformPoint(property.editColliderMesh.vertices[n]);
|
||||
localPos = trs.InverseTransformPoint(localPos);
|
||||
if (localPos.x < bounds.min.x) bounds.min.x = localPos.x;
|
||||
if (localPos.y < bounds.min.y) bounds.min.y = localPos.y;
|
||||
if (localPos.z < bounds.min.z) bounds.min.z = localPos.z;
|
||||
if (localPos.x > bounds.max.x) bounds.max.x = localPos.x;
|
||||
if (localPos.y > bounds.max.y) bounds.max.y = localPos.y;
|
||||
if (localPos.z > bounds.max.z) bounds.max.z = localPos.z;
|
||||
}
|
||||
}
|
||||
|
||||
if (property.originalSpline != null)
|
||||
{
|
||||
for (int n = 0; n < property.originalSpline.points.Length; n++)
|
||||
{
|
||||
Vector3 localPos = trs.InverseTransformPoint(property.originalSpline.points[n].position);
|
||||
if (localPos.x < bounds.min.x) bounds.min.x = localPos.x;
|
||||
if (localPos.y < bounds.min.y) bounds.min.y = localPos.y;
|
||||
if (localPos.z < bounds.min.z) bounds.min.z = localPos.z;
|
||||
if (localPos.x > bounds.max.x) bounds.max.x = localPos.x;
|
||||
if (localPos.y > bounds.max.y) bounds.max.y = localPos.y;
|
||||
if (localPos.z > bounds.max.z) bounds.max.z = localPos.z;
|
||||
}
|
||||
}
|
||||
bounds.CreateFromMinMax(bounds.min, bounds.max);
|
||||
}
|
||||
|
||||
public void CalculatePercents(BendProperty property)
|
||||
{
|
||||
if (property.transform.transform != trs) property.positionPercent = GetPercentage(trs.InverseTransformPoint(property.transform.position));
|
||||
else property.positionPercent = GetPercentage(Vector3.zero);
|
||||
if (property.editMesh != null)
|
||||
{
|
||||
if (property.vertexPercents.Length != property.editMesh.vertexCount) property.vertexPercents = new Vector3[property.editMesh.vertexCount];
|
||||
if (property.editColliderMesh != null)
|
||||
{
|
||||
if (property.colliderVertexPercents.Length != property.editMesh.vertexCount) property.colliderVertexPercents = new Vector3[property.editColliderMesh.vertexCount];
|
||||
}
|
||||
for (int i = 0; i < property.editMesh.vertexCount; i++)
|
||||
{
|
||||
Vector3 localVertex = property.transform.TransformPoint(property.editMesh.vertices[i]);
|
||||
localVertex = trs.InverseTransformPoint(localVertex);
|
||||
property.vertexPercents[i] = GetPercentage(localVertex);
|
||||
}
|
||||
if (property.editColliderMesh != null)
|
||||
{
|
||||
for (int i = 0; i < property.editColliderMesh.vertexCount; i++)
|
||||
{
|
||||
Vector3 localVertex = property.transform.TransformPoint(property.editColliderMesh.vertices[i]);
|
||||
localVertex = trs.InverseTransformPoint(localVertex);
|
||||
property.colliderVertexPercents[i] = GetPercentage(localVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (property.splineComputer != null)
|
||||
{
|
||||
SplinePoint[] points = property.splineComputer.GetPoints();
|
||||
property.splinePointPercents = new Vector3[points.Length];
|
||||
property.primaryTangentPercents = new Vector3[points.Length];
|
||||
property.secondaryTangentPercents = new Vector3[points.Length];
|
||||
for (int i = 0; i < points.Length; i++)
|
||||
{
|
||||
property.splinePointPercents[i] = GetPercentage(trs.InverseTransformPoint(points[i].position));
|
||||
property.primaryTangentPercents[i] = GetPercentage(trs.InverseTransformPoint(points[i].tangent));
|
||||
property.secondaryTangentPercents[i] = GetPercentage(trs.InverseTransformPoint(points[i].tangent2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Revert()
|
||||
{
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
bendProperties[i].Revert();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void UpdateReferences()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
if (PrefabUtility.GetPrefabType(gameObject) == PrefabType.Prefab) return;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
trs = transform;
|
||||
if (_bend)
|
||||
{
|
||||
for (int i = 0; i < bendProperties.Length; i++) bendProperties[i].Revert();
|
||||
}
|
||||
GetObjects();
|
||||
CalculateBounds();
|
||||
if (_bend)
|
||||
{
|
||||
Bend();
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
bendProperties[i].Apply(i > 0 || trs != spline.transform);
|
||||
bendProperties[i].Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void GetevalResult(Vector3 percentage)
|
||||
{
|
||||
switch (axis)
|
||||
{
|
||||
case Axis.X: Evaluate(percentage.x, evalResult); break;
|
||||
case Axis.Y: Evaluate(percentage.y, evalResult); break;
|
||||
case Axis.Z: Evaluate(percentage.z, evalResult); break;
|
||||
}
|
||||
switch (_normalMode)
|
||||
{
|
||||
case NormalMode.Auto: evalResult.up = Vector3.Cross(evalResult.forward, evalResult.right); break;
|
||||
case NormalMode.Custom: evalResult.up = _customNormal; break;
|
||||
}
|
||||
if (_forwardMode == ForwardMode.Custom) evalResult.forward = customForward;
|
||||
ModifySample(evalResult);
|
||||
Vector3 right = evalResult.right;
|
||||
|
||||
Quaternion axisRotation = Quaternion.identity;
|
||||
|
||||
switch (axis)
|
||||
{
|
||||
case Axis.Z:
|
||||
evalResult.position += right * Mathf.Lerp(bounds.min.x, bounds.max.x, percentage.x) * evalResult.size;
|
||||
evalResult.position += evalResult.up * Mathf.Lerp(bounds.min.y, bounds.max.y, percentage.y) * evalResult.size;
|
||||
break;
|
||||
case Axis.X:
|
||||
axisRotation = Quaternion.Euler(0f, -90f, 0f);
|
||||
evalResult.position += right * Mathf.Lerp(bounds.max.z, bounds.min.z, percentage.z) * evalResult.size;
|
||||
evalResult.position += evalResult.up * Mathf.Lerp(bounds.min.y, bounds.max.y, percentage.y) * evalResult.size;
|
||||
break;
|
||||
case Axis.Y:
|
||||
axisRotation = Quaternion.Euler(90f, 0f, 0f);
|
||||
evalResult.position += right * Mathf.Lerp(bounds.min.x, bounds.max.x, percentage.x) * evalResult.size;
|
||||
evalResult.position += evalResult.up * Mathf.Lerp(bounds.min.z, bounds.max.z, percentage.z) * evalResult.size;
|
||||
break;
|
||||
}
|
||||
|
||||
bendRotation = evalResult.rotation * axisRotation;
|
||||
normalMatrix = Matrix4x4.TRS(evalResult.position, bendRotation, Vector3.one * evalResult.size).inverse.transpose;
|
||||
}
|
||||
|
||||
private Vector3 GetPercentage(Vector3 point)
|
||||
{
|
||||
point.x = Mathf.InverseLerp(bounds.min.x, bounds.max.x, point.x);
|
||||
point.y = Mathf.InverseLerp(bounds.min.y, bounds.max.y, point.y);
|
||||
point.z = Mathf.InverseLerp(bounds.min.z, bounds.max.z, point.z);
|
||||
return point;
|
||||
}
|
||||
|
||||
protected override void Build()
|
||||
{
|
||||
base.Build();
|
||||
if (_bend) Bend();
|
||||
}
|
||||
|
||||
private void Bend()
|
||||
{
|
||||
if (sampleCount <= 1) return;
|
||||
if (bendProperties.Length == 0) return;
|
||||
for (int i = 0; i < bendProperties.Length; i++) BendObject(bendProperties[i]);
|
||||
}
|
||||
|
||||
public void BendObject(BendProperty p)
|
||||
{
|
||||
if (!p.enabled) return;
|
||||
|
||||
|
||||
GetevalResult(p.positionPercent);
|
||||
|
||||
p.transform.position = evalResult.position;
|
||||
if (p.applyRotation)
|
||||
{
|
||||
//p.transform.rotation = evalResult.rotation * axisRotation * p.originalRotation;
|
||||
p.transform.rotation = bendRotation * (Quaternion.Inverse(p.parentRotation) * p.originalRotation);
|
||||
} else p.transform.rotation = p.originalRotation;
|
||||
if (p.applyScale) p.transform.scale = p.originalScale * evalResult.size;
|
||||
|
||||
Matrix4x4 toLocalMatrix = Matrix4x4.TRS(p.transform.position, p.transform.rotation, p.transform.scale).inverse;
|
||||
if (p.editMesh != null)
|
||||
{
|
||||
BendMesh(p.vertexPercents, p.normals, p.editMesh, toLocalMatrix);
|
||||
p.editMesh.hasUpdate = true;
|
||||
}
|
||||
|
||||
if (p._editColliderMesh != null)
|
||||
{
|
||||
BendMesh(p.colliderVertexPercents, p.colliderNormals, p.editColliderMesh, toLocalMatrix);
|
||||
p.editColliderMesh.hasUpdate = true;
|
||||
}
|
||||
|
||||
if (p.originalSpline != null)
|
||||
{
|
||||
for (int n = 0; n < p.splinePointPercents.Length; n++)
|
||||
{
|
||||
SplinePoint point = p.originalSpline.points[n];
|
||||
GetevalResult(p.splinePointPercents[n]);
|
||||
point.position = evalResult.position;
|
||||
GetevalResult(p.primaryTangentPercents[n]);
|
||||
point.tangent = evalResult.position;
|
||||
GetevalResult(p.secondaryTangentPercents[n]);
|
||||
point.tangent2 = evalResult.position;
|
||||
switch (axis)
|
||||
{
|
||||
case Axis.X: point.normal = Quaternion.LookRotation(evalResult.forward, evalResult.up) * Quaternion.FromToRotation(Vector3.up, evalResult.up) * point.normal; break;
|
||||
case Axis.Y: point.normal = Quaternion.LookRotation(evalResult.forward, evalResult.up) * Quaternion.FromToRotation(Vector3.up, evalResult.up) * point.normal; break;
|
||||
case Axis.Z: point.normal = Quaternion.LookRotation(evalResult.forward, evalResult.up) * point.normal; break;
|
||||
}
|
||||
p.destinationSpline.points[n] = point;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BendMesh(Vector3[] vertexPercents, Vector3[] originalNormals, TS_Mesh mesh, Matrix4x4 worldToLocalMatrix)
|
||||
{
|
||||
if(mesh.vertexCount != vertexPercents.Length)
|
||||
{
|
||||
Debug.LogError("Vertex count mismatch");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < mesh.vertexCount; i++)
|
||||
{
|
||||
Vector3 percent = vertexPercents[i];
|
||||
if (axis == Axis.Y) percent.z = 1f - percent.z;
|
||||
GetevalResult(percent);
|
||||
mesh.vertices[i] = worldToLocalMatrix.MultiplyPoint3x4(evalResult.position);
|
||||
mesh.normals[i] = worldToLocalMatrix.MultiplyVector(normalMatrix.MultiplyVector(originalNormals[i]));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostBuild()
|
||||
{
|
||||
base.PostBuild();
|
||||
if (!_bend) return;
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
bendProperties[i].Apply(i > 0 || trs != spline.transform);
|
||||
bendProperties[i].Update();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LateRun()
|
||||
{
|
||||
base.LateRun();
|
||||
for (int i = 0; i < bendProperties.Length; i++)
|
||||
{
|
||||
bendProperties[i].Update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class BendProperty
|
||||
{
|
||||
public bool enabled = true;
|
||||
public bool isValid
|
||||
{
|
||||
get
|
||||
{
|
||||
return transform != null && transform.transform != null;
|
||||
}
|
||||
}
|
||||
public TS_Transform transform;
|
||||
public bool applyRotation = true;
|
||||
public bool applyScale = true;
|
||||
public bool bendMesh
|
||||
{
|
||||
get { return _bendMesh; }
|
||||
set
|
||||
{
|
||||
if (value != _bendMesh)
|
||||
{
|
||||
_bendMesh = value;
|
||||
if (value)
|
||||
{
|
||||
if (filter != null && filter.sharedMesh != null)
|
||||
{
|
||||
normals = originalMesh.normals;
|
||||
for (int i = 0; i < normals.Length; i++) normals[i] = transform.transform.TransformDirection(normals[i]);
|
||||
}
|
||||
} else RevertMesh();
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool generateLightmapUVs = false;
|
||||
public bool bendCollider
|
||||
{
|
||||
get { return _bendCollider; }
|
||||
set
|
||||
{
|
||||
if (value != _bendCollider)
|
||||
{
|
||||
_bendCollider = value;
|
||||
if (value)
|
||||
{
|
||||
if (collider != null && collider.sharedMesh != null && collider.sharedMesh != originalMesh) colliderNormals = originalColliderMesh.normals;
|
||||
}
|
||||
else RevertCollider();
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool bendSpline
|
||||
{
|
||||
get { return _bendSpline; }
|
||||
set
|
||||
{
|
||||
_bendSpline = value;
|
||||
if (value)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _bendMesh = true;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _bendSpline = true;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _bendCollider = true;
|
||||
|
||||
private float colliderUpdateDue = 0f;
|
||||
public float colliderUpdateRate = 0.2f;
|
||||
private bool updateCollider = false;
|
||||
|
||||
public Vector3 originalPosition = Vector3.zero;
|
||||
public Vector3 originalScale = Vector3.one;
|
||||
public Quaternion originalRotation = Quaternion.identity;
|
||||
public Quaternion parentRotation = Quaternion.identity;
|
||||
public Vector3 positionPercent;
|
||||
|
||||
public Vector3[] vertexPercents = new Vector3[0];
|
||||
public Vector3[] normals = new Vector3[0];
|
||||
public Vector3[] colliderVertexPercents = new Vector3[0];
|
||||
public Vector3[] colliderNormals = new Vector3[0];
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Mesh originalMesh = null;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Mesh originalColliderMesh = null;
|
||||
private Spline _originalSpline;
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Mesh destinationMesh = null;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Mesh destinationColliderMesh = null;
|
||||
public Spline destinationSpline;
|
||||
|
||||
public TS_Mesh editMesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!bendMesh || originalMesh == null) _editMesh = null;
|
||||
else if (_editMesh == null && originalMesh != null) _editMesh = new TS_Mesh(originalMesh);
|
||||
return _editMesh;
|
||||
}
|
||||
}
|
||||
public TS_Mesh editColliderMesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!bendCollider || originalColliderMesh == null) _editColliderMesh = null;
|
||||
else if (_editColliderMesh == null && originalColliderMesh != null && originalColliderMesh != originalMesh) _editColliderMesh = new TS_Mesh(originalColliderMesh);
|
||||
return _editColliderMesh;
|
||||
}
|
||||
}
|
||||
public Spline originalSpline
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!bendSpline || splineComputer == null) _originalSpline = null;
|
||||
else if (_originalSpline == null && splineComputer != null) {
|
||||
_originalSpline = new Spline(splineComputer.type);
|
||||
_originalSpline.points = splineComputer.GetPoints();
|
||||
}
|
||||
return _originalSpline;
|
||||
}
|
||||
}
|
||||
|
||||
public TS_Mesh _editMesh = null;
|
||||
public TS_Mesh _editColliderMesh = null;
|
||||
|
||||
public MeshFilter filter = null;
|
||||
public MeshCollider collider = null;
|
||||
public SplineComputer splineComputer = null;
|
||||
|
||||
public Vector3[] splinePointPercents = new Vector3[0];
|
||||
public Vector3[] primaryTangentPercents = new Vector3[0];
|
||||
public Vector3[] secondaryTangentPercents = new Vector3[0];
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool parent;
|
||||
|
||||
public BendProperty(Transform t, bool isParent = false)
|
||||
{
|
||||
parent = isParent;
|
||||
transform = new TS_Transform(t);
|
||||
originalPosition = t.localPosition;
|
||||
originalScale = t.localScale;
|
||||
originalRotation = t.localRotation;
|
||||
parentRotation = t.transform.rotation;
|
||||
if (t.transform.parent != null) parentRotation = t.transform.parent.rotation;
|
||||
filter = t.GetComponent<MeshFilter>();
|
||||
collider = t.GetComponent<MeshCollider>();
|
||||
if (filter != null && filter.sharedMesh != null)
|
||||
{
|
||||
originalMesh = filter.sharedMesh;
|
||||
normals = originalMesh.normals;
|
||||
for (int i = 0; i < normals.Length; i++) normals[i] = transform.transform.TransformDirection(normals[i]).normalized;
|
||||
}
|
||||
|
||||
if (collider != null && collider.sharedMesh != null)
|
||||
{
|
||||
originalColliderMesh = collider.sharedMesh;
|
||||
colliderNormals = originalColliderMesh.normals;
|
||||
for (int i = 0; i < colliderNormals.Length; i++) colliderNormals[i] = transform.transform.TransformDirection(colliderNormals[i]);
|
||||
}
|
||||
if (!parent) splineComputer = t.GetComponent<SplineComputer>();
|
||||
if (splineComputer != null)
|
||||
{
|
||||
if (splineComputer.isClosed) originalSpline.Close();
|
||||
destinationSpline = new Spline(originalSpline.type);
|
||||
destinationSpline.points = new SplinePoint[originalSpline.points.Length];
|
||||
destinationSpline.points = splineComputer.GetPoints();
|
||||
if (splineComputer.isClosed) destinationSpline.Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Revert()
|
||||
{
|
||||
if (!isValid) return;
|
||||
RevertTransform();
|
||||
RevertCollider();
|
||||
RevertMesh();
|
||||
if (splineComputer != null) splineComputer.SetPoints(_originalSpline.points);
|
||||
}
|
||||
|
||||
private void RevertMesh()
|
||||
{
|
||||
if (filter != null) filter.sharedMesh = originalMesh;
|
||||
destinationMesh = null;
|
||||
}
|
||||
|
||||
private void RevertTransform()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
transform.transform.localPosition = originalPosition;
|
||||
transform.transform.localRotation = originalRotation;
|
||||
}
|
||||
else
|
||||
{
|
||||
transform.localPosition = originalPosition;
|
||||
transform.localRotation = originalRotation;
|
||||
transform.Update();
|
||||
}
|
||||
#else
|
||||
transform.localPosition = originalPosition;
|
||||
transform.localRotation = originalRotation;
|
||||
transform.Update();
|
||||
#endif
|
||||
transform.scale = originalScale;
|
||||
transform.Update();
|
||||
}
|
||||
|
||||
private void RevertCollider()
|
||||
{
|
||||
if (collider != null) collider.sharedMesh = originalColliderMesh;
|
||||
destinationColliderMesh = null;
|
||||
}
|
||||
|
||||
public void Apply(bool applyTransform)
|
||||
{
|
||||
if (!enabled) return;
|
||||
if (!isValid) return;
|
||||
if(applyTransform) transform.Update();
|
||||
if (editMesh != null && editMesh.hasUpdate) ApplyMesh();
|
||||
if (bendCollider && collider != null)
|
||||
{
|
||||
if (!updateCollider)
|
||||
{
|
||||
if((editColliderMesh == null && editMesh != null) || editColliderMesh != null)
|
||||
{
|
||||
updateCollider = true;
|
||||
if(Application.isPlaying) colliderUpdateDue = Time.time + colliderUpdateRate;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (splineComputer != null) ApplySpline();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Time.time >= colliderUpdateDue && updateCollider)
|
||||
{
|
||||
updateCollider = false;
|
||||
ApplyCollider();
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyMesh()
|
||||
{
|
||||
if (filter == null) return;
|
||||
MeshUtility.CalculateTangents(editMesh);
|
||||
if (destinationMesh == null)
|
||||
{
|
||||
destinationMesh = new Mesh();
|
||||
destinationMesh.name = originalMesh.name;
|
||||
}
|
||||
|
||||
editMesh.WriteMesh(ref destinationMesh);
|
||||
destinationMesh.RecalculateBounds();
|
||||
filter.sharedMesh = destinationMesh;
|
||||
}
|
||||
|
||||
private void ApplyCollider()
|
||||
{
|
||||
if (collider == null) return;
|
||||
if (originalColliderMesh == originalMesh) collider.sharedMesh = filter.sharedMesh; //if the collider has the same mesh as the filter - just copy it
|
||||
else
|
||||
{
|
||||
MeshUtility.CalculateTangents(editColliderMesh);
|
||||
if (destinationColliderMesh == null)
|
||||
{
|
||||
destinationColliderMesh = new Mesh();
|
||||
destinationColliderMesh.name = originalColliderMesh.name;
|
||||
}
|
||||
editColliderMesh.WriteMesh(ref destinationColliderMesh);
|
||||
destinationColliderMesh.RecalculateBounds();
|
||||
collider.sharedMesh = destinationColliderMesh;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplySpline()
|
||||
{
|
||||
if (destinationSpline == null) return;
|
||||
splineComputer.SetPoints(destinationSpline.points);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Dreamteck/Splines/Components/ObjectBender.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f64d070be79692d449ab6f792ee7fb57
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 71feaa5f5395f3640a94b1ba649bc941, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
684
Assets/Dreamteck/Splines/Components/ObjectController.cs
Normal file
@@ -0,0 +1,684 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
|
||||
namespace Dreamteck.Splines
|
||||
{
|
||||
[AddComponentMenu("Dreamteck/Splines/Object Controller")]
|
||||
public class ObjectController : SplineUser
|
||||
{
|
||||
[System.Serializable]
|
||||
internal class ObjectControl
|
||||
{
|
||||
public bool isNull
|
||||
{
|
||||
get
|
||||
{
|
||||
return gameObject == null;
|
||||
}
|
||||
}
|
||||
public Transform transform
|
||||
{
|
||||
get {
|
||||
if (gameObject == null) return null;
|
||||
return gameObject.transform;
|
||||
}
|
||||
}
|
||||
public GameObject gameObject;
|
||||
public Vector3 position = Vector3.zero;
|
||||
public Quaternion rotation = Quaternion.identity;
|
||||
public Vector3 scale = Vector3.one;
|
||||
public bool active = true;
|
||||
|
||||
public Vector3 baseScale = Vector3.one;
|
||||
|
||||
public ObjectControl(GameObject input)
|
||||
{
|
||||
gameObject = input;
|
||||
baseScale = gameObject.transform.localScale;
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
if (gameObject == null) return;
|
||||
GameObject.Destroy(gameObject);
|
||||
}
|
||||
|
||||
public void DestroyImmediate()
|
||||
{
|
||||
if (gameObject == null) return;
|
||||
GameObject.DestroyImmediate(gameObject);
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if (gameObject == null) return;
|
||||
transform.position = position;
|
||||
transform.rotation = rotation;
|
||||
transform.localScale = scale;
|
||||
gameObject.SetActive(active);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum ObjectMethod { Instantiate, GetChildren }
|
||||
public enum Positioning { Stretch, Clip }
|
||||
public enum Iteration { Ordered, Random }
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
public GameObject[] objects = new GameObject[0];
|
||||
|
||||
public ObjectMethod objectMethod
|
||||
{
|
||||
get { return _objectMethod; }
|
||||
set
|
||||
{
|
||||
if (value != _objectMethod)
|
||||
{
|
||||
if (value == ObjectMethod.GetChildren)
|
||||
{
|
||||
_objectMethod = value;
|
||||
Spawn();
|
||||
}
|
||||
else _objectMethod = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int spawnCount
|
||||
{
|
||||
get { return _spawnCount; }
|
||||
set
|
||||
{
|
||||
if (value != _spawnCount)
|
||||
{
|
||||
if (value < 0) value = 0;
|
||||
if (_objectMethod == ObjectMethod.Instantiate)
|
||||
{
|
||||
if (value < _spawnCount)
|
||||
{
|
||||
_spawnCount = value;
|
||||
Remove();
|
||||
}
|
||||
else
|
||||
{
|
||||
_spawnCount = value;
|
||||
Spawn();
|
||||
}
|
||||
}
|
||||
else _spawnCount = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Positioning objectPositioning
|
||||
{
|
||||
get { return _objectPositioning; }
|
||||
set
|
||||
{
|
||||
if (value != _objectPositioning)
|
||||
{
|
||||
_objectPositioning = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Iteration iteration
|
||||
{
|
||||
get { return _iteration; }
|
||||
set
|
||||
{
|
||||
if (value != _iteration)
|
||||
{
|
||||
_iteration = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public bool retainPrefabInstancesInEditor
|
||||
{
|
||||
get { return _retainPrefabInstancesInEditor; }
|
||||
set
|
||||
{
|
||||
if (value != _retainPrefabInstancesInEditor)
|
||||
{
|
||||
_retainPrefabInstancesInEditor = value;
|
||||
Clear();
|
||||
Spawn();
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public int randomSeed
|
||||
{
|
||||
get { return _randomSeed; }
|
||||
set
|
||||
{
|
||||
if (value != _randomSeed)
|
||||
{
|
||||
_randomSeed = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 minOffset
|
||||
{
|
||||
get { return _minOffset; }
|
||||
set
|
||||
{
|
||||
if (value != _minOffset)
|
||||
{
|
||||
_minOffset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 maxOffset
|
||||
{
|
||||
get { return _maxOffset; }
|
||||
set
|
||||
{
|
||||
if (value != _maxOffset)
|
||||
{
|
||||
_maxOffset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool offsetUseWorldCoords
|
||||
{
|
||||
get { return _offsetUseWorldCoords; }
|
||||
set
|
||||
{
|
||||
if (value != _offsetUseWorldCoords)
|
||||
{
|
||||
_offsetUseWorldCoords = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 minRotation
|
||||
{
|
||||
get { return _minRotation; }
|
||||
set
|
||||
{
|
||||
if (value != _minRotation)
|
||||
{
|
||||
_minRotation = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 maxRotation
|
||||
{
|
||||
get { return _maxRotation; }
|
||||
set
|
||||
{
|
||||
if (value != _maxRotation)
|
||||
{
|
||||
_maxRotation = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 rotationOffset
|
||||
{
|
||||
get { return (_maxRotation+_minRotation)/2f; }
|
||||
set
|
||||
{
|
||||
if (value != _minRotation || value != _maxRotation)
|
||||
{
|
||||
_minRotation = _maxRotation = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 minScaleMultiplier
|
||||
{
|
||||
get { return _minScaleMultiplier; }
|
||||
set
|
||||
{
|
||||
if (value != _minScaleMultiplier)
|
||||
{
|
||||
_minScaleMultiplier = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 maxScaleMultiplier
|
||||
{
|
||||
get { return _maxScaleMultiplier; }
|
||||
set
|
||||
{
|
||||
if (value != _maxScaleMultiplier)
|
||||
{
|
||||
_maxScaleMultiplier = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 scaleMultiplier
|
||||
{
|
||||
get { return (_minScaleMultiplier + _maxScaleMultiplier) / 2f; }
|
||||
set
|
||||
{
|
||||
if (value != _minScaleMultiplier || value != _maxScaleMultiplier)
|
||||
{
|
||||
_minScaleMultiplier = _maxScaleMultiplier = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool shellOffset
|
||||
{
|
||||
get { return _shellOffset; }
|
||||
set
|
||||
{
|
||||
if (value != _shellOffset)
|
||||
{
|
||||
_shellOffset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool applyRotation
|
||||
{
|
||||
get { return _applyRotation; }
|
||||
set
|
||||
{
|
||||
if (value != _applyRotation)
|
||||
{
|
||||
_applyRotation = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool rotateByOffset
|
||||
{
|
||||
get { return _rotateByOffset; }
|
||||
set
|
||||
{
|
||||
if (value != _rotateByOffset)
|
||||
{
|
||||
_rotateByOffset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool applyScale
|
||||
{
|
||||
get { return _applyScale; }
|
||||
set
|
||||
{
|
||||
if (value != _applyScale)
|
||||
{
|
||||
_applyScale = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float evaluateOffset
|
||||
{
|
||||
get { return _evaluateOffset; }
|
||||
set
|
||||
{
|
||||
if (value != _evaluateOffset)
|
||||
{
|
||||
_evaluateOffset = value;
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private float _evaluateOffset = 0f;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private int _spawnCount = 0;
|
||||
#if UNITY_EDITOR
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _retainPrefabInstancesInEditor = true;
|
||||
#endif
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Positioning _objectPositioning = Positioning.Stretch;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Iteration _iteration = Iteration.Ordered;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private int _randomSeed = 1;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _minOffset = Vector3.zero;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _maxOffset = Vector3.zero;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _offsetUseWorldCoords = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _minRotation = Vector3.zero;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _maxRotation = Vector3.zero;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _minScaleMultiplier = Vector3.one;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private Vector3 _maxScaleMultiplier = Vector3.one;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _shellOffset = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _applyRotation = true;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _rotateByOffset = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private bool _applyScale = false;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private ObjectMethod _objectMethod = ObjectMethod.Instantiate;
|
||||
[HideInInspector]
|
||||
public bool delayedSpawn = false;
|
||||
[HideInInspector]
|
||||
public float spawnDelay = 0.1f;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private int lastChildCount = 0;
|
||||
[SerializeField]
|
||||
[HideInInspector]
|
||||
private ObjectControl[] spawned = new ObjectControl[0];
|
||||
|
||||
System.Random offsetRandomizer, shellRandomizer, rotationRandomizer, scaleRandomizer;
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (int i = 0; i < spawned.Length; i++)
|
||||
{
|
||||
if (spawned[i] == null || spawned[i].transform == null) continue;
|
||||
spawned[i].transform.localScale = spawned[i].baseScale;
|
||||
if (_objectMethod == ObjectMethod.GetChildren) spawned[i].gameObject.SetActive(false);
|
||||
else
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying) spawned[i].DestroyImmediate();
|
||||
else spawned[i].Destroy();
|
||||
#else
|
||||
spawned[i].Destroy();
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
spawned = new ObjectControl[0];
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (_spawnCount < 0) _spawnCount = 0;
|
||||
}
|
||||
|
||||
private void Remove()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
if (PrefabUtility.GetPrefabType(gameObject) == PrefabType.Prefab) return;
|
||||
#endif
|
||||
#endif
|
||||
if (_spawnCount >= spawned.Length) return;
|
||||
for (int i = spawned.Length - 1; i >= _spawnCount; i--)
|
||||
{
|
||||
if (i >= spawned.Length) break;
|
||||
if (spawned[i] == null) continue;
|
||||
spawned[i].transform.localScale = spawned[i].baseScale;
|
||||
if (_objectMethod == ObjectMethod.GetChildren) spawned[i].gameObject.SetActive(false);
|
||||
else
|
||||
{
|
||||
if (Application.isEditor) spawned[i].DestroyImmediate();
|
||||
else spawned[i].Destroy();
|
||||
|
||||
}
|
||||
}
|
||||
ObjectControl[] newSpawned = new ObjectControl[_spawnCount];
|
||||
for (int i = 0; i < newSpawned.Length; i++)
|
||||
{
|
||||
newSpawned[i] = spawned[i];
|
||||
}
|
||||
spawned = newSpawned;
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
public void GetAll()
|
||||
{
|
||||
ObjectControl[] newSpawned = new ObjectControl[transform.childCount];
|
||||
int index = 0;
|
||||
foreach (Transform child in transform)
|
||||
{
|
||||
if (newSpawned[index] == null)
|
||||
{
|
||||
newSpawned[index++] = new ObjectControl(child.gameObject);
|
||||
continue;
|
||||
}
|
||||
bool found = false;
|
||||
for (int i = 0; i < spawned.Length; i++)
|
||||
{
|
||||
if (spawned[i].gameObject == child.gameObject)
|
||||
{
|
||||
newSpawned[index++] = spawned[i];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) newSpawned[index++] = new ObjectControl(child.gameObject);
|
||||
}
|
||||
spawned = newSpawned;
|
||||
}
|
||||
|
||||
public void Spawn()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
if (PrefabUtility.GetPrefabType(gameObject) == PrefabType.Prefab) return;
|
||||
#endif
|
||||
#endif
|
||||
if (_objectMethod == ObjectMethod.Instantiate)
|
||||
{
|
||||
if (delayedSpawn && Application.isPlaying)
|
||||
{
|
||||
StopCoroutine("InstantiateAllWithDelay");
|
||||
StartCoroutine(InstantiateAllWithDelay());
|
||||
}
|
||||
else InstantiateAll();
|
||||
}
|
||||
else GetAll();
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
protected override void LateRun()
|
||||
{
|
||||
base.LateRun();
|
||||
if (_objectMethod == ObjectMethod.GetChildren && lastChildCount != transform.childCount)
|
||||
{
|
||||
Spawn();
|
||||
lastChildCount = transform.childCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IEnumerator InstantiateAllWithDelay()
|
||||
{
|
||||
if (spline == null) yield break;
|
||||
if (objects.Length == 0) yield break;
|
||||
for (int i = spawned.Length; i <= spawnCount; i++)
|
||||
{
|
||||
InstantiateSingle();
|
||||
yield return new WaitForSeconds(spawnDelay);
|
||||
}
|
||||
}
|
||||
|
||||
private void InstantiateAll()
|
||||
{
|
||||
if (spline == null) return;
|
||||
if (objects.Length == 0) return;
|
||||
for (int i = spawned.Length; i < spawnCount; i++) InstantiateSingle();
|
||||
}
|
||||
|
||||
private void InstantiateSingle()
|
||||
{
|
||||
if (objects.Length == 0) return;
|
||||
int index = 0;
|
||||
if (_iteration == Iteration.Ordered)
|
||||
{
|
||||
index = spawned.Length - Mathf.FloorToInt(spawned.Length / objects.Length) * objects.Length;
|
||||
}
|
||||
else index = Random.Range(0, objects.Length);
|
||||
if (objects[index] == null) return;
|
||||
|
||||
ObjectControl[] newSpawned = new ObjectControl[spawned.Length + 1];
|
||||
spawned.CopyTo(newSpawned, 0);
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying && retainPrefabInstancesInEditor)
|
||||
{
|
||||
GameObject go = (GameObject)UnityEditor.PrefabUtility.InstantiatePrefab(objects[index]);
|
||||
go.transform.position = transform.position;
|
||||
go.transform.rotation = transform.rotation;
|
||||
newSpawned[newSpawned.Length - 1] = new ObjectControl(go);
|
||||
} else
|
||||
{
|
||||
newSpawned[newSpawned.Length - 1] = new ObjectControl((GameObject)Instantiate(objects[index], transform.position, transform.rotation));
|
||||
}
|
||||
#else
|
||||
newSpawned[newSpawned.Length - 1] = new ObjectControl((GameObject)Instantiate(objects[index], transform.position, transform.rotation));
|
||||
#endif
|
||||
newSpawned[newSpawned.Length - 1].transform.parent = transform;
|
||||
spawned = newSpawned;
|
||||
}
|
||||
|
||||
protected override void Build()
|
||||
{
|
||||
base.Build();
|
||||
offsetRandomizer = new System.Random(_randomSeed);
|
||||
if(_shellOffset) shellRandomizer = new System.Random(_randomSeed + 1);
|
||||
rotationRandomizer = new System.Random(_randomSeed + 2);
|
||||
scaleRandomizer = new System.Random(_randomSeed + 3);
|
||||
bool randomScaleMultiplier = _minScaleMultiplier != _maxScaleMultiplier;
|
||||
for (int i = 0; i < spawned.Length; i++)
|
||||
{
|
||||
if (spawned[i] == null)
|
||||
{
|
||||
Clear();
|
||||
Spawn();
|
||||
break;
|
||||
}
|
||||
float percent = 0f;
|
||||
if (spawned.Length > 1)
|
||||
{
|
||||
if(spline.isClosed) percent = (float)i / spawned.Length;
|
||||
else percent = (float)i / (spawned.Length - 1);
|
||||
}
|
||||
percent += _evaluateOffset;
|
||||
if (percent > 1f) percent -= 1f;
|
||||
else if (percent < 0f) percent += 1f;
|
||||
if (objectPositioning == Positioning.Clip) spline.Evaluate(percent, evalResult);
|
||||
else Evaluate(percent, evalResult);
|
||||
ModifySample(evalResult);
|
||||
spawned[i].position = evalResult.position;
|
||||
|
||||
if (_applyScale)
|
||||
{
|
||||
Vector3 scale = spawned[i].baseScale * evalResult.size;
|
||||
if(randomScaleMultiplier)
|
||||
{
|
||||
scale.x *= Mathf.Lerp(_minScaleMultiplier.x, _maxScaleMultiplier.x, (float)scaleRandomizer.NextDouble());
|
||||
scale.y *= Mathf.Lerp(_minScaleMultiplier.y, _maxScaleMultiplier.y, (float)scaleRandomizer.NextDouble());
|
||||
scale.z *= Mathf.Lerp(_minScaleMultiplier.z, _maxScaleMultiplier.z, (float)scaleRandomizer.NextDouble());
|
||||
} else
|
||||
{
|
||||
scale.x *= scaleMultiplier.x;
|
||||
scale.y *= scaleMultiplier.y;
|
||||
scale.z *= scaleMultiplier.z;
|
||||
}
|
||||
spawned[i].scale = scale;
|
||||
}
|
||||
else spawned[i].scale = spawned[i].baseScale;
|
||||
Vector3 right = Vector3.Cross(evalResult.forward, evalResult.up).normalized;
|
||||
|
||||
Vector3 posOffset = _minOffset;
|
||||
if (_minOffset != _maxOffset)
|
||||
{
|
||||
if(_shellOffset)
|
||||
{
|
||||
float x = _maxOffset.x - _minOffset.x;
|
||||
float y = _maxOffset.y - _minOffset.y;
|
||||
float angleInRadians = (float)shellRandomizer.NextDouble() * 360f * Mathf.Deg2Rad;
|
||||
posOffset = new Vector2(0.5f * Mathf.Cos(angleInRadians), 0.5f * Mathf.Sin(angleInRadians));
|
||||
posOffset.x *= x;
|
||||
posOffset.y *= y;
|
||||
} else
|
||||
{
|
||||
float rnd = (float)offsetRandomizer.NextDouble();
|
||||
posOffset.x = Mathf.Lerp(_minOffset.x, _maxOffset.x, rnd);
|
||||
rnd = (float)offsetRandomizer.NextDouble();
|
||||
posOffset.y = Mathf.Lerp(_minOffset.y, _maxOffset.y, rnd);
|
||||
rnd = (float)offsetRandomizer.NextDouble();
|
||||
posOffset.z = Mathf.Lerp(_minOffset.z, _maxOffset.z, rnd);
|
||||
}
|
||||
}
|
||||
|
||||
if (_offsetUseWorldCoords) spawned[i].position += posOffset;
|
||||
else spawned[i].position += right * posOffset.x * evalResult.size + evalResult.up * posOffset.y * evalResult.size;
|
||||
|
||||
if (_applyRotation)
|
||||
{
|
||||
Quaternion offsetRot = Quaternion.Euler(Mathf.Lerp(_minRotation.x, _maxRotation.x, (float)rotationRandomizer.NextDouble()), Mathf.Lerp(_minRotation.y, _maxRotation.y, (float)rotationRandomizer.NextDouble()), Mathf.Lerp(_minRotation.z, _maxRotation.z, (float)rotationRandomizer.NextDouble()));
|
||||
if(_rotateByOffset) spawned[i].rotation = Quaternion.LookRotation(evalResult.forward, spawned[i].position - evalResult.position) * offsetRot;
|
||||
else spawned[i].rotation = evalResult.rotation* offsetRot;
|
||||
}
|
||||
|
||||
if (_objectPositioning == Positioning.Clip)
|
||||
{
|
||||
if (percent < clipFrom || percent > clipTo) spawned[i].active = false;
|
||||
else spawned[i].active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PostBuild()
|
||||
{
|
||||
base.PostBuild();
|
||||
for (int i = 0; i < spawned.Length; i++)
|
||||
{
|
||||
spawned[i].Apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Dreamteck/Splines/Components/ObjectController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: acb0592a986cebb4287d41702ab6ea22
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 809d29b9ca1b74947aca02225d2ec233, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||