예제 #1
0
        //get a direct distance, regardless of the walkable state
        public int GetDistance(Tile tile1, Tile tile2)
        {
            if (GridManager.GetTileType() == _TileType.Hex)
            {
                float x = Mathf.Abs(tile1.x - tile2.x);
                float y = Mathf.Abs(tile1.y - tile2.y);
                float z = Mathf.Abs(tile1.z - tile2.z);
                return((int)((x + y + z) / 2));
            }
            else
            {
                float   tileSize = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio();
                Vector3 pos1     = tile1.GetPos();
                Vector3 pos2     = tile2.GetPos();

                int dx = (int)Mathf.Round(Mathf.Abs(pos1.x - pos2.x) / tileSize);
                int dz = (int)Mathf.Round(Mathf.Abs(pos1.z - pos2.z) / tileSize);

                if (GridManager.EnableDiagonalNeighbour())
                {
                    int min = Mathf.Min(dx, dz);
                    int max = Mathf.Max(dx, dz);

                    return(min + (max - min));
                }

                return(dx + dz);
            }
        }
예제 #2
0
        public static bool HasObstacle(Tile tile1, Tile tile2)
        {
            Vector3 pos1 = tile1.GetPos();
            Vector3 pos2 = tile2.GetPos();

            float   dist      = Vector3.Distance(pos2, pos1);
            Vector3 dir       = (pos2 - pos1).normalized;
            Vector3 dirO      = new Vector3(-dir.z, 0, dir.x).normalized;
            float   posOffset = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * 0.4f;

            LayerMask mask = 1 << TBTK.GetLayerObstacleFullCover() | 1 << TBTK.GetLayerObstacleHalfCover();

            if (Physics.Raycast(pos1, dir, dist, mask))
            {
                return(true);
            }
            if (Physics.Raycast(pos1 + dirO * posOffset, dir, dist, mask))
            {
                return(true);
            }
            if (Physics.Raycast(pos1 - dirO * posOffset, dir, dist, mask))
            {
                return(true);
            }

            return(false);
        }
예제 #3
0
 public void SetFogOfWarObj(Transform fogObjT)
 {
     fogOfWarObj = fogObjT.gameObject;
     fogOfWarObj.transform.position    = transform.position;
     fogOfWarObj.transform.parent      = transform.parent;
     fogOfWarObj.transform.localScale *= GridManager.GetGridToTileSizeRatio();
     //fogOfWarObj.SetActive(!visible);
 }
