2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Cocos Creator 3 カンタン2Dゲーム制作(2)【プレハブの使い方】

Last updated at Posted at 2022-08-23

ページ一覧

Cocos Creator 3 導入編

Cocos Creator 3 カンタン2Dゲーム制作

アイテムを登場させる

魚が動くようになったところで、次にアイテムを登場させます。

アイテムの作成

ヒエラルキーパネルのCanvasを右クリックし、CreateEmpty Nodeを選択します。Nodeが追加されるので名前をItemsに変更します。

アセットパネルからCoinSyurikenをドラッグ&ドロップでヒエラルキーパネルのItemsの配下にコピーします。ノードの構成は以下のようになります。

Coinのノードを選んで、インスペクターパネルのcc.UITransformの下にあるContent Size60,60にします。同様の手順でSyurikenのノードも80,80にします。(なおノードのpisotionはどこでもいいです)

アイテムを出現させるスクリプト

アセットパネルから、Assets右クリック→CreateTypeScriptNewComponentで新しいスクリプトを作成します。名前をSpawnItemsとします。
もう一つ、同じ手順でFallingItemという名前のスクリプトを作ります。
それぞれのファイルに下記の内容を記述します。
スクリプトファイルが増えてきたのでAssetsの下にScriptというフォルダを作りスクリプトファイルを入れます。

SpawnItems.ts
import { _decorator, Component, Prefab, instantiate } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('SpawnItems')
export class SpawnItems extends Component {

    @property(Prefab)
    prefabCoin: Prefab = null;

    @property(Prefab)
    prefabObstacle: Prefab = null;

    _intervalCoin: number = 0;
    _intervalObstacle: number = 0;

    start() {
        this.setIntervalCoin();
        this.setIntervalObstacle();
    }

    setIntervalCoin() {
        this._intervalCoin += Math.random() * 3 + 1;

    }
    setIntervalObstacle() {
        this._intervalObstacle += Math.random() * 3 + 0.1;
    }

    update(deltaTime: number) {
        // コインの出現条件
        this._intervalCoin -= deltaTime;
        if (this._intervalCoin < 0) {
            this.node.addChild(instantiate(this.prefabCoin));
            this.setIntervalCoin();
        }

        // 障害物の出現条件
        this._intervalObstacle -= deltaTime;
        if (this._intervalObstacle < 0) {
            this.node.addChild(instantiate(this.prefabObstacle));
            this.setIntervalObstacle();
        }
    }
}
FallingItem.ts
import { _decorator, Component, Vec3, UITransform, view } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('FallingItem')
export class FallingItem extends Component {
    @property
    speed: number = 400;

    start() {
        const viewSize = view.getVisibleSize();
        const pos = {
            x: Math.random() * viewSize.x - (viewSize.x / 2),
            y: viewSize.y / 2 + 50
        };
        this.node.setPosition(new Vec3(pos.x, pos.y));
    }

    update(deltaTime: number) {
        const uitf = this.getComponent(UITransform);
        if (this.node.position.y < -(view.getVisibleSize().y / 2 + uitf.height)) {
            this.node.destroy();
            return;
        }
        let moveY = this.speed * deltaTime;
        this.node.setPosition(new Vec3(this.node.position.x, this.node.position.y - moveY));
    }
}

ノードとスクリプトの紐づけ

ヒエラルキーパネルにあるItemsを選択します。インスペクターパネルの一番下の、Add Componentボタンを押します。別の小窓が出るので、Search Nameと書かれたエリアにspawnと入力します。登録済みのスクリプトがCustom Scriptの下に表示されるので、SpawnItemsを選択します。
同様の手順で、CoinSyurikenにもFallingItemのスクリプトを紐づけます。ctrl+Sでシーンを保存します。
これまでに作成したノードとスクリプトファイルの関係を図示すると以下のようになります。

image.png

prefab(プレハブ)の作成

これまで、表示するノードはすべてシーン上に配置してきました。
今回はprefab(プレハブ)という機能を使って沢山のアイテムが出現する仕組みを作成します。

ヒエラルキーパネルからのプレハブの作成

