【Unity】タワーディフェンス(3) 砲台の作成【クソゲー制作】

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

Unity初心者が2Dタワーディフェンスを作っています。今回は砲台オブジェクトの作成、そしてマップのクリックしたタイルに砲台を生成する処理を実装します。

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

画像のインポート

STEP

ProjectビューのAssets/Imagesフォルダの下にTurretフォルダを作成して、そこに砲台用の画像データをドラッグ&ドロップしてインポートします。

タワーディフェンス20
STEP

インポートした画像を全選択し、インスペクターで「Pixels Per Unit」の値を64にして「Apply」ボタンをクリックします。画像の縦横のピクセル数が64なので64にしています。

タワーディフェンス21

今後、マップのタイル上に表示する画像はすべてこの設定をするので忘れないでね。

オブジェクトの作成

砲台は台座砲身の2つの画像を重ねて作ります。

タワーディフェンス22
STEP

ヒエラルキーに空のオブジェクトを作成して、名前をTurretにします。その配下に砲台の画像(台座と砲身)をドラッグ&ドロップします。

名前をそれぞれTurretBase, TurretHeadにします。

タワーディフェンス23
STEP

砲台をレイヤーの最前面に表示したいので、TurretBaseとTurretHeadのインスペクターで「Sprite Renderer > Additional Settings > Sorting Layer」「Object」にします。

STEP

砲身(TurretHead)を台座(TurretBase)よりも前面に表示したいので、TurretBaseの「Sprite Renderer > Additional Settings > Order in Layer」0に、TurretHeadは1にします。

タワーディフェンス24

同じSorting Layerのオブジェクトの重なり順はOrder in Layerで設定します。数値が大きいほうが手前に表示されます。

オブジェクトをプレハブ化

ProjectビューのAssets下にPrefabsフォルダを作成します。そこにTurretオブジェクトをドラッグ&ドロップしてプレハブ化します。

タワーディフェンス25

プレハブができたら、ヒエラルキーのTurretオブジェクトは用済みなので削除します(かわいそう)。

クリックしたタイルに砲台を生成

いよいよスクリプトを書いていきます。

STEP

Assetsフォルダの下にScriptsフォルダを作成します。そこにC#スクリプトを作成して、名前をTurretGeneratorにします。

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の座標を取得するため
    private Vector3Int gridPos;  // Tilemapのセル座標

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // 画面をクリックしたら
        {
            // クリック位置のスクリーン座標をワールド座標に変換しそれをセル座標に変換
            gridPos = grid.WorldToCell(Camera.main.ScreenToWorldPoint(Input.mousePosition));
            // 砲台を生成
            GenerateTurret(gridPos);
        }
    }

    /// <summary>
    /// 砲台生成
    /// </summary>
    /// <param name="gridPos"></param>
    private void GenerateTurret(Vector3Int gridPos)
    {
        // クリックした位置に砲台を配置
        GameObject turret = Instantiate(turretPrefab, gridPos, Quaternion.identity);
        // 砲台の位置がタイルの左下を 0,0 として生成しているので、タイルの中央にくるように位置を調整
        turret.transform.position = new Vector2(turret.transform.position.x + 0.5f, turret.transform.position.y + 0.5f);
    }
}
STEP

ヒエラルキーで空オブジェクトを作成し名前をTurretGeneratorにします。

TurretGeneratorオブジェクトにTurretGenerator.csをドラッグ&ドロップしてアタッチします。

STEP

TurretGeneratorのインスペクターで、「Turret Prefab」には「Assets/Prefabs/Turret」を、「Grid」にはGrid_Baseオブジェクトをドラッグ&ドロップしてアサインします。

タワーディフェンス26
STEP

ゲームを実行して動作確認をしてみます。

うまくいきました。わーい。

配置可能なタイルだけに砲台を生成

現在のところ、道や障害物(木、石)の上にも砲台を配置できてしまいます。また、すでに砲台があるタイルの上にも砲台を配置できてしまいます。

STEP

配置可能なタイルだけに砲台を配置できるようにスクリプトを修正します。

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
    private Vector3Int gridPos;  // Tilemapのセル座標
    private HashSet<Vector3Int> occupiedCells = new HashSet<Vector3Int>(); // 砲台配置済みセルを代入

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) // 画面をクリックしたら
        {
            // クリック位置のスクリーン座標をワールド座標に変換しそれをセル座標に変換
            gridPos = grid.WorldToCell(Camera.main.ScreenToWorldPoint(Input.mousePosition));
            // クリックしたタイルのコライダーがNoneならば
            if (tilemaps.GetColliderType(gridPos) == Tile.ColliderType.None)
            {
                // 砲台を生成
                GenerateTurret(gridPos);
            }
        }
    }

    /// <summary>
    /// 砲台生成
    /// </summary>
    /// <param name="gridPos"></param>
    private void GenerateTurret(Vector3Int gridPos)
    {
        // 配置済みの場合は処理を中断
        if (occupiedCells.Contains(gridPos))
        {
            Debug.Log("このセルにはすでに砲台が配置されています");
            return;
        }
        // クリックした位置に砲台を配置
        GameObject turret = Instantiate(turretPrefab, gridPos, Quaternion.identity);
        // 砲台の位置がタイルの左下を 0,0 として生成しているので、タイルの中央にくるように位置を調整
        turret.transform.position = new Vector2(turret.transform.position.x + 0.5f, turret.transform.position.y + 0.5f);
        // 配置されたセルを登録
        occupiedCells.Add(gridPos);
    }
}
STEP

TurretGeneratorのインスペクターでTilemapsGrid_WayTilemapをドラッグ&ドロップしてアサインします。

タワーディフェンス28
STEP

動作を確認します。

さいごに

まずは、砲台をマップ上に生成することに成功しました。いえい。

最終的にはいろんな種類の砲台の中から選択して配置するという処理をしたいのですが、まずは1つの砲台の配置を実装しました。楽しいね。

でわでわ

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

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

シェアしてね

コメント

コメントする

目次