【Unity/2D】スイカゲーム風の落ち物ゲームを作ってみる話 #4 ポインターから果物を生成する

記事をご覧いただき、誠にありがとうございます。
投稿主の無能です。

前回は、Prefab Variantを作成し果物を作成しました。

今回はポインターから果物を生成する機能を実装したいと思います。

果物を生成する

果物を生成していくんですが、今のところFruitsというタグで「果物」であるという事は分かっても、「果物の種類」までは判別が出来ません。

スイカゲームでは、同じ果物同士が接触した際に一つ上の果物に進化しますから、このままでは「果物」であることが分かると同時に「果物の種類」が分からないと、進化できない状態です。

そこで果物の種類をenum(列挙型)で準備しておいて、Prefab Variantの生成時に果物の種類を持たせます。

これで同じ果物同士が接触した時に進化ができます。

取り敢えず、同じ果物同士が接触したら接触した果物と自身の果物を破棄するようにしてみましょう。

スクリプトを準備する

果物のPrefab Variantにアタッチするスクリプトを作成します。

新たにスクリプトをScriptsフォルダに作成し、名前を「Fruits」にします。

「Fruits」スクリプトを作成

そしたらFruitsスクリプトをPrefabsフォルダのFruitsBaseにアタッチします。

FruitsスクリプトをFruitsBaseへアタッチ

スクリプトをアタッチした

果物のPrefab Variantは、基のPrefabの変更を引き継いでくれるので「FruitsBaseにFruitsスクリプトをアタッチした」という状態の変化が果物のPrefab Variantにも反映されています。
確認してみてください。

果物のPrefab Variant全てにスクリプトがアタッチされた

こういうところでアタッチし忘れを防げるのもいいですね。

次にFruitsGeneratorというスクリプトを作成し、ポインターにアタッチします。

FruitsGeneratorスクリプトを作成

ポインターにFruitsGeneratorスクリプトをアタッチ

ではスクリプトを編集していきましょう。

スクリプトの編集

Variables

まずVariablesからです。

Variables.cs
using UnityEngine;

public class Variables : MonoBehaviour
{
    #region Var-Number
    public const float zero = 0f;                               // floatの0
    #endregion

    #region Var-String
    public const string tag_Fruits = "Fruits";                  // タグ:果物
    #endregion
}

Fruitsのタグが追加されたので、タグ名を定数で追加しました。

Fruits

次に果物達にアタッチしたFruitsになります。

Fruits.cs
using UnityEngine;

public class Fruits : MonoBehaviour
{
    #region Var-Fruits
    [Header("果物の種類")]
    [SerializeField] type fruitsType;
    #endregion

    #region Var-Internal
    enum type                                                               // 果物の種類
    {
        cherry = 1, strawberry, grape, orange, persimmon, apple,
        pear, peach, pineapple, melon, watermelon
    }
    #endregion

    #region OnCollisionEnter2D
    // 果物の接触判定
    void OnCollisionEnter2D(Collision2D collision)
    {
        // 接触オブジェクトのタグが果物ではない場合
        if (!collision.gameObject.CompareTag(Variables.tag_Fruits))
        {
            // 処理を中断
            return;
        }
        // 接触オブジェクトと自身のFruitsを取得
        Fruits _collisionFruits = collision.gameObject.GetComponent<Fruits>(),
               _fruits = GetComponent<Fruits>();
        // 接触した果物と自身の果物の種類が同じ場合
        if (_collisionFruits.fruitsType == _fruits.fruitsType)
        {
            // 接触した果物を破棄
            Destroy(collision.gameObject);
            // 自身を破棄
            Destroy(gameObject);
        }
    }
    #endregion
}

メンバ変数

メンバ変数は果物の種類となるtypeのfruitsTypeです。

あとは内部処理用のenumのtypeになります。

このように書くことで、typeが列挙した項目がInspectorビューで選択して設定できるようになります。

では処理内容を見てみましょう。

OnCollisionEnter2D関数

OnCollisionEnter2D関数では、まず接触オブジェクトのタグがFruitsではない場合、処理を中断します。

次にローカル変数の_collisionFruitsで接触オブジェクトのFruitsを、_fruitsで自身のFruitsを取得します。

