Unityに関連する記事です

生成する干支の種類を指定した数に制限する


 12種類の干支がランダムで生成されてしまうと中々つながりません。そのため、生成する干支の種類の数を絞って生成させるようにしていきます。
 
 GameDataクラスに用意した etoTypeCount 変数を利用します。ここで指定した種類の干支だけがランダムで生成されるようにします。
指定した数が 5 であれば、毎回ランダムな 5 種類の干支が選択されて、ゲーム内に登場するようにします。
こうすることで干支通しが繋がりやすくなり、また、ランダムな 5 種類とすることで、繰り返し遊ぶ際のマンネリ化を防ぐことができます。

 設計としては、次のような処理の流れになります。

 GameDataクラスを修正し、新しいEtoDataクラスを用意する。このEtoDataを干支の数だけ(12種類)インスタンスして干支データとし、リスト化にする。
   ↓
 GamanManagerクラスを修正し、干支データのリストを使ってゲーム内で生成するランダムな干支を指定数(基準値は5種類)だけ選択して生成するようにする。
   ↓
 ランダムな干支はゲームを実行するたびに変化する。同じ種類の干支は重複せず、異なる種類で5種類用意する。


 実装の手順です。
 1.GameDataスクリプトを修正する
 2.GamanManagerスクリプトを修正する
 3.ゲームを実行して動作を確認する



 新しく学習する内容になります。

・クラス内に別のクラスを作成する(入れ子クラス)
・インスタンスしたクラスにコンストラクタを利用して値を代入する方法
・入れ子クラスを外部のクラスで宣言する方法
・コルーチンメソッド内における、while文によるループ処理


1.GameDataスクリプトを修正する


 干支データを管理するためにEtoDataという新しいクラスをGameDataクラス内に用意します。
またInitEtoDataListメソッドを新しく作成し、このEtoDataをインスタンスしてリスト化します。この手順によって、12種類の干支データが準備できます。
いままでGamanManagerスクリプトで管理していた干支の画像のリストはEtoData作成時のみに使用すればいいため、先ほどのInitEtoDataListメソッド内に処理に移します。
こうすることで同じような値を重複して用意することを避けるとともに、必要のない値はその処理の中のみで扱うように変更します。

GameData.cs

 <= クリックすると開きます。




 GameDataスクリプトの修正が終了したら、GameDataゲームオブジェクトのインスペクターを確認します。
宣言フィールドで追加した etoDataList 変数が追加されていれば大丈夫です。このListのSizeは 0 のままにしておきます。
現時点では、ゲームを実行しても、Size は 0 のまま、変わりません。

 次の GameManager に処理を追加することで、ゲーム実行に合わせて、ここに12種類の干支データが入るため、
GameManager を修正してからゲーム実行すると、Size が 0 から 12 に変更されて、値も設定されます。


GameDataのインスペクター画像



<クラス内に別のクラスを作成する(入れ子クラス)>


 GameDataクラスの宣言フィールドにおいて、別のクラスを作成しています。今回はEtoDataクラスです。
このようにC#では、1つの独立したクラス(ファイル)としてではなく、あるクラスの中に別のクラスを作成しても使用することができます。
これを入れ子(ネスト)クラスと言います。特定のクラスでのみ使用することが確定しているような、使用範囲の狭いクラスであれば、
このように入れ子クラスにした方がスクリプト・ファイルが増えずに済みます。
 また設計上、ファイルにはしたくない(隠しておきたい)クラスを作成する場合にも用いられます。

 使用方法は他のクラスと同じです。


<インスタンスしたクラスにコンストラクタを利用して値を代入する方法>


 コンストラクタとは、クラスがインスタンス(new によって初期化)されたときに、引数で指定した値の代入を強制する特殊なメソッドのことです。
クラス名(型名)と同じ名前で定義を作成します。またメソッドですが戻り値を持ちません。(戻り値を返せません。)

    /// <summary>
    /// 干支の基本情報を扱うクラス
    /// </summary>
    [System.Serializable]     // この属性を付与することでインスペクター上にこのクラスを表示できる
    public class EtoData {  // クラスは継承しない
	public EtoType etoType;
	public Sprite sprite;

        // コンストラクタ(クラス名と同名で定義)
	public EtoData(EtoType etoType, Sprite sprite) {
	    this.etoType = etoType;
	    this.sprite = sprite;
	}
    }
 

 クラスで用意している変数に対して、インスタンスを正しく(代入忘れのないように)処理を行うために用意されます。

 コンストラクタを使用する場合には、new による初期化の宣言と同時に、コンストラクタで引数を定義している場合には、引数が必要になります。
引数が必要な場合に引数がない場合にはエラーになります。

 初期化の方法です。

   EtoData etoData = new EtoData(弟1引数 EtoType etoType, 第2引数 Sprite sprite);

 コンストラクタが呼び出されて、処理が行われます。
処理の内容は通常のメソッドと同じです。多くの場合はここで、クラスに用意している変数に対して、引数の値を代入することによってクラスに情報を登録します。

    public EtoData(EtoType etoType, Sprite sprite) {
	this.etoType = etoType;
	this.sprite = sprite;
    }

 コンストラクタは引数のオーバーロードが可能です。
そのため、同じ名前のコンストラクタであっても引数を別々の形で定義しておくことで、複数のコンストラクタが作成可能です。
例えば、以下のような形で用意可能です。

    public EtoData(EtoType etoType, Sprite sprite) {
	this.etoType = etoType;
	this.sprite = sprite;
    }

    public EtoData() {
	
    }

    public EtoData(int num) {
	this.etoType = (EtoType)num;
    }

参考記事
未確認飛行C様
コンストラクタ
https://ufcpp.net/study/csharp/oo_construct.html


