//@TODO: Support region up. //@TODO: Support 6 directions. public void GenerateNodes(PathAgent pathAgent, Vector3 nodeUp) { Vector3 rayPosition = Extremes[0]; Vector3 endPosition = Extremes[1]; // Other regions do not know of the distribution. Therefore regions should perhaps be scaled to the spacing. // Regions that go out of boundaries should still spawn and solve what they can within boundaries. for (; rayPosition.x <= endPosition.x; rayPosition.x += _gridSpacing) { rayPosition.y = Extremes[0].y; for (int rowCount = 0; rayPosition.y <= endPosition.y; rayPosition.y += _gridSpacing, rowCount++) { Vector3 rayOrigin = rayPosition; // Shoves the entire row by half a spacing to form a diamond pattern. if (rowCount % 2 == 0) { rayOrigin.x += (_gridSpacing / 2); } Collider2D[] colliders = Physics2D.OverlapCircleAll(rayOrigin, pathAgent.Radius); //RaycastHit2D[] colliders = Physics2D.RaycastAll(rayOrigin, Vector3.forward, pathAgent.Height); if (colliders.Length == 0) { continue; } Debug.Log(colliders.Length); int priorityLayer = int.MaxValue; Collider2D priorityCollider = null; foreach (var collider in colliders) { rayOrigin.z = collider.transform.position.z; if (!collider.bounds.Contains(rayOrigin)) { continue; } int colliderLayer = collider.gameObject.layer; if (colliderLayer == PathNetwork.UnwalkableLayer || colliderLayer == PathNetwork.CustomLayer) { priorityLayer = colliderLayer; priorityCollider = collider; break; } if (colliderLayer < priorityLayer) { priorityLayer = colliderLayer; priorityCollider = collider; } } if (priorityCollider == null) { continue; } switch (priorityLayer) { case PathNetwork.CustomLayer: Debug.Log("Custom"); colliders = QuickSortByHeight(colliders); int length = colliders.Length - 2; for (int i = 0; i <= length; i++) { PathCollider pathCollider = colliders[i].transform.GetComponent <PathCollider>(); if (pathCollider != null) { if (pathCollider.IsStatic) { continue; } Collider2D collider = colliders[i + 1]; priorityLayer = collider.transform.gameObject.layer; if (PathNetwork.UnwalkableLayer == priorityLayer) { break; } // When you click it, the custom node should still be returned because of the pathCollider's collider. Debug.Log("CHECK"); Node node = CreateNode(rayOrigin, collider, collider.transform.gameObject.layer, nodeUp); pathCollider.OverlappedNodes.Add(node); break; } } break; case PathNetwork.UnwalkableLayer: Debug.Log("Break."); break; default: Debug.Log("Normal"); CreateNode(rayOrigin, priorityCollider, priorityLayer, nodeUp); break; } } } }
public Region(PathNetwork pathNetwork, Vector3 worldPosition, Vector3 regionSize, float gridSpacing, PathAgent pathAgent) { _pathNetwork = pathNetwork; WorldPosition = worldPosition; _gridSpacing = gridSpacing; Extremes = _pathNetwork.GetExtremes(WorldPosition, regionSize); GenerateNodes(pathAgent, -Vector3.forward); }
private void Load(PathAgent pathAgent) { // Load the correct file using the parameter and recreating the entire pathnetwork. // Load all the nodes. }
private void CreateNodeNetwork(PathAgent pathAgent) { _gridSpacing = pathAgent.Radius; if (_gridSpacing <= 0) { throw new System.Exception("pathAgent.Radius <= 0."); } if (_regionSize.x < _gridSpacing || _regionSize.y < _gridSpacing || _regionSize.z < _gridSpacing) { throw new System.Exception("One or more values in _regionSize is smaller than _gridSpacing."); } _sizeX = Mathf.Max(Mathf.RoundToInt(_pathNetworkSize.x / _gridSpacing), 1); _sizeY = Mathf.Max(Mathf.RoundToInt(_pathNetworkSize.y / _gridSpacing), 1); _sizeZ = Mathf.Max(Mathf.RoundToInt(_pathNetworkSize.z / _gridSpacing), 1); // First raytrace from character height. See where regions need to be made. // After regions are made, they are now self sustained. // However, with dynamics involved, new regions might have to be created. // usually, all 2d region should've been solved. This shouldn't hinder any flying units, etc. Therefore it should be ok. // Can use sphere detection for the regions. // Easiest way to see if there is anything within there. Could even be square. Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); if (_pathNetworkSize.x <= 0 || _pathNetworkSize.y <= 0) { throw new System.Exception("PathingNetworkSize too small."); } Regions = new List <Region>(); Vector3 halfPathingNetworkSize = _pathNetworkSize / 2; Vector3 halfRegionSize = _regionSize / 2; Vector3 startPosition = transform.position - halfPathingNetworkSize + halfRegionSize; Vector3 endPosition = transform.position + halfPathingNetworkSize - halfRegionSize; Vector3 regionOrigin = startPosition; Vector3 boxSize = _regionSize - new Vector3(_gridSpacing, _gridSpacing, _gridSpacing); // Regionsize / spacing == even works. Uneven doesn't. for (; regionOrigin.x <= endPosition.x; regionOrigin.x += _regionSize.x) { regionOrigin.y = startPosition.y; for (; regionOrigin.y <= endPosition.y; regionOrigin.y += _regionSize.y) { regionOrigin.z = startPosition.z; for (; regionOrigin.z <= endPosition.z; regionOrigin.z += _regionSize.y) { Collider2D[] colliders = Physics2D.OverlapBoxAll(regionOrigin, boxSize, 0, _collisionMask); if (colliders.Length == 0) { continue; } Region region = new Region(this, regionOrigin, _regionSize, _gridSpacing, pathAgent); Regions.Add(region); } } } stopWatch.Stop(); UnityEngine.Debug.Log("Created regions: " + stopWatch.ElapsedMilliseconds + " ms."); foreach (var region in Regions) { // Connect right and below. > continue to other region. //region.SetNeighboursForNodes(); } }
private void Save(PathAgent pathAgent) { // Store all the nodes. }