【Unity】タワーディフェンス(12) 砲台情報をサイドバーに表示【クソゲー制作】

タワーディフェンスを作る(12)

Unity初心者が2Dタワーディフェンスを作っています。今回は砲台をクリックしたときに砲台の情報をサイドバーに表示する処理を実装します。

環境
  • Mac mini (M1, 2020)
  • Unity 2022.3.36f1
目次

砲台情報パネルを作る

まずは、砲台情報を表示するためのパネルをサイドバー上に作成します。完成図はこんな感じです。

タワーディフェンス140
STEP

ヒエラルキーのSideBarオブジェクト上で右クリック「UI > Panel」を選択して、SideBarの配下にPanelオブジェクトを作成します。名前をTurretInfoにします。

タワーディフェンス141
STEP

TurretInfoオブジェクトの位置と色を適当に調整しましょう。

STEP

インスペクターの「Add Component」ボタンをクリックして、「Vertical Layout Group」コンポーネントを追加します。

タワーディフェンス142

これは、子オブジェクトを縦方向に整列させるための便利なコンポーネントです。

STEP

TurretInfoオブジェクトの配下にTextMeshProオブジェクトを作成します。

TextMeshProの設定
  1. 「TMP Importer」ウインドウが表示されたら「Import TMP Essentials」ボタンをクリックします。
  2. 「Assets > Fonts」フォルダを作成して、日本語フォントをインポートします。
  3. メニューの「Window > TextMeshPro > Font Asset Creator」を選択して「Font Asset Creator」ウインドウを開きます。
  4. 次のように設定して「Generate Font Atlas」ボタンをクリックします。
    タワーディフェンス143
  5. 次の画面で「Save」ボタンを押して保存します。
STEP

TurretInfoの下には、砲台の名前、攻撃力、攻撃範囲、攻撃速度などの情報を表示するためのTextMeshProオブジェクトを作成します。こんな感じです。

タワーディフェンス140
STEP

Vertical Layout Groupの設定をして、子オブジェクトがいい感じに並ぶようにします。

タワーディフェンス144
STEP

インスペクター左上のチェックを外してTurretInfo非表示にしておきます。

タワーディフェンス145

SideBarManagerスクリプトの作成

サイドバーを管理するためのスクリプトを作ります。

STEP

「Assets > Scripts」フォルダの下にC#スクリプトを作成します。名前を「SideBarManager」にします。内容は次のとおりです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro; // TextMeshProを使うために必要な宣言

public class SideBarManager : MonoBehaviour
{
    [SerializeField] private GameObject turretInfo; // 砲台情報パネルのオブジェクト
    [SerializeField] private TextMeshProUGUI turretNameText; // 砲台の名前のテキスト
    [SerializeField] private TextMeshProUGUI buildingCostText; // 建設コストのテキスト
    [SerializeField] private TextMeshProUGUI attackPowerText; // 攻撃力のテキスト
    [SerializeField] private TextMeshProUGUI attackIntervalText; // 攻撃速度のテキスト
    [SerializeField] private TextMeshProUGUI attackRangeText; // 攻撃範囲のテキスト

    /// <summary>
    /// 砲台情報を表示
    /// </summary>
    public void ShowTurretInfo(TurretSetting.TurretData turretData)
    {
        turretNameText.text = turretData.name;
        buildingCostText.text = turretData.buildingCost.ToString();
        attackPowerText.text = turretData.attackPower.ToString();
        attackIntervalText.text = turretData.attackInterval.ToString();
        attackRangeText.text = turretData.attackRange.ToString();
        turretInfo.SetActive(true); // 砲台情報パネルを表示する
    }

    /// <summary>
    /// 砲台情報を非表示
    /// </summary>
    public void HideTurretInfo()
    {
        turretInfo.SetActive(false); // 砲台情報パネルを非表示にする
    }
}

ShowTurretInfo()は砲台情報の各テキストオブジェクトにデータを代入してTurretInfoオブジェクトを表示するメソッドです。

HideTurretInfo()はTurretInfoオブジェクトを非表示にするメソッドです。とてもシンプルですね。

STEP

SideBarManagerスクリプトをSideBarオブジェクトにドラッグ&ドロップしてアタッチします。

STEP

