private void DrawPathOptions() { editOption = (PathModifierOption)EditorGUILayout.EnumPopup(editOption); switch (editOption) { case PathModifierOption.PlaceToGround: foreach (BezierPoint bp in script.bPoints) { //define ray to cast downwards waypoint position Ray ray = new Ray(bp.wp.position + new Vector3(0, 2f, 0), -Vector3.up); Undo.RecordObject(bp.wp, "Place To Ground"); RaycastHit hit; //cast ray against ground, if it hit: if (Physics.Raycast(ray, out hit, 100)) { //position waypoint to hit point bp.wp.position = hit.point; } //also try to raycast against 2D colliders RaycastHit2D hit2D = Physics2D.Raycast(ray.origin, -Vector2.up, 100); if (hit2D) { bp.wp.position = new Vector3(hit2D.point.x, hit2D.point.y, bp.wp.position.z); } } break; case PathModifierOption.InvertDirection: //does not do anything actually Undo.RecordObject(script, "Invert Direction"); //to reverse the whole path we need to know where the waypoints were before //for this purpose a new copy must be created List <List <Vector3> > waypointCopy = new List <List <Vector3> >(); for (int i = 0; i < script.bPoints.Count; i++) { BezierPoint curPoint = script.bPoints[i]; waypointCopy.Add(new List <Vector3>() { curPoint.wp.position, curPoint.cp[0].position, curPoint.cp[1].position }); } //reverse order based on the old list for (int i = 0; i < script.bPoints.Count; i++) { BezierPoint curPoint = script.bPoints[i]; curPoint.wp.position = waypointCopy[waypointCopy.Count - 1 - i][0]; curPoint.cp[0].position = waypointCopy[waypointCopy.Count - 1 - i][2]; curPoint.cp[1].position = waypointCopy[waypointCopy.Count - 1 - i][1]; } break; case PathModifierOption.RotateWaypointsToPath: Undo.RecordObject(script, "Rotate Waypoints"); //orient waypoints to the path in forward direction for (int i = 0; i < script.bPoints.Count; i++) { //save child rotations before applying waypoint rotation Vector3[] globalPos = new Vector3[script.bPoints[i].wp.childCount]; for (int j = 0; j < globalPos.Length; j++) { globalPos[j] = script.bPoints[i].wp.GetChild(j).position; } if (i == script.bPoints.Count - 1) { script.bPoints[i].wp.rotation = script.bPoints[i - 1].wp.rotation; } else { script.bPoints[i].wp.LookAt(script.bPoints[i + 1].wp); } //restore previous location after rotation for (int j = 0; j < globalPos.Length; j++) { script.bPoints[i].wp.GetChild(j).position = globalPos[j]; } } break; case PathModifierOption.RenameWaypoints: //disabled because of a Unity bug that crashes the editor //this is taken directly from the docs, thank you Unity. //http://docs.unity3d.com/ScriptReference/Undo.RegisterCompleteObjectUndo.html //Undo.RegisterCompleteObjectUndo(waypoints[0].gameObject, "Rename Waypoints"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Skip Custom Names?"); script.skipCustomNames = EditorGUILayout.Toggle(script.skipCustomNames, GUILayout.Width(20)); EditorGUILayout.EndHorizontal(); if (!GUILayout.Button("Rename Now")) { return; } RenameWaypoints(script.skipCustomNames); break; case PathModifierOption.UpdateFromChildren: Undo.RecordObject(script, "Update Path From Children"); script.Create(); SceneView.RepaintAll(); break; case PathModifierOption.ReplaceWaypointObject: //draw object field for new waypoint object script.replaceObject = (GameObject)EditorGUILayout.ObjectField("Replace Object", script.replaceObject, typeof(GameObject), true); //replace all waypoints with the prefab if (!GUILayout.Button("Replace Now")) { return; } else if (script.replaceObject == null) { Debug.LogWarning("No replace object set. Cancelling."); return; } //Undo.RecordObject(script, "Replace Object"); Undo.RegisterFullObjectHierarchyUndo(script.transform, "Replace Object"); //old waypoints to remove after replace List <GameObject> toRemove = new List <GameObject>(); //loop through waypoint list for (int i = 0; i < script.bPoints.Count; i++) { //get current bezier point at index position BezierPoint point = script.bPoints[i]; Transform curWP = point.wp; //instantiate new waypoint at old position Transform newCur = ((GameObject)Instantiate(script.replaceObject, curWP.position, Quaternion.identity)).transform; //Undo.RegisterCreatedObjectUndo(newCur.gameObject, "Replace Object"); //parent control points to the new bezier point Undo.SetTransformParent(point.cp[0], newCur, "Replace Object"); Undo.SetTransformParent(point.cp[1], newCur, "Replace Object"); //parent new waypoint to this path newCur.parent = point.wp.parent; //replace old waypoint at index script.bPoints[i].wp = newCur; //indicate to remove old waypoint toRemove.Add(curWP.gameObject); } //destroy old waypoint object for (int i = 0; i < toRemove.Count; i++) { Undo.DestroyObjectImmediate(toRemove[i]); } break; } editOption = PathModifierOption.SelectModifier; }
private void DrawPathOptions() { Transform[] waypoints = GetWaypointArray(); editOption = (PathModifierOption)EditorGUILayout.EnumPopup(editOption); switch (editOption) { case PathModifierOption.PlaceToGround: foreach (Transform trans in waypoints) { //define ray to cast downwards waypoint position Ray ray = new Ray(trans.position + new Vector3(0, 2f, 0), -Vector3.up); Undo.RecordObject(trans, "Place To Ground"); RaycastHit hit; //cast ray against ground, if it hit: if (Physics.Raycast(ray, out hit, 100)) { //position waypoint to hit point trans.position = hit.point; } //also try to raycast against 2D colliders RaycastHit2D hit2D = Physics2D.Raycast(ray.origin, -Vector2.up, 100); if (hit2D) { trans.position = new Vector3(hit2D.point.x, hit2D.point.y, trans.position.z); } } break; case PathModifierOption.InvertDirection: Undo.RecordObjects(waypoints, "Invert Direction"); //to reverse the whole path we need to know where the waypoints were before //for this purpose a new copy must be created Vector3[] waypointCopy = new Vector3[waypoints.Length]; for (int i = 0; i < waypoints.Length; i++) { waypointCopy[i] = waypoints[i].position; } //looping over the array in reversed order for (int i = 0; i < waypoints.Length; i++) { waypoints[i].position = waypointCopy[waypointCopy.Length - 1 - i]; } break; case PathModifierOption.RotateWaypointsToPath: Undo.RecordObjects(waypoints, "Rotate Waypoints"); //orient waypoints to the path in forward direction for (int i = 0; i < waypoints.Length - 1; i++) { waypoints[i].LookAt(waypoints[i + 1]); } waypoints[waypoints.Length - 1].rotation = waypoints[waypoints.Length - 2].rotation; break; case PathModifierOption.RenameWaypoints: //disabled because of a Unity bug that crashes the editor //this is taken directly from the docs, thank you Unity. //http://docs.unity3d.com/ScriptReference/Undo.RegisterCompleteObjectUndo.html //Undo.RegisterCompleteObjectUndo(waypoints[0].gameObject, "Rename Waypoints"); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Skip Custom Names?"); m_SkipNames.boolValue = EditorGUILayout.Toggle(m_SkipNames.boolValue, GUILayout.Width(20)); EditorGUILayout.EndHorizontal(); if (!GUILayout.Button("Rename Now")) { return; } RenameWaypoints(waypoints, m_SkipNames.boolValue); break; case PathModifierOption.UpdateFromChildren: Undo.RecordObjects(waypoints, "Update Path From Children"); (m_Object.targetObject as PathManager).Create(); SceneView.RepaintAll(); break; case PathModifierOption.ReplaceWaypointObject: //draw object field for waypoint prefab EditorGUILayout.PropertyField(m_WaypointPref); //replace all waypoints with the prefab if (!GUILayout.Button("Replace Now")) { return; } else if (m_WaypointPref == null || m_WaypointPref.objectReferenceValue == null) { Debug.LogWarning("No replace object set. Cancelling."); return; } //get prefab object and path transform var waypointPrefab = m_WaypointPref.objectReferenceValue as GameObject; var path = GetWaypointAtIndex(0).parent; Undo.RegisterFullObjectHierarchyUndo(path, "Replace Object"); //loop through waypoint array of this path for (int i = 0; i < m_WaypointsCount.intValue; i++) { //get current waypoint at index position Transform curWP = GetWaypointAtIndex(i); //instantiate new waypoint at old position Transform newCur = ((GameObject)Instantiate(waypointPrefab, curWP.position, Quaternion.identity)).transform; //parent new waypoint to this path newCur.parent = path; //replace old waypoint at index SetWaypoint(i, newCur); //destroy old waypoint object Undo.DestroyObjectImmediate(curWP.gameObject); } break; } editOption = PathModifierOption.SelectModifier; }