そして接触オブジェクトの_collisionFruitsと自身の_fruitsの果物の種類が同じ場合に、接触オブジェクトと自身を破棄します。

Fruitsスクリプトはこれで以上です。

次にポインターにアタッチしたFruitsGeneratorを見てみましょう。

FruitsGenerator

FruitsGenerator.cs
using UnityEngine;

public class FruitsGenerator : MonoBehaviour
{
    #region Var-Fruits
    [Header("果物")]
    [SerializeField] Fruits[] fruits;
    #endregion

    #region Update
    void Update()
    {
        // スペースキーが押された場合
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 果物を生成
            FruitsGenerate();
        }
    }
    #endregion

    #region FruitsGenerate
    // 果物の生成
    void FruitsGenerate()
    {
        // 果物のコピーを生成 生成物:登録された果物からランダムに生成
        Instantiate(fruits[Random.Range((int)Variables.zero, fruits.Length)],
                    // 位置:ポインターの位置 回転無し
                    transform.position, Quaternion.identity);
    }
    #endregion
}

メンバ変数

メンバ変数は果物達の配列になります。

どうしてGameObjectじゃなくてFruitsにしているかと言うと、このように書くとFruitsというコンポーネントがアタッチしてあるオブジェクトのみが設定可能になります。
(ここではFruitsスクリプトがアタッチされたオブジェクトが該当)

つまりInspectorビューで果物だけが設定できるようになるので、間違いを減らすことができます。

Update関数

Update関数では、スペースキーが押された場合にFruitsGenerate関数を呼んで果物を生成しています。

FruitsGenerate関数

FruitsGenerate関数では、Inspectorビューで設定された果物をランダムに選び、ポインターと同じ位置で回転無しでコピーを生成します。

ではスクリプトが編集できたので、Unityに戻って作業します。

Unityでの作業

はじめに果物達からです。
果物の種類という項目が追加されているので、01_Cherry~11_Watermelonまでの11種類の果物全てに果物と同じ種類を設定します。

01_Cherry

02_Strawberry

03_Grape

04_Orange

05_Persimmon

06_Apple

07_Pear

08_Peach

09_Pineapple

10_Melon

11_Watermelon

これで果物の種類が設定できました。

次はポインターの設定になります。

ポインターには果物という項目が追加されているので、01_Cherry~05_Persimmonまでの5種類の果物を設定します。


Variantsフォルダの果物をドラッグして設定しようとする場合、Inspectorビューがポインターのものから果物のものに動いてしまいます。

そういう時はInspectorビューの上部の右にある南京錠アイコンをクリックして、Inspectorビューを固定します。

Inspectorビューを固定した状態

もう一度クリックすると固定が解除されます。

Inspectorビューの固定を解除した状態

地味だけどよく使う機能なので覚えておきましょう。

あと配列に一度に複数登録する場合は、登録したいオブジェクト等を複数選択しておき、そのままドラッグしてInspectorビューの変数名の辺りでドロップすることで複数個を一度に登録できます。

今回の果物の登録を例にすると、01_Cherry~05_Persimmonまでの複数個を選択しておき、そのままポインターのの果物の変数名の辺りでドロップすると、選択した複数個が一度に登録できます。

このような小技も覚えておくと地味に便利だったりします。

では設定ができたので動作確認をします。

動作確認

今回の確認事項は
  • スペースキーを押す度に果物が生成されるか
  • 生成される果物は登録した果物からランダムに選ばれているか
  • 果物は同じ種類同士が接触した時に消えるか
になります。

では確認しましょう。

スペースキーを押すと果物が生成される

スペースキーを押す度に果物が生成され、ちゃんとランダムに生成されます。

同じ果物同士が接触したら消えた

同じ果物同士(今回はぶどう)が接触したらきちんと消えてくれます。

これで果物を生成する機能が実装できました。

まとめ

今回は
  • 果物の種類を設定できるようにした
  • 登録した果物をランダムで生成できるようにした
  • 同じ果物同士が接触したら消えるようにした
という事をやりました。

次回は、生成された果物がポインターにぶら下がるようにするのと、果物の生成から落下させるまでの時間を調整する機能を作っていきたいと思います。

では、また次回!

コメント