/// <summary>
        /// Return a list of path nodes from the start tile to the end tile ( Use RpgMapHelper class to get the tile index )
        /// </summary>
        /// <param name="startIdx"></param>
        /// <param name="endIdx"></param>
        /// <returns></returns>
        public IEnumerator GetRouteFromToAsync(int startIdx, int endIdx)
        {
            IPathNode start = GetMapTileNode(startIdx);

            EndNode = GetMapTileNode(endIdx);
            return(m_pathFinding.ComputePathAsync(start, EndNode));
        }
 public MapTileNode GetMapTileNode( int idx )
 {
     MapTileNode mapTileNode;
     bool wasFound = m_dicTileNodes.TryGetValue(idx, out mapTileNode);
     if(!wasFound)
     {
         mapTileNode = new MapTileNode(idx, this);
         m_dicTileNodes[idx] = mapTileNode;
     }
     return mapTileNode;
 }
 public MapTileNode GetMapTileNode( int idx )
 {
     MapTileNode mapTileNode;
     bool wasFound = m_dicTileNodes.TryGetValue(idx, out mapTileNode);
     if(!wasFound)
     {
         mapTileNode = new MapTileNode(idx, this);
         m_dicTileNodes[idx] = mapTileNode;
     }
     return mapTileNode;
 }
        // special case for walls
        bool _IsWallPassable(MapTileNode neighNode)
        {
            AutoTileMap        autoTileMap   = AutoTileMap.Instance;
            eTileCollisionType collType      = eTileCollisionType.EMPTY;
            eTileCollisionType collTypeNeigh = eTileCollisionType.EMPTY;

            for (int iLayer = autoTileMap.GetLayerCount() - 1; iLayer >= 0; --iLayer)
            {
                if (autoTileMap.MapLayers[iLayer].LayerType == eLayerType.Ground)
                {
                    AutoTile autoTile      = autoTileMap.GetAutoTile(TileX, TileY, iLayer);
                    AutoTile autoTileNeigh = autoTileMap.GetAutoTile(neighNode.TileX, neighNode.TileY, iLayer);

                    if (autoTile.Id == autoTileNeigh.Id) // you can walk over two wall tiles if they have the same type
                    {
                        if (autoTile.Id >= 0)
                        {
                            return(true);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        // collType will keep the first collision type found of type wall or passable
                        if (collType != eTileCollisionType.PASSABLE && collType != eTileCollisionType.WALL)
                        {
                            collType = autoTile.Id >= 0 ? autoTileMap.Tileset.AutotileCollType[autoTile.Id] : eTileCollisionType.EMPTY;
                        }
                        if (collTypeNeigh != eTileCollisionType.PASSABLE && collTypeNeigh != eTileCollisionType.WALL)
                        {
                            collTypeNeigh = autoTileNeigh.Id >= 0 ? autoTileMap.Tileset.AutotileCollType[autoTileNeigh.Id] : eTileCollisionType.EMPTY;
                        }

                        if (collType == eTileCollisionType.PASSABLE && collTypeNeigh == eTileCollisionType.PASSABLE)
                        {
                            return(true);
                        }
                        else if (collType == eTileCollisionType.WALL || collTypeNeigh == eTileCollisionType.WALL)
                        {
                            return(false);
                        }
                    }
                }
            }
            return(true);
        }
 public LinkedList<IPathNode> GetRouteFromTo(int startIdx, int endIdx)
 {
     LinkedList<IPathNode> nodeList = new LinkedList<IPathNode>();
     if (m_pathFinding.IsComputing)
     {
         Debug.LogWarning("PathFinding is already computing. GetRouteFromTo will not be executed!");
     }
     else
     {                
         IPathNode start = GetMapTileNode(startIdx);
         EndNode = GetMapTileNode(endIdx);
         nodeList = m_pathFinding.ComputePath(start, EndNode);
     }
     return nodeList;
 }
 public LinkedList<IPathNode> GetRouteFromTo(int startIdx, int endIdx)
 {
     LinkedList<IPathNode> nodeList = new LinkedList<IPathNode>();
     if (m_pathFinding.IsComputing)
     {
         Debug.LogWarning("PathFinding is already computing. GetRouteFromTo will not be executed!");
     }
     else
     {
         IPathNode start = GetMapTileNode(startIdx);
         EndNode = GetMapTileNode(endIdx);
         nodeList = m_pathFinding.ComputePath(start, EndNode);
     }
     return nodeList;
 }
        /// <summary>
        /// Return a list of path nodes from the start tile to the end tile ( Use RpgMapHelper class to get the tile index )
        /// </summary>
        /// <param name="startIdx"></param>
        /// <param name="endIdx"></param>
        /// <returns></returns>
        public LinkedList <IPathNode> GetRouteFromTo(int startIdx, int endIdx)
        {
            LinkedList <IPathNode> nodeList = new LinkedList <IPathNode>();

            if (m_pathFinding.IsComputing)
            {
                Debug.LogWarning("PathFinding is already computing. GetRouteFromTo will not be executed!");
            }
            else
            {
                IPathNode start = GetMapTileNode(startIdx);
                EndNode  = GetMapTileNode(endIdx);
                nodeList = m_pathFinding.ComputePath(start, EndNode);         //NOTE: the path is given from end to start ( change the order? )
            }
            return(nodeList);
        }
Beispiel #8
0
        IEnumerator ComputePath()
        {
            m_isComputing = true;
            IEnumerator coroutine = m_mapPathFinding.GetRouteFromToAsync(m_startTileIdx, m_endTileIdx);

            while (coroutine.MoveNext())
            {
                yield return(null);
            }
            //Debug.Log("GetRouteFromToAsync execution time(ms): " + (Time.realtimeSinceStartup - now) * 1000);
            PathFinding.FindingParams findingParams = (PathFinding.FindingParams)coroutine.Current;
            m_path = findingParams.computedPath;
            //+++find closest node and take next one if possible
            m_curNode = Path.First;
            if (m_curNode != null)
            {
                Vector3 vPos = transform.position; vPos.z = ((MapTileNode)m_curNode.Value).Position.z; // use same z level
                while (m_curNode != null && m_curNode.Next != null)
                {
                    MapTileNode n0       = m_curNode.Value as MapTileNode;
                    MapTileNode n1       = m_curNode.Next.Value as MapTileNode;
                    float       distSqr  = (vPos - n0.Position).sqrMagnitude;
                    float       distSqr2 = (vPos - n1.Position).sqrMagnitude;
                    if (distSqr2 < distSqr)
                    {
                        m_curNode = m_curNode.Next;
                    }
                    else
                    {
                        break;
                    }
                }
                // take next one, avoid moving backward in the path
                if (m_curNode.Next != null)
                {
                    m_curNode = m_curNode.Next;
                }
            }
            //---
            m_isComputing = false;
            if (OnComputedPath != null)
            {
                OnComputedPath(this);
            }
            yield return(null);
        }
        public override float GetNeigborMovingCost(int neigborIdx)
        {
            float fCost = 1f;

            //012 //
            //3X4 // neighbor index positions, X is the position of this node
            //567
            if (neigborIdx == 0 || neigborIdx == 2 || neigborIdx == 5 || neigborIdx == 7)
            {
                //check if can reach diagonals as it could be not possible if flank tiles are not passable
                MapTileNode nodeN = GetNeighbor(1) as MapTileNode;
                MapTileNode nodeW = GetNeighbor(3) as MapTileNode;
                MapTileNode nodeE = GetNeighbor(4) as MapTileNode;
                MapTileNode nodeS = GetNeighbor(6) as MapTileNode;
                if (
                    !m_owner.AllowDiagonals ||
                    (neigborIdx == 0 && (!nodeN.IsPassable() || !nodeW.IsPassable() || !_IsWallPassable(nodeN) || !_IsWallPassable(nodeW))) || // check North West
                    (neigborIdx == 2 && (!nodeN.IsPassable() || !nodeE.IsPassable() || !_IsWallPassable(nodeN) || !_IsWallPassable(nodeE))) || // check North East
                    (neigborIdx == 5 && (!nodeS.IsPassable() || !nodeW.IsPassable() || !_IsWallPassable(nodeS) || !_IsWallPassable(nodeW))) || // check South West
                    (neigborIdx == 7 && (!nodeS.IsPassable() || !nodeE.IsPassable() || !_IsWallPassable(nodeS) || !_IsWallPassable(nodeE)))    // check South East
                    )
                {
                    return(PathFinding.k_InfiniteCostValue);
                }
                else
                {
                    fCost = 1.41421356237f;
                }
            }
            else
            {
                fCost = 1f;
            }

            MapTileNode neighNode = GetNeighbor(neigborIdx) as MapTileNode;

            if (!_IsWallPassable(neighNode))
            {
                return(PathFinding.k_InfiniteCostValue);
            }

            return(fCost);
        }
Beispiel #10
0
        protected void FixedUpdate()
        {
            if (m_curNode != null)
            {
                MapTileNode curTileNode = m_curNode.Value as MapTileNode;
                AutoTile    autoTile    = RpgMapHelper.GetAutoTileByPosition(transform.position, 0);
                if (
                    (autoTile.TileX != curTileNode.TileX || autoTile.TileY != curTileNode.TileY) ||
                    GetDistToTarget(autoTile) > MinDistToMoveNextTarget // wait until min dist is reached
                    )
                {
                    Vector3 vSeek = curTileNode.Position; vSeek.z = transform.position.z; // put at this object level
                    if (m_movingBehavior)
                    {
                        if (m_curNode.Next != null)
                        {
                            m_movingBehavior.Seek(vSeek);
                        }
                        else
                        {
                            m_movingBehavior.Arrive(vSeek);
                        }
                    }
                }
                else
                {
                    m_curNode = m_curNode.Next;
                }
            }

            //if (TargetPos != null) //TODO: TargetPos can't be null
            {
                int prevTileidx = m_startTileIdx;
                m_startTileIdx  = RpgMapHelper.GetTileIdxByPosition(TargetPos);
                m_isUpdatePath |= prevTileidx != m_startTileIdx;
                if (m_isUpdatePath)//|| !m_isComputing) //Removed to keep actor moving until reach the center of the node
                {
                    m_isUpdatePath = false;
                    m_endTileIdx   = RpgMapHelper.GetTileIdxByPosition(transform.position);
                    //now = Time.realtimeSinceStartup;
                    StopCoroutine("ComputePath");
                    StartCoroutine("ComputePath");
                }
            }

            //+++ Debug
            for (LinkedListNode <IPathNode> it = Path.First; it != null; it = it.Next)
            {
                MapTileNode mapTileNode0 = it.Value as MapTileNode;
                if (it.Next != null)
                {
                    MapTileNode mapTileNode1 = it.Next.Value as MapTileNode;
                    Vector3     v0           = mapTileNode0.Position;
                    Vector3     v1           = mapTileNode1.Position;
                    v0.z = transform.position.z;
                    v1.z = transform.position.z;
                    Debug.DrawLine(v0, v1, Color.red);
                }
            }
            //---
        }
 public IEnumerator GetRouteFromToAsync( int startIdx, int endIdx )
 {
     IPathNode start = GetMapTileNode(startIdx);
     EndNode = GetMapTileNode(endIdx);
     return m_pathFinding.ComputePathAsync(start, EndNode);
 }
        // special case for walls
        bool _IsWallPassable( MapTileNode neighNode )
        {
            AutoTileMap autoTileMap = AutoTileMap.Instance;
            AutoTileMap.eTileCollisionType collType = AutoTileMap.eTileCollisionType.EMPTY;
            AutoTileMap.eTileCollisionType collTypeNeigh = AutoTileMap.eTileCollisionType.EMPTY;
            for (int iLayer = autoTileMap.GetLayerCount() - 1; iLayer >= 0; --iLayer)
            {
                if (autoTileMap.MapLayers[iLayer].LayerType == AutoTileMap.eLayerType.Ground)
                {
                    AutoTileMap.AutoTile autoTile = autoTileMap.GetAutoTile(TileX, TileY, iLayer);
                    AutoTileMap.AutoTile autoTileNeigh = autoTileMap.GetAutoTile(neighNode.TileX, neighNode.TileY, iLayer);

                    if (autoTile.Id == autoTileNeigh.Id) // you can walk over two wall tiles if they have the same type
                    {
                        if (autoTile.Id >= 0)
                            return true;
                        else
                            continue;
                    }
                    else
                    {
                        // collType will keep the first collision type found of type wall or passable
                        if (collType != AutoTileMap.eTileCollisionType.PASSABLE && collType != AutoTileMap.eTileCollisionType.WALL)
                            collType = autoTile.Id >= 0 ? autoTileMap.Tileset.AutotileCollType[autoTile.Id] : AutoTileMap.eTileCollisionType.EMPTY;
                        if (collTypeNeigh != AutoTileMap.eTileCollisionType.PASSABLE && collTypeNeigh != AutoTileMap.eTileCollisionType.WALL)
                            collTypeNeigh = autoTileNeigh.Id >= 0 ? autoTileMap.Tileset.AutotileCollType[autoTileNeigh.Id] : AutoTileMap.eTileCollisionType.EMPTY;

                        if( collType == AutoTileMap.eTileCollisionType.PASSABLE && collTypeNeigh == AutoTileMap.eTileCollisionType.PASSABLE )
                        {
                            return true;
                        }
                        else if (collType == AutoTileMap.eTileCollisionType.WALL || collTypeNeigh == AutoTileMap.eTileCollisionType.WALL)
                        {
                            return false;
                        }
                    }
                }
            }
            return true;
        }
        // special case for walls
        bool _IsWallPassable( MapTileNode neighNode )
        {
            bool isPassableAutoTile1 = false;
            bool isPassableAutoTileNeigh1 = false;
            for (int iLayer = 1; iLayer >= 0; --iLayer)
            {
                AutoTileMap.AutoTile autoTile = AutoTileMap.Instance.GetAutoTile(TileX, TileY, iLayer);
                AutoTileMap.AutoTile autoTileNeigh = AutoTileMap.Instance.GetAutoTile(neighNode.TileX, neighNode.TileY, iLayer);
                if (iLayer == 1)
                {
                    isPassableAutoTile1 = (autoTile.Idx >= 0 && AutoTileMap.Instance.Tileset.AutotileCollType[autoTile.Idx] == AutoTileMap.eTileCollisionType.PASSABLE);
                    isPassableAutoTileNeigh1 = (autoTileNeigh.Idx >= 0 && AutoTileMap.Instance.Tileset.AutotileCollType[autoTileNeigh.Idx] == AutoTileMap.eTileCollisionType.PASSABLE);
                }

                if (autoTile.Idx == autoTileNeigh.Idx) // you can walk over two wall tiles if they have the same type
                {
                    continue;
                }
                else
                {
                    bool isWall = (autoTile.Idx >= 0 && AutoTileMap.Instance.Tileset.AutotileCollType[autoTile.Idx] == AutoTileMap.eTileCollisionType.WALL);
                    bool isWallNeigh = (autoTileNeigh.Idx >= 0 && AutoTileMap.Instance.Tileset.AutotileCollType[autoTileNeigh.Idx] == AutoTileMap.eTileCollisionType.WALL);
                    if (iLayer == 0)
                    { // even if it's a wall, a NONE tile over it make it walkable
                        isWall &= !isPassableAutoTile1;
                        isWallNeigh &= !isPassableAutoTileNeigh1;
                    }
                    if (isWall || isWallNeigh)
                    {
                        return false;
                    }
                }
            }
            return true;
        }