Пример #1
0
		public void OnDrawGizmosSelected()
		{
			// the editor will draw paths when force straight line is on
			if( !forceStraightLinePath )
			{
				var spline = new Spline( nodes, useBezier, forceStraightLinePath );
				if( closePath )
					spline.closePath();
				
				Gizmos.color = pathColor;
				spline.drawGizmos( pathResolution, isInEditMode );
			}
		}
Пример #2
0
        public override void OnInspectorGUI()
        {
            showEditModeToggle();

            if (!_target.isInEditMode)
            {
                drawInstructions();
                return;
            }

            if (_target.useBezier && _target.nodes.Count < 4)
            {
                _target.useBezier = false;
            }

            // what kind of handles shall we use?
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Use Standard Handles");
            _target.useStandardHandles = EditorGUILayout.Toggle(_target.useStandardHandles);
            EditorGUILayout.EndHorizontal();


            // path name:
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Route Name");
            _target.pathName = EditorGUILayout.TextField(_target.pathName);
            EditorGUILayout.EndHorizontal();

            if (_target.pathName == string.Empty)
            {
                _target.pathName = "route" + Random.Range(1, 100000);
            }


            // path color:
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Route Color");
            _target.pathColor = EditorGUILayout.ColorField(_target.pathColor);
            EditorGUILayout.EndHorizontal();


            // force bezier:
            GUI.enabled = !_target.forceStraightLinePath;
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Use Bezier Path");
            EditorGUI.BeginChangeCheck();
            _target.useBezier = EditorGUILayout.Toggle(_target.useBezier);
            if (EditorGUI.EndChangeCheck() && _target.useBezier)
            {
                // validate
                // make sure we have enough nodes to use a bezier.  nodeCount - 1 must be divisible by 3
                if (_target.nodes.Count < 4)
                {
                    Debug.LogError("there must be at least 4 nodes to use a bezier");
                    _target.useBezier = false;
                }
                else
                {
                    var excessNodes = (_target.nodes.Count - 1) % 3;
                    if (excessNodes > 0)
                    {
                        _target.nodes.RemoveRange(_target.nodes.Count - excessNodes, excessNodes);
                        Debug.LogWarning("trimming " + excessNodes + " from the node list to make a proper bezier spline");
                    }
                }
            }
            EditorGUILayout.EndHorizontal();
            GUI.enabled = true;


            // force straight lines:
            GUI.enabled = !_target.useBezier;
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Force Straight Line Path");
            _target.forceStraightLinePath = EditorGUILayout.Toggle(_target.forceStraightLinePath);
            EditorGUILayout.EndHorizontal();
            GUI.enabled = true;


            // close path. only relevant for node counts greater than 5
            if (_target.nodes.Count < 5)
            {
                GUI.enabled = false;
            }

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Close Path");
            EditorGUI.BeginChangeCheck();
            _target.closePath = EditorGUILayout.Toggle(_target.closePath);
            if (EditorGUI.EndChangeCheck())
            {
                if (_target.closePath)
                {
                    closeRoute();
                }
            }
            EditorGUILayout.EndHorizontal();
            GUI.enabled = true;

            // resolution
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Editor Drawing Resolution");
            _target.pathResolution = EditorGUILayout.IntSlider(_target.pathResolution, 2, 100);
            EditorGUILayout.EndHorizontal();


            EditorGUILayout.Separator();


            // insert node - we need 3 or more nodes for insert to make sense
            if (_target.nodes.Count > 2)
            {
                EditorGUILayout.BeginHorizontal();

                GUI.enabled = _selectedNodeIndex != 0 && _selectedNodeIndex != -1;
                if (GUILayout.Button("Insert Node Before Selected"))
                {
                    insertNodeAtIndex(_selectedNodeIndex, false);
                }

                GUI.enabled = _selectedNodeIndex != _target.nodes.Count - 1 && _selectedNodeIndex != -1;
                if (GUILayout.Button("Insert Node After Selected"))
                {
                    insertNodeAtIndex(_selectedNodeIndex, true);
                }

                GUI.enabled = true;

                EditorGUILayout.EndHorizontal();
            }


            // shift the start point to the origin
            if (GUILayout.Button("Shift Path to Start at Origin"))
            {
                Undo.RecordObject(_target, "Path Vector Changed");

                var offset = Vector3.zero;

                // see what kind of path we are. the simplest case is just a straight line
                var path = new Spline(_target.nodes, _target.useBezier, _target.forceStraightLinePath);
                if (path.splineType == SplineType.StraightLine || path.splineType == SplineType.Bezier || _target.nodes.Count < 5)
                {
                    offset = Vector3.zero - _target.nodes[0];
                }
                else
                {
                    offset = Vector3.zero - _target.nodes[1];
                }

                for (var i = 0; i < _target.nodes.Count; i++)
                {
                    _target.nodes[i] += offset;
                }

                GUI.changed = true;
            }


            // reverse
            if (GUILayout.Button("Reverse Path"))
            {
                Undo.RecordObject(_target, "Path Vector Changed");
                _target.nodes.Reverse();
                GUI.changed = true;
            }


            // shifters. thse only make sense for straight line and catmull rom
            if (_target.forceStraightLinePath || (_target.nodes.Count > 4 && !_target.useBezier))
            {
                GUILayout.BeginHorizontal();

                if (GUILayout.Button("Shift Nodes Left"))
                {
                    Undo.RecordObject(_target, "Path Vector Changed");

                    var firstItem = _target.nodes[0];
                    _target.nodes.RemoveAt(0);
                    _target.nodes.Add(firstItem);

                    GUI.changed = true;
                }


                if (GUILayout.Button("Shift Nodes Right"))
                {
                    Undo.RecordObject(_target, "Path Vector Changed");

                    var lastItem = _target.nodes[_target.nodes.Count - 1];
                    _target.nodes.RemoveAt(_target.nodes.Count - 1);
                    _target.nodes.Insert(0, lastItem);

                    GUI.changed = true;
                }

                GUILayout.EndHorizontal();
            }


            if (GUILayout.Button("Clear Path"))
            {
                Undo.RecordObject(_target, "Path Vector Changed");
                _target.nodes.Clear();
                _target.nodes.Add(_target.transform.position);
                _target.nodes.Add(_target.transform.position + new Vector3(5f, 5f));

                GUI.changed = true;
            }


            if (GUILayout.Button("Move z-axis Values to 0"))
            {
                Undo.RecordObject(_target, "Path Vector Changed");

                for (var i = 0; i < _target.nodes.Count; i++)
                {
                    _target.nodes[i] = new Vector3(_target.nodes[i].x, _target.nodes[i].y, 0f);
                }

                GUI.changed = true;
            }


            // persist to disk
            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Save to/Read from Disk");

            EditorGUILayout.Space();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Serialize and Save Path");
            if (GUILayout.Button("Save"))
            {
                var path = EditorUtility.SaveFilePanel("Save path", Application.dataPath + "/StreamingAssets", _target.pathName + ".asset", "asset");
                if (path != string.Empty)
                {
                    persistRouteToDisk(path);

                    // fetch the filename and set it as the routeName
                    _target.pathName = Path.GetFileName(path).Replace(".asset", string.Empty);
                    GUI.changed      = true;
                }
            }
            EditorGUILayout.EndHorizontal();


            // load from disk
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel("Load saved path");
            if (GUILayout.Button("Load"))
            {
                var path = EditorUtility.OpenFilePanel("Choose path to load", Path.Combine(Application.dataPath, "StreamingAssets"), "asset");
                if (path != string.Empty)
                {
                    if (!File.Exists(path))
                    {
                        EditorUtility.DisplayDialog("File does not exist", "Path couldn't find the file you specified", "Close");
                    }
                    else
                    {
                        _target.nodes    = SplineAssetUtils.bytesToVector3List(File.ReadAllBytes(path));
                        _target.pathName = Path.GetFileName(path).Replace(".asset", string.Empty);
                        GUI.changed      = true;
                    }
                }
            }
            EditorGUILayout.EndHorizontal();


            // node display
            EditorGUILayout.Space();
            _showNodeDetails = EditorGUILayout.Foldout(_showNodeDetails, "Show Node Values");
            if (_showNodeDetails)
            {
                EditorGUI.indentLevel++;
                for (int i = 0; i < _target.nodes.Count; i++)
                {
                    _target.nodes[i] = EditorGUILayout.Vector3Field("Node " + (i + 1), _target.nodes[i]);
                }
                EditorGUI.indentLevel--;
            }

            drawInstructions();

            // update and redraw:
            if (GUI.changed)
            {
                EditorUtility.SetDirty(_target);
                Repaint();
            }
        }
