public void OnSceneGUI() { Event e = Event.current; if (e.type == EventType.Layout) { HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); } #region Set SceneView Settings SceneView currentView = SceneView.currentDrawingSceneView; if (view != currentView || !locked) { is2D = currentView.in2DMode; currentView.in2DMode = true; view = currentView; locked = true; } #endregion Points points = (Points)target; #region Determine Global Settings if (points.useGlobal) { if (!points.settings) { points.settings = (PointsSettings)Resources.Load("PointsSettings", typeof(PointsSettings)); } if (!points.settings) { Handles.BeginGUI(); GUI.Box(new Rect(5, 5, width + 10, height + 10), ""); GUILayout.BeginArea(new Rect(10, 10, width, height)); GUILayout.Label("Points Settings", EditorStyles.boldLabel); if (GUILayout.Button("Create Global Settings")) { string path = EditorUtility.SaveFolderPanel("Choose a folder", "", ""); string relative = path.Replace(Application.dataPath, "Assets"); if (AssetDatabase.IsValidFolder(relative)) { points.settings = CreateInstance <PointsSettings>(); AssetDatabase.CreateAsset(points.settings, relative + "/PointsSettings.asset"); } } if (GUILayout.Button("Locate Global Settings")) { string path = EditorUtility.OpenFilePanel("Find Points Settings", "", "asset"); string relative = path.Replace(Application.dataPath, "Assets"); points.settings = (PointsSettings)AssetDatabase.LoadAssetAtPath(relative, typeof(PointsSettings)); if (!points.settings) { Debug.LogError("Invalid File"); } } GUILayout.EndArea(); Handles.EndGUI(); return; } } #endregion Ray mouseRay = HandleUtility.GUIPointToWorldRay(e.mousePosition); float drawPlaneHeight = 0; float dstToDrawPlane = (drawPlaneHeight - mouseRay.origin.z) / mouseRay.direction.z; Vector3 mousePosition = mouseRay.GetPoint(dstToDrawPlane); if (e.type == EventType.Repaint && edit) { Draw(mousePosition); } else { Input(e, mousePosition); HandleUtility.Repaint(); } #region Control Window autoBuild = points.useGlobal ? points.settings.autoBuild : points.autoBuild; edit = points.useGlobal ? points.settings.edit : points.edit; Handles.BeginGUI(); GUI.Box(new Rect(5, 5, width + 10, height + 10), CreateTexture((int)width + 10, (int)height + 10, new Color(1, 1, 1, .75f))); GUI.contentColor = Color.black; GUI.backgroundColor = Color.white; GUILayout.BeginArea(new Rect(10, 10, width, height)); GUILayout.BeginHorizontal(); GUILayout.Label("Points Settings", EditorStyles.boldLabel); string str = points.useGlobal ? "Global" : "Local"; GUI.contentColor = Color.white; if (GUILayout.Button(str)) { points.useGlobal = !points.useGlobal; return; } GUILayout.EndHorizontal(); GUI.contentColor = Color.black; GUILayout.BeginHorizontal(); GUILayout.Label("Edit", GUILayout.Width(80)); if (!points.useGlobal) { points.edit = EditorGUILayout.Toggle(points.edit); } else { points.settings.edit = EditorGUILayout.Toggle(points.settings.edit); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Auto Build", GUILayout.Width(80)); if (!points.useGlobal) { points.autoBuild = EditorGUILayout.Toggle(points.autoBuild, GUILayout.Width(30)); } else { points.settings.autoBuild = EditorGUILayout.Toggle(points.settings.autoBuild, GUILayout.Width(30)); } if (!autoBuild) { GUI.contentColor = Color.white; if (GUILayout.Button("Build")) { points.BuildCollider(); } GUI.contentColor = Color.black; } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Handle Size", GUILayout.Width(80)); if (!points.useGlobal) { points.handleSize = GUILayout.HorizontalSlider(points.handleSize, 0, 1, GUILayout.Width(width - 85)); } else { points.settings.handleSize = GUILayout.HorizontalSlider(points.settings.handleSize, points.settings.handleRange.x, points.settings.handleRange.y, GUILayout.Width(width - 85)); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Handle Color", GUILayout.Width(80)); if (!points.useGlobal) { points.handleColor = EditorGUILayout.ColorField(points.handleColor); } else { points.settings.handleColor = EditorGUILayout.ColorField(points.settings.handleColor); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Line Color", GUILayout.Width(80)); if (!points.useGlobal) { points.lineColor = EditorGUILayout.ColorField(points.lineColor); } else { points.settings.lineColor = EditorGUILayout.ColorField(points.settings.lineColor); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Default Color", GUILayout.Width(80)); if (!points.useGlobal) { points.unselectedColor = EditorGUILayout.ColorField(points.unselectedColor); } else { points.settings.unselectedColor = EditorGUILayout.ColorField(points.settings.unselectedColor); } GUILayout.EndHorizontal(); GUILayout.Space(5); if (!points.useGlobal) { points.showControls = EditorGUILayout.Foldout(points.showControls, "Controls"); } else { points.settings.showControls = EditorGUILayout.Foldout(points.settings.showControls, "Controls", true); } showControls = points.useGlobal ? points.settings.showControls : points.showControls; if (showControls) { GUILayout.Label("Shift + Left Click = Add Point"); GUILayout.Label("Control + Left Click = Delete Point"); GUILayout.Label("Left Click + Drag = Move Point"); GUILayout.Label("Shift + Right Click = Add Path"); GUILayout.Label("Control + Right Click = Delete Path"); height = expandedHeight; } else { height = collapseHeight; } GUILayout.EndArea(); Handles.EndGUI(); #endregion #region Position Popup Settings if (showPositionSetting) { Handles.BeginGUI(); Vector3 pos = points.paths[currentPath].points[rightClickPoint]; pos.x = points.paths[currentPath].points[rightClickPoint].x + handleSize; Vector2 v2 = HandleUtility.WorldToGUIPoint(pos); GUI.DrawTexture(new Rect(v2.x + 5, v2.y - 15f, 260, 25), CreateTexture(215, 25, handleColor)); GUILayout.BeginArea(new Rect(v2.x + 10, v2.y - 10f, 250, 20)); EditorGUILayout.BeginHorizontal(); float x = points.paths[currentPath].points[rightClickPoint].x; float y = points.paths[currentPath].points[rightClickPoint].y; Color textColor = new Color(); if (handleColor.r < 0.5f && handleColor.g < 0.5f && handleColor.b < 0.5f) { textColor = Color.white; } else { textColor = Color.black; } GUISkin skin = (GUISkin)Resources.Load("2DCollisionSkin", typeof(GUISkin)); GUIStyle labelStyle = new GUIStyle(skin.GetStyle("label")); GUIStyle textStyle = new GUIStyle(skin.GetStyle("textField")); EditorGUI.BeginChangeCheck(); GUI.contentColor = textColor; EditorGUILayout.LabelField("x", labelStyle, GUILayout.Width(15)); GUI.contentColor = Color.white; x = EditorGUILayout.FloatField(x); GUI.contentColor = textColor; EditorGUILayout.LabelField("y", labelStyle, GUILayout.Width(15)); GUI.contentColor = Color.white; y = EditorGUILayout.FloatField(y); points.paths[currentPath].points[rightClickPoint] = new Vector3(x, y); if (GUI.changed) { if (autoBuild) { points.BuildCollider(); } } EditorGUILayout.EndHorizontal(); GUILayout.EndArea(); Handles.EndGUI(); } #endregion }
private void Input(Event e, Vector3 mouse) { Points points = (Points)target; Rect rect = new Rect(5, 5, width + 10, height + 10); #region Input while over point if (!rect.Contains(e.mousePosition) && mouseOverPoint != null) { if (mouseOverPoint != null) { if (dragging) { Undo.RecordObject(points, "Point Moved"); points.paths[currentPath].points[(int)mouseOverPoint] = mouse; if (autoBuild) { points.BuildCollider(); } } if (e.type == EventType.MouseDown && e.button == 0 && e.modifiers != EventModifiers.Shift) { if (e.modifiers != EventModifiers.Control) { dragging = true; } } if (e.type == EventType.MouseUp && e.button == 0) { dragging = false; } if (e.type == EventType.MouseDown && e.button == 0 && e.modifiers == EventModifiers.Control) { Undo.RecordObject(points, "Point Removed"); points.paths[currentPath].points.RemoveAt((int)mouseOverPoint); if (autoBuild) { points.BuildCollider(); } } if (e.type == EventType.MouseDown && e.button == 1 && e.modifiers != EventModifiers.Control) { positionSettingStart = e.mousePosition; GenericMenu menu = new GenericMenu(); menu.AddItem(new GUIContent("Set Position"), false, Callback, 1); string str = showPositionSetting ? "Close" : "Cancel"; menu.AddItem(new GUIContent(str), false, Callback, 2); menu.ShowAsContext(); } if (e.type == EventType.MouseDown && e.button == 1 && e.modifiers == EventModifiers.Control) { Undo.RecordObject(points, "Remove Path"); points.RemovePath(currentPath); if (autoBuild) { points.BuildCollider(); } } if (e.type == EventType.MouseDown) { if ((int)mouseOverPoint != rightClickPoint) { showPositionSetting = false; } } } } #endregion #region Input while not over point if (!rect.Contains(e.mousePosition) && mouseOverPoint == null) { if (e.type == EventType.MouseDown && e.button == 0 && e.modifiers == EventModifiers.Shift) { handleSize = points.useGlobal ? points.settings.handleSize : points.handleSize; float closestLine = handleSize; int index = -1; Vector2 m2 = new Vector2(mouse.x, mouse.y); for (int i = 0; i < points.paths.Count; i++) { for (int j = 0; j < points.paths[i].points.Count; j++) { Vector2 p1 = new Vector2(points.paths[i].points[j].x, points.paths[i].points[j].y); Vector2 p2 = Vector2.zero; if (j > 0) { p2 = new Vector2(points.paths[i].points[j - 1].x, points.paths[i].points[j - 1].y); } else { p2 = new Vector2(points.paths[i].points[points.paths[i].points.Count - 1].x, points.paths[i].points[points.paths[i].points.Count - 1].y); } float dist = HandleUtility.DistancePointToLineSegment(m2, p1, p2); if (dist < closestLine) { closestLine = dist; index = j; } } } Undo.RecordObject(points, "Add Point"); if (index > -1) { points.InsertPoint(m2, index, currentPath); } else { points.AddPoint(m2, currentPath); } SceneView.RepaintAll(); if (autoBuild) { points.BuildCollider(); } } if (e.type == EventType.MouseDown && e.button == 1 && e.modifiers == EventModifiers.Shift) { Undo.RecordObject(points, "Add Path"); points.AddPath(); currentPath = points.paths.Count - 1; points.AddPoint(mouse, currentPath); if (autoBuild) { points.BuildCollider(); } } } #endregion }