Пример #1
0
    private void initGraph(GridGraph g, Vector3 center, int width, int depth, int nodeSize)
    {
        g.center = center;
        g.width = width;
        g.depth = depth;
        g.nodeSize = nodeSize;
        g.maxSlope = 50;
        g.maxClimb = 0;

        g.autoLinkGrids = true;

        g.collision.collisionCheck = true;
        g.collision.diameter = 1.5f;
        g.collision.height = 3;
        g.collision.collisionOffset = 2;
        int obstacleLayer = LayerMask.NameToLayer("Obstacle");
        int obstacleMask = 1 << obstacleLayer;
        g.collision.mask = obstacleMask;
        g.collision.heightCheck = true;
        int groundLayer = LayerMask.NameToLayer("Ground");
        int groundMask = 1 << groundLayer;

        g.collision.heightMask = groundMask;

        g.UpdateSizeFromWidthDepth ();
        AstarPath.active.astarData.AddGraph(g);
    }
Пример #2
0
 public virtual void Start()
 {
     _transform = this.transform;
     _graph     = AstarPath.active.astarData.gridGraph;
     //_name      = this.gameObject.name;
     position   = this.transform.position;
 }
	public void Start () {
		if ( AstarPath.active == null ) throw new System.Exception ("There is no AstarPath object in the scene");

		graph = AstarPath.active.astarData.gridGraph;

		if ( graph == null ) throw new System.Exception ("The AstarPath object has no GridGraph");
		UpdateGraph ();
	}
Пример #4
0
		public static void SetGridGraph (int graphIndex, GridGraph graph) {
			if (_gridGraphs.Length <= graphIndex) {
				var gg = new GridGraph[graphIndex+1];
				for (int i=0;i<_gridGraphs.Length;i++) gg[i] = _gridGraphs[i];
				_gridGraphs = gg;
			}

			_gridGraphs[graphIndex] = graph;
		}
Пример #5
0
    /// <summary>
    /// This is the main function for creating the random maze.
    /// A random tree is created from a grid graph, and then maze rooms are
    /// created on nodes and maze doors / hallways on edges.
    /// </summary>     
    public void Generate() {

        MazeGrid = new GridGraph(size.x, size.z);
        cells = new MazeCell[MazeGrid.x, MazeGrid.y];
        

        //turn the grid graph into a spanning tree of the same nodes
        MazeGrid.RandomizedKruskals();

        CreateAllCellsAndHallwaysBasedOnGraph();
        
    }
Пример #6
0
    protected void Start()
    {
        gg = AstarPath.active.astarData.gridGraph;
        //InvokeRepeating("updateGraph", 0, 1);
        updateGraph();
        selectBox = gameObject.AddComponent ("SelectionManager") as SelectionManager;

        Simulator.Instance.setTimeStep(1);
        //sim.setTimeStep (0.25f);
        Simulator.Instance.setAgentDefaults(30, 20, 30, 15, 3.5f, 10, new RVO.Vector2());

        QualitySettings.antiAliasing = 8;
        System.Random rng = new System.Random();
        int randomX;
        int randomY;
        int randomZ;

        GameObject[] allUnits = GameObject.FindGameObjectsWithTag("Unit");
        for(int i = 0; i < allUnits.Length; i ++) {
            Unit unit = allUnits[i].GetComponent("Unit") as Unit;
            //unit.rotation = allUnits[i].transform.eulerAngles;
            unit.team = localPlayerTeam;
            objectList.Add (allUnits[i]);
            //Simulator.Instance.addAgent (new RVO.Vector2(unit.transform.position.x, unit.transform.position.z));
            //RVO.Vector2 goalVector = new RVO.Vector2(unit.transform.position.x, unit.transform.position.z) - Simulator.Instance.getAgentPosition(i);
            //Simulator.Instance.setAgentPrefVelocity (i, new RVO.Vector2(unit.transform.position.x, unit.transform.position.z));
            //if (RVOMath.absSq(goalVector) > 1.0f)
            {
                //goalVector = RVOMath.normalize(goalVector) * Time.deltaTime * 10;
                //Simulator.Instance.setAgentPrefVelocity(i, goalVector);
                //realGoal = (realGoal - unitPos).normalized;
            }
            unitList.Add (unit);
            //guo = new GraphUpdateObject(unit.collider.bounds);
            //guo.addPenalty = 0;
            //AstarPath.active.UpdateGraphs (guo);
        }
        for(int i = 0; i < unitList.Count; i++) {
            for(int z = 0; z < unitList.Count; z++) {
                unitList[i].addObstacle (unitList[z]);
            }
        }
        //Debug.Log (Simulator.Instance.getNumAgents ());
        allUnits = GameObject.FindGameObjectsWithTag("Building");
        for(int i = 0; i < allUnits.Length; i ++) {
            Building unit = allUnits[i].GetComponent("Building") as Building;
            //unit.rotation = allUnits[i].transform.eulerAngles;
            unit.team = localPlayerTeam;
            objectList.Add (allUnits[i]);
        }

        selectBox.ObjectList = objectList;
    }
Пример #7
0
 void createGrah(GridGraph player, int x, int y, Vector3 center)
 {
     player = data.AddGraph(typeof(GridGraph)) as GridGraph;
     player.width = x;
     player.depth = y;
     player.center = center;
     player.nodeSize = 0.5f;
     player.UpdateSizeFromWidthDepth();
     player.neighbours = NumNeighbours.Four;
     player.collision.type = Pathfinding.ColliderType.Capsule;
     player.collision.diameter = 1f;
     player.collision.height = 1;
     player.collision.mask = LayerMask.GetMask("Ignore Raycast", "Border");
     player.collision.heightCheck = false;
     //player.collision.thickRaycast = true;
     AstarPath.active.Scan();
 }
Пример #8
0
    private void init()
    {
        levelGraph = (GridGraph)AstarPath.active.astarData.CreateGraph(typeof(GridGraph));
        initGraph(levelGraph, new Vector3(160, -0.1f, 150), 130, 130, 2);

        //		Vector3 playerCenter = player.position;
        //		playerCenter.y = -0.1f;

        //playerGraph = (GridGraph)AstarPath.active.astarData.CreateGraph(typeof(GridGraph));
        //initGraph(playerGraph, playerCenter, 50, 50, 1);

        //Vector3 tresaureCenter = tresaure.position;
        //tresaureCenter.y = -0.1f;

        //tresaureGraph = (GridGraph)AstarPath.active.astarData.CreateGraph(typeof(GridGraph));
        //initGraph(tresaureGraph, tresaureCenter, 10, 10, 1);
        //Debug.Log("Initialized graphs");
    }
Пример #9
0
    public static IntRect getBoundsRect(Bounds b, GridGraph gg)
    {
        Vector3 min, max;
        gg.GetBoundsMinMax (b,gg.inverseMatrix,out min, out max);

        int minX = Mathf.RoundToInt (min.x-0.5F);
        int maxX = Mathf.RoundToInt (max.x-0.5F);

        int minZ = Mathf.RoundToInt (min.z-0.5F);
        int maxZ = Mathf.RoundToInt (max.z-0.5F);

        IntRect originalRect = new IntRect(minX,minZ,maxX,maxZ);

        IntRect gridRect = new IntRect(0,0,gg.width -1, gg.depth -1);
        IntRect clampedRect = IntRect.Intersection (originalRect, gridRect);

        return clampedRect;
    }
Пример #10
0
    private static IEnumerator SpawnObjects(GameObject obj, int Amount, GridGraph grid = null)
    {
        if (grid == null)
        {
            grid = GridManager.Grid;
        }
        if (grid.gridType == GridGraph.GridType.Plane)
        {
            float minX = grid.offset.x;
            float minY = grid.offset.z;

            float maxX = minX + grid.WorldSize.x;
            float maxY = minY + grid.WorldSize.y;

            Transform gridTransform = FindObjectOfType<GridManager>().transform;

            int i = 0;
            while (i < Amount && instance.gameObject.transform.childCount < instance.MaxAIs)
            {
                GameObject ob = (GameObject)Instantiate(obj, new Vector3(Random.Range(minX, maxX), 0, Random.Range(minY, maxY)), Quaternion.identity);
                ob.transform.parent = gridTransform;
                ob.name = obj.name;

                i++;
                yield return null;
            }
        }
        else
        {
            Transform gridTransform = FindObjectOfType<GridManager>().transform;

            int i = 0;
            while (i < Amount && instance.gameObject.transform.childCount < instance.MaxAIs)
            {
                GameObject ob = (GameObject)Instantiate(obj, Random.onUnitSphere * (grid.Radius + 2), Quaternion.identity);
                ob.transform.parent = gridTransform;
                ob.name = obj.name;

                i++;
                yield return null;
            }
        }
    }
Пример #11
0
	// Use this for initialization
	void Start () 
	{
		m_Difficulty = 5;
		m_Score = 0;
		m_Round = 1;
		m_RoundLimit = m_Round * 5;
		m_RoundTime = m_Round * 15;
		m_SpawnTime = m_Difficulty;
		m_Shortest = Mathf.Infinity;
		m_Scalar = 1;
		m_Ready = m_Done = false;

		tehPlayer = GameObject.FindGameObjectWithTag("Player").GetComponent<Player>();
		enemyPool = GameObject.FindGameObjectWithTag("Container");
		cam = GameObject.FindGameObjectWithTag("MainCamera");
		camSize = cam.camera.orthographicSize;
		ground = GameObject.FindGameObjectWithTag("Ground");
		currentScale = ground.transform.localScale;

		graph = (GridGraph)GameObject.FindGameObjectWithTag("Graph").GetComponent<AstarPath>().graphs[0];
		gus = GameObject.FindGameObjectWithTag ("Update").GetComponent<GraphUpdateScene> ();
		roundGUI = GameObject.FindGameObjectWithTag ("RoundGUI").GetComponent<GUIText> ();
	}
Пример #12
0
    //GraphUndo undoState;
    //byte[] savedBytes;

    public override void OnSceneGUI(NavGraph target)
    {
        Event e = Event.current;



        GridGraph graph = target as GridGraph;

        Matrix4x4 matrixPre = graph.matrix;

        graph.GenerateMatrix();

        if (e.type == EventType.MouseDown)
        {
            isMouseDown = true;
        }
        else if (e.type == EventType.MouseUp)
        {
            isMouseDown = false;
        }

        if (!isMouseDown)
        {
            savedMatrix = graph.boundsMatrix;
        }

        Handles.matrix = savedMatrix;

        if (graph.nodes == null || (graph.uniformWidhtDepthGrid && graph.depth * graph.width != graph.nodes.Length) || graph.matrix != matrixPre)
        {
            //Rescan the graphs
            if (AstarPath.active.AutoScan())
            {
                GUI.changed = true;
            }
        }

        Matrix4x4 inversed = savedMatrix.inverse;

        Handles.color = AstarColor.BoundsHandles;

        Handles.DrawCapFunction cap = Handles.CylinderCap;

        Vector2 extents = graph.unclampedSize * 0.5F;

        Vector3 center = inversed.MultiplyPoint3x4(graph.center);


#if UNITY_3_3
        if (Tools.current == 3)
        {
#else
        if (Tools.current == Tool.Scale)
        {
#endif

            Vector3 p1 = Handles.Slider(center + new Vector3(extents.x, 0, 0), Vector3.right, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(extents.x, 0, 0)), cap, 0);
            Vector3 p2 = Handles.Slider(center + new Vector3(0, 0, extents.y), Vector3.forward, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(0, 0, extents.y)), cap, 0);
            //Vector3 p3 = Handles.Slider (center+new Vector3 (0,extents.y,0),	Vector3.up,			0.1F*HandleUtility.GetHandleSize (center+new Vector3 (0,extents.y,0)),cap,0);

            Vector3 p4 = Handles.Slider(center + new Vector3(-extents.x, 0, 0), -Vector3.right, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(-extents.x, 0, 0)), cap, 0);
            Vector3 p5 = Handles.Slider(center + new Vector3(0, 0, -extents.y), -Vector3.forward, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(0, 0, -extents.y)), cap, 0);

            Vector3 p6 = Handles.Slider(center, Vector3.up, 0.1F * HandleUtility.GetHandleSize(center), cap, 0);

            Vector3 r1 = new Vector3(p1.x, p6.y, p2.z);
            Vector3 r2 = new Vector3(p4.x, p6.y, p5.z);

            //Debug.Log (graph.boundsMatrix.MultiplyPoint3x4 (Vector3.zero)+" "+graph.boundsMatrix.MultiplyPoint3x4 (Vector3.one));

            //if (Tools.viewTool != ViewTool.Orbit) {

            graph.center = savedMatrix.MultiplyPoint3x4((r1 + r2) / 2F);

            Vector3 tmp = r1 - r2;
            graph.unclampedSize = new Vector2(tmp.x, tmp.z);

            //}

#if UNITY_3_3
        }
        else if (Tools.current == 1)
        {
#else
        }
        else if (Tools.current == Tool.Move)
        {
#endif

            if (Tools.pivotRotation == PivotRotation.Local)
            {
                center = Handles.PositionHandle(center, Quaternion.identity);

                if (Tools.viewTool != ViewTool.Orbit)
                {
                    graph.center = savedMatrix.MultiplyPoint3x4(center);
                }
            }
            else
            {
                Handles.matrix = Matrix4x4.identity;

                center = Handles.PositionHandle(graph.center, Quaternion.identity);

                if (Tools.viewTool != ViewTool.Orbit)
                {
                    graph.center = center;
                }
            }
#if UNITY_3_3
        }
        else if (Tools.current == 2)
        {
#else
        }
        else if (Tools.current == Tool.Rotate)
        {
#endif
            //The rotation handle doesn't seem to be able to handle different matrixes of some reason
            Handles.matrix = Matrix4x4.identity;

            Quaternion rot = Handles.RotationHandle(Quaternion.Euler(graph.rotation), graph.center);

            if (Tools.viewTool != ViewTool.Orbit)
            {
                graph.rotation = rot.eulerAngles;
            }
        }

        //graph.size.x = Mathf.Max (graph.size.x,1);
        //graph.size.y = Mathf.Max (graph.size.y,1);
        //graph.size.z = Mathf.Max (graph.size.z,1);

        Handles.matrix = Matrix4x4.identity;
    }
