/* * ExecuteMovementGivenTarget * * given a target to move towards, find the * closest tile and move that way * * @param Unit unit - the unit that is undergoing the movement * @param Vector3 target - the vector to optimistically move towards * @returns void */ public void ExecuteMovementGivenTarget(Unit unit, Vector3 target) { //get a list of walkable tiles around the unit List <Tiles> walkable = GetArea.GetAreaOfSafeMoveable(map.GetTileAtPos(unit.transform.position), unit.movementPoints, map, unit); //worst possible score to start float bestMoveScore = float.MaxValue; //reference to the best tile that has been found Tiles bestTargetTile = null; //get the size of the walkable list int walkSize = walkable.Count; //iterate through all walkable tiles for (int i = 0; i < walkSize; i++) { //store in a temp variable Tiles tile = walkable[i]; //get the squared distance to the tile float sqrDistance = (tile.transform.position - target).sqrMagnitude; if (sqrDistance < bestMoveScore && tile.unit == null) { //bestTargetTile the best score bestTargetTile = tile; bestMoveScore = sqrDistance; } } //move towards the best tile if one was found if (bestTargetTile != null) { Move(unit, bestTargetTile.pos); } }
/* * Update * overrides UnitCommand's Update() * * called once per frame while the command is active * * @returns void */ public override void Update() { if (m_tilePath == null) { //get the start and end of the path Tiles startingTile = map.GetTileAtPos(unit.transform.position); startingTile.unit = null; //get the tile path to follow if (isSafeMove) { m_tilePath = AStar.GetSafeAStarPath(startingTile, endTile, unit, GetArea.GetAreaOfSafeMoveable(startingTile, unit.movementPoints, map, unit)); } else { m_tilePath = AStar.GetAStarPath(startingTile, endTile, unit); } //the path is clear, and the unit can move there if (m_tilePath.Count > 0 && m_tilePath.Count <= unit.movementPoints) { //subtract the path distance from the movement points unit.movementPoints -= m_tilePath.Count; startingTile.unit = null; endTile.unit = unit; } else { //Stop walking Anim if (unit.ArtLink != null) { unit.ArtLink.SetBool("IsWalking", false); } //the path failed startingTile.unit = unit; failedCallback(); return; } } m_timer += Time.deltaTime; //check if there is still a path to follow if (m_tilePath.Count > 0 && m_timer > m_waitTime) { if (m_finishedWaiting == false) { m_finishedWaiting = true; if (unit.ArtLink != null) { unit.ArtLink.SetBool("IsWalking", true); } } //get the next position to go to Tiles nextTile = m_tilePath[0]; //the 3D target of the movement Vector3 target = new Vector3(nextTile.pos.x, 0.15f, nextTile.pos.z); Vector3 relative = target - unit.transform.position; if (relative.magnitude < unit.movementSpeed * Time.deltaTime) { //this is a healing tile, heal the unit if (nextTile.IsHealing(false, unit)) { unit.Heal(GameManagment.stats.tileHealthGained); } //this is a trap tile, it could kill the unit if (nextTile.tileType == eTileType.PLACABLETRAP || nextTile.tileType == eTileType.DAMAGE) { m_timer = 0; m_finishedWaiting = false; if (unit.ArtLink != null) { unit.ArtLink.SetTrigger("TakeDamage"); } unit.Defend(GameManagment.stats.trapTileDamage); //explosion is required if (nextTile.tileType == eTileType.PLACABLETRAP) { //reset the explosion ParticleLibrary.explosionSystem.transform.position = nextTile.transform.position; ParticleLibrary.explosionSystem.time = 0.0f; ParticleLibrary.explosionSystem.Play(); } //Stop walking Anim if (unit.ArtLink != null) { unit.ArtLink.SetBool("IsWalking", false); } } unit.transform.position = target; m_tilePath.RemoveAt(0); if (unit.playerID == 0) { StatisticsTracker.tilesCrossed++; } } else { unit.transform.position += relative.normalized * unit.movementSpeed * Time.deltaTime; } } else if (m_timer > m_waitTime) { if (endTile.tileType == eTileType.PLACABLEDEFENSE || endTile.tileType == eTileType.DEFENSE) { //defensive buff endTile.unit.armour = endTile.unit.baseArmour + 1; } else { //remove the defensive buff endTile.unit.armour = endTile.unit.baseArmour; } successCallback(); //Stop walking Anim if (unit.ArtLink != null) { unit.ArtLink.SetBool("IsWalking", false); } return; } }