Пример #3
0
 /// <summary>
 /// generates an arc from start to end with the arc axis curvatureAxis
 /// </summary>
 /// <returns>The arc.</returns>
 /// <param name="start">Start.</param>
 /// <param name="end">End.</param>
 /// <param name="curvature">how far away from the line from start to end the arc extends</param>
 /// <param name="curvatureAxis">the axis which the arc should extend into</param>
 public static Spline generateArc(Vector3 start, Vector3 end, float curvature, Vector3 curvatureAxis)
 {
     curvatureAxis.Normalize();
     return(Spline.generateArc(start, end, curvature, curvatureAxis, curvatureAxis));
 }
Пример #4
0
 /// <summary>
 /// generates an arc from start to end with the arc axis perpendicular to start and end points
 /// </summary>
 /// <returns>The arc.</returns>
 /// <param name="start">Start.</param>
 /// <param name="end">End.</param>
 /// <param name="curvature">how far away from the line from start to end the arc extends</param>
 public static Spline generateArc(Vector3 start, Vector3 end, float curvature)
 {
     return(Spline.generateArc(start, end, curvature, Vector3.Cross(start, end)));
 }
Пример #5
0
		/// <summary>
		/// helper for drawing gizmos in the editor
		/// </summary>
		public static void drawGizmos( Vector3[] nodes, float resolution = 50, bool isInEditMode = false )
		{
			// horribly inefficient but it only runs in the editor
			var spline = new Spline( new List<Vector3>( nodes ) );
			spline.drawGizmos( resolution, isInEditMode );
		}