Пример #13
0
        /*
         * This method copies the existing car from the old to the new carpark. If number of cars is greater than
         * capacity of the new carpark, then they are destroyed. This is a coroutine which provides a callback so the
         * animation can be queued up.
         */
        private IEnumerator CopyVehiclesToNewCarpark(ListCarparkManager newCarparkManager,
                                                     List <IsoTransform> newCarpark, Action <bool> callback)
        {
            yield return(StartCoroutine(TransitionManager.SpawnCarparkEffect(newCarparkManager.GroundTiles,
                                                                             newCarparkManager.Decorations)));

            if (_currentListCarpark != null)
            {
                int completed = 0;
                int expected  = ActiveCarpark.Count;
                for (int i = 0; i < ActiveCarpark.Count; i++)
                {
                    if (GetVehicleAtPosition(ConvertTileToPosition(ActiveCarpark[i]), out GameObject vehicle))
                    {
                        if (i < newCarpark.Count)
                        {
                            StartCoroutine(WriteToIndex(vehicle, ConvertTileToPosition(newCarparkManager.Carparks[i]),
                                                        status =>
                            {
                                if (status)
                                {
                                    completed++;
                                }
                                else
                                {
                                    Debug.Log("Failed to copy cars");
                                    callback(false);
                                }
                            }));
                        }
                        else
                        {
                            Destroy(i, status =>
                            {
                                if (status)
                                {
                                    completed++;
                                }
                                else
                                {
                                    Debug.Log("Failed to destroy car when not list is smaller");
                                    callback(false);
                                }
                            });
                        }
                    }
                    else
                    {
                        expected--;
                    }
                }

                yield return(new WaitUntil(() => completed == expected));

                Debug.Log("Finished copying cars");

                yield return(TransitionManager.PanCameraEffect(FindObjectOfType <Camera>(), _shiftAmount));

                yield return(StartCoroutine(TransitionManager.DestroyCarparkEffect(_currentListCarpark.GroundTiles,
                                                                                   _currentListCarpark.Decorations)));

                DestroyImmediate(_currentListCarpark.gameObject);
            }

            _currentListCarpark = newCarparkManager;
            ActiveCarpark       = newCarpark;
            SetNewSpawnPoint(_currentListCarpark.SpawnTile);
            SetNewDestroyPoint(_currentListCarpark.DestroyTile);
            GridGraph.UpdateGraph();
            callback?.Invoke(true);
        }
Пример #14
0
    public override void OnInspectorGUI(NavGraph target)
    {
        GridGraph graph = target as GridGraph;

        //GUILayout.BeginHorizontal ();
        //GUILayout.BeginVertical ();
        Rect lockRect;
        Rect tmpLockRect;

        GUIStyle lockStyle = AstarPathEditor.astarSkin.FindStyle("GridSizeLock");

        if (lockStyle == null)
        {
            lockStyle = new GUIStyle();
        }

        bool sizeSelected1 = false;
        bool sizeSelected2 = false;
        int  newWidth      = IntField("Width (nodes)", graph.width, 50, 0, out lockRect, out sizeSelected1);
        int  newDepth      = IntField("Depth (nodes)", graph.depth, 50, 0, out tmpLockRect, out sizeSelected2);

        //Rect r = GUILayoutUtility.GetRect (0,0,lockStyle);

        lockRect.width  = lockStyle.fixedWidth;
        lockRect.height = lockStyle.fixedHeight;
        lockRect.x     += lockStyle.margin.left;
        lockRect.y     += lockStyle.margin.top;

        locked = GUI.Toggle(lockRect, locked, new GUIContent("", "If the width and depth values are locked, changing the node size will scale the grid which keeping the number of nodes consistent instead of keeping the size the same and changing the number of nodes in the graph"), lockStyle);

        //GUILayout.EndHorizontal ();



        if (newWidth != graph.width || newDepth != graph.depth)
        {
            SnapSizeToNodes(newWidth, newDepth, graph);
        }

        GUI.SetNextControlName("NodeSize");
        newNodeSize = EditorGUILayout.FloatField("Node size", graph.nodeSize);

        newNodeSize = newNodeSize <= 0.01F ? 0.01F : newNodeSize;

        //if ((GUI.GetNameOfFocusedControl () != "NodeSize" && Event.current.type == EventType.Repaint) || Event.current.keyCode == KeyCode.Return) {

        //Debug.Log ("Node Size Not Selected " + Event.current.type);

        if (graph.nodeSize != newNodeSize)
        {
            if (!locked)
            {
                graph.nodeSize = newNodeSize;
                Matrix4x4 oldMatrix = graph.matrix;
                graph.GenerateMatrix();
                if (graph.matrix != oldMatrix)
                {
                    //Rescann the graphs
                    //AstarPath.active.AutoScan ();
                    GUI.changed = true;
                }
            }
            else
            {
                float delta = newNodeSize / graph.nodeSize;
                graph.nodeSize      = newNodeSize;
                graph.unclampedSize = new Vector2(newWidth * graph.nodeSize, newDepth * graph.nodeSize);
                Vector3 newCenter = graph.matrix.MultiplyPoint3x4(new Vector3((newWidth / 2F) * delta, 0, (newDepth / 2F) * delta));
                graph.center = newCenter;
                graph.GenerateMatrix();

                //Make sure the width & depths stay the same
                graph.width = newWidth;
                graph.depth = newDepth;
                AstarPath.active.AutoScan();
            }
        }
        //}

        Vector3 pivotPoint;
        Vector3 diff;

        GUILayout.BeginHorizontal();

        switch (pivot)
        {
        case GridPivot.Center:
            graph.center = EditorGUILayout.Vector3Field("Center", graph.center);
            break;

        case GridPivot.TopLeft:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(0, 0, graph.depth));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Top-Left", pivotPoint);
            graph.center = pivotPoint - diff;
            break;

        case GridPivot.TopRight:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(graph.width, 0, graph.depth));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Top-Right", pivotPoint);
            graph.center = pivotPoint - diff;
            break;

        case GridPivot.BottomLeft:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(0, 0, 0));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Bottom-Left", pivotPoint);
            graph.center = pivotPoint - diff;
            break;

        case GridPivot.BottomRight:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(graph.width, 0, 0));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Bottom-Right", pivotPoint);
            graph.center = pivotPoint - diff;
            break;
        }

        graph.GenerateMatrix();

        pivot = PivotPointSelector(pivot);

        GUILayout.EndHorizontal();

        GUILayout.BeginHorizontal();
        graph.rotation = EditorGUILayout.Vector3Field("Rotation", graph.rotation);
        //Add some space to make the Rotation and postion fields be better aligned (instead of the pivot point selector)
        GUILayout.Space(19 + 4 + 7);
        GUILayout.EndHorizontal();

        if (GUILayout.Button(new GUIContent("Snap Size", "Snap the size to exactly fit nodes"), GUILayout.MaxWidth(100), GUILayout.MaxHeight(16)))
        {
            SnapSizeToNodes(newWidth, newDepth, graph);
        }

        Separator();

        graph.cutCorners = EditorGUILayout.Toggle("Cut Corners", graph.cutCorners);
        graph.neighbours = (NumNeighbours)EditorGUILayout.EnumPopup("Connections", graph.neighbours);

        //GUILayout.BeginHorizontal ();
        //EditorGUILayout.PrefixLabel ("Max Climb");
        graph.maxClimb = EditorGUILayout.FloatField("Max Climb", graph.maxClimb);
        EditorGUI.indentLevel++;
        graph.maxClimbAxis = EditorGUILayout.IntPopup("Climb Axis", graph.maxClimbAxis, new string[3] {
            "X", "Y", "Z"
        }, new int[3] {
            0, 1, 2
        });

        EditorGUI.indentLevel--;
        //GUILayout.EndHorizontal ();

        GUILayout.BeginHorizontal();
        bool preEnabled = GUI.enabled;

        GUI.enabled            = graph.useRaycastNormal;
        graph.maxSlope         = EditorGUILayout.Slider("Max Slope", graph.maxSlope, 0, 90F);
        GUI.enabled            = preEnabled;
        graph.useRaycastNormal = GUILayout.Toggle(graph.useRaycastNormal, new GUIContent("", "Use the heigh raycast's normal to figure out the slope of the ground and check if it flat enough to stand on"), GUILayout.Width(10));
        GUILayout.EndHorizontal();

        graph.erodeIterations = EditorGUILayout.IntField("Erode iterations", graph.erodeIterations);
        graph.erodeIterations = graph.erodeIterations > 16 ? 16 : graph.erodeIterations;         //Clamp iterations to 16

        DrawCollisionEditor(graph.collision);

        Separator();

        showExtra = EditorGUILayout.Foldout(showExtra, "Extra");

        if (showExtra)
        {
            EditorGUI.indentLevel += 2;

            graph.penaltyAngle = ToggleGroup("Angle Penalty", graph.penaltyAngle);
            //bool preGUI = GUI.enabled;
            //GUI.enabled = graph.penaltyAngle && GUI.enabled;
            if (graph.penaltyAngle)
            {
                EditorGUI.indentLevel++;
                graph.penaltyAngleFactor = EditorGUILayout.FloatField("Factor", graph.penaltyAngleFactor);
                //GUI.enabled = preGUI;
                HelpBox("Applies penalty to nodes based on the angle of the hit surface during the Height Testing");

                EditorGUI.indentLevel--;
            }

            graph.penaltyPosition = ToggleGroup("Position Penalty", graph.penaltyPosition);
            //EditorGUILayout.Toggle ("Position Penalty",graph.penaltyPosition);
            //preGUI = GUI.enabled;
            //GUI.enabled = graph.penaltyPosition && GUI.enabled;
            if (graph.penaltyPosition)
            {
                EditorGUI.indentLevel++;
                graph.penaltyPositionOffset = EditorGUILayout.FloatField("Offset", graph.penaltyPositionOffset);
                graph.penaltyPositionFactor = EditorGUILayout.FloatField("Factor", graph.penaltyPositionFactor);
                HelpBox("Applies penalty to nodes based on their Y coordinate\nSampled in Int3 space, i.e it is multiplied with Int3.Precision first (usually 100)");
                //GUI.enabled = preGUI;
                EditorGUI.indentLevel--;
            }

            GUI.enabled = false;
            ToggleGroup(new GUIContent("Use Texture", AstarPathEditor.AstarProTooltip), false);
            GUI.enabled            = true;
            EditorGUI.indentLevel -= 2;
        }
    }
Пример #15
0
 public void OnPathComplete(Path p)
 {
     if (this.lastRender == null)
     {
         return;
     }
     if (p.error)
     {
         this.ClearPrevious();
         return;
     }
     if (p.GetType() == typeof(MultiTargetPath))
     {
         List <GameObject> list = new List <GameObject>(this.lastRender);
         this.lastRender.Clear();
         MultiTargetPath multiTargetPath = p as MultiTargetPath;
         for (int i = 0; i < multiTargetPath.vectorPaths.Length; i++)
         {
             if (multiTargetPath.vectorPaths[i] != null)
             {
                 List <Vector3> list2 = multiTargetPath.vectorPaths[i];
                 GameObject     gameObject;
                 if (list.Count > i && list[i].GetComponent <LineRenderer>() != null)
                 {
                     gameObject = list[i];
                     list.RemoveAt(i);
                 }
                 else
                 {
                     gameObject = new GameObject("LineRenderer_" + i, new Type[]
                     {
                         typeof(LineRenderer)
                     });
                 }
                 LineRenderer component = gameObject.GetComponent <LineRenderer>();
                 component.sharedMaterial = this.lineMat;
                 for (int j = 0; j < list2.Count; j++)
                 {
                     component.SetPosition(j, list2[j] + this.pathOffset);
                 }
                 this.lastRender.Add(gameObject);
             }
         }
         for (int k = 0; k < list.Count; k++)
         {
             Object.Destroy(list[k]);
         }
     }
     else if (p.GetType() == typeof(ConstantPath))
     {
         this.ClearPrevious();
         ConstantPath     constantPath = p as ConstantPath;
         List <GraphNode> allNodes     = constantPath.allNodes;
         Mesh             mesh         = new Mesh();
         List <Vector3>   list3        = new List <Vector3>();
         bool             flag         = false;
         for (int l = allNodes.Count - 1; l >= 0; l--)
         {
             Vector3 vector = (Vector3)allNodes[l].position + this.pathOffset;
             if (list3.Count == 65000 && !flag)
             {
                 Debug.LogError("Too many nodes, rendering a mesh would throw 65K vertex error. Using Debug.DrawRay instead for the rest of the nodes");
                 flag = true;
             }
             if (flag)
             {
                 Debug.DrawRay(vector, Vector3.up, Color.blue);
             }
             else
             {
                 GridGraph gridGraph = AstarData.GetGraph(allNodes[l]) as GridGraph;
                 float     num       = 1f;
                 if (gridGraph != null)
                 {
                     num = gridGraph.nodeSize;
                 }
                 list3.Add(vector + new Vector3(-0.5f, 0f, -0.5f) * num);
                 list3.Add(vector + new Vector3(0.5f, 0f, -0.5f) * num);
                 list3.Add(vector + new Vector3(-0.5f, 0f, 0.5f) * num);
                 list3.Add(vector + new Vector3(0.5f, 0f, 0.5f) * num);
             }
         }
         Vector3[] array  = list3.ToArray();
         int[]     array2 = new int[3 * array.Length / 2];
         int       m      = 0;
         int       num2   = 0;
         while (m < array.Length)
         {
             array2[num2]     = m;
             array2[num2 + 1] = m + 1;
             array2[num2 + 2] = m + 2;
             array2[num2 + 3] = m + 1;
             array2[num2 + 4] = m + 3;
             array2[num2 + 5] = m + 2;
             num2            += 6;
             m += 4;
         }
         Vector2[] array3 = new Vector2[array.Length];
         for (int n = 0; n < array3.Length; n += 4)
         {
             array3[n]     = new Vector2(0f, 0f);
             array3[n + 1] = new Vector2(1f, 0f);
             array3[n + 2] = new Vector2(0f, 1f);
             array3[n + 3] = new Vector2(1f, 1f);
         }
         mesh.vertices  = array;
         mesh.triangles = array2;
         mesh.uv        = array3;
         mesh.RecalculateNormals();
         GameObject gameObject2 = new GameObject("Mesh", new Type[]
         {
             typeof(MeshRenderer),
             typeof(MeshFilter)
         });
         MeshFilter component2 = gameObject2.GetComponent <MeshFilter>();
         component2.mesh = mesh;
         MeshRenderer component3 = gameObject2.GetComponent <MeshRenderer>();
         component3.material = this.squareMat;
         this.lastRender.Add(gameObject2);
     }
     else
     {
         this.ClearPrevious();
         GameObject gameObject3 = new GameObject("LineRenderer", new Type[]
         {
             typeof(LineRenderer)
         });
         LineRenderer component4 = gameObject3.GetComponent <LineRenderer>();
         component4.sharedMaterial = this.lineMat;
         for (int num3 = 0; num3 < p.vectorPath.Count; num3++)
         {
             component4.SetPosition(num3, p.vectorPath[num3] + this.pathOffset);
         }
         this.lastRender.Add(gameObject3);
     }
 }
