예제 #1
0
        public virtual Vector2 GetPointAlongCenterPath(AreaPathNode endAreaPathNode, float normalizedDistance)
        {
            Vector2 output           = VectorExtensions.NULL2;
            float   centerPathLength = 0;
            List <LineSegment2D> centerPathSegments = new List <LineSegment2D>();
            List <AreaPathNode>  _areaPathNodes     = new List <AreaPathNode>();

            _areaPathNodes.AddRange(areaPathNodes);
            AreaPathNode  checkAreaPathNode;
            LineSegment2D centerPathSegment;

            while (endAreaPathNode != rootAreaPathNode)
            {
                for (int i = 0; i < _areaPathNodes.Count; i++)
                {
                    checkAreaPathNode = _areaPathNodes[i];
                    if (checkAreaPathNode.children.Contains(endAreaPathNode))
                    {
                        centerPathSegment = new LineSegment2D(checkAreaPathNode.trs.position, endAreaPathNode.trs.position);
                        centerPathSegments.Insert(0, centerPathSegment);
                        centerPathLength   += Vector2.Distance(endAreaPathNode.trs.position, checkAreaPathNode.trs.position);
                        endAreaPathNode     = checkAreaPathNode;
                        normalizedDistance -= centerPathSegment.GetLength() / centerPathLength;
                        if (normalizedDistance <= 0)
                        {
                            output = centerPathSegment.GetPointWithDirectedDistance(-normalizedDistance * centerPathLength);
                            break;
                        }
                        break;
                    }
                }
            }
            return(output);
        }
예제 #2
0
        public virtual LineSegment2D[] GetBorders(AreaPathNode node1, AreaPathNode node2)
        {
            LineSegment2D[] output        = new LineSegment2D[2];
            Vector2         lineDirection = (node2.trs.position - node1.trs.position).normalized.Rotate(90);
            LineSegment2D   line1         = new LineSegment2D((Vector2)node1.trs.position + (lineDirection * node1.radius), (Vector2)node1.trs.position - (lineDirection * node1.radius));
            LineSegment2D   line2         = new LineSegment2D((Vector2)node2.trs.position - (lineDirection * node2.radius), (Vector2)node2.trs.position + (lineDirection * node2.radius));

            output[0] = new LineSegment2D(line1.start, VectorExtensions.GetClosestPoint(line1.start, line2.start, line2.end));
            output[1] = new LineSegment2D(line1.end, VectorExtensions.GetClosestPoint(line1.end, line2.start, line2.end));
            return(output);
        }
예제 #3
0
        public virtual IEnumerator MakeRoutine()
        {
            Terrain[] terrains = FindObjectsOfType <Terrain>();
            for (int i = 0; i < terrains.Length; i++)
            {
                if (terrains[i].canBeErased && Contains(terrains[i]))
                {
                    terrains[i].gameObject.SetActive(false);
                }
            }
            if (surroundWithTerrains)
            {
                Vector2 currentPoint;
                do
                {
                    currentPoint = (Vector2)rootAreaPathNode.trs.position + (Random.insideUnitCircle.normalized * (rootAreaPathNode.radius + distToNodeForFirstTerrain));
                    yield return(new WaitForEndOfFrame());
                } while (Contains(currentPoint));
                yield return(EditorCoroutineUtility.StartCoroutine(MakeTerrainRoutine(currentPoint), this));

                AreaPathNode[] uncheckedAreaPathNodes = new AreaPathNode[1] {
                    rootAreaPathNode
                };
                AreaPathNode[] deadEndAreaPathNodes = new AreaPathNode[0];
                while (uncheckedAreaPathNodes.Length > 0)
                {
                    if (uncheckedAreaPathNodes[0].gameObject.activeInHierarchy)
                    {
                        uncheckedAreaPathNodes = uncheckedAreaPathNodes.AddRange(uncheckedAreaPathNodes[0].children);
                        if (uncheckedAreaPathNodes[0].children.Length == 0)
                        {
                            deadEndAreaPathNodes = deadEndAreaPathNodes.Add(uncheckedAreaPathNodes[0]);
                        }
                    }
                    uncheckedAreaPathNodes = uncheckedAreaPathNodes.RemoveAt(0);
                }
                float normalizedTraversedDistance = 0;
                foreach (AreaPathNode deadEndAreaPathNode in deadEndAreaPathNodes)
                {
                    do
                    {
                        currentPoint = GetPointAlongCenterPath(deadEndAreaPathNode, normalizedTraversedDistance + normalizedTraverseRate);
                        DebugExtensions.DrawPoint(currentPoint, 10, Color.red, .1f);
                        normalizedTraversedDistance = GetNormalizedDistanceOfClosestPointAlongCenterPath(deadEndAreaPathNode, currentPoint);
                        yield return(new WaitForEndOfFrame());
                    } while (normalizedTraversedDistance < 1);
                }
            }
        }