Пример #6
0
		private void closeRoute()
		{
			// we will use the GoSpline class to handle the dirtywork of closing the path
			var path = new Spline( _target.nodes, _target.useBezier, _target.forceStraightLinePath );
			path.closePath();
			
			_target.nodes = path.nodes;
			
			GUI.changed = true;
		}
Пример #7
0
		public override void OnInspectorGUI()
		{
			showEditModeToggle();

			if( !_target.isInEditMode )
			{
				drawInstructions();
				return;
			}

			if( _target.useBezier && _target.nodes.Count < 4 )
				_target.useBezier = false;

			// what kind of handles shall we use?
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Use Standard Handles" );
			_target.useStandardHandles = EditorGUILayout.Toggle( _target.useStandardHandles );
			EditorGUILayout.EndHorizontal();

			
			// path name:
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Route Name" );
			_target.pathName = EditorGUILayout.TextField( _target.pathName );
			EditorGUILayout.EndHorizontal();
			
			if( _target.pathName == string.Empty )
				_target.pathName = "route" + Random.Range( 1, 100000 );
			
			
			// path color:
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Route Color" );
			_target.pathColor = EditorGUILayout.ColorField( _target.pathColor );
			EditorGUILayout.EndHorizontal();


			// force bezier:
			GUI.enabled = !_target.forceStraightLinePath;
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Use Bezier Path" );
			EditorGUI.BeginChangeCheck();
			_target.useBezier = EditorGUILayout.Toggle( _target.useBezier );
			if( EditorGUI.EndChangeCheck() && _target.useBezier )
			{
				// validate
				// make sure we have enough nodes to use a bezier.  nodeCount - 1 must be divisible by 3
				if( _target.nodes.Count < 4 )
				{
					Debug.LogError( "there must be at least 4 nodes to use a bezier" );
					_target.useBezier = false;
				}
				else
				{
					var excessNodes = ( _target.nodes.Count - 1 ) % 3;
					if( excessNodes > 0 )
					{
						_target.nodes.RemoveRange( _target.nodes.Count - excessNodes, excessNodes );
						Debug.LogWarning( "trimming " + excessNodes + " from the node list to make a proper bezier spline" );
					}
				}
			}
			EditorGUILayout.EndHorizontal();
			GUI.enabled = true;

			
			// force straight lines:
			GUI.enabled = !_target.useBezier;
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Force Straight Line Path" );
			_target.forceStraightLinePath = EditorGUILayout.Toggle( _target.forceStraightLinePath );
			EditorGUILayout.EndHorizontal();
			GUI.enabled = true;


			// close path. only relevant for node counts greater than 5
			if( _target.nodes.Count < 5 )
				GUI.enabled = false;
			
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Close Path" );
			EditorGUI.BeginChangeCheck();
			_target.closePath = EditorGUILayout.Toggle( _target.closePath );
			if( EditorGUI.EndChangeCheck() )
			{
				if( _target.closePath )
					closeRoute();
			}
			EditorGUILayout.EndHorizontal();
			GUI.enabled = true;
			
			// resolution
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Editor Drawing Resolution" );
			_target.pathResolution = EditorGUILayout.IntSlider( _target.pathResolution, 2, 100 );
			EditorGUILayout.EndHorizontal();

			
			EditorGUILayout.Separator();
			
			
			// insert node - we need 3 or more nodes for insert to make sense
			if( _target.nodes.Count > 2 )
			{
				EditorGUILayout.BeginHorizontal();

				GUI.enabled = _selectedNodeIndex != 0 && _selectedNodeIndex != -1;
				if( GUILayout.Button( "Insert Node Before Selected" ) )
					insertNodeAtIndex( _selectedNodeIndex, false );

				GUI.enabled = _selectedNodeIndex != _target.nodes.Count - 1 && _selectedNodeIndex != -1;
				if( GUILayout.Button( "Insert Node After Selected" ) )
					insertNodeAtIndex( _selectedNodeIndex, true );
				
				GUI.enabled = true;

				EditorGUILayout.EndHorizontal();
			}


			// shift the start point to the origin
			if( GUILayout.Button( "Shift Path to Start at Origin" ) )
			{
				Undo.RecordObject( _target, "Path Vector Changed" );
				
				var offset = Vector3.zero;
				
				// see what kind of path we are. the simplest case is just a straight line
				var path = new Spline( _target.nodes, _target.useBezier, _target.forceStraightLinePath );
				if( path.splineType == SplineType.StraightLine || path.splineType == SplineType.Bezier || _target.nodes.Count < 5 )
					offset = Vector3.zero - _target.nodes[0];
				else
					offset = Vector3.zero - _target.nodes[1];
				
				for( var i = 0; i < _target.nodes.Count; i++ )
					_target.nodes[i] += offset;
				
				GUI.changed = true;
			}
			
			
			// reverse
			if( GUILayout.Button( "Reverse Path" ) )
			{
				Undo.RecordObject( _target, "Path Vector Changed" );
				_target.nodes.Reverse();
				GUI.changed = true;
			}


			// shifters. thse only make sense for straight line and catmull rom
			if( _target.forceStraightLinePath || ( _target.nodes.Count > 4 && !_target.useBezier ) )
			{			
				GUILayout.BeginHorizontal();

				if( GUILayout.Button( "Shift Nodes Left" ) )
				{
					Undo.RecordObject( _target, "Path Vector Changed" );

					var firstItem = _target.nodes[0];
					_target.nodes.RemoveAt( 0 );
					_target.nodes.Add( firstItem );

					GUI.changed = true;
				}


				if( GUILayout.Button( "Shift Nodes Right" ) )
				{
					Undo.RecordObject( _target, "Path Vector Changed" );

					var lastItem = _target.nodes[_target.nodes.Count - 1];
					_target.nodes.RemoveAt( _target.nodes.Count - 1 );
					_target.nodes.Insert( 0, lastItem );

					GUI.changed = true;
				}

				GUILayout.EndHorizontal();
			}


			if( GUILayout.Button( "Clear Path" ) )
			{
				Undo.RecordObject( _target, "Path Vector Changed" );
				_target.nodes.Clear();
				_target.nodes.Add( _target.transform.position );
				_target.nodes.Add( _target.transform.position + new Vector3( 5f, 5f ) );

				GUI.changed = true;
			}


			if( GUILayout.Button( "Move z-axis Values to 0" ) )
			{
				Undo.RecordObject( _target, "Path Vector Changed" );

				for( var i = 0; i < _target.nodes.Count; i++ )
					_target.nodes[i] = new Vector3( _target.nodes[i].x, _target.nodes[i].y, 0f );

				GUI.changed = true;
			}
			
			
			// persist to disk
			EditorGUILayout.Space();
			EditorGUILayout.LabelField( "Save to/Read from Disk" );

			EditorGUILayout.Space();
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Serialize and Save Path" );
			if( GUILayout.Button( "Save" ) )
			{
				var path = EditorUtility.SaveFilePanel( "Save path", Application.dataPath + "/StreamingAssets", _target.pathName + ".asset", "asset" );
				if( path != string.Empty )
				{
					persistRouteToDisk( path );
					
					// fetch the filename and set it as the routeName
					_target.pathName = Path.GetFileName( path ).Replace( ".asset", string.Empty );
					GUI.changed = true;
				}
			}
			EditorGUILayout.EndHorizontal();


			// load from disk
			EditorGUILayout.BeginHorizontal();
			EditorGUILayout.PrefixLabel( "Load saved path" );
			if( GUILayout.Button( "Load" ) )
			{
				var path = EditorUtility.OpenFilePanel( "Choose path to load", Path.Combine( Application.dataPath, "StreamingAssets" ), "asset" );
				if( path != string.Empty )
				{
					if( !File.Exists( path ) )
					{
						EditorUtility.DisplayDialog( "File does not exist", "Path couldn't find the file you specified", "Close" );
					}
					else
					{
						_target.nodes = SplineAssetUtils.bytesToVector3List( File.ReadAllBytes( path ) );
						_target.pathName = Path.GetFileName( path ).Replace( ".asset", string.Empty );
						GUI.changed = true;
					}
				}
			}
			EditorGUILayout.EndHorizontal();

					
			// node display
			EditorGUILayout.Space();
			_showNodeDetails = EditorGUILayout.Foldout( _showNodeDetails, "Show Node Values" );
			if( _showNodeDetails )
			{
				EditorGUI.indentLevel++;
				for( int i = 0; i < _target.nodes.Count; i++ )
					_target.nodes[i] = EditorGUILayout.Vector3Field( "Node " + ( i + 1 ), _target.nodes[i] );
				EditorGUI.indentLevel--;
			}

			drawInstructions();
			
			// update and redraw:
			if( GUI.changed )
			{
				EditorUtility.SetDirty( _target );
				Repaint();
			}
		}