Пример #16
0
 private void updateGraph(GridGraph g, Vector3 center)
 {
     g.center = center;
     Matrix4x4 m = g.matrix;
     g.GenerateMatrix();
     g.RelocateNodes (m, g.matrix);
     //Debug.Log("Graph updated!");
     return;
 }
 static object[] MakeBasicTestCase(GridGraph <int> graph, (int X, int Y) source, (int X, int Y)[] expectedSteps)
Пример #18
0
    void Spawn()
    {
        if (spawned == false)
        {
            spawned = true;
            if (openingDirection == 1)
            {
                // Need to spawn a room with a BOTTOM door.

                bool up     = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX && e.StatesY == roomParent.statesY + 2);
                bool right  = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX + 1 && e.StatesY == roomParent.statesY + 1);
                bool bottom = false;
                bool left   = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX - 1 && e.StatesY == roomParent.statesY + 1);

                AddRoom room = RoomTemplates.Instance.GetBottomRoomWithConstraint(up, right, bottom, left);
                room.SetNode(roomParent.statesX, roomParent.statesY + 1);

                Instantiate(room.gameObject, transform.position, room.transform.rotation);
            }
            else if (openingDirection == 2)
            {
                // Need to spawn a room with a TOP door.

                bool up     = false;
                bool right  = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX + 1 && e.StatesY == roomParent.statesY - 1);
                bool bottom = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX && e.StatesY == roomParent.statesY - 2);
                bool left   = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX - 1 && e.StatesY == roomParent.statesY - 1);

                AddRoom room = RoomTemplates.Instance.GetTopRoomWithConstraint(up, right, bottom, left);
                room.SetNode(roomParent.statesX, roomParent.statesY - 1);
                Instantiate(room.gameObject, transform.position, room.transform.rotation);
            }
            else if (openingDirection == 3)
            {
                // Need to spawn a room with a LEFT door.

                bool up     = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX + 1 && e.StatesY == roomParent.statesY + 1);
                bool right  = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX + 2 && e.StatesY == roomParent.statesY);
                bool bottom = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX + 1 && e.StatesY == roomParent.statesY - 1);
                bool left   = false;

                AddRoom room = RoomTemplates.Instance.GetLeftRoomWithConstraint(up, right, bottom, left);
                room.SetNode(roomParent.statesX + 1, roomParent.statesY);
                Instantiate(room.gameObject, transform.position, room.transform.rotation);
            }
            else if (openingDirection == 4)
            {
                // Need to spawn a room with a RIGHT door.

                bool up     = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX - 1 && e.StatesY == roomParent.statesY + 1);
                bool right  = false;
                bool bottom = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX - 1 && e.StatesY == roomParent.statesY - 1);
                bool left   = NodeRoomHelper.RoomNode.Any(e => e.StatesX == roomParent.statesX - 2 && e.StatesY == roomParent.statesY);

                AddRoom room = RoomTemplates.Instance.GetRightRoomWithConstraint(up, right, bottom, left);
                room.SetNode(roomParent.statesX - 1, roomParent.statesY);
                Instantiate(room.gameObject, transform.position, room.transform.rotation);
            }

            // This holds all graph data
            AstarData data = AstarPath.active.data;

            // This creates a Grid Graph
            GridGraph gg = data.AddGraph(typeof(GridGraph)) as GridGraph;

            // Setup a grid graph with some values
            int   width    = 26;
            int   depth    = 18;
            float nodeSize = 1;

            gg.center = this.transform.position;

            gg.rotation = new Vector3(90, 0, 0);

            gg.collision.heightCheck = false;

            gg.collision.mask = layer;
            // Updates internal size from the above values
            gg.SetDimensions(width, depth, nodeSize);
            gg.collision.use2D          = true;
            gg.collision.collisionCheck = true;
            gg.collision.type           = ColliderType.Ray;

            // Scans all graphs
            AstarPath.active.Scan();
        }
    }
Пример #19
0
    /// <summary>
    /// This function selects a way of finding the path based on the master distance, the current
    /// state of the AI. This is the main function of this script, it handles the AIs behavior. When
    /// it has found the method it sends it to the GridManager, which then processes it and send it
    /// back to the path variable in this script.
    /// </summary>
    private void FindPath()
    {
        if (Pause)
        {
            return;
        }
        Flocking flock = GetComponent<Flocking>();
        grid = GridManager.Grids[Mathf.Clamp(GridIndex, 0, GridManager.Grids.Count - 1)];
        bool t = false;
        if (flock && !flock.IsMaster && flock.DistanceMaster() > ViewDistance) //If the agent can't see the master.
        {
            target = null;
            t = true;
        }
        if (target == null || Flying)
        {
            if (Flying) //If flying is enabled
            {
                if (target = FindClosest()) //Check if a target is visible
                {
                    if (Type == AnimalType.aggressive) //If the animal is aggressive.
                    {
                        FindAirPath(target.transform.position); //Find a path to the target.
                    }
                    else if (Type == AnimalType.scared) //If the animal is scared.
                    {
                        FindAirPath(FindOpposite(target.transform.position)); //Find a path away from the target.
                    }
                }
                if (path == null) //If there wasn't any target visible.
                {
                    FindAirPath(); //Find an idle path.
                }
                return;
            }

            target = FindClosest(); //See if a target is visible.
            if (target == null) //If not try smelling for something.
            {
                target = Smell();
            }

            if (Type == AnimalType.aggressive) //If the animal is aggressive.
            {
                if (target != null && 100.0f - Data.Hunger <= target.GetComponent<AdvancedAI>().Size) //If hungry
                {
                    FindAPath(target.transform.position); //Find a path to the target.
                    return;
                }
            }
            else
            {
                FindAPath(FindOpposite(target.transform.position)); //If it is a scared animal run away from the danger.
                return;
            }

            if (AIState == CurrentAIState.Idling) //If the AI state is set to idling.
            {
                if (pt == PathType.none || t) //If there weren't any path, or there is a
                {
                    float dist = -ViewDistance / 2;

                    if (!flock || flock.IsMaster) //If I am the master.
                    {
                        FindAPath(transform.position + (grid.Vector2ToVector3(Random.insideUnitCircle * dist))); //Move normally
                    }
                    else if (flock.master != null)
                    {
                        FindAPath(flock.master.transform.position + (grid.Vector2ToVector3(Random.insideUnitCircle * dist))); //Move to the master.
                    }
                }
                return;
            }
            else if (AIState == CurrentAIState.GoingHome) //If the agent is planning on going home.
            {
                if (pt == PathType.none) //If there wasn't any path.
                {
                    FindAPath(Data.Home); //Find the quickest path home.
                }
                return;
            }
        }
        else if (pt == PathType.none) //If there is a target and there isn't any path, check if the target is still valid.
        {
            if (Physics.Linecast(transform.position, target.transform.position)) //If it still is visible.
            {
                FindAPath(target.transform.position); //Find a path to the target.
                return;
            }
            else
            {
                target = null; //Unset the target if it wasn't valid.
            }
        }
    }
 // Start is called before the first frame update
 void Start()
 {
     graphToScan = AstarPath.active?.data.gridGraph;
     breakList   = new HashSet <Tuple <Vector3, bool> >();
     map         = GetComponent <Tilemap>();
 }
Пример #21
0
        void mohogonyGrid()         // this is the optimized version. Other graphs cannot be optimised this way because they have irregular structures unfortunately. Still, we shouldn't miss on the advantages of this specific graph type, so I included it specifically.
        {
            nodes = new List <Node>();
            nodes.Add(node as Node);
            graph = AstarPath.active.graphs[node.graphIndex] as GridGraph;


            GraphUpdateShape gus = new GraphUpdateShape();

            if (useRealCollider.Value)
            {
                if (go.collider.GetType() == typeof(BoxCollider))                // take render bounds, then turn them into world coordinates
                {
                    Debug.Log("It's a box collider");
                    bounds.center = (go.collider as BoxCollider).center;
                    bounds.size   = (go.collider as BoxCollider).size;

                    calculateBox(gus);
                }
                else if (go.collider.GetType() == typeof(MeshCollider))
                {
                    gus.points = (go.collider as MeshCollider).sharedMesh.vertices;
                    for (var i = 0; i < gus.points.Count(); i++)
                    {
                        gus.points[i] = go.transform.TransformPoint((go.collider as MeshCollider).sharedMesh.vertices[i]);
                    }
                    Debug.Log("It's a mesh collider!");
                }
                else                 // any other collider
                {
                    calculateBox(gus);
                    Debug.Log("This type of collider is not specifically supported. Using bounds instead...");
                }
            }

            else             // get the points of the render bounds
            {
                bounds = (go.renderer.GetComponent(typeof(MeshFilter)) as MeshFilter).sharedMesh.bounds;
                calculateBox(gus);
            }

            //gus.convex = true;
            nodes = graph.GetNodesInArea(gus);

            if (getWalkableOnly.Value)
            {
                connected = new List <Node>();
                for (var i = 0; i < nodes.Count(); i++)
                {
                    if (nodes[i].walkable)
                    {
                        connected.Add(nodes[i]);                         // connected is a substitute for a better named one :D There is no real sense behind the name here.
                    }
                }
                nodesOutput.Value = SetNodes(connected);
            }

            else
            {
                nodesOutput.Value = SetNodes(nodes);
            }

            Debug.Log("i" + nodes.Count);


            return;
        }
Пример #22
0
 public Map()
 {
     Graph = new GridGraph<MapRoom, MapPath>();
 }
Пример #23
0
 public Astar(GridGraph gridGraph) : base(gridGraph)
 {
 }
Пример #24
0
    private void Show(Pos start, Pos goal, int[][] cost)
    {
        var objs = GameObject.FindGameObjectsWithTag("Unit");

        foreach (var o in objs)
        {
            Destroy(o);
        }

        // ----- BFS -----

        var         gridGraph  = new GridGraph(16, 16, cost);
        IPathFinder pathFinder = new BfsPathFinder();
        var         path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(0, 0), Color.white, path);

        var sumCost = 0;

        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("BFS 没有找到路径");
        }
        else
        {
            Debug.LogError($"BFS 总成本: {sumCost}, 总步数: {path.Count}");
        }

        // ----- Dijkstra -----

        pathFinder = new DijkstraPathFinder();
        path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(10, 0), Color.yellow, path);

        sumCost = 0;
        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("Dijkstra 没有找到路径");
        }
        else
        {
            Debug.LogError($"Dijkstra 总成本: {sumCost}, 总步数: {path.Count}");
        }

        // ----- GreedyBestFirst -----

        pathFinder = new GreedyBestFirstPathFinder();
        path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(0, 10), Color.grey, path);

        sumCost = 0;
        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("GreedyBestFirst 没有找到路径");
        }
        else
        {
            Debug.LogError($"GreedyBestFirst 总成本: {sumCost}, 总步数: {path.Count}");
        }

        // ----- AStar -----

        pathFinder = new AStarPathFinder();
        path       = pathFinder.Find(gridGraph, start, goal);

        Show(gridGraph, new Vector2(10, 10), Color.magenta, path);

        sumCost = 0;
        foreach (var p in path)
        {
            sumCost += cost[p.X][p.Y];
        }

        if (sumCost == 0)
        {
            Debug.LogError("AStar 没有找到路径");
        }
        else
        {
            Debug.LogError($"AStar 总成本: {sumCost}, 总步数: {path.Count}");
        }
    }
Пример #25
0
    // Update is called once per frame

    void Update()
    {
        if (player != null)
        {
            if (!active && player.transform.parent.name == gameObject.name && enemies.transform.childCount > 0)
            {
                if (topDoor.activeSelf)
                {
                    topDoor.GetComponent <Door>().animator.SetTrigger("Close");
                    topDoor.GetComponent <Door>().isOpen = false;
                }
                if (bottomDoor.activeSelf)
                {
                    bottomDoor.GetComponent <Door>().animator.SetTrigger("Close");
                    bottomDoor.GetComponent <Door>().isOpen = false;
                }
                if (leftDoor.activeSelf)
                {
                    leftDoor.GetComponent <Door>().animator.SetTrigger("Close");
                    leftDoor.GetComponent <Door>().isOpen = false;
                }
                if (rightDoor.activeSelf)
                {
                    rightDoor.GetComponent <Door>().animator.SetTrigger("Close");
                    rightDoor.GetComponent <Door>().isOpen = false;
                }
                active = true;
                pathing.SetActive(true);
                AstarPath astar = pathing.GetComponent <AstarPath>();
                test = astar.graphs[0].name;
                GridGraph g = (GridGraph)astar.graphs[0];
                g.center        = middle.transform.position;
                astar.graphs[0] = g;
                astar.graphs[0].Scan();

                /*
                 * foreach (Transform child in enemies.transform)
                 * {
                 *  try
                 *  {
                 *      child.GetComponent<AIPath>().enabled = true;
                 *      child.GetComponent<Seeker>().enabled = true;
                 *      child.GetComponent<AIDestinationSetter>().enabled = true;
                 *  }
                 *  catch
                 *  {
                 *     // do nothing;
                 *  }
                 * }
                 */
            }
            else if (active && enemies.transform.childCount == 0 && player != null)
            {
                active = false;
                if (topDoor.activeSelf)
                {
                    d        = topDoor.GetComponent <Door>();
                    d.isOpen = true;
                    openDoor();
                }
                if (bottomDoor.activeSelf)
                {
                    d        = bottomDoor.GetComponent <Door>();
                    d.isOpen = true;
                    openDoor();
                }
                if (leftDoor.activeSelf)
                {
                    d        = leftDoor.GetComponent <Door>();
                    d.isOpen = true;
                    openDoor();
                }
                if (rightDoor.activeSelf)
                {
                    d        = rightDoor.GetComponent <Door>();
                    d.isOpen = true;
                    openDoor();
                }
                pathing.SetActive(false);
                Destroy(this);
            }
        }
    }
Пример #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Node"/> class.
 /// </summary>
 /// <param name="graph">The graph that the node lies within.</param>
 /// <param name="coordinates">The coordinates of the node.</param>
 /// <param name="value">The vaue of the node.</param>
 internal Node(GridGraph <T> graph, (int X, int Y) coordinates, T value) => (this.graph, Coordinates, this.value) = (graph, coordinates, value);