예제 #4
0
 public virtual void OnDrawGizmos()
 {
     Gizmos.matrix = Matrix4x4.identity;
     LineSegment2D[] _borders               = new LineSegment2D[0];
     AreaPathNode[]  _areaPathNodes         = new AreaPathNode[0];
     AreaPathNode[]  uncheckedAreaPathNodes = new AreaPathNode[1] {
         rootAreaPathNode
     };
     LineSegment2D[] borderPair;
     while (uncheckedAreaPathNodes.Length > 0)
     {
         if (uncheckedAreaPathNodes[0] != null)
         {
             foreach (AreaPathNode childAreaPathNode in uncheckedAreaPathNodes[0].children)
             {
                 if (childAreaPathNode != null && childAreaPathNode.gameObject.activeInHierarchy)
                 {
                     if (_areaPathNodes.Contains(childAreaPathNode))
                     {
                         Debug.LogError("AreaPath " + name + " has a cycle");
                         return;
                     }
                     borderPair   = GetBorders(uncheckedAreaPathNodes[0], childAreaPathNode);
                     _borders     = _borders.AddRange(borderPair);
                     Gizmos.color = borderColor;
                     Gizmos.DrawLine(borderPair[0].start, borderPair[0].end);
                     Gizmos.DrawLine(borderPair[1].start, borderPair[1].end);
                     Gizmos.color = nodeConnectorColor;
                     Gizmos.DrawLine(uncheckedAreaPathNodes[0].trs.position, childAreaPathNode.trs.position);
                 }
             }
             if (uncheckedAreaPathNodes[0].gameObject.activeInHierarchy)
             {
                 uncheckedAreaPathNodes = uncheckedAreaPathNodes.AddRange(uncheckedAreaPathNodes[0].children);
                 _areaPathNodes         = _areaPathNodes.Add(uncheckedAreaPathNodes[0]);
             }
         }
         uncheckedAreaPathNodes = uncheckedAreaPathNodes.RemoveAt(0);
     }
     borders       = _borders;
     areaPathNodes = _areaPathNodes;
 }
예제 #5
0
        public virtual float GetNormalizedDistanceOfClosestPointAlongCenterPath(AreaPathNode endAreaPathNode, Vector2 point)
        {
            float output           = MathfExtensions.NULL_FLOAT;
            float centerPathLength = 0;
            List <LineSegment2D> centerPathSegments = new List <LineSegment2D>();
            List <AreaPathNode>  _areaPathNodes     = new List <AreaPathNode>();

            _areaPathNodes.AddRange(areaPathNodes);
            AreaPathNode  checkAreaPathNode;
            Vector2       closestPoint;
            float         distanceToClosestPoint = Mathf.Infinity;
            float         checkDistance;
            LineSegment2D centerPathSegment;
            float         currentNormalizedDistance = 0;
            Vector2       checkPoint;

            while (endAreaPathNode != rootAreaPathNode)
            {
                for (int i = 0; i < _areaPathNodes.Count; i++)
                {
                    checkAreaPathNode = _areaPathNodes[i];
                    if (checkAreaPathNode.children.Contains(endAreaPathNode))
                    {
                        centerPathSegment = new LineSegment2D(checkAreaPathNode.trs.position, endAreaPathNode.trs.position);
                        centerPathSegments.Insert(0, centerPathSegment);
                        centerPathLength += Vector2.Distance(endAreaPathNode.trs.position, checkAreaPathNode.trs.position);
                        endAreaPathNode   = checkAreaPathNode;
                        checkPoint        = centerPathSegment.ClosestPoint(point);
                        checkDistance     = Vector2.Distance(checkPoint, point);
                        if (checkDistance < distanceToClosestPoint)
                        {
                            distanceToClosestPoint = checkDistance;
                            closestPoint           = checkPoint;
                            output = currentNormalizedDistance + centerPathSegment.GetDirectedDistanceAlongParallel(closestPoint);
                        }
                        currentNormalizedDistance += centerPathSegment.GetLength() / centerPathLength;
                        break;
                    }
                }
            }
            return(output);
        }
예제 #6
0
 public virtual float GetWidthAtNormalizedDistanceAlongCenterPath(AreaPathNode endAreaPathNode, float normalizedDistance)
 {
     return(MathfExtensions.NULL_FLOAT);
 }