タワーデフェンスゲーム　Unity タレット設置機能 5/14　45-2 UIのタレットボタンを押すと　ノードオブジェクト上にタレットが生成するよう実装

# 概要

目次

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



今回はタレットボタンが押したら、タレットが生成するよう実装します。
以下gifアニメはその時の様子です。

![5-14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d80b519c-e82c-f8ed-067f-968aae011dd6.gif)



# 開発環境

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

# UnityEditor上の設定
タレットボタンのクリック時を実行するよう設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/742dd719-1b72-e4aa-7dc2-9006a3bab518.png)



# 実装のポイント
既存クラスのTurretCardとTurretShopManagerでオブサーバーパターンを作成します。
ObservaleはTurretShopManager ObserverはTurretCardです。
TurretCard.PlaceTurret→TurretShopManager.PlaceTurretの順で実行します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/8c850635-83c9-12ab-2ff1-96bd4dffa6b7.png)



UIManagerはSingletonにしておきます。


# コード部分

## 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 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;
+        TurretCard.OnPlaceTurret += PlaceTurret;
    }



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

}


```

## UIManager

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

- public class UIManager : MonoBehaviour
+ public class UIManager : Singleton<UIManager>
{
    [SerializeField] private GameObject turretShopPanel;
    
    private Node _currentNodeSelected;
    
    private void NodeSelected(Node nodeSelected)
    {
        _currentNodeSelected = nodeSelected;
        if (_currentNodeSelected.IsEmpty())
        {
            turretShopPanel.SetActive(true);
        }
    }
    private void OnEnable()
    {
        Node.OnNodeSelected += NodeSelected;
    }

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


```

## TurretCard

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

public class TurretCard : MonoBehaviour
{
+    public static Action<TurretSetting> OnPlaceTurret;
    [SerializeField] private Image turretImage;
    [SerializeField] private TextMeshProUGUI turretCost;

    public TurretSetting TurretLoaded { get; set; }
    
    public void SetupTurretButton(TurretSetting turretSetting)
    {
        TurretLoaded = turretSetting;
        turretImage.sprite = turretSetting.TurretShopSprite;
        turretCost.text = turretSetting.TurretShopCost.ToString();
        
    }

+    public void PlaceTurret()
+    {
+        if (CurrencySystem.Instance.TotalCoins >= TurretLoaded.TurretShopCost)
+        {
+            CurrencySystem.Instance.RemoveCoins(TurretLoaded.TurretShopCost);
+            OnPlaceTurret?.Invoke(TurretLoaded);
+        }
+    }
    
}


```


# 参考




Section8 45


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/fe1851a6e2aac995128e187f4734f92f4279bce9