Пример #27
0
        internal static void Search(GridGraph graph, GridSearch search, Vector2i start, Vector2i target)
        {
            search.Clear();
            int width  = graph.Width;
            int height = graph.Height;

            search.Parent[start.x, start.y] = start;

            var open = new List <Node>();

            open.Add(new Node(start.x, start.y));

            int g = 0;

            while (open.Count > 0)
            {
                var lowest = open.Min(n => n.f);
                var u      = open.First(n => n.f == lowest);

                open.Remove(u);
                search.IsVisited[u.x, u.y] = true;

                if (search.IsVisited[target.x, target.y])
                {
                    break;
                }

                int edge = graph.Edges[u.x, u.y];
                g++;

                for (int i = 0; i < 8; i++)
                {
                    int xi = u.x + D8.OFFSETS[i, 0];
                    int yi = u.y + D8.OFFSETS[i, 1];

                    if (xi < 0 || xi > width - 1)
                    {
                        continue;
                    }
                    if (yi < 0 || yi > height - 1)
                    {
                        continue;
                    }

                    if ((edge & 1 << i) == 0)
                    {
                        continue;
                    }
                    if (search.IsVisited[xi, yi])
                    {
                        continue;
                    }

                    int idx = Contains(xi, yi, open);
                    if (idx == -1)
                    {
                        var n = new Node(xi, yi);
                        n.g = g;
                        n.h = Distance(target.x, target.y, xi, yi);
                        n.f = n.g + n.h;

                        search.Parent[n.x, n.y] = new Vector2i(u.x, u.y);
                        open.Add(n);
                    }
                    else
                    {
                        var n = open[idx];
                        if (g + n.h < n.f)
                        {
                            n.g = g;
                            n.f = n.g + n.h;
                            search.Parent[n.x, n.y] = new Vector2i(u.x, u.y);
                            open[idx] = n;
                        }
                    }
                }
            }
        }
Пример #28
0
 private IEnumerator ScanAGrid(GridGraph grid)
 {
     isScanning = true;
     for (int x = 0; x < grid.Size.x; x++)
     {
         for (int y = 0; y < grid.Size.y; y++)
         {
             grid.ScanNode(x, y);
         }
         if (x % 25 == 0)
         {
             yield return null;
         }
     }
     grid.OnScanDone();
     isScanning = false;
 }
Пример #29
0
    //GraphUndo undoState;
    //byte[] savedBytes;

    public override void OnSceneGUI(NavGraph target)
    {
        Event e = Event.current;



        GridGraph graph = target as GridGraph;

        Matrix4x4 matrixPre = graph.matrix;

        graph.GenerateMatrix();

        if (e.type == EventType.MouseDown)
        {
            isMouseDown = true;
        }
        else if (e.type == EventType.MouseUp)
        {
            isMouseDown = false;
        }

        if (!isMouseDown)
        {
            savedMatrix = graph.boundsMatrix;
        }

        Handles.matrix = savedMatrix;

        if (graph.nodes == null || (graph.uniformWidhtDepthGrid && graph.depth * graph.width != graph.nodes.Length) || graph.matrix != matrixPre)
        {
            //Rescan the graphs
            if (AstarPath.active.AutoScan())
            {
                GUI.changed = true;
            }
        }

        Matrix4x4 inversed = savedMatrix.inverse;

        Handles.color = AstarColor.BoundsHandles;

        Handles.DrawCapFunction cap = Handles.CylinderCap;

        Vector2 extents = graph.unclampedSize * 0.5F;

        Vector3 center = inversed.MultiplyPoint3x4(graph.center);


#if UNITY_3_3
        if (Tools.current == 3)
        {
#else
        if (Tools.current == Tool.Scale)
        {
#endif

            Vector3 p1 = Handles.Slider(center + new Vector3(extents.x, 0, 0), Vector3.right, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(extents.x, 0, 0)), cap, 0);
            Vector3 p2 = Handles.Slider(center + new Vector3(0, 0, extents.y), Vector3.forward, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(0, 0, extents.y)), cap, 0);
            //Vector3 p3 = Handles.Slider (center+new Vector3 (0,extents.y,0),	Vector3.up,			0.1F*HandleUtility.GetHandleSize (center+new Vector3 (0,extents.y,0)),cap,0);

            Vector3 p4 = Handles.Slider(center + new Vector3(-extents.x, 0, 0), -Vector3.right, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(-extents.x, 0, 0)), cap, 0);
            Vector3 p5 = Handles.Slider(center + new Vector3(0, 0, -extents.y), -Vector3.forward, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(0, 0, -extents.y)), cap, 0);

            Vector3 p6 = Handles.Slider(center, Vector3.up, 0.1F * HandleUtility.GetHandleSize(center), cap, 0);

            Vector3 r1 = new Vector3(p1.x, p6.y, p2.z);
            Vector3 r2 = new Vector3(p4.x, p6.y, p5.z);

            //Debug.Log (graph.boundsMatrix.MultiplyPoint3x4 (Vector3.zero)+" "+graph.boundsMatrix.MultiplyPoint3x4 (Vector3.one));

            //if (Tools.viewTool != ViewTool.Orbit) {

            graph.center = savedMatrix.MultiplyPoint3x4((r1 + r2) / 2F);

            Vector3 tmp = r1 - r2;
            graph.unclampedSize = new Vector2(tmp.x, tmp.z);

            //}

#if UNITY_3_3
        }
        else if (Tools.current == 1)
        {
#else
        }
        else if (Tools.current == Tool.Move)
        {
#endif

            if (Tools.pivotRotation == PivotRotation.Local)
            {
                center = Handles.PositionHandle(center, Quaternion.identity);

                if (Tools.viewTool != ViewTool.Orbit)
                {
                    graph.center = savedMatrix.MultiplyPoint3x4(center);
                }
            }
            else
            {
                Handles.matrix = Matrix4x4.identity;

                center = Handles.PositionHandle(graph.center, Quaternion.identity);

                if (Tools.viewTool != ViewTool.Orbit)
                {
                    graph.center = center;
                }
            }
#if UNITY_3_3
        }
        else if (Tools.current == 2)
        {
#else
        }
        else if (Tools.current == Tool.Rotate)
        {
#endif
            //The rotation handle doesn't seem to be able to handle different matrixes of some reason
            Handles.matrix = Matrix4x4.identity;

            Quaternion rot = Handles.RotationHandle(Quaternion.Euler(graph.rotation), graph.center);

            if (Tools.viewTool != ViewTool.Orbit)
            {
                graph.rotation = rot.eulerAngles;
            }
        }

        //graph.size.x = Mathf.Max (graph.size.x,1);
        //graph.size.y = Mathf.Max (graph.size.y,1);
        //graph.size.z = Mathf.Max (graph.size.z,1);

        Handles.matrix = Matrix4x4.identity;



#if ASTARDEBUG
        //Draws some info over the node closest to the mouse
        Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

        Vector3 p = ray.GetPoint(100);


        if (Event.current.shift)
        {
            Node close = graph.GetNearest(p).node;

            if (close != null)
            {
                node1 = close;
            }

            if (node1 == null)
            {
                return;
            }

            Handles.SphereCap(0, (Vector3)node1.position, Quaternion.identity, graph.nodeSize * 0.5F);


            //Node node = node1;

            GUI.color = Color.white;
            //Handles.Label((Vector3)node.position + Vector3.up*2,"G : "+node.+"\nH : "+node.h+"\nF : "+node.f+"\nPosition : "+node.position.ToString (),EditorStyles.whiteBoldLabel);
        }
#endif
    }
Пример #30
0
 public void Awake()
 {
     instance = this;
 }
Пример #31
0
    // Use this for initialization
    void Awake()
    {
        //make sure to check for and inheret children of any pre-existing handler
        if (handler == null) {
            Debug.Log("Handler == null");
            DontDestroyOnLoad(gameObject);
            handler = this;
        } else {
            Debug.Log("Handler exists");
            InheritChildren();
            Destroy(gameObject);
        }

        if (AstarPath.active){
            path = AstarPath.active.astarData;
            graph = path.gridGraph;
        }
    }
Пример #32
0
 /// <summary>
 /// Request a path from point pathStart to point pathEnd, in a specific grid.
 /// </summary>
 /// <param name="pathStart">The starting point of the path</param>
 /// <param name="pathEnd">The ending point of the path</param>
 /// <param name="callback">A function with the parameters (Path)</param>
 /// <param name="grid">The specific grid you want to find the path on.</param>
 public static void RequestPath(Vector3 pathStart, Vector3 pathEnd, Action<Path> callback, GridGraph grid = null)
 {
     if (grid == null)
     {
         grid = Grid;
     }
     if (grid.Scanning)
     {
         return;
     }
     string Name = callback.GetHashCode().ToString();
     PathRequest newRequest = new PathRequest(pathStart, pathEnd, callback, Name, grid);
     PathRequest contains = instance.pathRequests.Contains(Name);
     if (contains != null)
     {
         instance.pathRequests.Remove(contains);
     }
     instance.pathRequests.Enqueue(newRequest);
     instance.Process();
 }
Пример #33
0
        /** Finds all contours of a collection of nodes in a grid graph.
         *
         * In the image below you can see the contour of a graph.
         * \shadowimage{grid_contour.png}
         *
         * In the image below you can see the contour of just a part of a grid graph (when the \a nodes parameter is supplied)
         * \shadowimage{grid_contour_partial.png}
         *
         * Contour of a hexagon graph
         * \shadowimage{grid_contour_hexagon.png}
         *
         * \param grid The grid to find the contours of
         * \param callback The callback will be called once for every contour that is found, the first parameter is the vertices
         *      and the second parameter indicates if that contour is a cycle or if it is just a chain (chains can only occur when you explicitly specify some nodes to search
         * \param nodes Only these nodes will be searched. If this parameter is null then all nodes in the grid graph will be searched.
         *
         *
         * \code
         * var grid = AstarPath.data.gridGraph;
         * // Find all contours in the graph and draw them using debug lines
         * FindAllContours(grid, (vertices, cycle) => {
         *     int end = cycle ? vertices.Length : vertices.Length - 1;
         *     for (int i = 0; i < end; i++) {
         *         Debug.DrawLine(vertices[i], vertices[(i+1)%vertices.Length], Color.red, 4);
         *     }
         * });
         * \endcode
         */
        static void FindAllContours(GridGraph grid, System.Action <Vector3[], bool> callback, GridNodeBase[] nodes = null)
        {
            // Use all nodes if the nodes parameter is null
            if (grid is LayerGridGraph)
            {
                nodes = nodes ?? (grid as LayerGridGraph).nodes;
            }
            nodes = nodes ?? grid.nodes;

            int[] neighbourXOffsets = grid.neighbourXOffsets;
            int[] neighbourZOffsets = grid.neighbourZOffsets;
            var   neighbourIndices  = grid.neighbours == NumNeighbours.Six ? GridGraph.hexagonNeighbourIndices : new [] { 0, 1, 2, 3 };
            var   offsetMultiplier  = grid.neighbours == NumNeighbours.Six ? 1 / 3f : 0.5f;

            if (nodes != null)
            {
                var seenVertices = new Dictionary <Int3, int>();
                // A dictionary which has all items (a,b) such that there is a contour edge going from vertex a to vertex b
                // The indices correspond to an index in the vertices list
                var outline = new Dictionary <int, int>();
                // Contains all elements x such that the outline dictionary has an item (_,x)
                // This is all vertices that has some other vertex pointing to it
                var hasInEdge = new HashSet <int>();
                var vertices  = ListPool <Vector3> .Claim();

                for (int i = 0; i < nodes.Length; i++)
                {
                    var node = nodes[i];
                    // The third check is a fast check for if the node has connections in all grid directions, if it has that we can skip processing it
                    if (node != null && node.Walkable && !node.HasConnectionsToAllEightNeighbours)
                    {
                        for (int d = 0; d < neighbourIndices.Length; d++)
                        {
                            var d1 = neighbourIndices[d];
                            // Check if there is an obstacle in that direction
                            if (node.GetNeighbourAlongDirection(d1) == null)
                            {
                                var d0 = neighbourIndices[(d - 1 + neighbourIndices.Length) % neighbourIndices.Length];
                                var d2 = neighbourIndices[(d + 1) % neighbourIndices.Length];

                                // Position in graph space of the vertex
                                Vector3 graphSpacePos = new Vector3(node.XCoordinateInGrid + 0.5f, 0, node.ZCoordinateInGrid + 0.5f);
                                graphSpacePos.x += neighbourXOffsets[d1] * offsetMultiplier;
                                graphSpacePos.z += neighbourZOffsets[d1] * offsetMultiplier;
                                graphSpacePos.y  = grid.transform.InverseTransform((Vector3)node.position).y;

                                // Offset along diagonal to get the correct XZ coordinates
                                Vector3 corner1, corner2;
                                corner1    = corner2 = graphSpacePos;
                                corner1.x += neighbourXOffsets[d0] * offsetMultiplier;
                                corner1.z += neighbourZOffsets[d0] * offsetMultiplier;
                                corner2.x += neighbourXOffsets[d2] * offsetMultiplier;
                                corner2.z += neighbourZOffsets[d2] * offsetMultiplier;

                                // Quantize vertices so that we can check for duplicates easier
                                Int3 c1 = (Int3)corner1;
                                Int3 c2 = (Int3)corner2;

                                int i1, i2;
                                if (seenVertices.TryGetValue(c1, out i1))
                                {
                                    // We only keep a vertex in the seenVertices dictionary until it has been used twice
                                    // This prevents more than 2 edges from enter or leaving a single vertex which would confuse
                                    // the algorithm that is used for following the contour.
                                    //
                                    // This can happen when in situations like this
                                    //   ____
                                    //  |    |
                                    //  |____|____
                                    //       |    |
                                    //       |____|
                                    //
                                    // I.e when a corner is shared by multiple contours
                                    // With this fix we will just duplicate those vertices when they are encountered
                                    seenVertices.Remove(c1);
                                }
                                else
                                {
                                    i1 = seenVertices[c1] = vertices.Count;
                                    vertices.Add(corner1);
                                }

                                if (seenVertices.TryGetValue(c2, out i2))
                                {
                                    seenVertices.Remove(c2);
                                }
                                else
                                {
                                    i2 = seenVertices[c2] = vertices.Count;
                                    vertices.Add(corner2);
                                }

                                outline.Add(i1, i2);
                                hasInEdge.Add(i2);
                            }
                        }
                    }
                }

                // Follow the pointers that we constructed above to trace out the contours
                var transform    = grid.transform;
                var vertexBuffer = ListPool <Vector3> .Claim();

                CompressContour(outline, hasInEdge, (chain, cycle) => {
                    vertexBuffer.Clear();
                    var v0 = vertices[chain[0]];
                    vertexBuffer.Add(v0);

                    // Add all other points in the chain but compress lines to just 2 points
                    for (int i = 1; i < chain.Count - 1; i++)
                    {
                        var v1  = vertices[chain[i]];
                        var v1d = v1 - v0;
                        var v2d = vertices[chain[i + 1]] - v0;
                        // Skip points if they are colinear with the point just before it and just after it, because that point wouldn't add much information, but it would add CPU overhead
                        if (((Mathf.Abs(v1d.x) > 0.01f || Mathf.Abs(v2d.x) > 0.01f) && (Mathf.Abs(v1d.z) > 0.01f || Mathf.Abs(v2d.z) > 0.01f)) || (Mathf.Abs(v1d.y) > 0.01f || Mathf.Abs(v2d.y) > 0.01f))
                        {
                            vertexBuffer.Add(v1);
                        }
                        v0 = v1;
                    }
                    vertexBuffer.Add(vertices[chain[chain.Count - 1]]);
                    var result = vertexBuffer.ToArray();
                    // Convert to world space
                    transform.Transform(result);
                    callback(result, cycle);
                });

                ListPool <Vector3> .Release(vertexBuffer);

                ListPool <Vector3> .Release(vertices);
            }
        }