アセットパネルでフォルダーPrefabを作ります。
そこにヒエラルキーパネルにあるCoinSyurikenをアセットパネルの方へドラッグ&ドロップでコピーします。すると緑色のアセットが登録されます。これがprefab(プレハブ)で、ヒエラルキーパネルにあったノードのコピー品がアセットとして登録されました。
ヒエラルキーパネルにあった元の2つは不要になったので削除します。

プレハブをダブルクリックすると、シーンパネルにそのプレハブが映り、インスペクターパネルの最下部に先ほど登録したFallingItemのスクリプトが紐づいてることが確認できます。
(アセットパネルのSeaSceneをダブルクリックして戻ります。)

プレハブを使ったアイテムの出現処理

ヒエラルキーパネルにあるItemsを選択します。
インスペクターパネルの最下部にほど紐づけたSpawnItemsが確認できます。その中に空の枠が2か所あります。
アセットパネルにあるCoinSyurikenを、それぞれPrefab CoinPrefab Obstacleの枠にコピーします。(枠の右にあるアイコンをクリックしてそこから選択することもできます)
これにより、SpawnItemsのスクリプト内で、アセットパネルにあるプレハブを使えるよう紐づけが行えました。

ここまでの動きの確認

▶ボタン(またはctrl+P)で動きを確認してみましょう。正しく作れていれば上からアイテムが降って来るのが確認できます。

スクリプトの解説

アイテムを出現させるスクリプト

まずはSpawnItems.tsから。このスクリプトは一定間隔でアイテムを出現させる処理を行います。

プロパティデコレータ

クラス内のプロパティですが、これはプロパティデコレータといて、コード上に@property()というデコレータを付けることで、インスペクターパネルで値の設定ができるようになるものです。先ほどの手順でプレハブをドラッグ&ドロップでセットしたのはこのプロパティに保持するためです。

@property(Prefab)
prefabCoin: Prefab = null;

アイテム出現処理

startメソッドでthis.setIntervalCoin()を呼び出し、最初にアイテムを出現するまでの秒数をランダムで決定します。値はthis._intervalCoinに格納します。

updateメソッドは画面の描写が行われるごとに毎回呼び出されます。
deltaTimeには前回の描画から今回までの経過時間が入っており、this._intervalCoinからその値を引いていき、0になるまで繰り返します。0になったとき、すなわち予定した時間が経過したとき、新たにinstantiateメソッドを使てプレハブを複製し、this.node.addChild()で、自身のノード(items)に追加し出現させます。出現させた後はthis.setIntervalCoin()を呼び出し、次回出現するまでの秒数をランダムで決定します。

this.node.addChild(instantiate(this.prefabCoin));

コインについて解説しましたが、手裏剣についてもランダムの秒数を多少変えているだけで同様の仕組みです。

アイテムを落下・消滅させるスクリプト

次に、SpawnItems.tsについて。
startメソッドでは画面の最上部より上に、アイテムを配置します。横の位置(x)はランダムです。
this.node.setPosition()によりノードの位置を設定ます。

updateメソッドはSpawnItems.ts同様、画面の描写が行われるごとに毎回呼び出される処理を書きます。
まず、this.getComponent(UITransform)でノードのサイズ情報を取得します。そして画面の最下部より下に行っているかどうかを判定し、そうであればthis.node.destroy()で自分自身のノードを削除します。
まだ、画面上にあるならdeltaTimespeedを使って、落下後の表示位置を計算します。

スクリプトの役割分担

さて、これらのスクリプトでポイントとなるのが「アイテムの出現処理」「アイテムの移動・消滅」をそれぞれ別スクリプトとして用意したことです。その気になれば1つのスクリプトにすべて処理を記述することも可能ですが、分けるメリットについて見ていきます。
一つはノードごとの役割が明確になり、それぞれ自律的に処理できることです。CoinSyurikenは「画面から見えなくなったら消える」という事が保証されているので、Itemsノードは「アイテムの出現処理」の機能だけを担えばよく、アイテムが沢山あっても一つ一つを監視する必要がありません。結果的にコードを簡潔に書くことができます。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?