protected override void DrawCollisionEditor (GraphCollision collision) {
			base.DrawCollisionEditor(collision);

			if (collision.thickRaycast) {
				EditorGUILayout.HelpBox ("Note: Thick raycast cannot be used with this graph type", MessageType.Error);
			}
		}
		protected virtual void DrawUse2DPhysics (GraphCollision collision) {
			collision.use2D = EditorGUILayout.Toggle (new GUIContent ("Use 2D Physics", "Use the Physics2D API for collision checking"), collision.use2D );
		}
		/** Draws the inspector for a \link Pathfinding.GraphCollision GraphCollision class \endlink */
		protected virtual void DrawCollisionEditor (GraphCollision collision) {

			collision = collision ?? new GraphCollision ();

			DrawUse2DPhysics (collision);

			collision.collisionCheck = ToggleGroup ("Collision testing",collision.collisionCheck);
			EditorGUI.BeginDisabledGroup(!collision.collisionCheck);

			collision.type = (ColliderType)EditorGUILayout.EnumPopup("Collider type",collision.type);

			EditorGUI.BeginDisabledGroup(collision.type != ColliderType.Capsule && collision.type != ColliderType.Sphere);
			collision.diameter = EditorGUILayout.FloatField (new GUIContent ("Diameter","Diameter of the capsule or sphere. 1 equals one node width"),collision.diameter);
			EditorGUI.EndDisabledGroup();

			EditorGUI.BeginDisabledGroup(collision.type != ColliderType.Capsule && collision.type != ColliderType.Ray);
			collision.height = EditorGUILayout.FloatField (new GUIContent ("Height/Length","Height of cylinder or length of ray in world units"),collision.height);
			EditorGUI.EndDisabledGroup();

			collision.collisionOffset = EditorGUILayout.FloatField (new GUIContent("Offset","Offset upwards from the node. Can be used so that obstacles can be used as ground and at the same time as obstacles for lower positioned nodes"),collision.collisionOffset);

			collision.mask = EditorGUILayoutx.LayerMaskField ("Mask",collision.mask);

			EditorGUI.EndDisabledGroup();

			GUILayout.Space (2);


			EditorGUI.BeginDisabledGroup(collision.use2D);
			collision.heightCheck = ToggleGroup ("Height testing",collision.heightCheck);
			EditorGUI.BeginDisabledGroup(!collision.heightCheck);

			collision.fromHeight = EditorGUILayout.FloatField (new GUIContent ("Ray length","The height from which to check for ground"),collision.fromHeight);

			collision.heightMask = EditorGUILayoutx.LayerMaskField ("Mask",collision.heightMask);

			collision.thickRaycast = EditorGUILayout.Toggle (new GUIContent ("Thick Raycast", "Use a thick line instead of a thin line"),collision.thickRaycast);

			if (collision.thickRaycast) {
				EditorGUI.indentLevel++;
				collision.thickRaycastDiameter = EditorGUILayout.FloatField (new GUIContent ("Diameter","Diameter of the thick raycast"),collision.thickRaycastDiameter);
				EditorGUI.indentLevel--;
			}

			collision.unwalkableWhenNoGround = EditorGUILayout.Toggle (new GUIContent ("Unwalkable when no ground","Make nodes unwalkable when no ground was found with the height raycast. If height raycast is turned off, this doesn't affect anything"), collision.unwalkableWhenNoGround);

			EditorGUI.EndDisabledGroup();
			EditorGUI.EndDisabledGroup();
		}
		public override void ScanInternal (OnScanStatus statusCallback) {

			AstarPath.OnPostScan += new OnScanDelegate (OnPostScan);

			if (nodeSize <= 0) {
				return;
			}

			// Make sure the matrix is up to date
			GenerateMatrix ();

			if (width > 1024 || depth > 1024) {
				Debug.LogError ("One of the grid's sides is longer than 1024 nodes");
				return;
			}

#if !ASTAR_JPS
			if (this.useJumpPointSearch) {
				Debug.LogError ("Trying to use Jump Point Search, but support for it is not enabled. Please enable it in the inspector (Grid Graph settings).");
			}
#endif

			SetUpOffsetsAndCosts ();

			// Get the graph index of this graph
			int graphIndex = AstarPath.active.astarData.GetGraphIndex(this);

			// Set a global reference to this graph so that nodes can find it
			GridNode.SetGridGraph (graphIndex,this);

			// Create all nodes
			nodes = new GridNode[width*depth];
			for (int i=0;i<nodes.Length;i++) {
				nodes[i] = new GridNode(active);
				nodes[i].GraphIndex = (uint)graphIndex;
			}

			// Create and initialize the collision class
			if (collision == null) {
				collision = new GraphCollision ();
			}
			collision.Initialize (matrix,nodeSize);

			textureData.Initialize ();

			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {

					var node = nodes[z*width+x];

					node.NodeInGridIndex = z*width+x;

					// Updates the position of the node
					// and a bunch of other things
					UpdateNodePositionCollision (node,x,z);

					// Apply texture data if necessary
					textureData.Apply (node,x,z);
				}
			}


			for (int z = 0; z < depth; z ++) {
				for (int x = 0; x < width; x++) {

					var node = nodes[z*width+x];

					// Recalculate connections to other nodes
					CalculateConnections (nodes,x,z,node);
				}
			}

			// Apply erosion
			ErodeWalkableArea ();
		}
		public GridGraph () {
			unclampedSize = new Vector2 (10,10);
			nodeSize = 1F;
			collision = new GraphCollision ();
		}
		protected override void DrawUse2DPhysics (GraphCollision collision) {
			// 2D physics does not make sense for a layered grid graph
			collision.use2D = false;
		}