パズルゲームの作り方講座の第3回ではunityスクリプトの書き方・使い方の導入を行いました。
前回の記事↓

第4回では、大きく分けて次の2つの処理を作成していきます。
- ボールを落とす位置の調整
- ボールの衝突判定の詳細設定
ボールを落とす位置の調整
前回作成したBallGeneratorを追加修正していきます。BallGeneratorから生成されるボールの落とす位置が中途半端だったため、フィールド上部で落とされるように調整していきます。
それでは、BallGeneratorクラスのUpdate関数内を次のようにしましょう(修正した点は下線の部分です)。
1 2 3 4 5 6 7 8 9 10 11 |
void Update() { cnt++; cnt%=MAXCNT; if(cnt==0) { GameObject gameObject = Instantiate(ballObj); gameObject.transform.parent = this.transform; gameObject.transform.localPosition = Vector3.zero; } } |
localPositionは親オブジェクト(BallGenerator)の相対位置を設定する変数です。localPositionにVector3.zeroで(0,0,0)の位置を与えると、子オブジェクトは親オブジェクトの位置である(0,12,0)に変換されて代入されます。つまり、BallGeneratorの位置を変えるとボールの生成位置も変わるようになりまs。
前回はBallGeneratorの位置が低かったため、BallGeneratorの位置をインスペクタから次の位置に変更しましょう。
オブジェクト名 | Position |
BallGenerator | (0, 12, 0) |
すると次のように高い位置から落ちるようになります。
実際にコードを書くとわかりますが、ボールの落ちてくる角度が上記画像のようになっていないと思います(真下に落ちちゃってますよね)。
ボールの落下に角度をつけるためにもう一文コードを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 |
void Update() { cnt++; cnt%=MAXCNT; if(cnt==0) { GameObject gameObject = Instantiate(ballObj); gameObject.transform.parent = this.transform; gameObject.transform.localPosition = Vector3.zero; gameObject.GetComponent<Rigidbody>().AddForce(Quaternion.Euler(0,0,UnityEngine.Random.RandomRange(-60.0f,60.0f))*Vector3.down*10f,ForceMode.Impulse); } } |
gameObject.GetComponent<Rigidbody>().AddForce(Quaternion.Euler(0,0,UnityEngine.Random.RandomRange(-60.0f,60.0f))*Vector3.down*10f,ForceMode.Impulse);
という行を追加しました。
やっていることは、ballGeneratorで生成したボールがただ垂直落下しかしない問題に対処するために「-60~60度の範囲でボールを落とす方向を変える処理」になります。
この行は処理の内容が難しいので詳しい解説は割愛します(クォータニオンやオイラー角といった概念を使います。やや高度な物理・数学なのでひとまずスルーして先に進みましょう)。
ボールの衝突判定の設定
前の回にて、衝突判定について解説していきました。この衝突判定が発生したタイミングで処理を行う関数がUnityには用意されています。この処理を使って、ボール同士の衝突を検知する処理を書いていきます。
まずはBallObjectという名前でスクリプトを作成しましょう。
作成したら、プレハブ内のゲームオブジェクトBallにスクリプトBallObjectを追加しましょう。
スクリプトでの衝突判定の扱い方
衝突判定を検知する関数一覧は以下の通りです。
関数名 | 詳細 |
OnCollisionEnter | 衝突した1フレームのみ実行 |
OnCollisionStay | 衝突している間実行 |
OnCollisionExit | 衝突しなくなった1フレームのみ実行 |
今回は衝突した瞬間を使いたいため、OnCollisionEnter関数を使用します。Update関数の下に次のようなOnCollisionEnter関数を書いてみましょう。
1 2 3 4 5 6 7 8 9 |
void Update() { //---- 省略 ---- } void OnCollisionEnter(Collision other) { //ボールにぶつかったとき Debug.Log("ぶつかった!"); } |
書き終えたら、実行してみましょう。すると、Console上(例では画面右下)でゲームオブジェクトが衝突した際に「ぶつかった!」と表示されます。
【Tips】タグ(Tag)とは
先ほどのコードでは、ボールとフィールドが衝突した場合でも「ぶつかった!」と表示されてしまう問題があります。どのオブジェクトがぶつかったかを識別するために、ここからはタグ(Tag)を使用していきます。
タグは、ゲームオブジェクトを分類するときに使用する機能です。
まずは、プレハブ上のBallのインスペクタを開いてみましょう。
初めはTagが「Untagged」になっています。これをクリックして、Add Tagを選択してください。
そして、Tagsのリストの右下の+ボタンを押して「Ball」タグを追加してみてください。
最後に、Ballのインスペクタに戻ってTagをBallに設定します。これでタグをつけることができました。
それでは、衝突したオブジェクトがボールか否かを識別するコードを書いていきましょう。
次のようなコードを書いてください。
1 2 3 4 5 6 7 8 9 10 11 12 |
void OnCollisionEnter(Collision other) { //ボールがぶつかったとき if(other.gameObject.tag == "Ball") { Debug.Log("ボールにぶつかった!"); } else { Debug.Log("ボールじゃないところにぶつかった!"); } } |
このgameObject.tagを使ってタグ名を取得していることが分かります。タグ名がBallであるかどうかをif文により分岐させて出力を分けました。
それではこの状態で実行してみましょう。
ボール同士がぶつかった際は「ボールにぶつかった!」を、それ以外の時は「ボールじゃないところにぶつかった!」と表示されている様子が確認できます。
おさらいと次回予告
今回は、2つの処理をスクリプトに書いていきました。
- ボールを落とす位置の調整
- ボールの衝突判定の詳細設定
次回は、マウス入力の検知に関する処理について説明していきます。
次回の記事↓

コメント