//private float optionsControlSize = 1.0f; public override void OnInspectorGUI() { LeanTweenPath path = target as LeanTweenPath; pos = path.transform.position; GUI.DrawTexture(new Rect(16, EditorGUILayout.GetControlRect().y - 16, 16, 16), LTEditor.EditorIcon()); EditorGUIUtility.labelWidth = 90f; EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel); EditorGUILayout.BeginHorizontal(); LeanTweenPath.LeanTweenPathType pathTypeLast = path.pathType; GUI.color = LTEditor.Shared.colorRefresh; path.pathType = (LeanTweenPath.LeanTweenPathType)EditorGUILayout.EnumPopup("Path Type", path.pathType); if (path.pathType != pathTypeLast) { Undo.RecordObject(path, "changing path type"); resetPath(); } bool isBezier = path.pathType == LeanTweenPath.LeanTweenPathType.bezier; EditorGUILayout.Space(); float controlSizeBefore = path.controlSize; GUI.color = Color.white; LTVisualShared.change(ref path.controlSize, EditorGUILayout.FloatField("Controls Size", path.controlSize, GUILayout.Width(120)), path, "changing control size"); if (path.controlSize != controlSizeBefore) { SceneView.RepaintAll(); } EditorGUILayout.EndHorizontal(); LTVisualShared.change(ref path.showArrows, EditorGUILayout.Toggle("Show Arrows", path.showArrows), path, "changing show arrows"); EditorGUILayout.Space(); GUI.color = LTEditor.Shared.colorRefresh; EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Reverse Direction", LTEditor.Shared.styleActionButton)) { Undo.RecordObject(path, "reversing direction"); Vector3[] newPath = new Vector3[path.pts.Length]; for (int i = 0; i < newPath.Length; i++) { // Debug.Log("pt at:"+(newPath.Length-i-1)+ " len:"+newPath.Length); Transform trans = path.pts[newPath.Length - i - 1]; if (trans == null) { trans = path.pts[newPath.Length - i - 2]; } newPath[i] = trans.position; } for (int i = 0; i < path.pts.Length; i++) { if (path.pts[i]) { path.pts[i].position = newPath[i]; } } } if (isBezier && GUILayout.Button("Easy Path Creator", LTEditor.Shared.styleActionButton)) { Undo.RecordObject(path, "expanding"); path.creatorMaximized = !path.creatorMaximized; } EditorGUILayout.Space(); EditorGUILayout.EndHorizontal(); EditorGUILayout.Separator(); EditorGUILayout.Separator(); int k; if (isBezier) { GUI.color = Color.white; EditorGUILayout.BeginHorizontal(); LTVisualShared.change(ref path.creatorMaximized, EditorGUILayout.Foldout(path.creatorMaximized, "Easy Path Creator", LTEditor.Shared.styleAreaFoldout), path, "creator maximized"); EditorGUILayout.EndHorizontal(); if (path.creatorMaximized) { selectedCreate = (PathCreateType)EditorGUILayout.EnumPopup("Type to create:", selectedCreate); LTVisualShared.change(ref optionsSize, EditorGUILayout.FloatField("Scale:", optionsSize), path, "change scale"); switch (selectedCreate) { case PathCreateType.RectangleRounded: optionsBevelSize = EditorGUILayout.Slider("Bevel Size:", optionsBevelSize, 0.0f, 1.399f); break; case PathCreateType.Snake: optionsLength = EditorGUILayout.FloatField("Length:", optionsLength); break; case PathCreateType.Random: optionsLength = EditorGUILayout.FloatField("Length:", optionsLength); EditorGUILayout.LabelField("Min Range:", optionsRangeMin.ToString()); EditorGUILayout.LabelField("Max Range:", optionsRangeMax.ToString()); EditorGUILayout.MinMaxSlider(ref optionsRangeMin, ref optionsRangeMax, 0.0f, 10.0f); break; case PathCreateType.Circle: optionsSegments = closestSegment(EditorGUILayout.IntSlider("Segments:", optionsSegments, 4, MAX_SPLINES)); break; case PathCreateType.Straight: optionsLength = EditorGUILayout.FloatField("Length:", optionsLength); optionsDirection = EditorGUILayout.Vector3Field("Direction:", optionsDirection); break; default: break; } GUI.color = LTEditor.Shared.colorRefresh; EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Create New Path", LTEditor.Shared.styleActionButton)) { Undo.RecordObject(path, "creating new path"); // path.arraySize = count.intValue*4; switch (selectedCreate) { case PathCreateType.RectangleRounded: resetPath(); float b = optionsBevelSize; float n = 0.1f; addTo(new Vector3[] { new Vector3(b, 0f, 0f), new Vector3(0f, 0f, 0f), new Vector3(0f, 0f, 0f), new Vector3(0f, b, 0f) , new Vector3(0f, b, 0f), new Vector3(0f, b + n, 0f), new Vector3(0f, 3f - b - n, 0f), new Vector3(0f, 3f - b, 0f) , new Vector3(0f, 3f - b, 0f), new Vector3(0f, 3f, 0f), new Vector3(0f, 3f, 0f), new Vector3(b, 3f, 0f) , new Vector3(b, 3f, 0f), new Vector3(3f - b - n, 3f, 0f), new Vector3(b + n, 3f, 0f), new Vector3(3f - b, 3f, 0f) , new Vector3(3f - b, 3f, 0f), new Vector3(3f, 3f, 0f), new Vector3(3f, 3f, 0f), new Vector3(3f, 3f - b, 0f) , new Vector3(3f, 3f - b, 0f), new Vector3(3f, b + n, 0f), new Vector3(3f, b + n, 0f), new Vector3(3f, b, 0f) , new Vector3(3f, b, 0f), new Vector3(3f, 0f, 0f), new Vector3(3f, 0f, 0f), new Vector3(3f - b, 0f, 0f) , new Vector3(3f - b, 0f, 0f), new Vector3(3f - b - n, 0f, 0f), new Vector3(b + n, 0f, 0f), new Vector3(b, 0f, 0f) }); break; case PathCreateType.Snake: resetPath(); path.path = new Vector3[(int)optionsLength * 4]; k = 0; for (int i = 0; i < path.path.Length; i++) { Vector3 vec3 = pos + new Vector3(k * optionsSize, 0f, k * optionsSize); if (i % 4 == 1) { vec3.x += 1 * optionsSize; } if (i % 4 == 2) { vec3.x += -1 * optionsSize; } path.path[i] = vec3; if (i % 2 == 0) { k++; } } break; case PathCreateType.Random: resetPath(); path.path = new Vector3[(int)optionsLength * 4]; k = 0; float rand = 0f; for (int i = 0; i < path.path.Length; i++) { Vector3 vec3 = pos + new Vector3(k * optionsSize, 0f, 0f); if (i % 4 == 1) { vec3.z += rand * optionsSize; } rand = Random.Range(optionsRangeMin, optionsRangeMax) * optionsSize; if (i % 4 == 2) { vec3.z += -rand * optionsSize; } path.path[i] = vec3; if (i % 2 == 0) { k++; } } break; case PathCreateType.Circle: resetPath(); //count.intValue = optionsSegments; Vector3[] v = generateCircularQuadraticBezierSegments(optionsSize, optionsSegments); //Debug.Log("v:"+v); addTo(v); break; case PathCreateType.Straight: resetPath(); path.path = new Vector3[(int)optionsLength * 4]; k = 0; for (int i = 0; i < path.path.Length; i++) { path.path[i] = pos + k * optionsDirection * optionsSize; if (i % 2 == 0) { k++; } } break; default: Debug.LogError("Unrecognized Option"); break; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); } // end if creatorMaximized } // end if isBezier EditorGUILayout.BeginHorizontal(); GUI.color = LTEditor.Shared.colorRefresh; LTVisualShared.change(ref path.nodesMaximized, EditorGUILayout.Foldout(path.nodesMaximized, "Nodes (" + path.count + ")", LTEditor.Shared.styleAreaFoldout), path, "nodes maximized"); //if(GUILayout.Button("Nodes", LTEditor.shared.styleGroupButton)) // path.nodesMaximized = !path.nodesMaximized; if (path.nodesMaximized) { if (isBezier) { bool refresh = GUILayout.Button("Refresh", GUILayout.Width(65), GUILayout.Height(22)); if (refresh) { Undo.RecordObject(path, "path refreshed"); Vector3[] from = path.vec3; path.path = new Vector3[from.Length]; for (int i = 0; i < from.Length; i++) { path.path[i] = from[i] - pos; } resetPath(); } } GUI.color = LTEditor.Shared.colorDestruct; bool deleted = GUILayout.Button("Delete All", GUILayout.Width(80), GUILayout.Height(22)); if (deleted) { Undo.RecordObject(path, "deleting all"); resetPath(); } } EditorGUILayout.EndHorizontal(); GUI.color = Color.white; if (path.nodesMaximized) { EditorGUILayout.Space(); bool needsPathScroll = path.pts.Length > 8; if (needsPathScroll) { scrollPathsViewPos = EditorGUILayout.BeginScrollView(scrollPathsViewPos, GUILayout.Height(150)); } k = 0; int j = 0; for (int i = 0; i < path.pts.Length; i++) { Transform t = path.pts[i]; GUI.color = LTEditor.Shared.colorNodes; if (t == null) { //EditorGUILayout.LabelField("Nothing here "+i); } else { EditorGUILayout.BeginHorizontal(); string label; bool isControl = true; if (isBezier) { isControl = i == 0 || i % 4 == 3; if (isControl) { label = " Node" + (j + 1); j++; k = 0; } else { label = " - Control" + k; k++; } } else { label = " Node" + i; } Vector3 position = EditorGUILayout.Vector3Field(label, t.localPosition); if (GUI.changed) { Undo.RecordObject(t, "Transform Change " + t.gameObject.name); t.localPosition = FixIfNaN(position); } if (isControl) { GUI.color = LTEditor.Shared.colorAdd; if (GUILayout.Button("+", LTEditor.Shared.styleOneCharButton)) { //Debug.Log("path.pts:"+path.pts); Undo.RecordObject(path, "adding new node"); path.addNodeAfter(i); SceneView.RepaintAll(); scrollPathsSetToEnd = 2; } if (i == 0) { GUI.color = Color.white * 0f; GUILayout.Button("X", LTEditor.Shared.styleOneCharButton); } GUI.color = LTEditor.Shared.colorDestruct; if (i != 0 && GUILayout.Button("X", LTEditor.Shared.styleOneCharButton)) { Undo.RecordObject(t, "Deleted Node " + t.gameObject.name); path.deleteNode(i); // Debug.Log("after:"+path.count); SceneView.RepaintAll(); } } else { GUI.color = Color.white * 0f; GUILayout.Button("X", LTEditor.Shared.styleOneCharButton); GUILayout.Button("X", LTEditor.Shared.styleOneCharButton); } EditorGUILayout.EndHorizontal(); } } if (needsPathScroll) { EditorGUILayout.EndScrollView(); } if (scrollPathsSetToEnd > 0) { scrollPathsSetToEnd--; scrollPathsViewPos = new Vector2(0, 10000f); } GUI.color = LTEditor.Shared.colorAdd; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("+ Node", LTEditor.Shared.styleActionButton)) { Undo.RecordObject(path, "adding new node"); path.addNode(); SceneView.RepaintAll(); scrollPathsSetToEnd = 2; } GUILayout.EndHorizontal(); } GUI.color = Color.white; path.importMaximized = EditorGUILayout.Foldout(path.importMaximized, "Import/Export", LTEditor.Shared.styleAreaFoldout); if (path.importMaximized) { EditorGUILayout.BeginHorizontal(GUILayout.Width(160)); EditorGUILayout.LabelField("Code Type", GUILayout.Width(80)); generateCode = EditorGUILayout.Popup(generateCode, new string[] { "C#", "Unityscript" }, GUILayout.Width(80)); EditorGUILayout.EndHorizontal(); if (generateCode != generateCodeLast) { string codeFormat = generateCode == 0 ? "new Vector3[]{ new Vector3(0f,0f,0f), ... }" : "[ Vector3(0.0,0.0,0.0), ... ]"; importArrValue = "Paste in format: " + codeFormat; generateCodeLast = generateCode; } EditorGUILayout.LabelField("Exported:", EditorStyles.boldLabel); if (Application.isPlaying == false) { string outputStr; if (generateCode == 0) { outputStr = "new Vector3[]{ "; for (int i = 0; i < path.pts.Length; i++) { Transform trans = path.pts[i]; if (isBezier) { trans = i > 3 && i % 4 == 0 ? path.pts[i - 1] : path.pts[i]; } if (trans != null) { outputStr += "new Vector3(" + trans.position.x + "f," + trans.position.y + "f," + trans.position.z + "f)"; if (i < path.pts.Length - 1) { outputStr += ", "; } } } outputStr += " }"; } else { outputStr = "["; for (int i = 0; i < path.pts.Length; i++) { Transform trans = path.pts[i]; if (isBezier) { trans = i > 3 && i % 4 == 0 ? path.pts[i - 1] : path.pts[i]; } if (trans != null) { outputStr += "Vector3(" + trans.position.x + "," + trans.position.y + "," + trans.position.z + ")"; if (i < path.pts.Length - 1) { outputStr += ", "; } } } outputStr += "]"; } scrollCodeViewPos = EditorGUILayout.BeginScrollView(scrollCodeViewPos, GUILayout.Height((int)Mathf.Min(70f, path.pts.Length * 7f))); EditorGUILayout.TextArea(outputStr, LTEditor.Shared.styleCodeTextArea); EditorGUILayout.EndScrollView(); } else { EditorGUILayout.LabelField(" Not available during runtime"); } EditorGUILayout.LabelField("Import:", EditorStyles.boldLabel); importArrValue = EditorGUILayout.TextArea(importArrValue, LTEditor.Shared.styleCodeTextArea); GUI.color = LTEditor.Shared.colorRefresh; GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Import Path", LTEditor.Shared.styleActionButton)) { Undo.RecordObject(path, "imported new path"); // Debug.Log("index:"+importArrValue.IndexOf("Paste")+" val:"+importArrValue); if (importArrValue.IndexOf("Paste") < 0) { // Debug.Log("Importing"); string subImport = ""; int start = importArrValue.IndexOf("{"); int end = importArrValue.IndexOf("}"); bool cSharpFormat = start >= 0; if (cSharpFormat) { if (start < 0) { Debug.LogError("No starting bracket'{'"); } else if (end < 0) { Debug.LogError("No ending bracket'}'"); } else { subImport = importArrValue.Substring(start + 1, end - 1 - start).Trim(); // Debug.Log("broken down importedArr:"+subImport); } } else { start = importArrValue.IndexOf("["); end = importArrValue.IndexOf("]"); if (start < 0) { Debug.LogError("No starting bracket'['"); } else if (end < 0) { Debug.LogError("No ending bracket']'"); } else { subImport = importArrValue.Substring(start + 1, end - 1 - start).Trim(); // Debug.Log("broken down importedArr:"+subImport); } } string[] stringArr = subImport.Split(new string[] { "Vector3" }, System.StringSplitOptions.RemoveEmptyEntries); int len = cSharpFormat ? (stringArr.Length - 1) : stringArr.Length; // Debug.Log("importing length:"+len); resetPath(); path.path = new Vector3[len]; k = 0; for (int i = 0; i < stringArr.Length; i++) { start = stringArr[i].IndexOf("("[0]); end = stringArr[i].IndexOf(")"[0]); // Debug.Log("i:"+i+" start:"+start+" end:"+end); if (start >= 0 && end > 0) { string vecStr = stringArr[i].Substring(start + 1, end - 1 - start); // Debug.Log("vec:"+vecStr); string[] numArr = vecStr.Split(","[0]); for (int j = 0; j < numArr.Length; j++) { if (numArr[j].IndexOf("("[0]) >= 0) { start = numArr[j].IndexOf("("[0]); numArr[j] = numArr[j].Substring(start + 1); } else if (numArr[j].IndexOf(")"[0]) >= 0) { end = numArr[j].IndexOf(")"[0]); numArr[j] = numArr[j].Substring(0, end); } if (numArr[j].IndexOf("f"[0]) >= 0) { end = numArr[j].IndexOf("f"[0]); numArr[j] = numArr[j].Substring(0, end); } // Debug.Log("num:"+numArr[j]); } Vector3 vec3 = new Vector3(float.Parse(numArr[0]), float.Parse(numArr[1]), float.Parse(numArr[2])); Debug.Log("importing k:" + k + " vec3:" + vec3); path.path[k] = vec3; k++; } } } } GUILayout.EndHorizontal(); } }