Example #1
0
        //called whenever this inspector window is loaded
        public void OnEnable()
        {
            //we create a reference to our script object by passing in the target
            script = (BezierPathManager)target;
            if (script.bPoints.Count == 0)
            {
                return;
            }

            //reposition handles of the first and last point to the waypoint
            //they only have one control point so we set the other one to zero
            BezierPoint first = script.bPoints[0];

            first.cp[0].position = first.wp.position;
            BezierPoint last = script.bPoints[script.bPoints.Count - 1];

            last.cp[1].position = last.wp.position;

            //recalculate path points
            script.CalculatePath();
        }
Example #2
0
        //bezier path placement
        void PlaceBezierPoint(Vector3 placePos)
        {
            //create new bezier point property class
            BezierPoint newPoint = new BezierPoint();

            //instantiate waypoint gameobject
            Transform wayp = new GameObject("Waypoint").transform;

            //assign waypoint to the class
            newPoint.wp = wayp;

            //same as above
            if (wpList.Count == 0)
            {
                pathMan.transform.position = placePos;
            }

            //position current waypoint at clicked position in scene view
            if (mode2D)
            {
                placePos.z = 0f;
            }
            wayp.position           = placePos;
            wayp.transform.rotation = Quaternion.Euler(-90, 0, 0);
            //parent it to the defined path
            wayp.parent = pathMan.transform;

            BezierPathManager thisPath = pathMan as BezierPathManager;
            //create new array with bezier point handle positions
            Transform left  = new GameObject("Left").transform;
            Transform right = new GameObject("Right").transform;

            left.parent = right.parent = wayp;

            //initialize positions and last waypoint
            Vector3 handleOffset = new Vector3(2, 0, 0);
            Vector3 targetDir    = Vector3.zero;
            int     lastIndex    = wpList.Count - 1;

            //position handles to the left/right of the waypoint respectively
            left.position  = wayp.position + wayp.rotation * handleOffset;
            right.position = wayp.position + wayp.rotation * -handleOffset;
            newPoint.cp    = new[] { left, right };

            //position first handle in direction of the second waypoint
            if (wpList.Count == 1)
            {
                targetDir = (wayp.position - wpList[0].transform.position).normalized;
                thisPath.bPoints[0].cp[1].localPosition = targetDir * 2;
            }
            //always position last handle to look at the previous waypoint
            else if (wpList.Count >= 1)
            {
                targetDir = (wpList[lastIndex].transform.position - wayp.position);
                wayp.transform.rotation = Quaternion.LookRotation(targetDir) * Quaternion.Euler(0, -90, 0);
            }

            //position handle direction to the center of both last and next waypoints
            //takes into account 2D mode
            if (wpList.Count >= 2)
            {
                //get last point and center direction
                BezierPoint lastPoint = thisPath.bPoints[lastIndex];
                targetDir = (wayp.position - wpList[lastIndex].transform.position) +
                            (wpList[lastIndex - 1].transform.position - wpList[lastIndex].transform.position);

                //rotate to the center 2D/3D
                Quaternion lookRot = Quaternion.LookRotation(targetDir);
                if (mode2D)
                {
                    float angle = Mathf.Atan2(targetDir.y, targetDir.x) * Mathf.Rad2Deg + 90;
                    lookRot = Quaternion.AngleAxis(angle, Vector3.forward);
                }
                lastPoint.wp.rotation = lookRot;

                //cache handle and get previous of last waypoint
                Vector3 leftPos    = lastPoint.cp[0].position;
                Vector3 preLastPos = wpList[lastIndex - 1].transform.position;

                //calculate whether right or left handle distance is greater to last waypoint
                //left handle should point to the last waypoint, so reposition if necessary
                if (Vector3.Distance(leftPos, preLastPos) > Vector3.Distance(lastPoint.cp[1].position, preLastPos))
                {
                    lastPoint.cp[0].position = lastPoint.cp[1].position;
                    lastPoint.cp[1].position = leftPos;
                }
            }

            //add waypoint to the list of waypoints
            thisPath.bPoints.Add(newPoint);
            thisPath.segmentDetail.Add(thisPath.pathDetail);
            //add waypoint to temporary list
            wpList.Add(wayp.gameObject);
            //rename waypoint to match the list count
            wayp.name = "Waypoint " + (wpList.Count - 1);
            //recalculate bezier path
            thisPath.CalculatePath();
        }
