ビリヤードゲームの作り方3 ビリヤードを打つ・穴に入ったら消す処理を作る

Unity C# ビリヤードの作り方


Unityの本格ゲーム制作講座はこちら
【30日間の全額返金保証付き】

前回に引き続きビリヤードゲームを作っていきます。前回はビリヤードボールの当たり判定・移動処理を作りました。

前回の記事 : 

ビリヤードゲームの作り方2 ボールの移動と当たり判定の処理を作る
本講座はUnityでビリヤードゲームの作り方について説明していきます。前回はプロジェクトを作成し、ビリヤード台とボールなどを作りました。 前回の記事: 第二回目はボールの移動と当たり判定処理を実装していきます。 今回から実...


第3回の今回は「マウスクリックによってボールを打つ、ボールが穴に入ったら消える、リセット」などゲームとして成立させるまでを作っていきます。

では始めていきましょう。


【Unity入門の森の最新ゲーム開発講座もお届け】

Unityにおけるマウスクリック処理の作り方について

マウスクリックによって何かを行う際は、Unityに用意されている関数を使うのが最も簡単です。

これらの関数でPCマウスのクリックを取得、処理できます。

Input.GetMouseButtonDown、Input.GetMouseButton、Input.GetMouseButtonUpの3つの関数を組み合わせていけばOKです。

ここで簡単にマウスクリック以外の処理の説明をしておきます。

if文

「( )」内の条件が成立する場合に「{ }」内の処理が実行されます。