SideBarオブジェクトのインスペクターで「Side Bar Manager (Script)」下の各変数にオブジェクトをドラッグ&ドロップしてアサインします。

サイドバーの砲台アイコン選択時

まずは、サイドバーの砲台アイコンをクリックしたときに砲台情報を表示する処理を実装します。

STEP

TurretGeneratorスクリプトを修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Tilemaps; // Tilemapを使うために必要な宣言

public class TurretGenerator : MonoBehaviour
{
    [SerializeField] private GameObject turretPrefab; // 砲台のプレハブ
    [SerializeField] private Grid grid; // Grid_BaseのGrid、Tilemapの座標を取得するため
    [SerializeField] private Tilemap tilemaps; // Grid_WayのTilemap
    [SerializeField] private GameObject selectedTurretIcon; // 追随する砲台アイコン
    [SerializeField] private GameObject selectedTurretHead; // 追随する砲台アイコンの砲身
    [SerializeField] private GameObject selectedTurretCross; // バツ印のオブジェクト
    // ここから 変数追加
    [SerializeField] private SideBarManager sideBarManager; // SideBarmanagerスクリプトの参照
    // ここまで
    private Vector3Int gridPos;  // Tilemapのセル座標
    private HashSet<Vector3Int> occupiedCells = new HashSet<Vector3Int>(); // 砲台配置済みセルを代入
    private TurretSetting.TurretData selectedTurretData = null; // 選択された砲台のデータ

    void Update()
    {
        // ...省略...
    }

    /// <summary>
    /// 砲台生成
    /// </summary>
    /// <param name="gridPos"></param>
    private void GenerateTurret(Vector3Int gridPos)
    {
        // ...省略...
    }

    /// <summary>
    /// 砲台を選択する
    /// </summary>
    public void SelectTurret(int index)
    {
        selectedTurretData = DBManager.instance.turretSetting.turretDataList[index];
        Debug.Log($"{selectedTurretData.name} を選択");
        // アイコンを表示
        selectedTurretIcon.SetActive(true);
        // 砲身のスプライトを設定
        SpriteRenderer iconRenderer = selectedTurretHead.GetComponent<SpriteRenderer>();
        iconRenderer.sprite = selectedTurretData.turretHeadSprite;
        // ここから
        sideBarManager.ShowTurretInfo(selectedTurretData); // 砲台情報を表示
        // ここまで
    }
}

砲台を選択したときにShowTurretInfo()を呼び出して砲台情報を表示します。引数として選択した砲台のデータ(selectedTurretData)を渡しています。

STEP

TurretGeneratorオブジェクトのインスペクターで「TurretGenerator (Script) > Side Bar Manager」SideBarオブジェクトをドラッグ&ドロップしてアサインします。

以上で、サイドバーの砲台アイコンをクリックしたときに砲台情報が表示されるようになりました。

マップの砲台選択時

マップ上に設置された砲台をクリックしたときに砲台情報を表示する処理を実装します。こちらはかなりややこしい処理になります。

STEP

GameManagerスクリプトを修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// ここから
using UnityEngine.EventSystems; // EventSystemを使用するために必要
// ここまで

public class GameManager : MonoBehaviour
{
    [SerializeField] private int targetFrameRate = 60; // フレームレートの目標値
    [SerializeField] private EnemySpawner enemySpawner;
    // ここから
    [SerializeField] private SideBarManager sideBarManager; // SideBarmanagerスクリプトの参照
    // ここまで
    public bool isSpawning; // 敵を生成するかどうかを制御するフラグ
    public int spawnInterval; // 敵を生成する間隔(単位はフレーム)
    public int spawnedEnemyCount; // これまでに生成された敵の数
    public int maxSpawnCount; // 敵の最大生成数

    void Awake()
    {
        // ...省略...
    }

    void Start()
    {
        // ...省略...
    }