예제 #4
0
        //used in edit mode only
        public void AddWall(float angle, Tile neighbour, int wallType = 0)
        {
            if (neighbour == null)
            {
                return;
            }

            if (angle > 360)
            {
                angle -= 360;
            }

            if (IsWalled(angle))
            {
                return;
            }

            float gridSize = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio();

            if (type == _TileType.Square)
            {
                gridSize *= 2;
            }

                        #if UNITY_EDITOR
            Transform wallT = (Transform)PrefabUtility.InstantiatePrefab(GridManager.GetWallObstacleT(wallType));
            Undo.RecordObject(this, "Tile");
            Undo.RecordObject(neighbour, "NeighbourTile");
            Undo.RegisterCreatedObjectUndo(wallT.gameObject, "Wall");
                        #else
            Transform wallT = (Transform)Instantiate(GridManager.GetWallObstacleT(wallType));
                        #endif

            float wallTAngle = angle + 90;

            if (type == _TileType.Square)
            {
                wallTAngle = 360 - (angle - 90);
            }
            else if (type == _TileType.Hex)
            {
                wallTAngle = 360 - (angle - 90);
            }

            wallT.rotation    = Quaternion.Euler(0, wallTAngle, 0);
            wallT.position    = (GetPos() + neighbour.GetPos()) / 2;
            wallT.localScale *= gridSize;
            wallT.parent      = transform;
            wallList.Add(new Wall(angle, wallT));

            if ((angle += 180) >= 360)
            {
                angle -= 360;
            }

            neighbour.wallList.Add(new Wall(angle, wallT));
        }
        public static void InitCoverForTile(Tile tile)
        {
            List <Tile>  neighbourList = tile.GetNeighbourList();
            List <Cover> coverList     = new List <Cover>();

            for (int i = 0; i < tile.GetNeighbourList().Count; i++)
            {
                Vector3 dir  = (neighbourList[i].GetPos() - tile.GetPos()).normalized;
                float   dist = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * .75f;

                LayerMask  mask = 1 << TBTK.GetLayerObstacleFullCover() | 1 << TBTK.GetLayerObstacleHalfCover();
                RaycastHit hit;
                if (Physics.Raycast(tile.GetPos(), dir, out hit, dist, mask))
                {
                    Cover cover = new Cover();
                    cover.angle = Mathf.Round(Utilities.Vector2ToAngle(new Vector2(dir.x, dir.z)));

                    if (GridManager.GetTileType() == _TileType.Square)                          //when diagonal neighbour is enabled, avoid adding cover to diagonal neighbour
                    {
                        if (cover.angle % 90 != 0)
                        {
                            continue;
                        }
                    }

                    int layer = hit.transform.gameObject.layer;
                    if (layer == TBTK.GetLayerObstacleFullCover())
                    {
                        cover.type = _CoverType.Full;
                        Debug.DrawLine(tile.GetPos(), tile.GetPos() + dir * dist, Color.red, 2);
                    }
                    else if (layer == TBTK.GetLayerObstacleHalfCover())
                    {
                        cover.type = _CoverType.Half;
                        Debug.DrawLine(tile.GetPos(), tile.GetPos() + dir * dist, Color.white, 2);
                    }


                    if (GridManager.GetTileType() == _TileType.Square)
                    {
                        cover.overlayPos = tile.GetPos() + dir * dist * 0.4f;
                    }
                    else if (GridManager.GetTileType() == _TileType.Hex)
                    {
                        cover.overlayPos = tile.GetPos() + dir * dist * 0.35f;
                    }

                    float angleY = cover.angle + 90;
                    if (cover.angle == 30)
                    {
                        angleY = cover.angle + 30;
                    }
                    else if (cover.angle == 150)
                    {
                        angleY = cover.angle - 30;
                    }
                    else if (cover.angle == 210)
                    {
                        angleY = cover.angle + 30;
                    }
                    else if (cover.angle == 330)
                    {
                        angleY = cover.angle - 30;
                    }
                    cover.overlayRot = Quaternion.Euler(0, angleY, 0);

                    coverList.Add(cover);
                }
            }

            tile.coverList = coverList;
        }
예제 #6
0
        //search for a path, through walkable tile only
        //for normal movement, return the path in a list of hexTile
        public static List <Tile> SearchWalkableTile(Tile originTile, Tile destTile)
        {
            List <Tile> closeList = new List <Tile>();
            List <Tile> openList  = new List <Tile>();

            Tile currentTile = originTile;

            float currentLowestF = Mathf.Infinity;
            int   id             = 0;
            int   i = 0;

            while (true)
            {
                //if we have reach the destination
                if (currentTile == destTile)
                {
                    break;
                }

                //move currentNode to closeList;
                closeList.Add(currentTile);
                currentTile.aStar.listState = TileAStar._AStarListState.Close;

                //loop through the neighbour of current loop, calculate  score and stuff
                currentTile.aStar.ProcessWalkableNeighbour(destTile);

                //put all neighbour in openlist
                foreach (Tile neighbour in currentTile.aStar.GetNeighbourList(true))
                {
                    if (neighbour.aStar.listState == TileAStar._AStarListState.Unassigned || neighbour == destTile)
                    {
                        //~ //set the node state to open
                        neighbour.aStar.listState = TileAStar._AStarListState.Open;
                        openList.Add(neighbour);
                    }
                }

                //clear the current node, before getting a new one, so we know if there isnt any suitable next node
                currentTile = null;


                currentLowestF = Mathf.Infinity;
                id             = 0;
                for (i = 0; i < openList.Count; i++)
                {
                    if (openList[i].aStar.scoreF < currentLowestF)
                    {
                        currentLowestF = openList[i].aStar.scoreF;
                        currentTile    = openList[i];
                        id             = i;
                    }
                }


                //if there's no node left in openlist, path doesnt exist
                if (currentTile == null)
                {
                    break;
                }

                openList.RemoveAt(id);
            }

            if (currentTile == null)
            {
                float tileSize = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio();
                currentLowestF = Mathf.Infinity;
                for (i = 0; i < closeList.Count; i++)
                {
                    float dist = Vector3.Distance(destTile.GetPos(), closeList[i].GetPos());
                    if (dist < currentLowestF)
                    {
                        currentLowestF = dist;
                        currentTile    = closeList[i];
                        if (dist < tileSize * 1.5f)
                        {
                            break;
                        }
                    }
                }
            }

            List <Tile> path = new List <Tile>();

            while (currentTile != null)
            {
                if (currentTile == originTile || currentTile == currentTile.aStar.parent)
                {
                    break;
                }
                path.Add(currentTile);
                currentTile = currentTile.aStar.parent;
            }

            path = InvertTileArray(path);

            ResetGraph(destTile, openList, closeList);

            return(path);
        }
