UnityUnityメモ

Unity 時間経過でInstantiateを止める【初心者向け】

Unity

はじめに

Unityでゲームを作るとき、プレハブ(Prefab)を使ってオブジェクトを簡単に生成できます。でも、ある条件で生成を止めたい場合はどうすればいいのでしょうか?今回は、1秒おきにボールを生成し、5秒経過したら生成を止める詳しい手順を解説します。

1.ボールを作成

プレハブの準備 まず、生成するボールのプレハブを作ります。3Dオブジェクトの「Sphere」を作成し、プレハブとして保存します。

  • ヒエラルキーウィンドウで右クリックし、「3D Object」→「Sphere」を選びます。
  • 名前を「Ball」などにしておくとわかりやすいです。

物理特性を追加する

  • ヒエラルキーの「Spehre」を選択します。
  • inspector画面の「AddComponent」から「Rigidbody」を検索して追加します。

ボールのスクリプト

次に、ボールのスクリプトを作成します。以下の手順でスクリプトを作成し、内容を記述します。

  • プロジェクトウィンドウで右クリックし、「Create」→「C# Script」を選びます。
  • スクリプト名を「SphereMove」に変更します。
  • 作成したスクリプトをダブルクリックして、Visual Studio(またはお好みのコードエディタ)で開きます

コード全体の説明

このスクリプトは、UnityのRigidbodyコンポーネントを使って、オブジェクト(ここでは球体)を前方向に動かします。

各部分の説明

  1. using System.Collections; using System.Collections.Generic; using UnityEngine;
    • これらは必要なライブラリを使うための宣言です。System.CollectionsSystem.Collections.Genericはコレクションを扱うためのもの、UnityEngineはUnityの機能を使うためのものです。
  2. public class SphereMove : MonoBehaviour
    • SphereMoveというクラスを定義しています。MonoBehaviourを継承しているので、Unityのコンポーネントとして動作します。
  3. private Rigidbody rb;
    • Rigidbodyという変数を宣言しています。この変数は、オブジェクトに物理的な動きを与えるために使います。
  4. void Start()
    • ゲームが始まったときに一度だけ呼ばれる関数です。ここでは、オブジェクトにアタッチされているRigidbodyコンポーネントを取得しています。
  5. void Update()
    • 毎フレーム(1秒間に何回も)呼ばれる関数です。ここでは、Rigidbodyに前方向の力を加えています。
  6. rb.AddForce(new Vector3(0, 0, 5));
    • AddForceはRigidbodyに力を加える関数です。new Vector3(0, 0, 5)は3D空間での力の方向と大きさを示しています。ここでは、Z軸方向(前方向)に5の力を加えています。

全体の動き

このスクリプトがアタッチされたオブジェクト(例えば、球体)は、ゲームが始まると毎フレーム、前方向に力を受け続けます。そのため、球体はどんどん前に進んでいきます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class SphereMove : MonoBehaviour
{
    private Rigidbody rb;
 
    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }
 
    void Update()
    {
        rb.AddForce(new Vector3(0,0,5));
    }
}

Prefabにする

  • 作成したスクリプトを「Sphere」にアタッチします。
  • Sphereをプロジェクトウィンドウにドラッグ&ドロップしてプレハブにしておきます。



2.ボールを生成するスクリプト

次に、ボールを生成するスクリプトを作成します。以下の手順でスクリプトを作成し、内容を記述します。

  • プロジェクトウィンドウで右クリックし、「Create」→「C# Script」を選びます。
  • スクリプト名を「GameManager」に変更します。
  • 作成したスクリプトをダブルクリックして、Visual Studio(またはお好みのコードエディタ)で開きます

全体の説明

このスクリプトはUnityでボールを生成するマネージャーの役割を果たします。一定の時間ごとにボールを生成し、特定の条件下でのみ動作するように設定されています。

各部分の説明

  1. 宣言部
    これらの行は、スクリプトで使用するライブラリをインポートしています。System.CollectionsSystem.Collections.Genericは、リストや配列などのコレクションを扱うためのものです。UnityEngineはUnityの基本的な機能を使うためのライブラリです。
  2. クラスの定義
    GameManagerという名前のクラスを定義しています。このクラスはMonoBehaviourを継承しており、Unityのゲームオブジェクトにアタッチすることで使用できます。
  3. 変数の定義
    • [SerializeField] GameObject ball;ballという名前のゲームオブジェクトを設定しています。この変数は、Unityのエディタでオブジェクトを割り当てることができます。
    • private float countTime;:カウントタイムを保持する変数です。
    • private float timer;:タイマーを保持する変数です。
  4. Startメソッド
    Startメソッドは、スクリプトが初めて実行されるときに呼び出されます。
    ここでは、countTimetimerを初期化しています。
  5. Updateメソッド
    Updateメソッドは、フレームごとに呼び出されます。ここで行われているのは次の通りです:
    • countTimetimerTime.deltaTime(前のフレームから経過した時間)だけ増加させます。
    • timerが5秒以内の場合に次の処理を実行します。
    • countTimeが1秒以上経過している場合に、countTimeをリセットし、ballオブジェクトを生成します。

全体の動き

このスクリプトはゲームが始まると同時にcountTimetimerを0にリセットします。ゲームが進行する中で、毎フレームごとにUpdateメソッドが呼び出され、タイマーが増加します。timerが5秒以内の場合に、1秒ごとに指定された場所にボールを生成します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GameManager : MonoBehaviour
{
    [SerializeField] GameObject ball;
    private float countTime;
    private float timer;
 
    void Start()
    {
        countTime = 0;
        timer = 0;
    }
 
    void Update()
    {
        countTime += Time.deltaTime;
        timer += Time.deltaTime;
        
        //5秒以内であれば実行
        if(timer <= 5 )
        {
            //1秒おきに生成
            if(countTime >= 1)
            {
                countTime = 0;
                Instantiate(ball,new Vector3(0, 0, 0),Quaternion.identity);
            }
        }
    }
}



3.スクリプトのアタッチ

  1. スクリプトをオブジェクトにアタッチします。
    • ヒエラルキーウィンドウで空のGameObjectを作成(右クリック→「Create Empty」)
    • 作成したGameObjectを選択
    • 「GameManager」スクリプトをドラッグ&ドロップしてGameObjectにアタッチ
    • インスペクターウィンドウで「ball」フィールドに、作成したボールのプレハブをドラッグ&ドロップ

4.テストプレイ

準備が終わったらゲームをプレイしてみましょう!

これで、1秒おきにボールが生成され、5秒経過すると生成が止まります。とてもシンプルなスクリプトですが、これを応用すればもっと複雑な条件でオブジェクトを生成したり止めたりすることができます。



よくある質問

Q
プレハブが生成されない場合、何が問題ですか?
A

スクリプトのballフィールドに正しいプレハブが設定されているか確認してください。また、プレハブが正しく作成されているかも確認してください。

Q
スクリプトを改良して、10秒後に再度生成を始めることはできますか?
A

はい、できます。コルーチン内で生成を止めた後に、再度生成を始める処理を追加すれば実現可能です。具体的には、一定時間待つためのWaitForSecondsを使ってください。

Q
複数の種類のプレハブをランダムに生成するにはどうすればいいですか?
A

複数のプレハブを配列で持ち、ランダムなインデックスでプレハブを選んで生成するようにすれば実現できます。Random.Rangeを使うと便利です。