(関連記事:Unity C#の条件分岐の使い方 if文・switch文

Debug.Log

Unityの「Console」画面に「( )」内の文字を出力します。直接文字を打ち込む場合は「” “」で囲う必要があります。(囲うことでこれは文字列だよと示す事ができる)

Update()は前回お話しましたが、毎フレーム実行され続ける関数です。

なのでこの処理は「毎フレームif文によってマウスのクリックを監視し続けて、クリックされたら各処理を行う」というスクリプトになります。

の「( 0 )」に当たる部分は

0 右クリック
1 左クリック
2 真ん中クリック

のようにボタンを表しています。

クリック操作によって方向を決めてボールを打つ処理を作る

では実際にクリックによってボールを打つ処理を作成していきましょう。

まずこれから作成する処理を文章で表すと

となります。

ビリヤードのボールが動く進路となるラインの作成

クリックで方向を決める際に今どの方向を向いているのかを示すための線となるゲームオブジェクトを作成しましょう。

まずヒエラルキーの「Ball」の子に「Line」という空Objectを作成します。

「Ballを右クリック→Create Empty」です。

そして「Line」を右クリックして「UI→Canvas」を作成します。

「Canvas」はUIなど2Dのものを表示するためのものですが、今回は少し設定と大きさをを変更していきます。下記のように変更しましょう。

そして設定し終えた「Canvas」を右クリックして「UI→Image」を配置します。

「Image」を下記のように設定します。

これでボールの方向を示すラインができました。

ビリヤードボールの動作スクリプトの作成

これからスクリプトを記載していきますが、先に今回作成するスクリプトを作ってオブジェクトに予めセットしましょう。

まずは前回作成した「BallController」です。これは中身を書き換えますが、そのまま「Ball」にセットしておいてください。

今回、新しく2つのスクリプトを作成します。

「ProjectWindow」の「Script」フォルダで右クリック→Create→C# Script

を選択肢新しくC#ファイルを作成し名前を「Hole」と「ColorBall」とします。

「Hole」はヒエラルキー「Table」の子「Hole」の子にある6つの「Cylinder」を複数選択し、インスペクターにドラック&ドロップをしすべてのシリンダーに「Hole」コンポーネントをセットします。

「ColorBall」はプレハブになっているカラーボールのプレハブを開き、インスペクターにドラック&ドロップしてカラーボールのプレハブに「ColorBall」のコンポーネントをセットします。

カラーこれでボール全てにセットされます。

 

手玉ボールを打つ処理の記述

ここから本格的にスクリプトを書いていきます。

まずは先にこれから書いていく「BallController」のソースコードを掲載します。前回書いた「Start」内の処理は消してしまって構いません。

分割して説明していきましょう。
 
冒頭部分

個々の部分は現状ではファイル名以外はお約束だと思って下さい。少しだけ説明すると。

using 名前空間(namespace)と言われるもので、Unityで定義されているオブジェクト(UnityEngine)やシステムで定義されているものを、使いますよーっていう宣言。
MonoBehaviour

クラス名のあとに「 : 」をつけて書くことを「継承」と呼び、オブジェクト指向のプログラミングにおいての基礎になります。

今回は「MonoBehaviour」というクラスを継承した「BallController」というクラスを作成しています。

MonoBehaviour」というのはUnityで用意されているクラスで、StartやUpdateといった関数を使用できるのはこれを継承しているためです。

(関連記事:UnityC# クラスの継承・抽象メソッドとオーバライドの使い方)

変数

ここは、変数の定義です。コメント記載しているような変数の箱を予め用意していると思って下さい。

変数は基本として

のように表記します。

(関連記事:Unity C# 変数と型の使い方 宣言や代入・型変換について

「SerializeField」は前回お話した、Unityエディターのインスペクターで設定できるようになる表記です。後々ここにセットしていきます。

「GameObject」「Transform」「List」「Rigidbody」「Vector3」「float」は「」を表しておりそれぞれ別の形の箱になっている言うイメージを持っておきましょう。それぞれの型についても簡単に解説しておきます。

GameObject Unityのゲームオブジェクト型
Transform Unityの位置、角度、スケールなどを扱う型
Rigidbody Unityのリジッドボディ型
List リスト型。何のリストかは「List<float>」のように表記する
Vector3 3次元ベクトル型、3Dゲームを作る際はよく使います。
float

単精度浮動小数点数、要は小数型、数字のあとに「f」をつける(10.0fなど)。

(関連記事:UnityC# Listの使い方

Start

ここでは、前回にも出てきたように「mainBallからRigidbodyを取得してmainRigid」に保管しています。

また、リセットを行うときのために「mainBall」の位置を「mainBallDefaultPosition」に保管しています。

条件分岐

最初にも登場しましたが「if文」は「()」の中の条件が成立するときに括弧内の処理を実行します。「else」は条件が成立しない場合の処理になります。

今回は「mainBall」が「activeSelf」= ゲームオブジェクトがアクティブなら「if」の括弧内、そうでないなら「else」の括弧内の処理が実行されます。

「else」内の処理は最後に説明しますので、ここから「if」の処理の解説をしていきます。

マウスクリック開始

先にお話したように

はマウスがクリックされたときの処理です。

ソースコードのコメントに書かれているように、開始時の位置を保管、方向先を示すゲームオブジェクトの表示を行い、コンソールにログを表示しています。

マウスクリック中

これは前述の通りマウスを押している最中の処理です。

この中が少し複雑な計算をしていますので簡単に解説します。

まず位置を保管しているのは前と同じですが、「角度を算出」の部分だけ少し説明します。

これはベクトル計算です。数学、物理の分野になりますが二点間のベクトルを計算で、現在のマウスの位置からクリック開始時の位置までのベクトルを算出しています。

ベクトルは

の計算をすることでベクトルB→Aベクトルを得ることができるため、クリック開始位置から終了を引くことで、終了位置→開始位置のベクトル、つまりボールの飛ぶ方向を算出しています。

そして、そのベクトルを「アークタンジェント」という数学の逆三角関数をつかって角度(ラジアン単位)を算出、そのラジアンの角度を度数(「°」)に変換し「angle」という変数に入れています。

アークタンジェントとは、底辺と対辺の2辺の比に対しての角度θを考える逆三角関数で、先に算出した、ボールの飛ぶ方向のベクトルのx軸からの角度を算出しています。

ベクトル、アークタンジェントを図解しておきますので参考にして下さい。

 

「Mathf」というのがUnityにおいて数学の公式を使うための記載になります。

そして、その角度を「Vector3」として扱うために新しいVector3を作成し「rot」に保管。

その「rot」を「Quaternion」というUnityで角度を表すために用いられる型に変換し「qua」に保管しています。

そして最後に、方向線の角度を「qua」に変更、位置を「mainBall」の位置に移動させています。

マウスクリック終了

最後に、同じように位置を「upPosition」に保管。最終的に打ち出す方向をベクトル計算をして算出。

ここで、算出した値に「power」をかけて実際に力を加えます。

ここまで来たら実際に動かしてみましょう。

インスペクターの設定

では、Unityに戻って、「SerializeField」に設定したオブジェクトや数値を設定していきましょう。

画像を参考に「MainBallにMainBall」「ArrowにLine」「BallListに各ボール」をドラック&ドロップしましょう。「BallList」は右の数字を入力すると項目数を変更できます。

「Power」はボールを打つ強さが変わりますので自由に変更してみましょう。

 

手玉ボールを実際に打ってみる

ではPlayしてみましょう。

マウスをクリックして、そのままドラックして方向線が正しく動くか、クリックを離したときに線の方向に飛んでいくかを確認しましょう。

カラーボール、ビリヤード穴、ゲームリセット処理のスクリプトの作成

次に、最初に作成した「ColorBall」「Hole」のスクリプトを記述していきます。

ColorBallスクリプト

「ColorBall」の全文です。

似たような記載が多いので詳細説明は省きますが、後半部分の解説を簡単にします。

ここで「Reset」という関数を定義しています。「pubic」というのは他の関数から呼び出せるように公開するといった意味で捉えておきましょう。

こうすることで「Reset」関数を他のスクリプトから呼び出すことができます。内部で行っていることはコメントを参考にしてください。

Holeスクリプト

「Hole」の全文です。

ここで重要なのは

これは、Unityに用意されている「IsTriggerがオンになっているコライダーに他のコライダーが侵入したときに実行される関数」です。

前回「Hole」オブジェクトには、コライダーを設定しており「IsTrigger」をオンに設定していますので、ボールがこの「Hole」に侵入すると「{}」内の処理が実行されます。

リセット処理をBallControllerスクリプトに追加する

リセット処理はリセットはボタンを配置して、押したらリセットするという形にしていきます。BallControllerのOnResetButtonClicked()の中身を書いていきます。

ボタンに設定するためにはこの関数のスコープを「public」にする必要があります(関連記事:UnityC#のフィールド・プロパティ・アクセス修飾子の使い方 スコープの概念を理解する)。
そうすると、Unityのインスペクターからこの関数を選択できるようになります(後述)。
 

「foreach」はリストや、配列などの要素全てに対して繰り返し処理を行うことができます(関連記事:Unity C#の繰り返し処理の使い方 for文・while文・foreach文)。

ここでは、「ballList」の要素「ColorBall」に「ball」という名前をつけて、すべての要素に「{}」内の処理を行います。

リセットボタンの設置

スクリプトに書いたリセット処理ををボタンを押して起動できるように画面にボタンを設置していきます。ヒエラルキーの最初に作成した「Canvas」を右クリックして「UI→Button」でボタンを設置します。

 

設置したボタンの位置、大きさ、色を調整していきます。まずはアンカーを設定していきます。

アンカーとは親の「Canvas」に対してどこを基準に位置を設定するかを定める機能です。

「RectTransform」左上に有る四角いマークをクリックして設定します。(Anchorの数値を直接記入して変更することも可能ですが今回はより簡単な方法を解説します)

「Button」のインスペクター「RectTransform」の右上の四角いマークをクリックし「right/top」を選択しましょう。こうすると「Canvas」の右上を基準にした数値を入力することになります。

では、数値の入力をしていきましょう。「Button」の「RectTransform」の値を変更していきます。

入力すると画像のような位置になります。

そして文字と色を変更、ボタンを押したときの処理を登録していきます。

まずはヒエラルキーの「Button」を選択しインスペクターの「Image」の「Color」をクリックして「A」の数値を「120」ほどに変更します。カラーのそれぞれは「R=赤、G=緑、B=青、A=アルファ」となっており「アルファ」とは透明度を表します。これを下げると半透明、0にすると見えなくなります。

次に「Button」の子にある「Text」を選択、インスペクターの「Text」コンポーネントに「Reset」という文字を入力しましょう。これでボタンにResetという文字が表示されます。また、TextのFontSizeを25に変更しておきましょう。

「Button」コンポーネントの「OnClick」の右下にある「+」ボタンを押して新しいイベント登録欄を出します。そしてその「None(Object)」となっているところに、「BallController」が設定されているヒエラルキーの「MainBall」オブジェクトをドラック&ドロップします。

すると右側に「No Function」という項目が有効になりますのでそこを開き作成した「BallController→OnResetButtonClicked」を選択します。

これでボタンを押したら、「OnResetButtonClicked」が実行されるようになりました。

elseの処理 手玉が穴に落ちた時の処理

最後に「else」の内容を見ていきましょう。

elseの条件は「mainBall」がアクティブでないときなので、それは「mainBall」が穴に落ちて「Hole」のスクリプトの処理によって非アクティブになったときと言い換えることができます。

そうなるゲームが進行できませんので、コンソールにログを出し、リセットしています。

ゲームとしての完成度

以上で今回作成するゲームのPCでの内容は完成となります。

しかしあくまでボールを打つ、穴に落ちたら消える、再スタートといった基本しか作っていません。

例えば、本来のビリヤードゲームであれば、落ちたボールを画面に表示したり、ステージ選択ができたりするでしょう。

また、現状白い玉が動いている最中でも更にボールが打てたりするバグも残っています。

ゲームとしての完成度はまだまだ低いと言えるでしょう。

ぜひこの記事を読んだあなたが自由にこのビリヤードゲームを拡張してみてください。

次回は最後にこのビリヤードゲームをスマホ対応できるように、タッチ入力に変更していきます。

次回の記事:

ビリヤードゲームの作り方4 スマホタップに対応させてモバイルゲームを作る
前回まででビリヤードゲームの基本部分が出来上がりました。 前回の記事 :  第4回の今回は「スマホタップに対応させてモバイルゲームを作る」です。 では始めていきましょう。  スマホへの対応方法 BuildingSetti...

Unity C# ビリヤードゲームの作り方に戻る>>


【Unity入門の森の最新ゲーム開発講座もお届け】

コメント

タイトルとURLをコピーしました