    // ここから
    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // マウスの左ボタンがクリックされたら
        {
            DetectClick();
        }
    }
    // ここまで

    /// <summary>
    /// フレームレートを固定
    /// </summary>
    private void FixFrameRate()
    {
        // ...省略...
    }

    /// <summary>
    /// 敵の情報をListに追加
    /// </summary>
    public void AddEnemyToList()
    {
        // ...省略...
    }

    /// <summary>
    /// 敵の生成が上限に達したかを確認
    /// </summary>
    public void CheckSpawnLimit()
    {
        // ...省略...
    }

    // ここから
    /// <summary>
    /// マウスのクリックを検出
    /// </summary>
    void DetectClick()
    {
        // UIがクリックされた場合は何もしない
        if (EventSystem.current.IsPointerOverGameObject())
        {
            return;
        }
        // クリック位置のスクリーン座標をワールド座標に変換
        Vector2 worldPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        // クリック位置から見えるオブジェクトに対してレイキャスト(Ignore Raycastレイヤーを除外)
        RaycastHit2D hit = Physics2D.Raycast(worldPoint, Vector2.zero, Mathf.Infinity, ~LayerMask.GetMask("Ignore Raycast"));
        if (hit.collider != null) // クリックしたオブジェクトにコライダーがあれば
        {
            TurretController turret = hit.collider.GetComponent<TurretController>(); // TurretControllerを取得
            if (turret != null) // クリックしたオブジェクトが砲台ならば
            {
                turret.OnTurretClicked(turret); // 砲台情報を表示
                return;
            }
        }
        // 砲台以外をクリックした場合は砲台情報パネルを非表示
        sideBarManager.HideTurretInfo();
    }
    // ここまで
}

Update()は毎フレーム呼び出されるメソッドです。この中でマウスの左ボタンクリックが検出されたらDetectClick()メソッドを呼び出します。

71行目、EventSystem.current.IsPointerOverGameObject()は、マウスクリックがUIオブジェクト上で行われたかどうかを判定するためのメソッドです。UIがクリックされたときには何もしない(砲台情報パネルを非表示にしない)ようにしています。これは砲台情報パネル上のボタンをクリックできるようにするためです。

78行目、Physics2D.Raycast()を使ってクリック位置にあるオブジェクトを取得しています。

  • 第1引数: レイの開始位置(worldPointはクリック位置のワールド座標)
  • 第2引数: レイの進む方向(Vector2.zeroはゼロベクトルなので、その点にあるオブジェクトを指す)
  • 第3引数: レイの最大距離(Mathf.Infinityは無限の距離をあらわすが、方向がゼロベクトルなのでクリック位置の一点のみが対象になる)
  • 第4引数: レイヤーマスク(~LayerMask.GetMask("Ignore Raycast")でレイヤーがIgnore Raycastのオブジェクトを無視する)

79 – 87行目、クリックしたオブジェクトが砲台ならば、砲台情報を表示します。

なぜこんなにややこしいことをするのか

最初、私は砲台オブジェクトにButtonコンポーネントを追加してOnClick()でこの処理を実装しようとしました。でもダメでした。なぜならButtonコンポーネントはUIオブジェクトでしか動作しないからです。マップ上に設置された砲台はUIオブジェクトではありません。残念無念。

次に、砲台オブジェクトにコライダーを追加してOnMouseDown()でクリックを検知しようとしました。ダメでした。砲台オブジェクトの子オブジェクトにAttackRangeがあって、こいつもコライダーを持っています。そのコライダーにもクリックが反応してしまうのです。残念無念。

というわけで、レイキャストを使うことになりました。

レイキャストって何

で、レイキャストとは何かというと、ある点から特定の方向に向かって仮想の光線(レイ)を飛ばして衝突するオブジェクトを検出する機能のことです。

ここでは、クリックした点から同じ点にレイを飛ばして、レイヤーが”Ignore Raycast”ではないオブジェクトを検出しています。

STEP

GameManagerオブジェクトのインスペクターで「Game Manager (Script) > Side Bar Manager」SideBarオブジェクトをドラッグ&ドロップしてアサインします。

STEP

