タワーデフェンスゲーム　Unity タレット設置機能 8/14 47-2 Upgradeボタンを押す処理を実装

# 概要
目次

https://qiita.com/RYA234/private/c3d52a0f4ab3258a494a


今回はUpgradeボタンをクリックするとタレットが強化されるよう処理を実装します。
従来はDボタンを押したら強化されましたが今回はUI経由で実行できるようにします。
下記事参照

https://qiita.com/RYA234/items/c861c08378533b145c4c


下gifアニメはタレット設置済みのNodeを選択してUpgradeボタンを押してタレットを強化している様子です。右側のインスペクターでTotalCoinが減少していることを確認できます。

![8-14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/9bee7822-2a87-5628-bd22-a7e205a6aced.gif)







# 開発環境

IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10

# UnityEditor上の設定
Updateボタンクリック時UIManager.UpgradeTurretメソッドを実行する様に設定します。


# 実装のポイント
新規クラスは無く、既存クラスの修正のみです。
UIManagerクラス：UpgradeTurretメソッドを追加します。
Turretクラス：UIManagerクラスがアクセスできるように　public TurretUpgradeを新規追加します。
TurretUpgradeクラス：他のクラスから実行できるように　UpdateTurretをpublicに変更します。
下図参照
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2a19b67e-581b-d182-218b-a6ea54fd2be2.png)


# コード部分

## UIManager

```diff_c_sharp:UIManager.cs
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class UIManager : Singleton<UIManager>
{
    [Header("Panels")]
    [SerializeField] private GameObject turretShopPanel;

    [SerializeField] private GameObject nodeUIPanel;
    [SerializeField] private TextMeshProUGUI upgradeText;
    [SerializeField] private TextMeshProUGUI sellText;
+    public TurretUpgrade TurretUpgrade { get; set; }
    private Node _currentNodeSelected;

    // 追加箇所
    public void CloseTurretShopPanel()
    {
        turretShopPanel.SetActive(false);
    }


+    public void UpgradeTurret()
+    {
+        _currentNodeSelected.Turrets.TurretUpgrade.UpgradeTurret();
+        UpdateUpgradeText();
+    }
    private void ShowNodeUI()
    { 
        nodeUIPanel.SetActive(true);
       // UpdateUpgradeText();
    }

+    private void UpdateUpgradeText()
+    {
+        upgradeText.text = _currentNodeSelected.Turrets.TurretUpgrade.UpgradeCost.ToString();
+    }
    private void NodeSelected(Node nodeSelected)
    {
        _currentNodeSelected = nodeSelected;
        if (_currentNodeSelected.IsEmpty())
        {
            turretShopPanel.SetActive(true);
        }
        else
        {
            ShowNodeUI();
        }
    }
    private void OnEnable()
    {
        Node.OnNodeSelected += NodeSelected;
    }

    private void OnDisable()
    {
        Node.OnNodeSelected -= NodeSelected;
    }
}



```


## TurretUpgrade

```diff_c_sharp:TurretUpgrade.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TurretUpgrade : MonoBehaviour
{
    
    [SerializeField] private int upgradeInitialCost;
    [SerializeField] private int upgradeCostIncremental;
    [SerializeField] private float damageIncremental;
    [SerializeField] private float delayReduce;
    private TurretProjectTile _turretProjectTile;
    
    public int UpgradeCost { get; set;}
    private void Start()
    {
        _turretProjectTile = GetComponent<TurretProjectTile>();
        UpgradeCost = upgradeInitialCost;
    }

-   private void UpgradeTurret()
+   public void UpgradeTurret()
   {
       if (CurrencySystem.Instance.TotalCoins >= UpgradeCost)
       {
           _turretProjectTile.Damage += damageIncremental;
           _turretProjectTile.DelayPerShot -= delayReduce;
           UpdateUpgrade();
       }
   }

   private void UpdateUpgrade()
   {
       CurrencySystem.Instance.RemoveCoins(UpgradeCost);
       UpgradeCost += upgradeCostIncremental;
   }
}


```

## Turrets

```diff_c_sharp:Turrets.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Turrets : MonoBehaviour
{
    [SerializeField] private float attackRange = 3f;
    public Enemy CurrentEnemyTarget { get; set; }
+    public TurretUpgrade TurretUpgrade { get; set; }
    
    private bool _gameStarted;

    private List<Enemy> _enemies;
    
    private void Start()
    {
        _gameStarted = true;
        _enemies = new List<Enemy>();
        
+        TurretUpgrade = GetComponent<TurretUpgrade>();
    }

    private void Update()
    {
        GetCurrentEnemyTarget();
        RotateTowardsTarget();
    }

    private void GetCurrentEnemyTarget()
    {
        if (_enemies.Count <= 0)
        {
            CurrentEnemyTarget = null;
            return;
        }

        CurrentEnemyTarget = _enemies[0];
    }

    private void RotateTowardsTarget()
    {
        if (CurrentEnemyTarget == null)
        {
            return;
        }

        Vector3 targetPos = CurrentEnemyTarget.transform.position - transform.position;
        float angle = Vector3.SignedAngle(transform.up, targetPos, transform.forward);
        transform.Rotate(0f,0f,angle);
    }
    
    private void OnTriggerEnter2D(Collider2D other)
    {
        if (other.CompareTag("Enemy"))
        {
            Enemy newEnemy = other.GetComponent<Enemy>();
            _enemies.Add(newEnemy);
        }

        // CurrentEnemyTarget = _enemies[0];
        
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        if(other.CompareTag("Enemy"))
        {
            Enemy enemy = other.GetComponent<Enemy>();
            if (_enemies.Contains(enemy))
            {
                _enemies.Remove(enemy);
            }
        }
    }

    private void OnDrawGizmos()
    {
        if (!_gameStarted)
        {
            GetComponent<CircleCollider2D>().radius = attackRange;
        }
        
        Gizmos.DrawWireSphere(transform.position, attackRange);
    }
}


```



# 参考




Section8 47

https://www.udemy.com/course/learn-how-to-create-a-2d-tower-defense-game-in-unity-2020/learn/lecture/23145742#content

github コミット分


https://github.com/RYA234/2DTowerDeffenceMyLearning/commit/7249f7d78ebf344457f227bc3f5596009a20a211