//analyse the grid to know where the unit should move to private Tile Analyse(Unit unit, _AIMode activeMode) { //get all wakable tiles in range first List <Tile> walkableTilesInRange = GridManager.GetTilesWithinDistance(unit.tile, unit.GetEffectiveMoveRange(), true); walkableTilesInRange.Add(unit.tile); //get all visible hostile List <Unit> allHostileInSight = FactionManager.GetAllHostileUnit(unit.factionID); if (GameControl.EnableFogOfWar()) { for (int i = 0; i < allHostileInSight.Count; i++) { if (!FogOfWar.IsTileVisibleToFaction(allHostileInSight[i].tile, unit.factionID)) { allHostileInSight.RemoveAt(i); i -= 1; } } } //if cover system is in used if (GameControl.EnableCover()) { Tile tile = AnalyseCoverSystem(unit, walkableTilesInRange, allHostileInSight); if (tile != null) { return(tile); } } //if there are hostile if (allHostileInSight.Count > 0) { //fill up the walkableTilesInRange hostile list //then filter thru walkableTilesInRange, those that have a hostile in range will be add to a tilesWithHostileInRange List <Tile> tilesWithHostileInRange = new List <Tile>(); GridManager.SetupHostileInRangeforTile(unit, walkableTilesInRange); for (int i = 0; i < walkableTilesInRange.Count; i++) { if (walkableTilesInRange[i].GetHostileInRange().Count > 0) { tilesWithHostileInRange.Add(walkableTilesInRange[i]); } } //if the tilesWithHostileInRange is not empty after the process, means there's tiles which the unit can move into and attack //return one of those in the tilesWithHostileInRange so the unit can attack if (tilesWithHostileInRange.Count > 0) { //if the unit current tile is one of those tiles with hostile, just stay put and attack if (tilesWithHostileInRange.Contains(unit.tile)) { //randomize it a bit so the unit do move around but not stay in place all the time if (Random.Range(0f, 1f) > 0.25f) { return(unit.tile); } } return(tilesWithHostileInRange[Random.Range(0, tilesWithHostileInRange.Count)]); } } //if there's not potential target at all, check if the unit has any previous attacker //if there are, go after the last attacker if (unit.lastAttacker != null) { return(unit.lastAttacker.tile); } //for aggresive mode with FogOfWar disabled, try move towards the nearest unit if (activeMode == _AIMode.Aggressive && Random.Range(0f, 1f) > 0.25f) { List <Unit> allHostile = FactionManager.GetAllHostileUnit(unit.factionID); float nearest = Mathf.Infinity; int nearestIndex = 0; for (int i = 0; i < allHostile.Count; i++) { float dist = GridManager.GetDistance(allHostile[i].tile, unit.tile); if (dist < nearest) { nearest = dist; nearestIndex = i; } } return(allHostile[nearestIndex].tile); } //if there's really no hostile to go after, then just move randomly in one of the walkable int rand = Random.Range(0, walkableTilesInRange.Count); //clear in hostileInRange list for all moveable tile so, just in case the list is not empty (hostileInRange dont clear after each move) //so the unit dont try to attack anything when it moves into the targetTile walkableTilesInRange[rand].SetHostileInRange(new List <Tile>()); return(walkableTilesInRange[rand]); }