Unityに関連する記事です

1.コルーチンを活用したゲーム内の実装例


 以下は、コルーチンを使用してゲーム内で一般的に行われるタスクを実行するサンプルコードです。


<1.点滅するエフェクト>


 プレイヤーキャラクターがダメージを受けた際に点滅するエフェクトを実装します。

 WaitForSeconds クラスを利用して、引数に指定した時間、処理を中断して再開させる機能を実装しています。


参考サイト
Unity 公式スクリプト・リファレンス
WaitForSeconds



using UnityEngine;
using System.Collections;

public class PlayerHealth : MonoBehaviour
{
    private Renderer playerRenderer;
    private bool isInvulnerable = false;

    void Start()
    {
        playerRenderer = GetComponent<Renderer>();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && !isInvulnerable)
        {
            StartCoroutine(TakeDamage());
        }
    }

    IEnumerator TakeDamage()
    {
        isInvulnerable = true;

        for (int i = 0; i < 5; i++)
        {
            playerRenderer.enabled = false;
            yield return new WaitForSeconds(0.2f);
            playerRenderer.enabled = true;
            yield return new WaitForSeconds(0.2f);
        }

        isInvulnerable = false;
    }
}

 このコードは、プレイヤーキャラクターがダメージを受けると、点滅するエフェクトを5回繰り返します。
また isInvulnerable フラグを使用して、連続してダメージを受けないようにします。


<2.指定した秒数ごとに敵を生成する>


 このサンプルでは、指定した秒数ごとに敵を生成する例を示します。


using UnityEngine;
using System.Collections;

public class EnemySpawner : MonoBehaviour
{
    public GameObject enemyPrefab;
    public float spawnInterval = 3.0f;

    void Start()
    {
        StartCoroutine(SpawnEnemies());
    }

    IEnumerator SpawnEnemies()
    {
        while (true)
        {
            Instantiate(enemyPrefab, transform.position, Quaternion.identity);
            yield return new WaitForSeconds(spawnInterval);
        }
    }
}

 このコードでは、enemyPrefab 変数に生成したい敵のプレハブを割り当て、spawnInterval 変数に生成間隔を秒単位で指定します。
コルーチン SpawnEnemies は、指定された間隔ごとに敵を生成します。



 上記の処理の場合、ゲーム実行中はずっと敵が生成され続けます。

 正常に動作することが確認できたら、処理を修正し、指定された数だけ敵を生成したら、生成を停止する処理を作ってみましょう。

 指定した数だけ敵を生成したら処理を停止させるには、変数を使用して生成した敵の数をカウントし、特定の条件が満たされたらコルーチンを終了することで表現できます。

 以下は、指定した数の敵を生成したらコルーチンを終了するサンプルコードです。


using UnityEngine;
using System.Collections;

public class EnemySpawner : MonoBehaviour
{
    public GameObject enemyPrefab;
    public int maxEnemiesToSpawn = 10; // 生成する最大の敵の数
    public float spawnInterval = 3.0f;

    private int spawnedEnemiesCount = 0; // 生成された敵の数

    void Start()
    {
        StartCoroutine(SpawnEnemies());
    }

    IEnumerator SpawnEnemies()
    {
        while (spawnedEnemiesCount < maxEnemiesToSpawn)
        {
            Instantiate(enemyPrefab, transform.position, Quaternion.identity);
            spawnedEnemiesCount++; // 生成された敵の数を増やす
            yield return new WaitForSeconds(spawnInterval);
        }
    }
}

 このコードでは、maxEnemiesToSpawn フィールドで生成する最大の敵の数を指定し、spawnedEnemiesCount 変数で生成された敵の数をカウントしています。
コルーチン内で生成した敵の数が maxEnemiesToSpawn に達した場合、ループを抜けてコルーチンが終了し、敵の生成が停止します。


<3.エフェクトを生成する>


 先ほどの【2】の処理を応用し、指定時間ごとにエフェクトを生成する機能を実装します。

 ここでは花火のエフェクトを生成するイメージで、生成される位置にランダム性を設けて、同じ位置に花火が上がらないようにしています。


using UnityEngine;
using System.Collections;

public class FireworksController : MonoBehaviour
{
    [SerializeField]
    private GameObject fireworksPrefab;

    [SerializeField]
    private int numberOfFireworks = 10; // 生成する花火の数

    [SerializeField]
    private float spawnInterval = 5.0f;

    [SerializeField]
    private float minOffset = -1.0f; // ランダムな位置の最小オフセット

    [SerializeField]
    private float maxOffset = 1.0f; // ランダムな位置の最大オフセット

    void Start()
    {
        StartCoroutine(SpawnFireworks());
    }

    IEnumerator SpawnFireworks()
    {
        int fireworksCount = 0; // ローカル変数として fireworksCount を定義

        while (fireworksCount < numberOfFireworks)
        {
            Vector3 spawnPosition = transform.position + new Vector3(Random.Range(minOffset, maxOffset), 0f, Random.Range(minOffset, maxOffset));
            Instantiate(fireworksPrefab, spawnPosition, Quaternion.identity);
            fireworksCount++;
            yield return new WaitForSeconds(spawnInterval);
        }
    }
}



 配列を利用することにより、花火の種類をランダムに変化させるように修正してみましょう。
