/// <summary> /// main method it will be called when the cursor in the scene view /// most of the functionality is in here /// </summary> void OnSceneGUI() { if (spline) { Undo.RecordObject(spline, "Spline edit"); } #region Init //getting spline asset from the SplineWindow object splineWindow = (SplineWindow)target; spline = splineWindow.spline; if (!splineWindow) { return; } if (!spline && splineWindow) { DestroyImmediate(spline); splineWindow.spline = Spline.CreateSpline(splineWindow.splineRefernce); splineWindow.SetWorldPositions(); if (SplineTools.Instance) { SplineTools.Instance.Repaint(); } if (!spline) { return; } } CheckSelection(); //make sure to follow parent when nothing is selected if (selectedPoint == -1) { splineWindow.SetWorldPositions(); //make sure that the main handle shows up when nothing is selected DefaultHandles.Hidden = false; } else { DefaultHandles.Hidden = hideDefaultHandles; } SetCurrPositions(); #endregion #region drawing points if (selectedPoints.Count > 1) { CalculateCenterPos(); } bool setWorldPos = true; bool setLocalPos = false; for (int i = 0; i < spline.Length; i++) { Handles.color = splineWindow.pointColor; if (!hideArrows) { DrawArrow(i); } #region unselected points //draw points ( main ) Vector3 pos = spline.GetPosition(i); if (currPos[i] != pos) { Undo.RecordObject(spline, "Move point"); } List <Vector3> handles = new List <Vector3>(spline[i].handles); Handles.color = splineWindow.pointColor; float size = HandleUtility.GetHandleSize(pos); if (!InSelection(i)) { // point ( main ) pressed if (Handles.Button(pos, Quaternion.identity, size / 5, size / 5, Handles.SphereCap)) { SelectPoint(i); } //draw points ( handles ) if (!hideHandles) { Handles.color = splineWindow.handlesColor; foreach (Vector3 h in handles) { size = HandleUtility.GetHandleSize(h); size *= 0.5f; // point ( handles ) pressed if (Handles.Button(h, Quaternion.identity, size / 5, size / 5, Handles.CubeCap)) { SelectPoint(i); } //drawing the blue lines between main point and handle point Handles.DrawLine(pos, h); } } } #endregion #region selected points // moving selected point if (InSelection(i)) { // hold the position to know later if it got changed Vector3 temp = pos; Vector3 hTemp = Vector3.zero; // drawing points when multiple are selected if (selectedPoints.Count > 1) { Handles.color = splineWindow.selectedColor; if (Handles.Button(pos, Quaternion.identity, size / 4, size / 4, Handles.SphereCap)) { // removes the point from selection or remove other points if (Event.current.shift) { selectedPoints.Remove(i); } else { SelectPoint(i); } } pos += centerDelta; } else { switch (Tools.current) { case Tool.Rotate: rotation = Handles.DoRotationHandle(rotation, pos); Handles.SphereCap(0, pos, Quaternion.identity, size / 5); if (rotation != Quaternion.identity) { for (int h = 0; h < handles.Count; h++) { if (handleStartPositions.Count > h) { handles[h] = rotation * (handleStartPositions[h] - pos); handles[h] += pos; } } } else { handleStartPositions = new List <Vector3>(handles); } scale = 1; break; case Tool.Scale: Vector3 s = new Vector3(scale, 1, 1); s = Handles.DoScaleHandle(s, pos, Quaternion.identity, size); scale = s.x; if (scale != 1) { for (int h = 0; h < handles.Count; h++) { if (handleStartPositions.Count > h) { handles[h] = handleStartPositions[h] + (handleStartPositions[h] - pos).normalized * (scale - 1); } } } else { handleStartPositions = new List <Vector3>(handles); } rotation = Quaternion.identity; break; default: if (isDragMode) { Handles.color = splineWindow.selectedColor; pos = Handles.FreeMoveHandle(pos, Quaternion.identity, size / 4, Vector3.zero, Handles.SphereCap); } else { pos = Handles.PositionHandle(pos, Quaternion.identity); Handles.color = splineWindow.selectedColor; Handles.SphereCap(0, pos, Quaternion.identity, size / 4); } scale = 1; rotation = Quaternion.identity; break; } } //checking if our pos changed to reset the values if (temp != pos) { setLocalPos = true; setWorldPos = false; } if (Tools.current != Tool.Rotate && Tools.current != Tool.Scale) { MoveHandlesWithPoint(i, pos, handles); if (!hideHandles) { for (int a = 0; a < handles.Count; a++) { hTemp = handles[a]; if (isDragMode) { Handles.color = splineWindow.handlesColor; Vector3 tempHandles = Handles.FreeMoveHandle(handles[a], Quaternion.identity, size / 7, Vector3.zero, Handles.CubeCap); handles[a] = tempHandles; } else { Handles.color = splineWindow.handlesColor; handles[a] = Handles.PositionHandle(handles[a], Quaternion.identity); Handles.CubeCap(0, handles[a], Quaternion.identity, size / 7); } if (hTemp != handles[a]) { setLocalPos = true; setWorldPos = false; } Handles.DrawLine(pos, handles[a]); } } } else if (!hideHandles) { foreach (Vector3 handle in handles) { Handles.CubeCap(0, handle, Quaternion.identity, size / 7); Handles.DrawLine(pos, handle); if (hTemp != handle) { setLocalPos = true; setWorldPos = false; } } } } currPos[i] = pos; #endregion //reassign values spline[i].handles = handles.ToArray(); spline[i].position = pos; if (showIndex) { GUIStyle style = new GUIStyle(); style.normal.textColor = Color.grey; style.fontSize = 20; Handles.Label(spline[i].position, i.ToString(), style); } } if (setLocalPos) { splineWindow.SetLocalPositions(); } if (setWorldPos) { splineWindow.SetWorldPositions(); } #endregion #region insert point // insert by clicking on some collider if (Event.current.control == SplinePrefs.addPointMouse.ctrl && Event.current.alt == SplinePrefs.addPointMouse.alt && Event.current.shift == SplinePrefs.addPointMouse.shift) { //making clicking with left click on objects disabled HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); if (spline.Length == 0 || selectedPoint >= 0) { if (Event.current.clickCount == 1) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { Insert(hit.point); splineWindow.SetLocalPositions(); } } } } if (spline.IsValid(selectedPoint)) { //insert by a shortcut if (Event.current.keyCode == SplinePrefs.addPointKeyboard.keyCode && Event.current.shift && Event.current.type == EventType.KeyDown) { Insert(spline[selectedPoint].position + Vector3.forward); splineWindow.SetLocalPositions(); } } #endregion #region keyboard actions // sticking to ground if (HotkeyPressed(SplinePrefs.stickToGround) && selectedPoint != -1) { Undo.RecordObject(splineWindow, "stick to ground"); foreach (int i in selectedPoints) { StickToGround(i); } } // drawing line if (HotkeyPressed(SplinePrefs.drawLine) && selectedPoints.Count == 2) { spline.DrawLine(selectedPoints[0], selectedPoints[1]); } // remove point if (HotkeyPressed(SplinePrefs.removePoint)) { foreach (int i in selectedPoints) { spline.RemovePoint(i); } splineWindow.SetLocalPositions(); selectedPoints = new List <int>(); } if (HotkeyPressed(SplinePrefs.sharpen)) { Undo.RecordObject(spline, "Sharpen"); foreach (int i in selectedPoints) { spline.Sharpen(i); splineWindow.SetLocalPositions(); SceneView.RepaintAll(); } } #endregion #region others SplineMesh sm = splineWindow.GetComponent <SplineMesh>(); if (sm != null) { sm.UpdatePosition(); } if (Event.current.commandName == "UndoRedoPerformed") { Repaint(); } #endregion }
/// <summary> /// make a point stick to ground bu any given index /// </summary> public void StickToGround(int i) { Waypoint wp = splineWindow.spline[i]; disableHandleMoving = true; int index = -1; int tIndex = -1; Ray ray = new Ray(wp.position + Vector3.up * 5, Vector3.down); RaycastHit[] hits = Physics.RaycastAll(ray); for (int x = 0; x < hits.Length; x++) { if (!hits[x].collider.isTrigger) { index = x; break; } else { tIndex = x; } } if (index == -1 && tIndex != -1) { index = tIndex; } if (index != -1) { wp.position = hits[index].point; splineWindow.SetLocalPositions(); EditorUtility.SetDirty(splineWindow.spline); } for (int h = 0; h < wp.handles.Length; h++) { ray = new Ray(wp.handles[h] + Vector3.up * 5, Vector3.down); hits = Physics.RaycastAll(ray); index = -1; tIndex = -1; for (int x = 0; x < hits.Length; x++) { if (!hits[x].collider.isTrigger) { index = x; break; } else { tIndex = x; } } if (index == -1 && tIndex != -1) { index = tIndex; } if (index != -1) { wp.handles[h] = hits[index].point; splineWindow.SetLocalPositions(); EditorUtility.SetDirty(splineWindow.spline); } } }
void OnGUI() { #region checkers if (Selection.activeGameObject == null) { NotSelectedOptions(); return; } SplineWindow splineWindow = Selection.activeGameObject.GetComponent <SplineWindow>(); if (splineWindow == null) { NotSelectedOptions(); return; } Spline spline = splineWindow.spline; SplineEditor splineEditor = SplineEditor.current; if (spline == null || splineEditor == null) { NotSelectedOptions(); return; } #endregion scrollView = GUILayout.BeginScrollView(scrollView); #region buttons if (GUILayout.Button("Show/Hide", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { if (showHidePopup != null) { showHidePopup.Close(); showHidePopup = null; } else { showHidePopup = ShowHidePopUp.CreateInstance <ShowHidePopUp>(); showHidePopup.ShowPopup(); showHidePopup.position = new Rect(Event.current.mousePosition.x + position.x, Event.current.mousePosition.y + position.y, 100, (HEIGHT / 2) * 3); } } if (GUILayout.Button("Deselect\nAll", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { splineEditor.selectedPoints = new List <int>(); splineEditor.Repaint(); SceneView.RepaintAll(); } if (GUILayout.Button("Center\nPivot", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { splineEditor.CenterOnChildern(); SceneView.RepaintAll(); } if (GUILayout.Button(splineEditor.isDragMode ? "use\nhandles" : "use\ndrag", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { splineEditor.isDragMode = !splineEditor.isDragMode; EditorPrefs.SetBool(SplineEditor.IS_DRAG_MODE_KEY, splineEditor.isDragMode); SceneView.RepaintAll(); } GUILayout.BeginHorizontal(); if (GUILayout.Button(new GUIContent(delete, "Delets all points in spline"), GUILayout.Width(WIDTH / 2), GUILayout.Height(HEIGHT / 2))) { spline.waypoints = new Waypoint[] { }; splineEditor.Repaint(); SceneView.RepaintAll(); } GUILayout.Space(-5); if (GUILayout.Button(new GUIContent(reload, "Reloads the spline"), GUILayout.Width(WIDTH / 2), GUILayout.Height(HEIGHT / 2))) { Undo.RecordObject(splineWindow.spline, "Undo reload"); splineEditor.selectedPoints = new List <int>(); splineWindow.spline = Spline.CreateSpline(splineWindow.splineRefernce); splineEditor.Repaint(); SceneView.RepaintAll(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (!splineWindow.splineRefernce.Equals(spline)) { GUI.color = Color.red; } if (GUILayout.Button(new GUIContent(save, "Saves the spline"), GUILayout.Width(WIDTH / 2), GUILayout.Height(HEIGHT / 2))) { splineEditor.Save(); } GUI.color = Color.white; GUILayout.Space(-5); if (GUILayout.Button(new GUIContent(saveAs, "Save the spline in new path"), GUILayout.Width(WIDTH / 2), GUILayout.Height(HEIGHT / 2))) { //ScriptableObjectUtility.CreateAsset<Spline>(); Spline temp = Spline.CreateSpline(); string assetName = AssetDatabase.GenerateUniqueAssetPath("Assets/" + splineWindow.splineRefernce.name + "_Copy.asset"); AssetDatabase.CreateAsset(temp, assetName); Selection.activeObject = temp; AssetDatabase.SaveAssets(); //temp.name = sw.splineRefernce.name + "_Copy"; splineWindow.splineRefernce = temp; splineEditor.Save(); } GUILayout.EndHorizontal(); if (GUILayout.Button("stick to \n ground", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { Undo.RecordObject(spline, "stick to ground"); for (int i = 0; i < spline.Length; i++) { splineEditor.StickToGround(i); } SceneView.RepaintAll(); } //clean button if (GUILayout.Button("Clean", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { Undo.RecordObject(spline, "Clean"); spline.CleanSpline(); splineEditor.Repaint(); SceneView.RepaintAll(); } if (splineEditor.selectedPoints.Count < 1) { GUI.enabled = false; } if (GUILayout.Button("Sharpen", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { Undo.RecordObject(spline, "Sharpen"); foreach (int i in splineEditor.selectedPoints) { spline.Sharpen(i); splineWindow.SetLocalPositions(); SceneView.RepaintAll(); } } GUI.enabled = true; #endregion #region buttons when 2 points are selected if (splineEditor.selectedPoints.Count != 2) { GUI.enabled = false; } if (GUILayout.Button(drawLine, GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT))) { spline.DrawLine(splineEditor.selectedPoints[0], splineEditor.selectedPoints[1]); splineWindow.SetLocalPositions(); splineEditor.Repaint(); SceneView.RepaintAll(); } // addpoint between button if (GUILayout.Button("subdivide", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { spline.Subdivide(splineEditor.selectedPoints[0], splineEditor.selectedPoints[1]); splineWindow.SetLocalPositions(); splineEditor.Repaint(); SceneView.RepaintAll(); } if (GUILayout.Button("Merge", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { spline.Merge(splineEditor.selectedPoints[0], splineEditor.selectedPoints[1]); splineWindow.SetLocalPositions(); splineEditor.Repaint(); SceneView.RepaintAll(); } if (GUILayout.Button("Remove\nline", GUILayout.Width(WIDTH), GUILayout.Height(HEIGHT / 2))) { spline.RemoveLine(splineEditor.selectedPoints[0], splineEditor.selectedPoints[1]); splineWindow.SetLocalPositions(); splineEditor.Repaint(); SceneView.RepaintAll(); } #endregion GUILayout.EndScrollView(); }