Unity初心者講座_ボタンだけのゲーム
注意書き
このチュートリアルは、Unity6(6000.0.35f1) の環境で作成しています。
Unityインストール
Unity公式より、Unityハブをダウンロードしてインストール
Unityアカウントを作成して、サインインしておきましょう。
設定(Preferences)から、ライセンス(Licenses)をインストールしておきます。
無料のPersonalで問題ありません。
Inatallから、Unity6をインストールします。
※Unity6でなくても大きな問題はありません。
本チュートリアルでは、UnityRoomでの公開を前提とした解説をしています。
インストールの際に、WebGL Build Support のチェックを入れておいてください。
(後で追加も出来ます)
テンプレートファイルをダウンロード
再配布可の素材などをまとめたテンプレート用のアセットを配布しています。
ダウンロードしておいてください。
プロジェクト作成、テンプレートを実行
New Project から
Universal 2D で新規プロジェクトを作成
ダウンロードしておいた、テンプレートファイル(FSGJ_日付.unitypackage)を、Project ビューのどこかにドラッグ&ドロップ
Import ボタンをクリックして、インポート
タイトルシーンを開いて実行する
Asetts → Scenes → TitleScene の順にフォルダを開き、 TitleScene をダブルクリック
ゲームビューに切り替えて、実行画面サイズを変更する。
タイトルシーンの挙動
Start ボタンをクリックすると SampleStageSceneに移動、Credit ボタンをクリックすると CreditSceneに移動
・・・するはずが、実行してボタンをクリックするとエラー発生になります。
エラーの内容は、SampleStage_Sceneシーンを読み込もうとしたけれど、build profilesにそのシーンが登録されていない、という意味です。
使いたいシーンを、build profilesで追加する必要があります。
使用するシーンを Build Profilesで追加する
上部メニューから、File → Build Profiles と進み、 Build Profilesを開き、
Open Scenes List クリック
Scene Listに、追加したいシーンをドラッグ&ドロップで追加していく。
TitleScene、SampleStage_Scene、SampleStage_ClearScenee、CreditScene を追加。
Titleシーンを一番上に移動する。
このScene Listの一番上にあるシーンが、ゲームを起動したときに実行される。
再度、タイトルシーンを実行して動作を確認
別のシーンに移動できることを確認しましょう。
ボタンクリックでシーン移動する仕組み
タイトルシーンに配置されている2つのボタンには、クリックされたときに指定したシーンに移動する振る舞いをするコンポーネントが付いています。
Hierarchyで見えている Button_Start は、ゲームオブジェクト。
Button_Start を選択すると、 Button_Startオブジェクトの Inspectorが開く。
Inspectorは、それぞれのゲームオブジェクトに付いている、コンポーネントが表示されている。
どのコンポーネントが付いているかで、ゲームオブジェクトの見た目や振る舞いが変わってくる。
これがUnityのゲームオブジェクトとコンポーネントの基本です。
Unityは、ゲームオブジェクトにコンポーネントを付けて、コンポーネントの値を変えていくことによってゲームを作っていきます。
例えば、Start_Buttonオブジェクトがボタンになっているのは、Start_Buttonオブジェクトに Buttonコンポーネントが付いているから。
クリックすると、SampleStage_Sceneに移動するのは、Button_Scriptコンポーネントの Scene Nameの値が SampleStage_Sceneになっているから。
SampleStage_Scene
Scenes → SampleStage フォルダに、SampleStage_Sceneがあるので、ダブルクリックでシーンを開く。
SampleStage_Sceneにも、最初からいくつかのゲームオブジェクトが配置されている。
Hierarchyにゲームオブジェクトを追加する
SampleStage_Sceneを実行してみましょう。
ネコとコアラの画像があります。クリックしてみても何も起こらず、何の動きもないですね。
音も出ないので退屈です。
Hierarchyにゲームオブジェクトを追加して、取りあえず動くようにしてみましょう。
Projectビューから、 SharedDirectory → Prefabs を開くと、青いキューブ型のアイコンのファイルがいくつかあります。
青いキューブ型アイコンのBGMをHierarchyにドラッグ&ドロップして、SampleStage_Sceneにゲームオブジェクトを追加しましょう。
BGMは、BGMを再生することが出来るゲームオブジェクトです。
Inspectorを見てみると、Audio Source コンポーネントが付いています。
Audio Source コンポーネントは、音を再生する機能を持つコンポーネントで、これが付いているBGMオブジェクトを追加したから音楽が再生される訳です。
Audio Sourceコンポーネント
- Audio Resource:再生する音声ファイルをセットする
- Play On Awake:チェックを入れるとシーン開始時に自動的に音声ファイルを再生
- Loop:音声ファイルをループ再生
- Volume:音量調整
他にも色々ありますが、今はこれだけ覚えておきましょう。
同じように、GManagerオブジェクトも追加します。
これを使うのは後になりますが、シーン間でのデータ共有をするために用意しているオブジェクトです。
細かいことは気にせずに、全てのシーンにこのオブジェクトを配置してください。
(細かいことを気にできるようになったら、自分で同じようなものを作っていけば良いです)
GManagerオブジェクトは追加して実行しても見た目の挙動は変わりません。
今はHierarchy上に存在していれば構いません。
次に、CountDownTimerオブジェクトを追加しますが、このオブジェクトはCanvasの中に追加する必要があります。ドラッグ&ドロップする時に、 Canvasオブジェクトの上に持っていくように気をつけてください。
これで実行すると、残り時間が表示されるようになり、残り時間が0になるとステージ1のクリア画面に移動します。
このように、Herarchyに何かを追加するとゲーム画面にも反映されます。
サンプルステージを完成させる
背景画像を変更する
Canvas内のImageオブジェクトを選択し、SourceImageを他の画像に変更してみましょう。
Imageフォルダなどに好きな画像を入れておけば、
Imageコンポーネントの Source Imageを変更することで好きな背景画像に差し替えることが出来ます。
ボタン(ネコアラ) の挙動
最初から作られている、ネコとコアラの画像は実はボタンになっています。
ボタンにもImageコンポーネントが付いていて、先ほどと同じように Source Imageを変えることでボタンの画像を変えることが出来ます。好きな画像に変えてみましょう。
ネコとコアラはボタンなのでクリックすることが出来ます。
クリックしてみると、実はスコアが加算されています。GManagerを選択した状態でゲームを再生してみてください。
ネコ、コアラをクリックすると、Sample_scoreが 1 増えるのが確認出来ます。また、ネコのボタンは5回までクリア出来るのでスコアもその分増えていきます。
ネコとコアラのボタンは、クリックすると GManagerのsample_scoreを1増やす振る舞いを持ったコンポーネントを持っているということです。
Inspectorを見てみると、SampleStage_Button1 のコンポーネントが付いていますね。
このコンポーネントがボタンをクリックしたときの振る舞いを決めています。
Speed の下に3つの入力欄(x, y, z)がありますね。
これは、ボタンの移動速度です。x に 3 を入力してゲームを再生してみましょう。
ボタンが動くようになりました。
(Button2にはSpeedの値を持つコンポーネントは付いていません)
ボタンを複製しよう
ゲームを再生して、残り時間が0になるとステージクリア画面に移動しますが、「もっとがんばりましょう」と出てしまいますね。
ちょっと腹が立つので、もっとスコアを稼いで見返してやりましょう。
SampleStage_ClearSceneには、ちょっとした仕掛けがしてあり、GManagerのsample_scoreが10以上なら「もっとがんばりましょう」ではなく、別の表示に変わるようになっています。
しかし、今はボタンが2つしかないので、ボタン1とボタン2で最高でも6点しか稼げません。
Button1かButton2のどちらかを選択して、Ctrl + D でオブジェクトを複製出来ます。
複製されたオブジェクトには、 (1) 等の連番が付与されています。
同じ場所に複製されているので見た目上は一つのボタンに見えていますが、MoveToolで移動させてみるとボタンが増えていることが分かります。
複製したオブジェクトは、元のオブジェクトのコンポーネントなども含めて複製されているので、クリックするとスコアも加算されます。
同様の操作でボタンを複製して、10点分のスコアを稼げる数のボタンを作ってみましょう。
十分な数のボタンを作ってからゲームを実行すると、クリア画面のメッセージが変わるはずです。
自分でステージを作成する
次はサンプルステージと同じものを作って行きましょう。
シーンを作成
シーンを作成していく前に、そのシーンに必要なものをまとめておくためのフォルダを作成します。
Scenesフォルダを開き、 Projectビューの下にある + ボタンから Folderを作成します。
作成したフォルダにはStage1のように名前を付けておきましょう。
Canvasを追加、設定する
作成したStage1シーンを開いて、必要なゲームオブジェクトを追加していきましょう。
Hierarchyの + ボタンから、 UI → Canvas とクリックしていき、
Canvasゲームオブジェクトを追加しましょう。
続けて、Canvasの設定をしていきましょう。
Canvasを選択してInspectorを開きます。
Canvasコンポーネントの Render Mode を、 Screen Space - Overlay から、 Screen Space -Camera に変更します。
[Render Camera]の右にある二重丸をクリックして、Main Camera(Camera)を選択します。(Sceneタブを選ぶ必要があります)
[Canvas Scaler]コンポーネントの[UI Scale Mode]を、[Constant Pixel Size]から[Scale With Screen Size]に変更し、[Reference Resolution]を X 960 Y 540 に設定します(Gameビューで設定したサイズと同じにする)
これでCanvasの設定は完了です。新しいシーンを作るたびにこの操作を行っておきましょう。
背景画像を表示する
背景画像を表示できるように、Imageオブジェクトを配置しましょう。
HierarchyでCanvasを選択して、 + ボタンから UI → Image でImageオブジェクトをCanvas内に作成します。
オブジェクトの名前を、Background_Imageのような分かりやすい名前に変えておきましょう。
Background_Imageを選択して、 Rect Tool で画面一杯にImageオブジェクトを広げましょう。
Imageコンポーネントの Source Image に好きな画像を入れて背景画像を変更しましょう。
必要なオブジェクトを追加
SampleStage_Sceneと同様に、 BGM、GManager、CountDownTimer オブジェクトを追加します。
ここまで出来たら、一度動作を確認しておきましょう。
残り時間が0になったら次のシーン(デフォルトだとタイトルシーン)に移動するようになっているはずです。
ボタンを作成する
Canvasオブジェクトを選択して、 UI → Legacy → Button とクリックして、ボタンオブジェクトを作成します。 Button - TextMeshPro というオブジェクトもありますが、今回はLegacy → Buttonを使用します。
名前をButton1などに変えておきましょう。
Button1オブジェクトのImageコンポーネントでボタンの画像を好きな画像に変更、
Rectツールなどで丁度いい大きさに調整してください。
Buttonオブジェクトは、子オブジェクト(自身にぶら下がっているオブジェクト)にText (Legacy) を持っています。普通のボタンなら文字があってもいいですが、今回のように画像を使う場合には無い方がいいですね。
Text (Legacy)を選択して、Inspectorの一番上のチェックを外してしまいましょう。
不要なオブジェクトは、Inspectorで非表示にすることが出来ます。
ボタンを動かすためのスクリプト(プログラム)を作成
ボタンを作りましたが、このままでは動きません。
ボタンオブジェクトに、ボタンを動かすコンポーネントが付いていないためです。
サンプルステージでは、ボタン1にはSampleStage_Button1が付いていて、このコンポーネントがボタンの振る舞いを決めていました。今作ったボタンにもこのようなコンポーネントを追加して動きを付けてあげる必要があります。
ImageやAudioSourceコンポーネント等、Unityには様々なコンポーネントが用意されていますが、自分が動かしたいようにオブジェクトを動かすコンポーネントは存在しません。
好きなように動かしたければ、自分でコンポーネントを作らないといけない訳です。
プログラムを書いてスクリプトを作ることで、独自のコンポーネントを自作することができます。
Stage1のフォルダに、MonoBehaviourScriptを作成しましょう。
作成したら名前を変更します。Stage1_Button1_Script と名前を変更しましょう。
注意:名前をつけ間違えてしまったとき
MonoBehaviourScriptの名前をつけ間違えてしまった場合、エラーが出てゲームが動かなくなってしまいます。デフォルトのNewMonoBehaviourScriptのまま確定させてしまった場合など、名前を間違えたときには、一度そのスクリプトを削除してしまいましょう。スクリプトの中身(プログラム)を修正すればエラーは消せますが、エラーが出る原因を理解できるまでは削除して作り直したほうが良いです。
スクリプトを編集する
作成したスクリプトをダブルクリックするとスクリプトエディターが開きます。
(Visual Studio か Visual Studio Codeが開くはずです。もし、エディターが開かない場合は「Unity VisualStudio 設定」などのキーワードで検索して開くようにしておきましょう。)
ボタンをクリックしたときに呼び出すプログラムを書いていきます。
void Update()
{
}
の下に、
public void Button1Click()
{
}
と記述しましょう。全て半角英数で記述してください。特に、カッコなどの記号が全角になっていないか、全角のスペースが書かれていないかなどに気をつけてください。
プログラムは、 ( ) や { } 等のカッコの開き閉じがセットになっています。
プログラムを書く際やコピーする場合には、カッコの対応に十分気をつけてください。閉じ括弧が足りなかったりするとエラーが出てきます。(開いたカッコは必ず閉じる)
(0 個の参照 はプログラムを書くと勝手に表示されるものです。自分で書く必要はありません。)
今書いたプログラムは、「メソッド宣言」と言います。今から、ボタンをクリックした時に行いたい動作をプログラムで書いていきますが、ボタンクリック時に行いたいことは一つではなく複数あります。これらの処理をまとめておくために、Button1Clickという名前を付けて { } で囲んでおきます。
まず、ボタンをクリックしたらそのボタンを削除するようにしましょう。
Button1Clickメソッドのブロック({ } の中)に、
Destroy(gameObject);
と記述しましょう。最後のセミコロンの書き忘れに気をつけてください。
これで、ボタンをクリックした時に Button1Clickメソッドを呼び出せばボタンを消すことが出来るようになります。
ボタンにスクリプトを登録する
・・・実行してクリックしても何も起こりませんね。
スクリプトは作っただけでは動かないので、そのスクリプトで動作させたいオブジェクトのコンポーネントに追加しなければいけません。
Button1を選択して、
Inspectorの一番下にある Add Component ボタンをクリック
Button1と検索窓に入力して、
Stage1_Button1_ScriptをButton1のコンポーネントとして追加しましょう。
ボタンオブジェクトは、スクリプトを追加するだけではなく、クリックしたときに呼び出すメソッドを指定する必要があります。
Buttonコンポーネントの、 On Click() の右下の + をクリック
None (Object) の右の◎をクリックして、 Sceneタブから Button1を探して選択
No Functionをクリックして、
Stage1_Button1_Script → Button1Click() と選択します。
つまり、さっき作ったメソッドを指定しましょう。
これで、Button1をクリックすると Stage1_Button1_Script に書いた Button1Click() メソッドを呼び出すことが出来るようになります。
実行して、クリックしたらボタンが消えることを確認しましょう。
スコアを増やす、何回かクリックしたら消えるようにする
今は、ボタンを1回クリックしたら消えてしまいます。複数回クリックで消すようにしてみましょう。
public class Stage1_Button1_Script : MonoBehaviour
{
の下に、
public int clickNum = 0;
と記述します。
public は自身以外からも参照可にする修飾子(公開)、int は整数型、clickNumは変数の名前、 = 0 はclickNumに0を代入(clickNumを0にする)の意味です。
変数の型 変数名 = 初期値;
で好きな変数を宣言することが出来ます。
public は最初の頃は付けておくようにしましょう。publicが付いている変数は、ゲーム実行中にInspectorで値を確認できるようになるので、動作の確認が楽になります。
(最初は綺麗でなくても一向に構いませんが、何でもかんでもpublicにするのはあまり綺麗なプログラムではありません。少し慣れてきたら、「Unity public private 違い」で検索して調べてみましょう。)
次に、Button1Clickメソッドを下記に書き換えます。
public void Button1Click()
{
clickNum += 1;
GManager.instance.stage1_score += 1;
if (clickNum >= 5)
{
Destroy(gameObject);
}
}
カッコの対応に気をつけて、記述してください。
clickNum += 1; は、clickNumを1増やす。
GManager.instance.stage1_score += 1; は、GManagerのinstanceのstage1_scoreを1増やす。
if (clickNum >= 5) は、もしもclickNumが5以上だったら、の意味になります。
これで、ボタンがクリックされるごとにclickNumが1ずつ増えて、clickNumが5以上になったらボタンが消えるようになります。
ボタンを移動させる
public int clickNum = 0;
の下に、
public Vector3 speed;
のプログラムを追加して、
void Update()
{
}
のカッコの中に、
transform.position += speed * Time.deltaTime;
if (transform.position.x >= 10 || transform.position.x <= -10)
{
speed *= -1;
}
のプログラムを追加してください。
transform.position += speed * Time.deltaTime;
は、このスクリプトが付いているゲームオブジェクトの、transformコンポーネントの、positionの x に、speed×Time.deltaTimeを足すの意味になります。
if (transform.position.x >= 10 || transform.position.x <= -10)
は、もしtransformのpositionのxが10以上 または transformのpositionのxが-10以下 の意味です。この条件に合致する場合(つまり、オブジェクトの横方向の座標が 10 以上か-10以下(画面外になるくらい右か左))なら、 speed *= -1 の処理を実行します。
speedは3次元のベクトルです。-1をかけると 移動ベクトルを反転させることが出来ます。
(要するに、逆側に動くようになるということ)
Button1のInspectorで、Stage1_Button1_Scriptの Speedの X を0以外の値に変えて実行してみましょう。
ボタンが動くようになります。
実行したままButton1を選択してみましょう。
transformコンポーネントのPositionの X が増減しているのが分かります。
これは、Move Toolなどで自分でオブジェクトを動かした場合でも同じで、transformコンポーネントのPositionを変えると、ゲーム画面内でのオブジェクトの場所(座標)が変わります。
スクリプトで記述した、transform.position += speed * Time.deltaTime; のプログラムが実行されることによって、transformコンポーネントのPositionに speed 分の値が足される事になり、その結果としてオブジェクトが動いていた訳です。
このように、Unityではスクリプトによって、オブジェクトに付いているコンポーネントの値を変える事によって様々な動きを付けていきます。この、関係が分かってくると色々なことが出来るようになってきます。少しずつ慣れて行きましょう。
Button2とButton3を作ろう
では、同じようにして2つ目、3つ目のボタンを作ってみてください。
2つ目のボタンは5回クリックしたら消えるではなく1回クリックしたら消えるように、横移動ではなく縦移動になるようにしてみましょう。
縦移動は x ではなく y 座標になるので、
transform.position += speed * Time.deltaTime;
if (transform.position.y >= 5 || transform.position.y <= -5)
{
speed *= -1;
}
のようにしましょう。
3つ目のボタンの動きは何でも構いません。2つのボタンと少しでいいので違う動きをさせてみましょう。
クリアシーンを作成する
3つボタンを作れたら、クリアシーンを作成しましょう。
ステージ1を作ったときと同じようにして、シーンを作成し、GManagerとBGMをHierarchyに追加してください。CountDownTimerは必要ありません(ただし、自動的に次のシーンに移動したいなら入れてもいいですね)。
次のステージに移動するボタンを作成
次のステージに移動するボタンを作成しましょう。
Button(Legacy)オブジェクトを追加して、NextButtonに名前を変更します。
NextButtonの子オブジェクトのText(Legacy)を選択して、Inspectorを開きます。
Textコンポーネントの値を変更して、画像のように設定しましょう。
Fontをデフォルトから変更するのを忘れないようにしてください。
デフォルトフォントは、WebGL形式で公開した時に日本語が文字化けしてしまいます。
次のシーンに移動させる
NextButtonオブジェクトを選択して、Add ComponentからButtonScriptを追加します。
ButtonScriptはテンプレートで最初から用意してあるスクリプトで、自分で作成する必要はありません。
ボタンクリック時に呼び出すメソッドを設定してください。
ButtonScriptのOnButtonClickedを選択します。
SceneNameをStage1_Sceneなどに変更して、ボタンをクリックするとシーン移動することを確かめましょう。
クリア時のメッセージを表示する
Canvasの中に、 UI → Legacy → Text(Legacy)と選択して、Text(Legacy)オブジェクトを追加しましょう。好きなクリアメッセージをTextに記入すれば、クリア時のメッセージを出すことが出来ます。得点が低かったときのメッセージにしておいてください。
メッセージは出ましたが、これだとスコアに応じた表示に出来ませんね。
スコア(GManagerのstage1_score)に応じて、表示するメッセージを変えるコンポーネントを追加しましょう。
Stage1_ClearText_Script を作成して、
2行目( using UnityEngine; の下)に、
using UnityEngine.UI;
を、
public class Stage1_ClearText_Script : MonoBehaviour
{
の下に、
public Text clearText;
を、
void Start()メソッドの中に、
if (GManager.instance.stage1_score >= 10)
{
clearText.text = "よくできました";
}
else
{
clearText.text = "まだまだだね";
}
を記述してください。
これで、GManagerの stage1_score が 10以上なら clearTextのtext を書き換える事ができます。
else は それ以外 の意味です。この場合だと、stage1_scoreが10以上でない場合なので、10未満のときに clearText.text を まだまだだね に変えることになります。
Inspectorからオブジェクトを登録する
さて、clearText.text を書き換えることが出来る、と言いましたが、clearText ってなんでしょう?
public Text clearText;
で、Text型の変数を宣言(作った)したので、これのことですが、具体的に何を指しているのかわかりませんね。
Text_Score に Stage1_ClearText_Script を追加して、
Clear Text の右の◎をクリック、
Text_Scoreを選択しましょう。
これで、 clearText に Text_Score オブジェクトを割り当てることが出来ます。
他のオブジェクトのコンポーネントに対して何かをしたいときは、このようにしてスクリプトからアクセスすることが出来ます。
ゲームを完成させよう
以上で、最低限必要な要素は整いました。
- タイトル画面からステージ1に移動する
- ステージ1 に 3種類以上のボタンを作る
- ステージ1 で GManagerの stage1_scoreを10以上に出来るだけのボタンを配置
- ステージ1 の CountDownTimerで Stage1_Clear_Sceneに移動させる
- Stage1_Clear_Scene で GManagerの stage1_scoreの値に応じてメッセージを変える(10以上ならよく出来ました、など)
- Stage1_Clear_Scene から、他のシーンに移動できるようにする
これで、最低限動作する格好になりました。
後は、各ステージでボタンをクリックしたときの動きを付けてあげれば、最低限のゲームとして完成させられます。
Discussion