TurretControllerスクリプトを修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TurretController : MonoBehaviour
{
    [SerializeField] private int attackPower = 1; // 攻撃力
    [SerializeField] private float attackInterval = 60.0f; // 攻撃間隔(単位はフレーム)
    [SerializeField] private Transform turretHead; // 砲身のTransform
    [SerializeField] private GameObject shellPrefab; // 砲弾のプレハブ
    [SerializeField] private Transform firePoint; // 砲弾の発射位置
    [SerializeField] private CircleCollider2D attackRange; //攻撃範囲のコライダー
    [SerializeField] private SpriteRenderer turretHeadSpriteRenderer; // 砲身のSpriteRenderer
    private List<EnemyController> enemiesInRange = new List<EnemyController>(); // 攻撃範囲内の敵リスト
    private EnemyController targetEnemy = null; // 現在のターゲット
    private bool isAttacking = false; // 攻撃中フラグ
    private Coroutine attackCoroutine; // 現在の攻撃コルーチン
    // ここから
    private TurretSetting.TurretData turretData; // 砲台データ
    // ここまで

    private void Update()
    {
        // ...省略...
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        // ...省略...
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        // ...省略...
    }

    /// <summary>
    /// 砲台データを初期化
    /// </summary>
    // ここから
    //public void InitializeTurret(TurretSetting.TurretData turretData)
    public void InitializeTurret(TurretSetting.TurretData data)
    {
        turretData = data;
    // ここまで
        attackPower = turretData.attackPower; // 攻撃力を設定
        attackInterval = turretData.attackInterval; // 攻撃間隔を設定
        attackRange.radius = turretData.attackRange; // 攻撃範囲を設定
        turretHeadSpriteRenderer.sprite = turretData.turretHeadSprite; // 砲身の画像を設定
        Debug.Log($"砲台を初期化: {turretData.name}");
    }

    /// <summary>
    /// 砲台に最も近い敵を選択
    /// </summary>
    private void UpdateTargetEnemy()
    {
        // ...省略...
    }

    /// <summary>
    /// 攻撃間隔管理
    /// </summary>
    public IEnumerator ManageAttacks()
    {
        // ...省略...
    }

    /// <summary>
    /// 攻撃
    /// </summary>
    private void Attack()
    {
        // ...省略...
    }

    /// <summary>
    /// 砲身を敵の方向に回転させる
    /// </summary>
    private void RotateTurretHeadTowardsEnemy()
    {
        // ...省略...
    }

    // ここから
    /// <summary>
    /// 砲台がクリックされたときの処理
    /// </summary>
    public void OnTurretClicked(TurretController turret)
    {
        SideBarManager sideBarManager = FindObjectOfType<SideBarManager>();
        sideBarManager.ShowTurretInfo(turretData);
        Debug.Log($"クリックした砲台: {turretData.name}");
    }
    // ここまで
}

OnTurretClicked()を追加しました。マップ上の砲台がクリックされたときに砲台情報を表示するメソッドです。

STEP

「Assets > Prefabs > Turret」をダブルクリックしてTurretプレハブの編集モードに入ります。

Box Collider 2Dコンポーネントを追加して、「Is Trigger」のチェックを入れます。

タワーディフェンス146
STEP

AttackRangeオブジェクトのインスペクターで「Layer」「Ignore Raycast」に設定します。

タワーディフェンス147

砲台設置時は売却ボタンを押せないようにする

砲台情報パネルの下部に砲台の売却ボタンがあります。マップ上に設置した砲台を売却するためのボタンなのですが、砲台設置時には使わないので押せないようにしておきましょう。

STEP

SideBarManagerスクリプトを修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro; // TextMeshProを使うために必要な宣言
// ここから
using UnityEngine.UI; // UIを扱うために必要な宣言
// ここまで

public class SideBarManager : MonoBehaviour
{
    [SerializeField] private GameObject turretInfo; // 砲台情報パネルのオブジェクト
    [SerializeField] private TextMeshProUGUI turretNameText; // 砲台の名前のテキスト
    [SerializeField] private TextMeshProUGUI buildingCostText; // 建設コストのテキスト
    [SerializeField] private TextMeshProUGUI attackPowerText; // 攻撃力のテキスト
    [SerializeField] private TextMeshProUGUI attackIntervalText; // 攻撃速度のテキスト
    [SerializeField] private TextMeshProUGUI attackRangeText; // 攻撃範囲のテキスト
    // ここから
    [SerializeField] private Button sellButton; // 売却ボタン
    // ここまで