Пример #34
0
 /// <summary>
 /// Scan a specific grid in the grid array.
 /// </summary>
 /// <param name="grid">The grid that is going to be scanned.</param>
 public static void ScanGrid(GridGraph grid = null)
 {
     if (instance == null)
     {
         Debug.Log("A GridManager wasn't found in the scene!");
         return;
     }
     if (grid == null)
     {
         grid = Grid;
     }
     instance.StartCoroutine(instance.ScanA(grid));
 }
Пример #35
0
    //GraphUndo undoState;
    //byte[] savedBytes;

    public override void OnSceneGUI(NavGraph target)
    {
        Event e = Event.current;



        GridGraph graph = target as GridGraph;

        Matrix4x4 matrixPre = graph.matrix;

        graph.GenerateMatrix();

        if (e.type == EventType.MouseDown)
        {
            isMouseDown = true;
        }
        else if (e.type == EventType.MouseUp)
        {
            isMouseDown = false;
        }

        if (!isMouseDown)
        {
            savedMatrix = graph.boundsMatrix;
        }

        Handles.matrix = savedMatrix;

        if (graph.nodes == null || (graph.uniformWidhtDepthGrid && graph.depth * graph.width != graph.nodes.Length) || graph.matrix != matrixPre)
        {
            //Rescann the graphs
            AstarPath.active.AutoScan();
            GUI.changed = true;
        }

        Matrix4x4 inversed = savedMatrix.inverse;

        Handles.color = AstarColor.BoundsHandles;

        Handles.DrawCapFunction cap = Handles.CylinderCap;

        Vector2 extents = graph.unclampedSize * 0.5F;

        //Tools.current is an undocumented editor variable, remove the UseUndocumentedEditorFeatures define at the top of the script to make sure it's forward compatible

        /*if (undoState == null) {
         *      undoState = ScriptableObject.CreateInstance<GraphUndo>();
         * }
         *
         * if (undoState.hasBeenReverted) {
         *      undoState.ApplyUndo (graph);
         *      GUI.changed = true;
         * }*/

        /*if (Event.current.button == 0 && Event.current.isMouse && (/*Event.current.type == EventType.MouseUp || /Event.current.type == EventType.MouseDown)) {
         *      AstarSerializer sz = new AstarSerializer ();
         *      sz.OpenSerializeSettings ();
         *      sz.SerializeSettings (graph,AstarPath.active);
         *      byte[] bytes = (sz.writerStream.BaseStream as System.IO.MemoryStream).ToArray ();
         *      sz.Close ();
         *
         *      undoState.data = bytes;
         *      undoState.hasBeenReverted = true;
         *
         *      Undo.RegisterUndo (undoState,"Graph stuff");
         *      undoState.hasBeenReverted = false;
         *
         * }*/

        //Undo.SetSnapshotTarget (AstarPath.active.astarData,"Change graph");

        Vector3 center = inversed.MultiplyPoint3x4(graph.center);         //Vector3.zero;//inversed.MultiplyPoint3x4 (graph.center);//graph.center;


#if UNITY_3_3
        if (Tools.current == 3)
        {
#else
        if (Tools.current == Tool.Scale)
        {
#endif

            Vector3 p1 = Handles.Slider(center + new Vector3(extents.x, 0, 0), Vector3.right, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(extents.x, 0, 0)), cap, 0);
            Vector3 p2 = Handles.Slider(center + new Vector3(0, 0, extents.y), Vector3.forward, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(0, 0, extents.y)), cap, 0);
            //Vector3 p3 = Handles.Slider (center+new Vector3 (0,extents.y,0),	Vector3.up,			0.1F*HandleUtility.GetHandleSize (center+new Vector3 (0,extents.y,0)),cap,0);

            Vector3 p4 = Handles.Slider(center + new Vector3(-extents.x, 0, 0), -Vector3.right, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(-extents.x, 0, 0)), cap, 0);
            Vector3 p5 = Handles.Slider(center + new Vector3(0, 0, -extents.y), -Vector3.forward, 0.1F * HandleUtility.GetHandleSize(center + new Vector3(0, 0, -extents.y)), cap, 0);

            Vector3 p6 = Handles.Slider(center, Vector3.up, 0.1F * HandleUtility.GetHandleSize(center), cap, 0);

            Vector3 r1 = new Vector3(p1.x, p6.y, p2.z);
            Vector3 r2 = new Vector3(p4.x, p6.y, p5.z);

            //Vector3 min = Vector3.Min (r1,r2);
            //Vector3 max = Vector3.Max (r1,r2);

            /*b.Encapsulate (p1);
            *  b.Encapsulate (p2);
            *  b.Encapsulate (p3);
            *  b.Encapsulate (p4);
            *  b.Encapsulate (p5);
            *  b.Encapsulate (p6);*/

            //Debug.Log (graph.boundsMatrix.MultiplyPoint3x4 (Vector3.zero)+" "+graph.boundsMatrix.MultiplyPoint3x4 (Vector3.one));

            //if (Tools.viewTool != ViewTool.Orbit) {

            graph.center = savedMatrix.MultiplyPoint3x4((r1 + r2) / 2F);

            Vector3 tmp = r1 - r2;
            graph.unclampedSize = new Vector2(tmp.x, tmp.z);

            //}

#if UNITY_3_3
        }
        else if (Tools.current == 1)
        {
#else
        }
        else if (Tools.current == Tool.Move)
        {
#endif

            if (Tools.pivotRotation == PivotRotation.Local)
            {
                center = Handles.PositionHandle(center, Quaternion.identity);

                if (Tools.viewTool != ViewTool.Orbit)
                {
                    graph.center = savedMatrix.MultiplyPoint3x4(center);
                }
            }
            else
            {
                Handles.matrix = Matrix4x4.identity;

                center = Handles.PositionHandle(graph.center, Quaternion.identity);

                if (Tools.viewTool != ViewTool.Orbit)
                {
                    graph.center = center;
                }
            }
#if UNITY_3_3
        }
        else if (Tools.current == 2)
        {
#else
        }
        else if (Tools.current == Tool.Rotate)
        {
#endif
            //The rotation handle doesn't seem to be able to handle different matrixes of some reason
            Handles.matrix = Matrix4x4.identity;

            Quaternion rot = Handles.RotationHandle(Quaternion.Euler(graph.rotation), graph.center);

            if (Tools.viewTool != ViewTool.Orbit)
            {
                graph.rotation = rot.eulerAngles;
            }
        }

        //graph.size.x = Mathf.Max (graph.size.x,1);
        //graph.size.y = Mathf.Max (graph.size.y,1);
        //graph.size.z = Mathf.Max (graph.size.z,1);

        Handles.matrix = Matrix4x4.identity;



        Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);

        Vector3 p = ray.GetPoint(100);


        if (Event.current.shift)
        {
            Node close = graph.GetNearest(p);

            if (close != null)
            {
                node1 = close;
            }
        }


        if (node1 == null)
        {
            return;
        }

        Handles.SphereCap(0, node1.position, Quaternion.identity, graph.nodeSize);


        Node node = node1;

        GUI.color = Color.white;
        Handles.Label((Vector3)node.position + Vector3.up * 2, "G : " + node.g + "\nH : " + node.h + "\nF : " + node.f + "\nPosition : " + node.position.ToString(), EditorStyles.whiteBoldLabel);
    }
Пример #36
0
    /// <summary>
    /// Find the quickest path from point 1 to point 2
    /// </summary>
    /// <param name="startPos">The start-position of the path</param>
    /// <param name="targetPos">The target-position for the path</param>
    /// <param name="grid">The grid that it should perform the search on.</param>
    /// <returns></returns>
    private IEnumerator FindThePath(Vector3 startPos, Vector3 targetPos, GridGraph grid)
    {
        if (grid.nodes == null || grid.nodes.Length == 0)
        {
            ScanGrid(grid);
        }
        if (grid.Scanning)
        {
            yield break;
        }

        float max = 300; //Maximum number of nodes, before canceling the path.

        Path p = new Path(grid);
        bool pathSuccess = false;

        Node startNode = grid.NodeFromWorldPos(startPos);
        Node targetNode = grid.NodeFromWorldPos(targetPos);

        if (startNode == null || targetNode == null)
        {
            OnProccesingDone(p, false);
            yield break;
        }

        if (startNode.Walkable && targetNode.Walkable)
        {
            List<Node> open = new List<Node>(grid.maxSize);
            HashSet<Node> closed = new HashSet<Node>();
            open.Add(startNode);
            int cur = 0;

            while (open.Count > 0)
            {
                Node currentNode = open[0];
                open.RemoveAt(0);
                closed.Add(currentNode);
                cur++;

                if (currentNode == targetNode)
                {
                    pathSuccess = true;
                    break;
                }

                foreach (Node neighbour in grid.GetNeighbours(currentNode))
                {
                    if (neighbour == null || !neighbour.Walkable || closed.Contains(neighbour))
                    {
                        continue;
                    }

                    int newMovementCostToNeighbour = currentNode.gCost + grid.GetDistance(currentNode, neighbour);
                    if (newMovementCostToNeighbour < neighbour.gCost || !open.Contains(neighbour))
                    {
                        neighbour.gCost = newMovementCostToNeighbour;
                        neighbour.hCost = grid.GetDistance(neighbour, targetNode);
                        neighbour.parent = currentNode;

                        if (!open.Contains(neighbour))
                            open.Add(neighbour);
                    }
                }
                if (cur > max)
                {
                    break;
                }
            }
        }
        if (pathSuccess)
        {
            p = grid.RetracePath(startNode, targetNode, grid);
        }
        OnProccesingDone(p, pathSuccess);
    }
Пример #37
0
    //Create the grid squares
    void Update()
    {
        if(mReaderObject == null)
        {
            mReaderObject = GameObject.Find("A*").GetComponent<MissionReader>();
        }
        if(AstarPath.active.graphs[0] != null && (graphObject == null || graphObject != AstarPath.active.graphs[0] as GridGraph))
        {
            graphObject = AstarPath.active.graphs[0] as GridGraph;
        }
        if(mReaderObject.returnLayoutCompleted() == true)
        {
            if(gridParent == null)
            {
                gridParent = GameObject.Instantiate(Resources.Load("GridParent")) as GameObject;
            }
            if(depthCounter==graphObject.depth){
                createGrid = false;
                }
            if(createGrid){
                gridParent.transform.position = astarGrid.GetComponent<AstarPath>().astarData.gridGraph.center;
                for(int i = 0; i < graphObject.width; i++)
                {

                    instantiatedCollider = Instantiate(theCollider) as GameObject;
                    createdCount++;

                    if(atStart)
                    {
                        positionValues.y = astarGrid.transform.position.y+0.25f;
                        positionValues.x = astarGrid.transform.position.x + graphObject.nodeSize/2 - graphObject.unclampedSize.x/2;
                        positionValues.z = astarGrid.transform.position.z - graphObject.nodeSize/2 + graphObject.unclampedSize.y/2;
                        atStart = false;
                    }
                    else if(!atStart && !reset)
                    {
                        if(positionValues.x+graphObject.nodeSize >= astarGrid.transform.position.x + graphObject.unclampedSize.x/2)
                        {
                            depthCounter++;
                            positionValues.z -= graphObject.nodeSize;
                            positionValues.x = astarGrid.transform.position.x + graphObject.nodeSize/2 - graphObject.unclampedSize.x/2;
                        }
                        else
                        {
                            positionValues.x += graphObject.nodeSize;
                        }
                    }
                 	instantiatedCollider.transform.position = positionValues;
                    instantiatedCollider.name = instantiatedCollider.name + createdCount.ToString();
                    instantiatedCollider.GetComponent<Grid>().setXY(i+1,depthCounter);
                    instantiatedCollider.transform.parent = gridParent.transform;
                    gridColliders.Add(instantiatedCollider);
                }

                //This is mostly debug, we will be doing this with the mission creator later
            } else if(!missionInit){
                if(astarGrid.GetComponent<MissionReader>().rotate == true){
                    gridParent.transform.rotation = Quaternion.Euler(astarGrid.GetComponent<AstarPath>().astarData.gridGraph.rotation);

                }
                missionInit = true;
                if(mReaderObject.currentMission == 2){
                    mReaderObject.optionalTiles.Add(GameObject.Find("GridSquare(Clone)4"));
                    mReaderObject.optionalTiles.Add(GameObject.Find("GridSquare(Clone)5"));
                    mReaderObject.optionalTiles.Add(GameObject.Find("GridSquare(Clone)6"));
                }
                mReaderObject.PositionUnits();
            }
        }
            if(mReaderObject.returnNewMission() == true && gridColliders.Count > 0)
            {
                gridParent.transform.rotation = Quaternion.identity;
                int gridSquareCounter = 0;
                foreach(GameObject gridSquare in gridColliders)
                {
                    DestroyObject(gridColliders[gridSquareCounter]);
                    gridSquareCounter++;
                }
                graphObject = null;
                depthCounter = 1;
                atStart = true;
                createGrid = true;
                createdCount = 0;
                missionInit = false;
                gridColliders.Clear();

            }
        //		if(mReaderObject.returnLayoutCompleted() == false){
        //			if(graphObject == null)
        //			{
        //				graphObject = AstarPath.active.graphs[0] as GridGraph;
        //			}
        //		}
    }