2.GamanManagerスクリプトを修正する

 GamanManagerスクリプトを修正します。宣言フィールドには、ランダムで選択された干支データを代入するためのリストを用意します。
ゲームを実行するたびに、このリストにランダムに選択された干支データが規定数(基準値は5種類)が代入されます。

 GameDataスクリプトには干支データを管理させるようにしました。
そこでまずはGamanManagerスクリプトのStartメソッド内でこの干支データが存在しているかどうかを確認します。
もしも干支データが存在していない(作成されていない)場合には、まず干支データを作成する処理を行うようにします。

 この手続きが終了してから干支の生成処理に移るようにします。(干支データがないのに生成を始めればエラーで終了するでしょう)

 最後に、干支を生成する処理(CreateEtosメソッド)を修正し、以前は12種類の干支をランダムに生成していましたが
ここで修正を加えて、上記のランダムで選択された干支データから干支を生成するようにします。
これによりゲーム内で生成される干支の種類は5種類になります。(残りの7種類は生成されません)

GameManager.cs

 <= クリックすると開きます。




 GamanManageスクリプトの修正が終了したら、GamanManageゲームオブジェクトのインスペクターを確認します。
宣言フィールドで削除したetoSprites変数がなくなり、代わりに新しく追加したselectedEtoDataList変数が表示されていると思います。

selectedEtoDataListのSizeは 0 のままで大丈夫です。ゲーム内の処理が終了すると、このListに今回のゲームで生成する干支データが5種類追加されます。

GameManagerゲームオブジェクトのインスペクター画像



<入れ子クラスを外部のクラスで宣言する方法>


 GameDataに入れ子クラスとして作成しているEtoDataクラスを外部のクラスで用いる場合には、入れ子の親クラスを記述した上で宣言するようになります。

 下記のように書きます。

GameData.EtoData etoData;

List<GameData.EtoData> etoDatas = new List<GameData.EtoData>();


<コルーチンメソッド内における、while文によるループ処理>

 while文によるループ処理はコルーチンメソッド内でも記述することができます。この場合には何秒後にループする、といった柔軟な書式が可能になります。
今回は yield return null を利用し、1フレームだけ待機してループするという処理を実装しています。

 なお、while文は条件式を誤ると無限ループに入ってしまってUnityエディターが停止してしまいます。
こうなると再起動しなければならなくなりますので、while文を使用する際には注意してください。

private IEnumerator SetUpEtoTypes(int typeCount) {

    // while 文は 条件式 を満たす限りループする。ここでは typeCount 変数の値が 0 よりも大きい間は while 内の処理が繰り返し実行される
    while (typeCount > 0) {
	    
        // 処理を記述する 
			
        // 処理を1フレーム待機させて再開する。よって毎フレームのループ処理になる
        yield return null;
    }

    // while文の外に処理が記述されていた場合には、上記のwhile文の処理が終了してからでないと処理が実行されない
}

参考記事
@kwst様
コルーチンの初歩的な使い方【Unity, 初心者】
https://qiita.com/kwst/items/ce04abce7c1e2c72e023


3.ゲームを実行して動作を確認する

 
 ゲームを実行する前に、どのような状態で実行すると、どのような挙動が行われるのかを確認しておきます。
そうしないとこれからデバッグを行った際に、どれが正しい挙動なのか、どこに不具合があるのかの判断ができないためです。

 GameData の etoDataList の Size が 0 になっていることを確認します。
この値が 0 である場合にかぎり、etoDataList には EtoData の情報が追加されます。
そのため、Size が 0 になっていないと、正常に List に EtoData が追加されません。

 この理由については、GameData のスクリプトの InitEtoDataList メソッドの処理を見直して、処理の内容を確認しておいてください。
処理の内容を理解できていないと、どのような挙動になれば正しいのかを判断することが出来ません。

 これは教材での学習が終わって、1人でゲームを製作する場合にも大切な考え方になります。



 デバッグする内容を理解した上で、ゲームを実行して動作を確認します。
まず、GameDataゲームオブジェクトのインスペクターを確認してください。
ゲームを実行すると同時にetoDataListのSizeが0から12になり、各干支のデータが代入されます。12種類になっているかを確認してください。

GameDataのインスペクター画像


GameDataのインスペクター画像



 つづいて、GamanManagerゲームオブジェクトのインスペクターを確認し、selectedEtoDataListに5種類の干支データが代入されているかを確認してください。
このとき重複する干支データはないはずですので、何回か試して、重複していないかも合わせて確認してください。なおランダムで選択されているので
干支データの順番はバラバラになります。(干支の並び順では入りません)

GamanManagerゲームオブジェクトのインスペクター画像



 どちらも成功していれば、ゲームに生成される干支は5種類になっています。


<実行動画> 

GameDataゲームオブジェクトの EtoDataList 変数のSizeが 0 から12 に変更される(干支のデータが代入されているEtoDataがインスタンスされた結果)
GamanManagerゲームオブジェクトの SelectedEtoDataList 変数のSizeが 0 から 5 に変更される(EtoDataListの中から5種類がランダムで選択されている)
https://gyazo.com/ed636125db145f0f8eb52ebe4b386fce

selectedEtoDataList 変数に5種類の干支がランダムに選択されて追加され、それを元に干支が生成される
https://gyazo.com/35fb0dc7b341bc44bed9ba4cebcd4413



 以上でこの手順は終了です。

 次は 発展2 です。

コメントをかく


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

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

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

3D脱出ゲーム(抜粋)

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

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

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

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

3Dトップビューアクション(白猫風)

VideoPlayer イベント連動の実装例

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

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

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

private



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

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