Example #3
0
        public override void OnInspectorGUI()
        {
            //don't draw inspector fields if the path contains less than 2 points
            //(a path with less than 2 points really isn't a path)
            if (script.bPoints.Count < 2)
            {
                //button to create path manually
                if (GUILayout.Button("Create Path from Children"))
                {
                    Undo.RecordObject(script, "Create Path");
                    script.Create();
                    SceneView.RepaintAll();
                }

                return;
            }

            //create new checkboxes for path gizmo property
            script.showHandles    = EditorGUILayout.Toggle("Show Handles", script.showHandles);
            script.connectHandles = EditorGUILayout.Toggle("Connect Handles", script.connectHandles);
            script.drawCurved     = EditorGUILayout.Toggle("Draw Smooth Lines", script.drawCurved);
            script.drawDirection  = EditorGUILayout.Toggle("Draw Direction", script.drawDirection);

            //create new color fields for editing path gizmo colors
            script.color1 = EditorGUILayout.ColorField("Color1", script.color1);
            script.color2 = EditorGUILayout.ColorField("Color2", script.color2);
            script.color3 = EditorGUILayout.ColorField("Color3", script.color3);

            //calculate path length of all waypoints
            float pathLength = WaypointManager.GetPathLength(script.pathPoints);

            GUILayout.Label("Path Length: " + pathLength);

            float thisDetail = script.pathDetail;

            //slider to modify the smoothing factor of the final path,
            //round because of path point imprecision placement (micro loops)
            script.pathDetail = EditorGUILayout.Slider("Path Detail", script.pathDetail, 0.5f, 10);
            script.pathDetail = Mathf.Round(script.pathDetail * 10f) / 10f;
            //toggle custom detail when modifying the whole path
            if (thisDetail != script.pathDetail)
            {
                script.customDetail = false;
            }
            //draw custom detail settings
            DetailSettings();

            //button for switching over to the WaypointManager for further path editing
            if (GUILayout.Button("Continue Editing"))
            {
                Selection.activeGameObject = (GameObject.FindObjectOfType(typeof(WaypointManager)) as WaypointManager).gameObject;
                WaypointEditor.ContinuePath(script);
            }

            //more path modifiers
            DrawPathOptions();
            EditorGUILayout.Space();

            //waypoint index header
            GUILayout.Label("Waypoints: ", EditorStyles.boldLabel);

            //loop through the waypoint array
            for (int i = 0; i < script.bPoints.Count; i++)
            {
                GUILayout.BeginHorizontal();
                //indicate each array slot with index number in front of it
                GUILayout.Label(i + ".", GUILayout.Width(20));

                //create an object field for every waypoint
                EditorGUILayout.ObjectField(script.bPoints[i].wp, typeof(Transform), true);

                //display an "Add Waypoint" button for every array row except the last one
                //on click we call AddWaypointAtIndex() to insert a new waypoint slot AFTER the selected slot
                if (i < script.bPoints.Count && GUILayout.Button("+", GUILayout.Width(30f)))
                {
                    AddWaypointAtIndex(i);
                    break;
                }

                //display an "Remove Waypoint" button for every array row except the first and last one
                //on click we call RemoveWaypointAtIndex() to delete the selected waypoint slot
                if (i > 0 && i < script.bPoints.Count - 1 && GUILayout.Button("-", GUILayout.Width(30f)))
                {
                    RemoveWaypointAtIndex(i);
                    break;
                }

                GUILayout.EndHorizontal();
            }

            //recalculate on inspector changes
            if (GUI.changed)
            {
                script.CalculatePath();
                EditorUtility.SetDirty(target);
            }
        }