Пример #38
0
    private IEnumerator ScanA(GridGraph grid)
    {
        grid.Scanning = true;
        Vector3 Size = grid.Size;
        if (grid.gridType == GridGraph.GridType.Plane)
        {
            for (int x = 0; x < Size.x; x++)
            {
                for (int y = 0; y < Size.y; y++)
                {
                    grid.ScanNode(x, y);
                }
                if (x % 25 == 0)
                {
                    yield return null;
                }
            }
        }
        else if (grid.gridType == GridGraph.GridType.Sphere)
        {
            //-Z
            for (int y = 0; y <= Size.x; y++)
            {
                for (int x = 0; x <= Size.x; x++)
                {
                    grid.ScanNode(x, y, 0, 0);
                }

                //+X
                for (int z = 0; z <= Size.x; z++)
                {
                    grid.ScanNode(Mathf.RoundToInt(Size.x), y, z, 1);
                }

                //+Z
                for (int x = Mathf.RoundToInt(Size.x); x >= 0; x--)
                {
                    grid.ScanNode(x, y, Mathf.RoundToInt(Size.x), 2);
                }

                //-X
                for (int z = Mathf.RoundToInt(Size.x); z >= 0; z--)
                {
                    grid.ScanNode(0, y, z, 3);
                }
            }
            //+Y
            for (int z = 0; z <= Size.x; z++)
            {
                for (int x = 0; x <= Size.x; x++)
                {
                    grid.ScanNode(x, Mathf.RoundToInt(Size.x), z, 4);
                }
            }
            //-Y
            for (int z = 0; z <= Size.x; z++)
            {
                for (int x = 0; x <= Size.x; x++)
                {
                    grid.ScanNode(x, 0, z, 5);
                }
            }
        }
        grid.OnScanDone();
        pathRequests = new queue();
        currentPathRequest = null;
        grid.Scanning = false;
    }
Пример #39
0
    /** Get the path back */
    public void OnPathComplete(Path p)
    {
        //To prevent it from creating new GameObjects when the application is quitting when using multithreading.
        if (lastRender == null)
        {
            return;
        }

        if (p.error)
        {
            ClearPrevious();
            return;
        }


        if (p.GetType() == typeof(MultiTargetPath))
        {
            List <GameObject> unused = new List <GameObject> (lastRender);
            lastRender.Clear();

            MultiTargetPath mp = p as MultiTargetPath;

            for (int i = 0; i < mp.vectorPaths.Length; i++)
            {
                if (mp.vectorPaths[i] == null)
                {
                    continue;
                }

                List <Vector3> vpath = mp.vectorPaths[i];

                GameObject ob = null;
                if (unused.Count > i && unused[i].GetComponent <LineRenderer>() != null)
                {
                    ob = unused[i];
                    unused.RemoveAt(i);
                }
                else
                {
                    ob = new GameObject("LineRenderer_" + i, typeof(LineRenderer));
                }

                LineRenderer lr = ob.GetComponent <LineRenderer>();
                lr.sharedMaterial = lineMat;
                lr.SetWidth(lineWidth, lineWidth);

                lr.SetVertexCount(vpath.Count);
                for (int j = 0; j < vpath.Count; j++)
                {
                    lr.SetPosition(j, vpath[j] + pathOffset);
                }

                lastRender.Add(ob);
            }

            for (int i = 0; i < unused.Count; i++)
            {
                Destroy(unused[i]);
            }
        }
        else if (p.GetType() == typeof(ConstantPath))
        {
            ClearPrevious();
            //The following code will build a mesh with a square for each node visited

            ConstantPath     constPath = p as ConstantPath;
            List <GraphNode> nodes     = constPath.allNodes;

            Mesh mesh = new Mesh();

            List <Vector3> verts = new List <Vector3>();

            bool drawRaysInstead = false;

            // Just some debugging code which selects random points on the nodes

            /*List<Vector3> pts = Pathfinding.PathUtilities.GetPointsOnNodes (nodes, 20, 0);
             * Vector3 avg = Vector3.zero;
             * for (int i=0;i<pts.Count;i++) {
             *      Debug.DrawRay (pts[i], Vector3.up*5, Color.red, 3);
             *      avg += pts[i];
             * }
             *
             * if (pts.Count > 0) avg /= pts.Count;
             *
             * for (int i=0;i<pts.Count;i++) {
             *      pts[i] -= avg;
             * }
             *
             * Pathfinding.PathUtilities.GetPointsAroundPoint (start.position, AstarPath.active.astarData.graphs[0] as IRaycastableGraph, pts, 0, 1);
             *
             * for (int i=0;i<pts.Count;i++) {
             *      Debug.DrawRay (pts[i], Vector3.up*5, Color.blue, 3);
             * }*/

            //This will loop through the nodes from furthest away to nearest, not really necessary... but why not :D
            //Note that the reverse does not, as common sense would suggest, loop through from the closest to the furthest away
            //since is might contain duplicates and only the node duplicate placed at the highest index is guarenteed to be ordered correctly.
            for (int i = nodes.Count - 1; i >= 0; i--)
            {
                Vector3 pos = (Vector3)nodes[i].position + pathOffset;
                if (verts.Count == 65000 && !drawRaysInstead)
                {
                    Debug.LogError("Too many nodes, rendering a mesh would throw 65K vertex error. Using Debug.DrawRay instead for the rest of the nodes");
                    drawRaysInstead = true;
                }

                if (drawRaysInstead)
                {
                    Debug.DrawRay(pos, Vector3.up, Color.blue);
                    continue;
                }

                //Add vertices in a square

                GridGraph gg    = AstarData.GetGraph(nodes[i]) as GridGraph;
                float     scale = 1F;

                if (gg != null)
                {
                    scale = gg.nodeSize;
                }

                verts.Add(pos + new Vector3(-0.5F, 0, -0.5F) * scale);
                verts.Add(pos + new Vector3(0.5F, 0, -0.5F) * scale);
                verts.Add(pos + new Vector3(-0.5F, 0, 0.5F) * scale);
                verts.Add(pos + new Vector3(0.5F, 0, 0.5F) * scale);
            }

            //Build triangles for the squares
            Vector3[] vs   = verts.ToArray();
            int[]     tris = new int[(3 * vs.Length) / 2];
            for (int i = 0, j = 0; i < vs.Length; j += 6, i += 4)
            {
                tris[j + 0] = i;
                tris[j + 1] = i + 1;
                tris[j + 2] = i + 2;

                tris[j + 3] = i + 1;
                tris[j + 4] = i + 3;
                tris[j + 5] = i + 2;
            }

            Vector2[] uv = new Vector2[vs.Length];
            //Set up some basic UV
            for (int i = 0; i < uv.Length; i += 4)
            {
                uv[i]     = new Vector2(0, 0);
                uv[i + 1] = new Vector2(1, 0);
                uv[i + 2] = new Vector2(0, 1);
                uv[i + 3] = new Vector2(1, 1);
            }

            mesh.vertices  = vs;
            mesh.triangles = tris;
            mesh.uv        = uv;
            mesh.RecalculateNormals();

            GameObject go = new GameObject("Mesh", typeof(MeshRenderer), typeof(MeshFilter));
            MeshFilter fi = go.GetComponent <MeshFilter>();
            fi.mesh = mesh;
            MeshRenderer re = go.GetComponent <MeshRenderer>();
            re.material = squareMat;

            lastRender.Add(go);
        }
        else
        {
            ClearPrevious();

            GameObject   ob = new GameObject("LineRenderer", typeof(LineRenderer));
            LineRenderer lr = ob.GetComponent <LineRenderer>();
            lr.sharedMaterial = lineMat;
            lr.SetWidth(lineWidth, lineWidth);

            lr.SetVertexCount(p.vectorPath.Count);
            for (int i = 0; i < p.vectorPath.Count; i++)
            {
                lr.SetPosition(i, p.vectorPath[i] + pathOffset);
            }

            lastRender.Add(ob);
        }
    }
Пример #40
0
 public Map()
 {
     Graph = new GridGraph <MapRoom, MapPath>();
 }
 public void Awake()
 {
     instance = this;
 }
Пример #42
0
 public GridGraphPathFinder(GridGraph gridGraph)
 {
     this.gridGraph = gridGraph;
 }
 public void Construct(GridGraph gridGraph)
 {
     this.gridGraph = gridGraph;
 }
Пример #44
0
 public AStar(GridGraph g)
 {
     this.Graph = g;
 }
Пример #45
0
        public IEnumerator DemoConstantPath()
        {
            ConstantPath constPath = ConstantPath.Construct(end.position, searchLength, null);

            AstarPath.StartPath(constPath);
            lastPath = constPath;
            // Wait for the path to be calculated
            yield return(StartCoroutine(constPath.WaitForPath()));

            ClearPrevious();

            // The following code will build a mesh with a square for each node visited
            List <GraphNode> nodes = constPath.allNodes;

            Mesh mesh = new Mesh();

            List <Vector3> verts = new List <Vector3>();



            bool drawRaysInstead = false;

            // This will loop through the nodes from furthest away to nearest, not really necessary... but why not :D
            for (int i = nodes.Count - 1; i >= 0; i--)
            {
                Vector3 pos = (Vector3)nodes[i].position + pathOffset;
                if (verts.Count == 65000 && !drawRaysInstead)
                {
                    Debug.LogError("Too many nodes, rendering a mesh would throw 65K vertex error. Using Debug.DrawRay instead for the rest of the nodes");
                    drawRaysInstead = true;
                }

                if (drawRaysInstead)
                {
                    Debug.DrawRay(pos, Vector3.up, Color.blue);
                    continue;
                }

                // Add vertices in a square

                GridGraph gg    = AstarData.GetGraph(nodes[i]) as GridGraph;
                float     scale = 1F;

                if (gg != null)
                {
                    scale = gg.nodeSize;
                }

                verts.Add(pos + new Vector3(-0.5F, 0, -0.5F) * scale);
                verts.Add(pos + new Vector3(0.5F, 0, -0.5F) * scale);
                verts.Add(pos + new Vector3(-0.5F, 0, 0.5F) * scale);
                verts.Add(pos + new Vector3(0.5F, 0, 0.5F) * scale);
            }

            // Build triangles for the squares
            Vector3[] vs   = verts.ToArray();
            int[]     tris = new int[(3 * vs.Length) / 2];
            for (int i = 0, j = 0; i < vs.Length; j += 6, i += 4)
            {
                tris[j + 0] = i;
                tris[j + 1] = i + 1;
                tris[j + 2] = i + 2;

                tris[j + 3] = i + 1;
                tris[j + 4] = i + 3;
                tris[j + 5] = i + 2;
            }

            Vector2[] uv = new Vector2[vs.Length];
            // Set up some basic UV
            for (int i = 0; i < uv.Length; i += 4)
            {
                uv[i]     = new Vector2(0, 0);
                uv[i + 1] = new Vector2(1, 0);
                uv[i + 2] = new Vector2(0, 1);
                uv[i + 3] = new Vector2(1, 1);
            }

            mesh.vertices  = vs;
            mesh.triangles = tris;
            mesh.uv        = uv;
            mesh.RecalculateNormals();

            GameObject go = new GameObject("Mesh", typeof(MeshRenderer), typeof(MeshFilter));
            MeshFilter fi = go.GetComponent <MeshFilter>();

            fi.mesh = mesh;
            MeshRenderer re = go.GetComponent <MeshRenderer>();

            re.material = squareMat;

            lastRender.Add(go);
        }
    public void GraphMap()
    {
        hexGraph = ResizeMD (hexGraph, height, width);
        //Debug.Log ("Lengths: " + hexGraph.GetLength (0) + ", " + hexGraph.GetLength (1));

        if (graph == null) {
            graph = GameControlScript.control.graph;
        }
        graph.width = width * 2;
        graph.depth = Convert.ToInt32 ((height * 2) * 0.87);
        graph.center = new Vector3((graph.width / 2) * graph.nodeSize, 0, (graph.depth / 2) * graph.nodeSize);

        graph.UpdateSizeFromWidthDepth();

        int columns = width;
        int col = 0;
        int c = 0;
        int rows = height;
        int row = 0;
        int r = 0;

        for (int a = 0; a < ((columns * rows)); a++) {
            //int c = col;
            //int r = row;

            if(hexGraph[r, c] == null){
                CreateHex (r, c, painterIndex);
            }

            if (r == 0 || c == columns - 1){
                if (row < rows - 1){
                    //Debug.Log ("row++");
                    row++;
                    r = row;
                    c = col;
                }
                else if (col < columns - 1){
                    //Debug.Log ("col++");
                    col++;
                    r = row;
                    c = col;
                }
            }
            else if (r > 0 && c < columns){
                //Debug.Log ("r- c+");
                r--;
                c++;
            }
        }

        if (width > 9 || height > 9) {
            //GameObject.Find ("Main Camera").GetComponent<Camera>().
        }
        AstarPath.active.Scan ();
    }
Пример #47
0
    /** Draws settings for using a texture as source for a grid.
     * \astarpro */
    public void DrawTextureData(GridGraph.TextureData data, GridGraph graph)
    {
        if (data == null)
        {
            return;
        }

        data.enabled = ToggleGroup("Use Texture", data.enabled);
        //EditorGUILayout.Toggle ("Use Texture",data.enabled);
        //data.enabled = ToggleGroup ("Use Texture",data.enabled);
        if (!data.enabled)
        {
            return;
        }

        bool preGUI = GUI.enabled;

        GUI.enabled = data.enabled && GUI.enabled;

        EditorGUI.indentLevel++;
        //data.source = EditorGUILayout.ObjectField ("Source",data.source,typeof(Texture2D),false) as Texture2D;
        data.source = ObjectField("Source", data.source, typeof(Texture2D), false) as Texture2D;

        if (data.source != null)
        {
            string path = AssetDatabase.GetAssetPath(data.source);

            if (path != "")
            {
                TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
                if (!importer.isReadable)
                {
                    if (FixLabel("Texture is not readable"))
                    {
                        importer.isReadable = true;
                        EditorUtility.SetDirty(importer);
                        AssetDatabase.ImportAsset(path);
                    }
                }
            }
        }

        for (int i = 0; i < 3; i++)
        {
            string channelName = i == 0 ? "R" : (i == 1 ? "G" : "B");
            data.channels[i] = (GridGraph.TextureData.ChannelUse)EditorGUILayout.Popup(channelName, (int)data.channels[i], ChannelUseNames);

            if (data.channels[i] != GridGraph.TextureData.ChannelUse.None)
            {
                EditorGUI.indentLevel++;
                data.factors[i] = EditorGUILayout.FloatField("Factor", data.factors[i]);

                string help = "";
                switch (data.channels[i])
                {
                case GridGraph.TextureData.ChannelUse.Penalty:
                    help = "Nodes are applied penalty according to channel '" + channelName + "', multiplied with factor";
                    break;

                case GridGraph.TextureData.ChannelUse.Position:
                    help = "Nodes Y position is changed according to channel '" + channelName + "', multiplied with factor";

                    if (graph.collision.heightCheck)
                    {
                        HelpBox("Getting position both from raycast and from texture. You should disable one of them");
                    }
                    break;

                case GridGraph.TextureData.ChannelUse.WalkablePenalty:
                    help = "If channel '" + channelName + "' is 0, the node is made unwalkable. Otherwise the node is applied penalty multiplied with factor";
                    break;
                }

                HelpBox(help);

                EditorGUI.indentLevel--;
            }
        }

        if (GUILayout.Button("Generate Reference"))
        {
            SaveReferenceTexture(graph);
        }

        GUI.enabled = preGUI;
        EditorGUI.indentLevel--;
    }