エフェクトをランダムに変更するために、エフェクトのプレハブを配列に格納し、ランダムなインデックスを選択して生成することができます。

 以下は、修正されたコードです。


using UnityEngine;
using System.Collections;

public class FireworksController : MonoBehaviour
{
    [SerializeField]
    private GameObject[] fireworksPrefabs; // 複数の花火のプレハブを格納する配列

    [SerializeField]
    private int numberOfFireworks = 10; // 生成する花火の数

    [SerializeField]
    private float spawnInterval = 5.0f;

    [SerializeField]
    private float minOffset = -1.0f; // ランダムな位置の最小オフセット

    [SerializeField]
    private float maxOffset = 1.0f; // ランダムな位置の最大オフセット

    void Start()
    {
        StartCoroutine(SpawnFireworks());
    }

    IEnumerator SpawnFireworks()
    {
        int fireworksCount = 0; // ローカル変数として fireworksCount を定義

        while (fireworksCount < numberOfFireworks)
        {
            // ランダムな花火のプレハブを選択
            int randomIndex = Random.Range(0, fireworksPrefabs.Length);
            GameObject selectedPrefab = fireworksPrefabs[randomIndex];

            // ランダムな位置に花火を生成
            Vector3 spawnPosition = transform.position + new Vector3(Random.Range(minOffset, maxOffset), 0f, Random.Range(minOffset, maxOffset));
            Instantiate(selectedPrefab, spawnPosition, Quaternion.identity);

            fireworksCount++;
            yield return new WaitForSeconds(spawnInterval);
        }
    }
}

 この修正されたコードでは、fireworksPrefabs 配列に複数の花火のプレハブを格納し、ランダムなインデックスを選択して花火を生成します。

 これにより、花火に限らず、ランダムなエフェクトが生成されるようになります。

 これを先ほどの敵の生成に応用すれば、ランダムな敵が、ランダムな位置から生成される機能を作ることが出来ます。

 プログラムはすべて基礎の応用です。
あなた頭に浮かんだゲーム内の処理をどのようにすれば表現できるか、イメージを考えてみましょう。



<4.特定の条件を満たすまで処理を中断する>


 マウスクリックが行われるまで待機するサンプルコードです。

 WaitForSeconds クラスの代わりに WaitUntil クラスを利用し、特定の条件を満たすまで処理を中断する機能を実装しています。


参考サイト
Unity 公式スクリプト・リファレンス
WaitUntil



using UnityEngine;
using System.Collections;

public class MouseClickWait : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(WaitForMouseClick());
    }

    IEnumerator WaitForMouseClick()
    {
        yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
        Debug.Log("マウスクリックが検出されました。");
    }
}



 上記の処理を改良し、マウスクリックしたらシーン遷移する処理を考えてみましょう。
例えば、タイトルシーン→メインシーン、メインシーン→リザルトシーンといった部分で利用するイメージです。


using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;

public class MouseClickToStart : MonoBehaviour
{
    [SerializeField]
    private string nextSceneName = "NextScene"; // 次のシーンの名前

    void Start()
    {
        StartCoroutine(WaitForMouseClick());
    }

    IEnumerator WaitForMouseClick()
    {
        yield return new WaitUntil(() => Input.GetMouseButtonDown(0));
        
        // マウスクリックを感知したら指定したシーンに遷移する
        SceneManager.LoadScene(nextSceneName);
    }
}

 マウスクリックの部分をキーボードに変更すれば、特定のボタンと紐づけることが出来ます。


<5.while 文と yield return ステートメントの組み合わせ>


 while ループと yield return ステートメントを組み合わせて、一定の条件を満たすまで待機するための独自の待機ループを作成することができます。

 以下は、while ループを使用して条件が満たされるまで待機するサンプルコードです。


using System.Collections;
using UnityEngine;

public class Example : MonoBehaviour
{
    bool conditionMet = false; // 待機条件

    IEnumerator WaitForCondition()
    {
        while (!conditionMet)
        {
            // 条件が満たされるまで待機
            yield return null;
        }

        // 条件が満たされた後の処理
        Debug.Log("条件が満たされました!");
    }

    void Start()
    {
        StartCoroutine(WaitForCondition());
        // ある条件が満たされたと仮定
        StartCoroutine(SimulateConditionMet());
    }

    IEnumerator SimulateConditionMet()
    {
        yield return new WaitForSeconds(3.0f); // 3秒後に条件を満たす
        conditionMet = true;
    }
}

 このコードでは、WaitForCondition コルーチンが conditionMet フラグが true になるまで待機します。
待機中は yield return null を使用して、次のフレームまでコルーチンを中断します。

 SimulateConditionMet コルーチンは3秒後に conditionMet フラグを true に設定し、待機を解除します。

 複数の yield ステートメントを利用することにより、自分自身の条件に合わせたカスタムの待機ループを作成できます。
必要に応じて、他の条件を監視し、特定の条件が満たされたらコルーチンを続行することができます。



 なお、while 文内に yield ステートメントの処理を入れない場合、無限ループが発生してエラーになります。
これはコルーチンの制御フローが正しく動作しないためです。

 コルーチン内で while 文を用いる場合、yieldステートメントを使わないと、そのコルーチンが完了することなく、無限に同じフレーム内で処理がループし続けます。
そのため、ゲームが停止してしまいますので、利用する場合には注意してください。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます