Пример #1
0
    /// <summary>
    /// ダメージ値を計算します
    /// </summary>
    /// <param name="attacker">Attacker.</param>
    public int CalcurateDamageValue(Main_Unit attacker)
    {
        // 三つ巴的な相性ダメージ Kuro < Shiro < Tora < Kuro ...
        var unitTypeBonus = new float[] { 1f, 2f, 0.5f }[(((int)attacker.unitType - (int)unitType) + 3) % 3];
        var damage        = Mathf.RoundToInt(attacker.AttackPower * unitTypeBonus * (1f - attacker.Cell.ReduceRate));

        return(damage);
    }
 /// <summary>
 /// 対象ユニットに攻撃します
 /// </summary>
 /// <param name="fromUnit">From unit.</param>
 /// <param name="toUnit">To unit.</param>
 public void AttackTo(Main_Unit fromUnit, Main_Unit toUnit)
 {
     Battle_SceneController.attacker = fromUnit;
     Battle_SceneController.defender = toUnit;
     SceneManager.LoadScene("Battle", LoadSceneMode.Additive);
     ClearHighlight();
     FocusingUnit.IsMoved = true;
 }
    /// <summary>
    /// 敵ユニットに攻撃可能となるマスを取得します
    /// </summary>
    /// <returns>The attack base cells.</returns>
    /// <param name="unit">Unit.</param>
    Main_Cell[] GetAttackBaseCells(Main_Unit unit)
    {
        var cells = new List <Main_Cell>();

        foreach (var enemyUnit in map.GetEnemyUnits())
        {
            cells.AddRange(map.GetCellsByDistance(enemyUnit.Cell, unit.attackRangeMin, unit.attackRangeMax).Where(c => c.Cost < 999));
        }
        return(cells.Distinct().ToArray());
    }
 /// <summary>
 /// 移動の終了を待つコルーチン
 /// </summary>
 /// <returns>The move coroutine.</returns>
 /// <param name="unit">Unit.</param>
 /// <param name="cell">Cell.</param>
 IEnumerator WaitMoveCoroutine(Main_Unit unit, Main_Cell cell)
 {
     while (true)
     {
         if (cell.Unit == unit)
         {
             break;
         }
         yield return(new WaitForSeconds(0.1f));
     }
     yield return(new WaitForSeconds(0.5f));
 }
 void RefreshImages(List <Image> images, Main_Unit unit, bool needToAnimate = false)
 {
     for (var i = images.Count; i > Mathf.CeilToInt((float)unit.Life / (float)unit.LifeMax * 10f); i--)
     {
         var index = Random.Range(0, images.Count);
         if (needToAnimate)
         {
             var image = images[index];
             image.transform.DOLocalMoveY(image.transform.localPosition.y - 100f, 0.3f)
             .OnComplete(() =>
             {
                 Destroy(image.gameObject);
             });
         }
         else
         {
             Destroy(images[index].gameObject);
         }
         images.RemoveAt(index);
     }
 }
    /// <summary>
    /// 指定座標にユニットを配置します
    /// </summary>
    /// <param name="x">The x coordinate.</param>
    /// <param name="y">The y coordinate.</param>
    /// <param name="unitPrefab">Unit prefab.</param>
    public void PutUnit(int x, int y, Main_Unit unitPrefab, Main_Unit.Teams team)
    {
        var unit = Instantiate(unitPrefab);

        unit.team = team;
        switch (unit.team)
        {
        case Main_Unit.Teams.Player2:
            // 敵ユニットはちょっと色を変えて反転
            var image = unit.GetComponent <Image>();
            image.color = new Color(1f, 0.7f, 0.7f);
            var scale = image.transform.localScale;
            scale.x *= -1f;
            image.transform.localScale = scale;
            break;
        }
        unit.gameObject.SetActive(true);
        unit.transform.SetParent(unitContainer);
        unit.transform.position = cells.First(c => c.X == x && c.Y == y).transform.position;
        unit.x = x;
        unit.y = y;
    }
    /// <summary>
    /// ユニットを対象のマスに移動させます
    /// </summary>
    /// <param name="cell">Cell.</param>
    public void MoveTo(Main_Unit unit, Main_Cell cell)
    {
        ClearHighlight();
        var routeCells = CalculateRouteCells(unit.x, unit.y, unit.moveAmount, cell);
        var sequence   = DOTween.Sequence();

        for (var i = 1; i < routeCells.Length; i++)
        {
            var routeCell = routeCells[i];
            sequence.Append(unit.transform.DOMove(routeCell.transform.position, 0.1f).SetEase(Ease.Linear));
        }
        sequence.OnComplete(() =>
        {
            unit.x = routeCells[routeCells.Length - 1].X;
            unit.y = routeCells[routeCells.Length - 1].Y;
            // 攻撃可能範囲のチェック
            var isAttackable = HighlightAttackableCells(unit.x, unit.y, unit.attackRangeMin, unit.attackRangeMax);
            if (!isAttackable)
            {
                unit.IsMoved = true;
            }
        });
    }
    IEnumerator AttackIfPossibleCoroutine(Main_Unit unit)
    {
        var attackableCells = map.GetAttackableCells();

        if (0 < attackableCells.Length)
        {
            if (Random.Range(0, 100) < randomizeAttackTarget)
            {
                // ランダムで対象を選ぶ
                attackableCells[Random.Range(0, attackableCells.Length)].Unit.OnClick();
            }
            else
            {
                // 攻撃可能なマスのうち、できるだけ倒せる/大ダメージを与えられる/反撃が痛くないマスに攻撃
                attackableCells.OrderByDescending(x =>
                {
                    var damageValue = x.Unit.CalcurateDamageValue(unit);
                    return(damageValue * (x.Unit.Life <= damageValue ? 10 : 1) - unit.CalcurateDamageValue(x.Unit));
                }).First().Unit.OnClick();
            }
            yield return(WaitBattleCoroutine());
        }
    }