Пример #48
0
	public void SaveReferenceTexture (GridGraph graph) {
		//GridGraph graph = target as GridGraph;
		
		if (graph.nodes == null || graph.nodes.Length != graph.width * graph.depth) {
			AstarPath.active.Scan ();
		}
		
		if (graph.nodes.Length != graph.width * graph.depth) {
			Debug.LogError ("Couldn't create reference image since width*depth != nodes.Length");
			return;
		}
		
		if (graph.nodes.Length == 0) {
			Debug.LogError ("Couldn't create reference image since the graph is too small (0*0)");
			return;
		}
		
		Texture2D tex = new Texture2D (graph.width,graph.depth);
		
		float maxY = float.NegativeInfinity;
		for (int i=0;i<graph.nodes.Length;i++) {
			Vector3 p = graph.inverseMatrix.MultiplyPoint ((Vector3)graph.nodes[i].position);
			maxY = p.y > maxY ? p.y : maxY;
		}
		
		Color[] cols = new Color[graph.width*graph.depth];
		
		for (int z=0;z<graph.depth;z++) {
			for (int x=0;x<graph.width;x++) {
				Node node = graph.nodes[z*graph.width+x];
				float v = node.walkable ? 1F : 0.0F;
				Vector3 p = graph.inverseMatrix.MultiplyPoint ((Vector3)node.position);
				float q = p.y / maxY;
				cols[z*graph.width+x] = new Color (v,q,0);
			}
		}
		tex.SetPixels (cols);
		tex.Apply ();
		
		string path = AssetDatabase.GenerateUniqueAssetPath ("Assets/gridReference.png");
		
		using (System.IO.StreamWriter outstream = new System.IO.StreamWriter (path)) {
			using (System.IO.BinaryWriter outfile = new System.IO.BinaryWriter (outstream.BaseStream)) {
				outfile.Write (tex.EncodeToPNG ());
			}
		}
		AssetDatabase.Refresh ();
		Object obj = AssetDatabase.LoadAssetAtPath (path,typeof (Texture));
		
		EditorGUIUtility.PingObject (obj);
	}
Пример #49
0
    public override void OnInspectorGUI(NavGraph target)
    {
        GridGraph graph = target as GridGraph;

        //GUILayout.BeginHorizontal ();
        //GUILayout.BeginVertical ();
        Rect lockRect;
        Rect tmpLockRect;

        GUIStyle lockStyle = AstarPathEditor.astarSkin.FindStyle("GridSizeLock");

        if (lockStyle == null)
        {
            lockStyle = new GUIStyle();
        }

        bool sizeSelected1 = false;
        bool sizeSelected2 = false;

#if UNITY_4
        int newWidth = IntField(new GUIContent("Width (nodes)", "Width of the graph in nodes"), graph.width, 100, 0, out lockRect, out sizeSelected1);
        int newDepth = IntField(new GUIContent("Depth (nodes)", "Depth (or height you might also call it) of the graph in nodes"), graph.depth, 100, 0, out tmpLockRect, out sizeSelected2);
#else
        int newWidth = IntField(new GUIContent("Width (nodes)", "Width of the graph in nodes"), graph.width, 50, 0, out lockRect, out sizeSelected1);
        int newDepth = IntField(new GUIContent("Depth (nodes)", "Depth (or height you might also call it) of the graph in nodes"), graph.depth, 50, 0, out tmpLockRect, out sizeSelected2);
#endif

        //Rect r = GUILayoutUtility.GetRect (0,0,lockStyle);

        lockRect.width  = lockStyle.fixedWidth;
        lockRect.height = lockStyle.fixedHeight;
        lockRect.x     += lockStyle.margin.left;
        lockRect.y     += lockStyle.margin.top;

        locked = GUI.Toggle(lockRect, locked, new GUIContent("", "If the width and depth values are locked, changing the node size will scale the grid which keeping the number of nodes consistent instead of keeping the size the same and changing the number of nodes in the graph"), lockStyle);

        //GUILayout.EndHorizontal ();

        if (newWidth != graph.width || newDepth != graph.depth)
        {
            SnapSizeToNodes(newWidth, newDepth, graph);
        }

        GUI.SetNextControlName("NodeSize");
        newNodeSize = EditorGUILayout.FloatField(new GUIContent("Node size", "The size of a single node. The size is the side of the node square in world units"), graph.nodeSize);

        newNodeSize = newNodeSize <= 0.01F ? 0.01F : newNodeSize;

        float prevRatio = graph.aspectRatio;
        graph.aspectRatio = EditorGUILayout.FloatField(new GUIContent("Aspect Ratio", "Scaling of the nodes width/depth ratio. Good for isometric games"), graph.aspectRatio);


        //if ((GUI.GetNameOfFocusedControl () != "NodeSize" && Event.current.type == EventType.Repaint) || Event.current.keyCode == KeyCode.Return) {

        //Debug.Log ("Node Size Not Selected " + Event.current.type);

        if (graph.nodeSize != newNodeSize || prevRatio != graph.aspectRatio)
        {
            if (!locked)
            {
                graph.nodeSize = newNodeSize;
                Matrix4x4 oldMatrix = graph.matrix;
                graph.GenerateMatrix();
                if (graph.matrix != oldMatrix)
                {
                    //Rescann the graphs
                    //AstarPath.active.AutoScan ();
                    GUI.changed = true;
                }
            }
            else
            {
                float delta = newNodeSize / graph.nodeSize;
                graph.nodeSize      = newNodeSize;
                graph.unclampedSize = new Vector2(newWidth * graph.nodeSize, newDepth * graph.nodeSize);
                Vector3 newCenter = graph.matrix.MultiplyPoint3x4(new Vector3((newWidth / 2F) * delta, 0, (newDepth / 2F) * delta));
                graph.center = newCenter;
                graph.GenerateMatrix();

                //Make sure the width & depths stay the same
                graph.width = newWidth;
                graph.depth = newDepth;
                AstarPath.active.AutoScan();
            }
        }
        //}

        Vector3 pivotPoint;
        Vector3 diff;

        EditorGUIUtility.LookLikeControls();
#if !UNITY_4
        EditorGUILayoutx.BeginIndent();
#else
        GUILayout.BeginHorizontal();
#endif

        switch (pivot)
        {
        case GridPivot.Center:
            graph.center = EditorGUILayout.Vector3Field("Center", graph.center);
            break;

        case GridPivot.TopLeft:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(0, 0, graph.depth));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Top-Left", pivotPoint);
            graph.center = pivotPoint - diff;
            break;

        case GridPivot.TopRight:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(graph.width, 0, graph.depth));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Top-Right", pivotPoint);
            graph.center = pivotPoint - diff;
            break;

        case GridPivot.BottomLeft:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(0, 0, 0));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Bottom-Left", pivotPoint);
            graph.center = pivotPoint - diff;
            break;

        case GridPivot.BottomRight:
            pivotPoint   = graph.matrix.MultiplyPoint3x4(new Vector3(graph.width, 0, 0));
            diff         = pivotPoint - graph.center;
            pivotPoint   = EditorGUILayout.Vector3Field("Bottom-Right", pivotPoint);
            graph.center = pivotPoint - diff;
            break;
        }

        graph.GenerateMatrix();

        pivot = PivotPointSelector(pivot);

#if !UNITY_4
        EditorGUILayoutx.EndIndent();

        EditorGUILayoutx.BeginIndent();
#else
        GUILayout.EndHorizontal();
#endif

        graph.rotation = EditorGUILayout.Vector3Field("Rotation", graph.rotation);
        //Add some space to make the Rotation and postion fields be better aligned (instead of the pivot point selector)
        GUILayout.Space(19 + 7);
        //GUILayout.EndHorizontal ();

#if !UNITY_4
        EditorGUILayoutx.EndIndent();
#endif
        EditorGUIUtility.LookLikeInspector();

        if (GUILayout.Button(new GUIContent("Snap Size", "Snap the size to exactly fit nodes"), GUILayout.MaxWidth(100), GUILayout.MaxHeight(16)))
        {
            SnapSizeToNodes(newWidth, newDepth, graph);
        }

        Separator();

        graph.cutCorners = EditorGUILayout.Toggle(new GUIContent("Cut Corners", "Enables or disables cutting corners. See docs for image example"), graph.cutCorners);
        graph.neighbours = (NumNeighbours)EditorGUILayout.EnumPopup(new GUIContent("Connections", "Sets how many connections a node should have to it's neighbour nodes."), graph.neighbours);

        //GUILayout.BeginHorizontal ();
        //EditorGUILayout.PrefixLabel ("Max Climb");
        graph.maxClimb = EditorGUILayout.FloatField(new GUIContent("Max Climb", "How high, relative to the graph, should a climbable level be. A zero (0) indicates infinity"), graph.maxClimb);
        EditorGUI.indentLevel++;
        graph.maxClimbAxis = EditorGUILayout.IntPopup(new GUIContent("Climb Axis", "Determines which axis the above setting should test on"), graph.maxClimbAxis, new GUIContent[3] {
            new GUIContent("X"), new GUIContent("Y"), new GUIContent("Z")
        }, new int[3] {
            0, 1, 2
        });

        EditorGUI.indentLevel--;
        //GUILayout.EndHorizontal ();

        graph.maxSlope = EditorGUILayout.Slider(new GUIContent("Max Slope", "Sets the max slope in degrees for a point to be walkable. Only enabled if Height Testing is enabled."), graph.maxSlope, 0, 90F);

        graph.erodeIterations = EditorGUILayout.IntField(new GUIContent("Erode iterations", "Sets how many times the graph should be eroded. This adds extra margin to objects. This will not work when using Graph Updates, so if you can, use the Diameter setting in collision settings instead"), graph.erodeIterations);
        graph.erodeIterations = graph.erodeIterations > 16 ? 16 : graph.erodeIterations;         //Clamp iterations to 16

        graph.erosionUseTags = EditorGUILayout.Toggle(new GUIContent("Erosion Uses Tags", "Instead of making nodes unwalkable, " +
                                                                     "nodes will have their tag set to a value corresponding to their erosion level, " +
                                                                     "which is a quite good measurement of their distance to the closest wall."),
                                                      graph.erosionUseTags);
        if (graph.erosionUseTags)
        {
            EditorGUI.indentLevel++;
            graph.erosionFirstTag = EditorGUILayoutx.SingleTagField("First Tag", graph.erosionFirstTag);
            EditorGUI.indentLevel--;
        }

        DrawCollisionEditor(graph.collision);

        Separator();

        showExtra = EditorGUILayout.Foldout(showExtra, "Extra");

        if (showExtra)
        {
            EditorGUI.indentLevel += 2;

            graph.penaltyAngle = ToggleGroup(new GUIContent("Angle Penalty", "Adds a penalty based on the slope of the node"), graph.penaltyAngle);
            //bool preGUI = GUI.enabled;
            //GUI.enabled = graph.penaltyAngle && GUI.enabled;
            if (graph.penaltyAngle)
            {
                EditorGUI.indentLevel++;
                graph.penaltyAngleFactor = EditorGUILayout.FloatField(new GUIContent("Factor", "Scale of the penalty. A negative value should not be used"), graph.penaltyAngleFactor);
                //GUI.enabled = preGUI;
                HelpBox("Applies penalty to nodes based on the angle of the hit surface during the Height Testing");

                EditorGUI.indentLevel--;
            }

            graph.penaltyPosition = ToggleGroup("Position Penalty", graph.penaltyPosition);
            //EditorGUILayout.Toggle ("Position Penalty",graph.penaltyPosition);
            //preGUI = GUI.enabled;
            //GUI.enabled = graph.penaltyPosition && GUI.enabled;
            if (graph.penaltyPosition)
            {
                EditorGUI.indentLevel++;
                graph.penaltyPositionOffset = EditorGUILayout.FloatField("Offset", graph.penaltyPositionOffset);
                graph.penaltyPositionFactor = EditorGUILayout.FloatField("Factor", graph.penaltyPositionFactor);
                HelpBox("Applies penalty to nodes based on their Y coordinate\nSampled in Int3 space, i.e it is multiplied with Int3.Precision first (" + Int3.Precision + ")\n" +
                        "Be very careful when using negative values since a negative penalty will underflow and instead get really high");
                //GUI.enabled = preGUI;
                EditorGUI.indentLevel--;
            }

            if (textureVisible)
            {
                DrawTextureData(graph.textureData, graph);
            }
            EditorGUI.indentLevel -= 2;
        }
    }
Пример #50
0
	/** Draws settings for using a texture as source for a grid.
	 * \astarpro */
	public void DrawTextureData (GridGraph.TextureData data, GridGraph graph) {
		if (data == null) {
			return;
		}
		
		data.enabled = ToggleGroup ("Use Texture",data.enabled);
			//EditorGUILayout.Toggle ("Use Texture",data.enabled);
		//data.enabled = ToggleGroup ("Use Texture",data.enabled);
		if (!data.enabled) {
			return;
		}
		
		bool preGUI = GUI.enabled;
		GUI.enabled = data.enabled && GUI.enabled;
		
		EditorGUI.indentLevel++;
		//data.source = EditorGUILayout.ObjectField ("Source",data.source,typeof(Texture2D),false) as Texture2D;
		data.source = ObjectField ("Source",data.source,typeof(Texture2D),false) as Texture2D;
		
		if (data.source != null) {
			string path = AssetDatabase.GetAssetPath (data.source);
			
			if (path != "") {
				TextureImporter importer = AssetImporter.GetAtPath (path) as TextureImporter;
				if (!importer.isReadable) {
					if (FixLabel ("Texture is not readable")) {
						importer.isReadable = true;
						EditorUtility.SetDirty (importer);
						AssetDatabase.ImportAsset (path);
					}
				}
			}
		}
		
		for (int i=0;i<3;i++) {
			string channelName = i == 0 ? "R" : (i == 1 ? "G" : "B");
			data.channels[i] = (GridGraph.TextureData.ChannelUse)EditorGUILayout.Popup (channelName, (int)data.channels[i], ChannelUseNames);
			
			if (data.channels[i] != GridGraph.TextureData.ChannelUse.None) {
				EditorGUI.indentLevel++;
				data.factors[i] = EditorGUILayout.FloatField ("Factor",data.factors[i]);
				
				string help = "";
				switch (data.channels[i]) {
				case GridGraph.TextureData.ChannelUse.Penalty:
					help = "Nodes are applied penalty according to channel '"+channelName+"', multiplied with factor";
					break;
				case GridGraph.TextureData.ChannelUse.Position:
					help = "Nodes Y position is changed according to channel '"+channelName+"', multiplied with factor";
					
					if (graph.collision.heightCheck) {
						HelpBox ("Getting position both from raycast and from texture. You should disable one of them");
					}
					break;
				case GridGraph.TextureData.ChannelUse.WalkablePenalty:
					help = "If channel '"+channelName+"' is 0, the node is made unwalkable. Otherwise the node is applied penalty multiplied with factor";
					break;
				}
				
				HelpBox (help);
				
				EditorGUI.indentLevel--;
			}
			
		}
		
		if (GUILayout.Button ("Generate Reference")) {
			SaveReferenceTexture (graph);
		}
		
		GUI.enabled = preGUI;
		EditorGUI.indentLevel--;
	}