    /// <summary>
    /// 砲台情報を表示
    /// </summary>
    // ここから
    //public void ShowTurretInfo(TurretSetting.TurretData turretData)
    public void ShowTurretInfo(TurretSetting.TurretData turretData, bool sellButtonInteractable)
    // ここまで
    {
        turretNameText.text = turretData.name;
        buildingCostText.text = turretData.buildingCost.ToString();
        attackPowerText.text = turretData.attackPower.ToString();
        attackIntervalText.text = turretData.attackInterval.ToString();
        attackRangeText.text = turretData.attackRange.ToString();
        // ここから
        // 売却ボタンのinteractableを切り替え
        sellButton.interactable = sellButtonInteractable;
        // ここまで
        turretInfo.SetActive(true); // 砲台情報パネルを表示する
    }

    /// <summary>
    /// 砲台情報を非表示
    /// </summary>
    public void HideTurretInfo()
    {
        turretInfo.SetActive(false); // 砲台情報パネルを非表示にする
    }
}

ShowTurretInfo()メソッドに第2引数を追加して売却ボタンのinteractableを変更できるようにしました。

STEP

TurretGeneratorスクリプトを修正します。

public class TurretGenerator : MonoBehaviour
{
    // ...省略...

    /// <summary>
    /// 砲台を選択する
    /// </summary>
    public void SelectTurret(int index)
    {
        selectedTurretData = DBManager.instance.turretSetting.turretDataList[index];
        Debug.Log($"{selectedTurretData.name} を選択");
        // アイコンを表示
        selectedTurretIcon.SetActive(true);
        // 砲身のスプライトを設定
        SpriteRenderer iconRenderer = selectedTurretHead.GetComponent<SpriteRenderer>();
        iconRenderer.sprite = selectedTurretData.turretHeadSprite;
        // ここから
        //sideBarManager.ShowTurretInfo(selectedTurretData); // 砲台情報を表示
        sideBarManager.ShowTurretInfo(selectedTurretData, false); // 砲台情報を表示、売却ボタンを押せないように
        // ここまで
    }
}

ShowTurretInfo()メソッドの第2引数をfalseにして、砲台設置時は売却ボタンを押せないようにします。

STEP

TurretControllerスクリプトを修正します。

public class TurretController : MonoBehaviour
{
    // ...省略...

    /// <summary>
    /// 砲台がクリックされたときの処理
    /// </summary>
    public void OnTurretClicked(TurretController turret)
    {
        SideBarManager sideBarManager = FindObjectOfType<SideBarManager>();
        // ここから
        //sideBarManager.ShowTurretInfo(turretData);
        sideBarManager.ShowTurretInfo(turretData, true);
        // ここまで
        Debug.Log($"クリックした砲台: {turretData.name}");
    }
}

ShowTurretInfo()メソッドの第2引数をtrueにして、マップの砲台選択時は売却ボタンを押せるようにします。

STEP

SideBarオブジェクトのインスペクターで「Side Bar Manager (Script) > Sell Button」SellButtonオブジェクトをドラッグ&ドロップしてアサインします。

タワーディフェンス148

マップに攻撃範囲を表示

マップ上の砲台を選択したときに攻撃範囲が表示されたらオシャレじゃない?というわけで、Line Rendererを使って線を描画します。

STEP

「Assets > Prefabs > Turret」をダブルクリックしてプレハブの編集画面に入ります。

TurretオブジェクトのインスペクターでLine Rendererコンポーネントを追加します。

タワーディフェンス149

Line Rendererの設定はスクリプトでやるので、ここでは何もしません。

STEP

