タワーデフェンスゲーム　Unity タレット設置機能 10/14　48 タレットを売る処理を実装する

# 概要

目次

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



今回は以下2点を実装します。
１．UpgradeUIでSellボタンを押すとタレットを売却できるようにする
　　具体的には選択したタレットを失って、所持金を増えるようにします。

２．タレットの売却値をUIで表示します。

以下gifアニメは、タレットを売却している様子です。
売却時CurrencySystemのTotalCoinsが増加（490→495）していることを確認できます。

![10-14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/79b58755-7012-93bf-ea3e-237e85784e38.gif)





# 開発環境

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

# UnityEditor上の設定
Upgradeボタンのクリック時にUIManager.SellTurretメソッドを実行するよう設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/1258b271-1216-5a51-51ca-b65e4a21e5aa.png)


UIManagerクラスにSellTextをアタッチします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/eab28c0f-5574-d954-c897-d1a96c491550.png)



# 実装のポイント

下図はupgradeボタンを押して実行する関数の順番
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/901149fc-f759-1b51-1147-606791d4aacf.png)


売却する金額をUI上に表示する流れ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/a0b18fe9-ff0b-08fe-cd03-3001460eb09b.png)


# コード部分

## TurretShopManager

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

public class TurretShopManager : MonoBehaviour
{
    [SerializeField] private GameObject turretCardPrefab;
    [SerializeField] private Transform turretPanelContainer;

    [Header("Turret Setting")] [SerializeField]
    private TurretSetting[] turrets;
    
    private Node _currentNodeSelected;

    private void Start()
    {
        for (int i = 0; i < turrets.Length; i++)
        {
            CreateTurretCard(turrets[i]);
        }
    }
    
    private void CreateTurretCard(TurretSetting turretSetting)
    {
        GameObject newInstance = Instantiate(turretCardPrefab, turretPanelContainer.position, Quaternion.identity);
        newInstance.transform.SetParent(turretPanelContainer);
        newInstance.transform.localScale = Vector3.one;

        TurretCard cardButton = newInstance.GetComponent<TurretCard>();
        cardButton.SetupTurretButton(turretSetting);
        
    }
    private void NodeSelected(Node nodeSelected)
    {
        _currentNodeSelected = nodeSelected;
    }

+    private void TurretSold()
+    {
+        _currentNodeSelected = null;
+    }
    

    private void PlaceTurret(TurretSetting turretSetting)
    {
        if (_currentNodeSelected != null)
        {
            GameObject turretInstance = Instantiate(turretSetting.TurretPrefab);
            turretInstance.transform.localPosition = _currentNodeSelected.transform.position;
            turretInstance.transform.parent = _currentNodeSelected.transform;
            
            Turrets turretPlaced = turretInstance.GetComponent<Turrets>();
            _currentNodeSelected.SetTurret(turretPlaced);
        }
    }

    private void OnEnable()
    {
        Node.OnNodeSelected += NodeSelected;
+        Node.OnTurretSold += TurretSold;
        TurretCard.OnPlaceTurret += PlaceTurret;
        
    }



    private void OnDisable()
    {
        Node.OnNodeSelected -= NodeSelected;
+        Node.OnTurretSold -= TurretSold;
        TurretCard.OnPlaceTurret -= PlaceTurret;
    }

}


```

## 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;
    [SerializeField] private TextMeshProUGUI turretLevelText;
    public TurretUpgrade TurretUpgrade { get; set; }
    private Node _currentNodeSelected;
    

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

    public void UpgradeTurret()
    {
        _currentNodeSelected.Turrets.TurretUpgrade.UpgradeTurret();
        UpdateUpgradeText();
        UpdateTurretLevel();
+        UpdateSellValue();
    }

+    public void SellTurret()
+    {
+        _currentNodeSelected.SellTurret();
+        _currentNodeSelected = null;
+        nodeUIPanel.SetActive(false);
+        
+    }
    private void ShowNodeUI()
    { 
        nodeUIPanel.SetActive(true);
        UpdateUpgradeText();
        UpdateTurretLevel();
        UpdateSellValue();
    }

    private void UpdateUpgradeText()
    {
        upgradeText.text = _currentNodeSelected.Turrets.TurretUpgrade.UpgradeCost.ToString();
    }

    private void UpdateTurretLevel()
    {
        turretLevelText.text = $"Level {_currentNodeSelected.Turrets.TurretUpgrade.Level}";
    }

+    private void UpdateSellValue()
+    {
+        int sellAmount = _currentNodeSelected.Turrets.TurretUpgrade.GetSellValue();
+        sellText.text = sellAmount.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;
    }
}


```

## Node

```diff_c_sharp:Node.cs
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class Node : MonoBehaviour
{
    public static Action<Node> OnNodeSelected;
+    public static Action OnTurretSold;
    
    public Turrets Turrets { get; set; }

    public void SetTurret(Turrets turrets)
    {
        Turrets = turrets;
    }

    public bool IsEmpty()
    {
        return Turrets == null;
    }

    public void SelectTurret()
    {
        OnNodeSelected?.Invoke(this);
    }

+    public void SellTurret()
+    {
+        if (!IsEmpty())
+        {
+            CurrencySystem.Instance.AddCoins(Turrets.TurretUpgrade.UpgradeCost);
+            Destroy(Turrets.gameObject);
+            Turrets = null;
+            OnTurretSold?.Invoke();
+        }
+    }
}


```

## 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 Level { get; set; }
+    [Header("Sell")] [SerializeField] private float sellPert;
+    public float SellPerc { get; set; }
    
    
    public int UpgradeCost { get; set;}
    private void Start()
    {
        _turretProjectTile = GetComponent<TurretProjectTile>();
        UpgradeCost = upgradeInitialCost;
+        SellPerc = sellPert;
        Level = 1;
    }


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

+   public int GetSellValue()
+   {
+       int sellValue = Mathf.RoundToInt(UpgradeCost * SellPerc);
+       return sellValue;
+   }

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


```



# 参考




Section1

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

github コミット分

https://github.com/RYA234/2DTowerDeffenceMyLearning/commit/7a0e01cca53df35ad8f846f438cdd4f7c6b777e1#diff-551fbd16a1030b416b24e57d93084acfc07594060f1fc316f909fd3c64c68a01