Пример #51
0
        public override void Open(NodeRunData nodeRunData, NodeRun nodeR, Int3 targetPosition, Path path)
        {
            BaseOpen(nodeRunData, nodeR, targetPosition, path);

            GridGraph graph = gridGraphs[indices >> 24];

            int[]  neighbourOffsets = graph.neighbourOffsets;
            int[]  neighbourCosts   = graph.neighbourCosts;
            Node[] nodes            = graph.nodes;

            int index = GetIndex();             //indices & 0xFFFFFF;

            for (int i = 0; i < 8; i++)
            {
                if (GetConnection(i))
                {
                    //if (((flags >> i) & 1) == 1) {

                    Node node = nodes[index + neighbourOffsets[i]];

                    if (!path.CanTraverse(node))
                    {
                        continue;
                    }

                    NodeRun nodeR2 = node.GetNodeRun(nodeRunData);


                    if (nodeR2.pathID != nodeRunData.pathID)
                    {
                        nodeR2.parent = nodeR;
                        nodeR2.pathID = nodeRunData.pathID;

                        nodeR2.cost = (uint)neighbourCosts[i];

                        node.UpdateH(targetPosition, path.heuristic, path.heuristicScale, nodeR2);
                        node.UpdateG(nodeR2, nodeRunData);


                        nodeRunData.open.Add(nodeR2);
                    }
                    else
                    {
                        //If not we can test if the path from the current node to this one is a better one then the one already used
                        uint tmpCost = (uint)neighbourCosts[i];                        //(current.costs == null || current.costs.Length == 0 ? costs[current.neighboursKeys[i]] : current.costs[current.neighboursKeys[i]]);

                        if (nodeR.g + tmpCost + node.penalty
                            + path.GetTagPenalty(node.tags)
                            < nodeR2.g)
                        {
                            nodeR2.cost = tmpCost;
                            //node.extraCost = extraCost2;
                            nodeR2.parent = nodeR;

                            node.UpdateAllG(nodeR2, nodeRunData);

                            //open.Add (node);
                            //Debug.DrawLine (current.vectorPos,current.neighbours[i].vectorPos,Color.cyan); //Uncomment for @Debug
                        }

                        else if (nodeR2.g + tmpCost + penalty
                                 + path.GetTagPenalty(tags)
                                 < nodeR.g)                          //Or if the path from this node ("node") to the current ("current") is better

                        /*bool contains = false;
                         *
                         * //[Edit, no one-way links between nodes in a single grid] Make sure we don't travel along the wrong direction of a one way link now, make sure the Current node can be accesed from the Node.
                         * /*for (int y=0;y<node.connections.Length;y++) {
                         *      if (node.connections[y].endNode == this) {
                         *              contains = true;
                         *              break;
                         *      }
                         * }
                         *
                         * if (!contains) {
                         *      continue;
                         * }*/

                        {
                            nodeR.parent = nodeR2;
                            nodeR.cost   = tmpCost;
                            //extraCost = extraCost2;

                            UpdateAllG(nodeR, nodeRunData);
                            //open.Add (this);
                            //Debug.DrawLine (current.vectorPos,current.neighbours[i].vectorPos,Color.blue); //Uncomment for @Debug

                            //open.Add (this);
                        }
                    }
                }
            }
        }
Пример #52
0
 // Start is called before the first frame update
 void Start()
 {
     node = AstarPath.active.data.gridGraph;
 }
Пример #53
0
    public void OnConstantPathComplete(Path p)
    {
        ConstantPath     constPath = p as ConstantPath;
        List <GraphNode> nodes     = constPath.allNodes;

        MoveableNodes = nodes;

        Mesh mesh = new Mesh();

        List <Vector3> verts = new List <Vector3> ();

        bool drawRaysInstead = false;

        List <Vector3> pts = Pathfinding.PathUtilities.GetPointsOnNodes(nodes, 20, 0);
        Vector3        avg = Vector3.zero;

        for (int i = 0; i < pts.Count; i++)
        {
            Debug.DrawRay(pts [i], Vector3.up * 5, Color.red, 3);
            avg += pts [i];
        }

        if (pts.Count > 0)
        {
            avg /= pts.Count;
        }

        for (int i = 0; i < pts.Count; i++)
        {
            pts [i] -= avg;
        }

        Pathfinding.PathUtilities.GetPointsAroundPoint(transform.position, AstarPath.active.astarData.graphs [0] as IRaycastableGraph, pts, 0, 1);

        for (int i = 0; i < pts.Count; i++)
        {
            Debug.DrawRay(pts [i], Vector3.up * 5, Color.blue, 3);
        }

        //This will loop through the nodes from furthest away to nearest, not really necessary... but why not :D
        //Note that the reverse does not, as common sense would suggest, loop through from the closest to the furthest away
        //since is might contain duplicates and only the node duplicate placed at the highest index is guarenteed to be ordered correctly.
        for (int i = nodes.Count - 1; i >= 0; i--)
        {
            Vector3 pos = (Vector3)nodes [i].position + PathOffset;
            if (verts.Count == 65000 && !drawRaysInstead)
            {
                Debug.LogError("Too many nodes, rendering a mesh would throw 65K vertex error. Using Debug.DrawRay instead for the rest of the nodes");
                drawRaysInstead = true;
            }

            if (drawRaysInstead)
            {
                Debug.DrawRay(pos, Vector3.up, Color.blue);
                continue;
            }

            //Add vertices in a square

            GridGraph gg    = AstarData.GetGraph(nodes [i]) as GridGraph;
            float     scale = 1F;

            if (gg != null)
            {
                scale = gg.nodeSize;
            }

            verts.Add(pos + new Vector3(-0.5F, 0, -0.5F) * scale);
            verts.Add(pos + new Vector3(0.5F, 0, -0.5F) * scale);
            verts.Add(pos + new Vector3(-0.5F, 0, 0.5F) * scale);
            verts.Add(pos + new Vector3(0.5F, 0, 0.5F) * scale);
        }

        //Build triangles for the squares
        Vector3[] vs   = verts.ToArray();
        int[]     tris = new int[(3 * vs.Length) / 2];
        for (int i = 0, j = 0; i < vs.Length; j += 6, i += 4)
        {
            tris [j + 0] = i;
            tris [j + 1] = i + 1;
            tris [j + 2] = i + 2;

            tris [j + 3] = i + 1;
            tris [j + 4] = i + 3;
            tris [j + 5] = i + 2;
        }

        Vector2[] uv = new Vector2[vs.Length];
        //Set up some basic UV
        for (int i = 0; i < uv.Length; i += 4)
        {
            uv [i]     = new Vector2(0, 0);
            uv [i + 1] = new Vector2(1, 0);
            uv [i + 2] = new Vector2(0, 1);
            uv [i + 3] = new Vector2(1, 1);
        }

        mesh.vertices  = vs;
        mesh.triangles = tris;
        mesh.uv        = uv;
        mesh.RecalculateNormals();

        GameObject go = new GameObject("Mesh", typeof(MeshRenderer), typeof(MeshFilter));
        MeshFilter fi = go.GetComponent <MeshFilter> ();

        fi.mesh = mesh;
        MeshRenderer re = go.GetComponent <MeshRenderer> ();

        re.material = SquareMat;

        RenderedGrid.Add(go);
    }
Пример #54
0
	public void SnapSizeToNodes (int newWidth, int newDepth, GridGraph graph) {
		//Vector2 preSize = graph.unclampedSize;
		
		/*if (locked) {
			graph.unclampedSize = new Vector2 (newWidth*newNodeSize,newDepth*newNodeSize);
			graph.nodeSize = newNodeSize;
			graph.GenerateMatrix ();
			Vector3 newCenter = graph.matrix.MultiplyPoint3x4 (new Vector3 (newWidth/2F,0,newDepth/2F));
			graph.center = newCenter;
			AstarPath.active.AutoScan ();
		} else {*/
			graph.unclampedSize = new Vector2 (newWidth*graph.nodeSize,newDepth*graph.nodeSize);
			Vector3 newCenter = graph.matrix.MultiplyPoint3x4 (new Vector3 (newWidth/2F,0,newDepth/2F));
			graph.center = newCenter;
			graph.GenerateMatrix ();
			AstarPath.active.AutoScan ();
		//}
		
		GUI.changed = true;
	}
Пример #55
0
        private static void FindAllContours(GridGraph grid, Action <Vector3[], bool> callback, GridNodeBase[] nodes = null)
        {
            if (grid is LayerGridGraph)
            {
                nodes = (nodes ?? (grid as LayerGridGraph).nodes);
            }
            nodes = (nodes ?? grid.nodes);
            int[] neighbourXOffsets = grid.neighbourXOffsets;
            int[] neighbourZOffsets = grid.neighbourZOffsets;
            int[] array;
            if (grid.neighbours == NumNeighbours.Six)
            {
                array = GridGraph.hexagonNeighbourIndices;
            }
            else
            {
                RuntimeHelpers.InitializeArray(array = new int[4], fieldof(< PrivateImplementationDetails >.$field - 02E4414E7DFA0F3AA2387EE8EA7AB31431CB406A).FieldHandle);
            }
            int[] array2 = array;
            float num    = (grid.neighbours != NumNeighbours.Six) ? 0.5f : 0.333333343f;

            if (nodes != null)
            {
                Dictionary <Int3, int> dictionary  = new Dictionary <Int3, int>();
                Dictionary <int, int>  dictionary2 = new Dictionary <int, int>();
                HashSet <int>          hashSet     = new HashSet <int>();
                List <Vector3>         vertices    = ListPool <Vector3> .Claim();

                foreach (GridNodeBase gridNodeBase in nodes)
                {
                    if (gridNodeBase != null && gridNodeBase.Walkable && !gridNodeBase.HasConnectionsToAllEightNeighbours)
                    {
                        for (int j = 0; j < array2.Length; j++)
                        {
                            int num2 = array2[j];
                            if (gridNodeBase.GetNeighbourAlongDirection(num2) == null)
                            {
                                int     num3   = array2[(j - 1 + array2.Length) % array2.Length];
                                int     num4   = array2[(j + 1) % array2.Length];
                                Vector3 vector = new Vector3((float)gridNodeBase.XCoordinateInGrid + 0.5f, 0f, (float)gridNodeBase.ZCoordinateInGrid + 0.5f);
                                vector.x += (float)neighbourXOffsets[num2] * num;
                                vector.z += (float)neighbourZOffsets[num2] * num;
                                vector.y  = grid.transform.InverseTransform((Vector3)gridNodeBase.position).y;
                                Vector3 vector3;
                                Vector3 vector2 = vector3 = vector;
                                vector3.x += (float)neighbourXOffsets[num3] * num;
                                vector3.z += (float)neighbourZOffsets[num3] * num;
                                vector2.x += (float)neighbourXOffsets[num4] * num;
                                vector2.z += (float)neighbourZOffsets[num4] * num;
                                Int3 key  = (Int3)vector3;
                                Int3 key2 = (Int3)vector2;
                                int  key3;
                                if (dictionary.TryGetValue(key, out key3))
                                {
                                    dictionary.Remove(key);
                                }
                                else
                                {
                                    int count = vertices.Count;
                                    dictionary[key] = count;
                                    key3            = count;
                                    vertices.Add(vector3);
                                }
                                int num5;
                                if (dictionary.TryGetValue(key2, out num5))
                                {
                                    dictionary.Remove(key2);
                                }
                                else
                                {
                                    int count = vertices.Count;
                                    dictionary[key2] = count;
                                    num5             = count;
                                    vertices.Add(vector2);
                                }
                                dictionary2.Add(key3, num5);
                                hashSet.Add(num5);
                            }
                        }
                    }
                }
                GraphTransform transform    = grid.transform;
                List <Vector3> vertexBuffer = ListPool <Vector3> .Claim();

                RVONavmesh.CompressContour(dictionary2, hashSet, delegate(List <int> chain, bool cycle)
                {
                    vertexBuffer.Clear();
                    Vector3 vector4 = vertices[chain[0]];
                    vertexBuffer.Add(vector4);
                    for (int k = 1; k < chain.Count - 1; k++)
                    {
                        Vector3 vector5 = vertices[chain[k]];
                        Vector3 vector6 = vector5 - vector4;
                        Vector3 vector7 = vertices[chain[k + 1]] - vector4;
                        if (((Mathf.Abs(vector6.x) > 0.01f || Mathf.Abs(vector7.x) > 0.01f) && (Mathf.Abs(vector6.z) > 0.01f || Mathf.Abs(vector7.z) > 0.01f)) || Mathf.Abs(vector6.y) > 0.01f || Mathf.Abs(vector7.y) > 0.01f)
                        {
                            vertexBuffer.Add(vector5);
                        }
                        vector4 = vector5;
                    }
                    vertexBuffer.Add(vertices[chain[chain.Count - 1]]);
                    Vector3[] array3 = vertexBuffer.ToArray();
                    transform.Transform(array3);
                    callback(array3, cycle);
                });
                ListPool <Vector3> .Release(vertexBuffer);

                ListPool <Vector3> .Release(vertices);
            }
        }
Пример #56
0
 void AddGraphObstacles(Pathfinding.RVO.Simulator sim, GridGraph grid)
 {
     FindAllContours(grid, (vertices, cycle) => obstacles.Add(sim.AddObstacle(vertices, wallHeight, true)));
 }