TurretControllerスクリプトを修正します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TurretController : MonoBehaviour
{
    // ...省略...
    // ここから
    [SerializeField] private LineRenderer lineRenderer; // 攻撃範囲を描画するLineRenderer
    private bool isRangeVisible = false; // 攻撃範囲の表示状態
    private Coroutine hideRangeCoroutine; // 攻撃範囲を非表示にするコルーチン
    // ここまで

    // ここから
    private void Awake()
    {
        // LineRendererの設定
        lineRenderer.positionCount = 50;
        lineRenderer.startWidth = 0.08f;
        lineRenderer.endWidth = 0.08f;
        lineRenderer.loop = true;
        lineRenderer.material = new Material(Shader.Find("Sprites/Default"));
        lineRenderer.startColor = new Color(0, 0, 1, 0.3f);
        lineRenderer.endColor = new Color(0, 0, 1, 0.3f);
        lineRenderer.sortingLayerName = "Object";
        lineRenderer.sortingOrder = 0;
        lineRenderer.enabled = false; // 最初は非表示
    }
    // ここまで

    private void Update()
    {
        // ...省略...
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        // ...省略...
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        // ...省略...
    }

    /// <summary>
    /// 砲台データを初期化
    /// </summary>
    public void InitializeTurret(TurretSetting.TurretData data)
    {
        // ...省略...
    }

    /// <summary>
    /// 砲台に最も近い敵を選択
    /// </summary>
    private void UpdateTargetEnemy()
    {
        // ...省略...
    }

    /// <summary>
    /// 攻撃間隔管理
    /// </summary>
    public IEnumerator ManageAttacks()
    {
        // ...省略...
    }

    /// <summary>
    /// 攻撃
    /// </summary>
    private void Attack()
    {
        // ...省略...
    }

    /// <summary>
    /// 砲身を敵の方向に回転させる
    /// </summary>
    private void RotateTurretHeadTowardsEnemy()
    {
        // ...省略...
    }

    /// <summary>
    /// 砲台がクリックされたときの処理
    /// </summary>
    public void OnTurretClicked(TurretController turret)
    {
        SideBarManager sideBarManager = FindObjectOfType<SideBarManager>();
        sideBarManager.ShowTurretInfo(turretData, true);
        Debug.Log($"クリックした砲台: {turretData.name}");

        // ここから
        // 攻撃範囲の表示切り替え
        isRangeVisible = !isRangeVisible;
        lineRenderer.enabled = isRangeVisible;
        if (isRangeVisible)
        {
            DrawAttackRange();
            // すでにコルーチンが動いていたら一度止める
            if (hideRangeCoroutine != null)
            {
                StopCoroutine(hideRangeCoroutine);
            }
            // 新しくコルーチンを開始
            hideRangeCoroutine = StartCoroutine(HideRangeAfterDelay(4f));
        }
        // ここまで
    }

    // ここから
    /// <summary>
    /// 攻撃範囲を描画
    /// </summary>
    private void DrawAttackRange()
    {
        float radius = attackRange.radius; // 攻撃範囲の半径
        Vector3 center = transform.position; // 砲台の位置
        int points = lineRenderer.positionCount; // 円を描くための点の数

        for (int i = 0; i < points; i++)
        {
            float angle = i * 2 * Mathf.PI / points;
            float x = center.x + Mathf.Cos(angle) * radius;
            float y = center.y + Mathf.Sin(angle) * radius;
            lineRenderer.SetPosition(i, new Vector3(x, y, 0));
        }
    }

    /// <summary>
    /// 一定時間後に攻撃範囲を非表示にするコルーチン
    /// </summary>
    private IEnumerator HideRangeAfterDelay(float delay)
    {
        yield return new WaitForSeconds(delay);
        isRangeVisible = false;
        lineRenderer.enabled = false;
    }
    // ここまで
}

マップ上の砲台をクリックするたびに攻撃範囲の表示をオン/オフできるようにしました。さらに、表示がオンの状態が4秒続くと自動的に表示が消えるようにしました。これはコルーチンで実現しています。

DrawAttackRange()でLine Rendererを使って円を描画しています。三角関数を使ってますね。「サイン、コサイン、タンジェント」という呪文は今でも覚えていますが、意味は忘れました。

STEP

「Assets > Prefabs > Turret」をダブルクリックしてプレハブの編集画面に入ります。Turretオブジェクトのインスペクターで「Turret Controller (Script) > Line Renderer」Turretオブジェクトをドラッグ&ドロップしてアサインします。

タワーディフェンス150

動作確認

さあ、動作確認をしましょう。

以下の機能が実装されました。

  • サイドバーの砲台アイコンを選択したら、砲台情報を表示。売却ボタンは非アクティブ。
  • マップの砲台を選択したら、砲台情報を表示。売却ボタンはアクティブ。攻撃範囲を青い円で表示。
  • 攻撃範囲のオン/オフは砲台のクリックで切り替え。
  • 攻撃範囲をオフにしなかったら4秒後に自動オフ。

さいごに

マップ上の砲台を選択したときの処理でかなり試行錯誤しました。結局レイキャストを使ったんだけど、もっと簡単な方法がありそう。

でわでわ

タワーディフェンスを作る(12)

この記事が気に入ったら
いいね または フォローしてね!

シェアしてね

コメント

コメントする

目次