예제 #7
0
        public static bool InLOS(Tile tile1, Tile tile2, float peekFactor, bool debugging = false)
        {
            Vector3 pos1 = tile1.GetPos();
            Vector3 pos2 = tile2.GetPos();

            if (peekFactor < 0)
            {
                peekFactor = GameControl.GetPeekFactor();
            }

            float   dist      = Vector3.Distance(pos2, pos1);
            Vector3 dir       = (pos2 - pos1).normalized;
            Vector3 dirO      = new Vector3(-dir.z, 0, dir.x).normalized;
            float   posOffset = GridManager.GetTileSize() * GridManager.GetGridToTileSizeRatio() * peekFactor;

            LayerMask mask = 1 << TBTK.GetLayerObstacleFullCover();        // | 1<<LayerManager.GetLayerObstacleHalfCover();

            bool flag = false;

            if (!LOSRaycast(pos1, dir, dist, mask, debugging))
            {
                if (debugging)
                {
                    flag = true;
                }
                else
                {
                    return(true);
                }
            }

            if (posOffset == 0)
            {
                return(flag);
            }

            if (!LOSRaycast(pos1 + dirO * posOffset, dir, dist, mask, debugging))
            {
                if (debugging)
                {
                    flag = true;
                }
                else
                {
                    return(true);
                }
            }
            if (!LOSRaycast(pos1 - dirO * posOffset, dir, dist, mask, debugging))
            {
                if (debugging)
                {
                    flag = true;
                }
                else
                {
                    return(true);
                }
            }

            return(flag);
        }
예제 #8
0
        public void AddObstacle(int obsType, float gridSize)
        {
            if (obstacleT != null)
            {
                if (obstacleT.gameObject.layer == TBTK.GetLayerObstacleHalfCover() && obsType == 1)
                {
                    return;
                }
                if (obstacleT.gameObject.layer == TBTK.GetLayerObstacleFullCover() && obsType == 2)
                {
                    return;
                }

                                #if UNITY_EDITOR
                Undo.DestroyObjectImmediate(obstacleT.gameObject);
                                #endif
            }

            if (wallList.Count > 0)
            {
                if (!Application.isPlaying)
                {
                    Grid grid = GridManager.GetInstance().GetGrid();
                    while (wallList.Count > 0)
                    {
                        RemoveWall(wallList[0].angle, grid.GetNeighbourInDir(this, wallList[0].angle));
                    }
                }
                else
                {
                    while (wallList.Count > 0)
                    {
                        RemoveWall(wallList[0].angle, GetNeighbourFromAngle(wallList[0].angle));
                    }
                }
            }

            //float gridSize=GridManager.GetTileSize();

                        #if UNITY_EDITOR
            Transform obsT = (Transform)PrefabUtility.InstantiatePrefab(GridManager.GetObstacleT(obsType));
            Undo.RecordObject(this, "Tile");
            Undo.RecordObject(GetComponent <Renderer>(), "TileRenderer");
            Undo.RegisterCreatedObjectUndo(obsT.gameObject, "Obstacle");
                        #else
            Transform obsT = (Transform)Instantiate(GridManager.GetObstacleT(obsType));
                        #endif



            //~ float offsetY=0;
            //~ if(type==_TileType.Square){
            //~ if(obsType==1)offsetY=obsT.localScale.z*gridSize/4;
            //~ if(obsType==2)offsetY=obsT.localScale.z*gridSize/2;
            //~ }
            //~ else if(type==_TileType.Hex) offsetY=obsT.localScale.z*gridSize/4;

            obsT.position = GetPos();          //+new Vector3(0, offsetY, 0);

            obsT.localScale *= gridSize * GridManager.GetGridToTileSizeRatio();
            obsT.parent      = transform;

            obstacleT = obsT;
            walkable  = false;

            GetComponent <Renderer>().enabled = false;

            //SetState(_TileState.Default);
        }