質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.98%

  • C#

    5791questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3039questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    556questions

ObjectPoolを使ってInvokeしたGameObjectがコルーチン中のfor文で連続生成できない

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 206

white_No.53

score 2

前提・実現したいこと

unityのHPに掲載されているObjectPoolのコードを使って敵機を生成したいです。
iTween(iTween.Pathを使ってます)を使って動かす機体(曲線挙動)と単純に直線的に動かす機体(直線挙動)で分けます。

発生している問題

曲線挙動の機体はコルーチン中のfor文で複数を生成することができるのですが
直線挙動の機体は一つの機体を作った後、その機体が消えるまで次の行程に移動してくれません。
上記2種類の機体を同時に生成しようとすると、両方とも1機ずつ作成し、直線挙動の機体を消すと、両方とも次の行程に移ります。

該当のソースコード

  • Waveを管理するスクリプト
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Wave : MonoBehaviour {
    public struct DENEMY  //作成する敵機の特徴
    {
        public GameObject Module;//見た目
        public string Line;//使う線
        public iTween.EaseType ease;//動かし方
        public int tamaNum;//敵が撃つ弾の数
        public float time;//iTweenのtime
        public float shottiming;//どれくらいのタイミングで撃ち始めるか
        public DENEMY(GameObject module,string line,iTween.EaseType Ease,int TamaNum,float TIME,float Shottiming)
        {
            Module = module;
            Line = line;
            ease = Ease;
            tamaNum = TamaNum;
            time = TIME;
            shottiming = Shottiming;
        }
    }
    public GameObject[] mod;
    public string[] lin;
    public iTween.EaseType[] eas;
    public int[] tam;
    public float[] sho, tim;
    List<DENEMY> enemy=new List<DENEMY>();    // Use this for initialization
    IEnumerator Start () { 
        for(int i = 0; i < mod.Length; i++)
        {
            enemy.Add(new DENEMY(mod[i], lin[i], eas[i], tam[i], tim[i], sho[i]));//publicで入力した物を入れる。

        }
        StartCoroutine(Wave0());
        yield return StartCoroutine(Wave1());
        yield return new WaitForSeconds(2f);
        yield return StartCoroutine(Wave2());
        yield return new WaitForSeconds(2f);
        yield return StartCoroutine(Wave3());

    }

    // Update is called once per frame
    void Update () {

    }
    IEnumerator Wave0()//問題のコルーチン
    {
        for (int i = 0; i < 5; i++)
        {
            GameObject a = ObjectPool.instance.GetGameObject(enemy[0].Module, new Vector2(i * 2 - 4, 5), Quaternion.Euler(180, 0, 0));
            a.GetComponent<DEnemy>().useline = false;//iTweenを使わない設定にする。
            a.GetComponent<Rigidbody2D>().velocity = -transform.up;//直線的に動かす
            yield return new WaitForSeconds(0.5f);//ちょっと待つ
        }
    }
    IEnumerator Wave1()
    {

        for (int i = 0; i < 4; i++)
        {
            Go(enemy[0], new Vector2(-5, 5));
            yield return new WaitForSeconds(0.5f);
            Go(enemy[1], new Vector2(5, 5));
            yield return new WaitForSeconds(0.5f);
        }
    }
    IEnumerator Wave2()
    {
        Go(enemy[2], new Vector2(5, 4.5f));
        Go(enemy[3], new Vector2(-5, 4.5f));
        yield return new WaitForSeconds(1f);
    }
    IEnumerator Wave3()
    {
        for (int i=0;i<3;i++) {
            Go(enemy[4],new Vector2(3, 5));
            Go(enemy[5], new Vector2(-3, 5));
            yield return new WaitForSeconds(1f);
            Go(enemy[6], new Vector2(5, 4.5f));
            Go(enemy[7], new Vector2(-5, 4.5f));
        }
    }
   void Go(DENEMY ene,Vector2 start)
    {
        GameObject a = ObjectPool.instance.GetGameObject(ene.Module, start, Quaternion.Euler(180, 0, 0));
        a.SetActive(false);
        a.GetComponent<DEnemy>().Line=ene.Line;
        a.GetComponent<DEnemy>().ease=ene.ease;
        a.GetComponent<DEnemy>().time=ene.time;
        a.GetComponent<DEnemy>().tamaNum=ene.tamaNum;
        a.GetComponent<DEnemy>().shottiming = ene.shottiming;
        a.SetActive(true);
    }
}
  • ObjectPool
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectPool : MonoBehaviour {
    private static ObjectPool _instance;

    //シングルトン
    public static ObjectPool instance
    {
        get
        {
            if (_instance == null)
            {
                //シーン上から取得する
                _instance = FindObjectOfType<ObjectPool>();

                if (_instance == null)
                {
                    //ゲームオブジェクトを作成しObjectPoolオブジェクトコンポーネントを追加する。
                    _instance = new GameObject("ObjectPool").AddComponent<ObjectPool>();
                }
            }
            return _instance;
        }
    }
    //ゲームオブジェクトのDictionary
    private Dictionary<int, List<GameObject>> pooledGameObjects = new Dictionary<int, List<GameObject>>();

    //ゲームオブジェクトをpooledGameObjectsから取得する。必要であれば新たに生成する。
    public GameObject GetGameObject(GameObject prefab, Vector2 position, Quaternion rotation)
    {
        //プレハブのインスタンスIDを取得する。
        int key = prefab.GetInstanceID();

        //Dictionaryにkeyが存在しなければ作成する。
        if (pooledGameObjects.ContainsKey(key) == false)
        {
            pooledGameObjects.Add(key, new List<GameObject>());
        }
        List<GameObject> gameObjects = pooledGameObjects[key];

        GameObject go = null;

        for(int i = 0; i < gameObjects.Count; i++)
        {
            go = gameObjects[i];

            //現在非アクティブ(未使用)であれば
            if (go.activeInHierarchy == false)
            {
                //位置を設定する
                go.transform.position = position;

                //角度を設定する
                go.transform.rotation = rotation;

                //これから使用するのでアクティブにする
                go.SetActive(true);

                return go;
            }
        }
        //使用できる物がないので新たに作成する
        go = (GameObject)Instantiate(prefab, position, rotation);

        //ObujectPoolの子要素にする
        go.transform.parent = transform;

        //リストに追加
        gameObjects.Add(go);

        return go;
    }
    //ゲームオブジェクトを非アクティブにする。これで再利用可能。
    public void ReleaseGameObject(GameObject go)
    {
        go.SetActive(false);
    }
    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

試したこと

GameObjectのaをListにしたり、配列にしてみたりしましたがダメでした。

補足情報(言語/FW/ツール等のバージョンなど)

ObjectPool掲載ページ

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.98%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    5791questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Unity

    3039questions

    Unityは、ユニティテクノロジーが開発したゲームエンジンです。 主にモバイルやブラウザ向けのゲーム製作に利用されていましたが、3Dの重力付きゲームが簡単に作成できることから需要が増え、現在はマルチプラットフォームに対応しています。 言語はC言語/C++で書かれていますが、C#、JavaScript、Booで書かれたコードにも対応しています。

  • Unity2D

    556questions