Пример #9
0
 /// <summary>
 /// ダメージを与えます
 /// </summary>
 /// <param name="attacker">Attacker.</param>
 public void Damage(Main_Unit attacker)
 {
     life = Mathf.Max(0, life - CalcurateDamageValue(attacker));
 }
    IEnumerator MoveAndAttackCoroutine(Main_Unit unit)
    {
        // 移動可能な全てのマスまでの移動コストを取得
        var moveCosts = map.GetMoveCostToAllCells(unit.Cell);

        var attackBaseCells = GetAttackBaseCells(unit).ToList();

        if (attackBaseCells.Count() == 0)
        {
            // 攻撃拠点となるマスが無いなら行動終了
            yield return(new WaitForSeconds(0.5f));

            unit.IsMoved = true;
            yield return(new WaitForSeconds(0.5f));

            yield break;
        }

        // 攻撃拠点となるマスのうち、一番近い場所を目標地点とする
        var targetCell = attackBaseCells.OrderBy(cell => moveCosts.First(cost =>
        {
            return(cost.coordinate.x == unit.Cell.X && cost.coordinate.y == unit.Cell.Y);
        }).value).First();

        // ユニットを選択
        unit.OnClick();

        var route        = map.CalcurateRouteCoordinatesAndMoveAmount(unit.Cell, targetCell);
        var movableCells = map.GetMovableCells().ToList();

        if (movableCells.Count == 0)
        {
            yield return(AttackIfPossibleCoroutine(unit));

            if (!unit.IsMoved)
            {
                // 行動不能な場合は行動終了
                unit.OnClick();
                yield return(new WaitForSeconds(0.5f));

                unit.IsMoved = true;
                yield return(new WaitForSeconds(0.5f));
            }
        }
        else
        {
            // 自分の居るマスも移動先の選択肢に含める
            movableCells.Add(unit.Cell);
            var moveTargetCell = movableCells.OrderByDescending(c =>
            {
                var matchedRoute = route.FirstOrDefault(r => r.coordinate.x == c.X && r.coordinate.y == c.Y);
                return((null != matchedRoute ? matchedRoute.value : 0) +
                       c.ReduceRate * cellReduceRateImportance);
            }).First();

            if (moveTargetCell != unit.Cell)
            {
                yield return(new WaitForSeconds(0.5f));

                moveTargetCell.OnClick();
                // 移動完了を待つ
                yield return(WaitMoveCoroutine(unit, moveTargetCell));
            }

            yield return(AttackIfPossibleCoroutine(unit));
        }
    }