Unity5で
ボールころがしゲームを
作ろう!
琉球大学工学部情報工学科3年次
親川大樹 @daiki_all
私のゲーム
LostSheep
U Hockey
今回作成するゲーム
ボールころがし
ボールを操作して、フィールドから落ちないように
ゴールを目指すゲーム。
まず、新しいプロジェクトを作る。
Unityを起動したら、「New project」をクリック。
Project nameに「BallGame」と入力し、「Create project」をクリック。
1
2
ようこそ、Unity5へ。
エディタ画面が起動する。ここでゲームを作っていくよ!
ウィンドウの説明①
Projectウィンドウ
ウィンドウの説明②
Hierarchy(ヒエラルキー)ウィンドウ ・ Scene(シーン)ウィンドウ
ウィンドウの説明④
Inspector(インスペクター)ウィンドウ
※Unityの基本操作
Sceneウィンドウで右クリックしたままマウスを動かすと、作業用カメラの視点が動く。
右クリックしたまま↑↓←→キー(またはWASDキー)を押すと、作業用カメラの位置が移動する。
色んな角度から3D世界を眺めてみよう!
視点の角度
+
移動
土台を作る
HierarchyウィンドウのCreateボタンから3D Objectを選択し、Cubeをクリック。すると、SceneにCubeが現れる。
Cubeを選択した状態でInspectorウィンドウのTransformを確認しよう。Position(位置)とRotation(角度)とScale(大きさ)を調整する。Scaleのxとzを少し大きくしてみる。
ボールを作る
土台の時と同じように、HierarchyウィンドウのCreateボタンから3D Objectを選択し、Sphereをクリック。
ボールの位置は土台の少し上になるようにしよう。Positionのyを調整する。
次に、Inspectorウィンドウの中の下側にある「AddComponent」ボタンを押し、Physics → Rigidbodyと選択していく。
これで、RigidbodyというComponentがボールに追加され、ボールが落下するようになった。
ゲームを再生してみよう
とりあえずボールが落下するようになったので、ここでゲームをスタートさせてみよう。
画面上の真ん中にある、▶ボタンを押すとゲームが始まる。すぐにボールが落下し、土台の上に乗るはずだ。
再生を終わる時は、もう一度▶ボタンを押す。
再生中でも座標の移動や値の調整はできるが、再生が終わると再生前の状態に戻ってしまうので注意しよう。
こまめなセーブを忘れずに!
ここで、現在作っているSceneを保存しておこう。Controlキー+S で、Sceneの保存ができる。最初なので保存場所を聞かれるが場所はそのままにして、名前は「Main」と入力しておこう。
すると、ProjectウィンドウにMainというSceneファイルができている。
この後は好きなタイミングでControl+Sを押して、こまめにセーブしよう。
ボールを操作したい!
ボールをキーボードで転すため、スクリプトファイルを作ろう。
ProjectウィンドウのCreateボタンを押し、C# Scriptを選択し、「BallMove」というScriptファイルを作る。
このBallMoveスクリプトをダブルクリックすると、自動でエディタが開く。(MonoDevelop)
ボールを操作するスクリプト
右のように、BallMove.csにスクリプトを書こう。
// がつく行はコメント文というメモ書きなので、書かなくても良い。
書き終わったら、Control+Sで保存しておこう。
using UnityEngine;�using System.Collections;��public class BallMove : MonoBehaviour {� // ボールが動く速度� public float speed = 10.0f;�� // Use this for initialization� void Start () {�� }� � // Update is called once per frame� void Update () {� // 左右キー・上下キーの入力を取得する。� float speed_x = Input.GetAxis ("Horizontal") * speed;� float speed_y = Input.GetAxis ("Vertical") * speed;�� // 自分(ボール)に力を加え、転がす。� this.GetComponent<Rigidbody> ().AddForce (speed_x, 0, speed_y);� }�}
BallMoveをボールにアタッチ
このままゲームを再生しても、まだボールは操作できない。
作ったBallMove.csスクリプトを、HierarchyウィンドウのSphereにドラッグしてくっつけてみよう。その後、Sphereを選択してInspectorウィンドウを見るとBallMoveコンポーネントがアタッチ(追加)されていることがわかる。
ここでゲームを再生すると、ボールを操作できる!
ドラッグ
ある!
カメラマン、仕事しろ!
ボールが動いたのはいいけど、カメラがボールの背後にあるため非常に見づらい。すこし上から撮ると同時に、カメラがボールについて行くようにしたい。
カメラを子にする
GameObjectメニューからCreate Emptyを選び、空のGameObjectを作成する。名前をCamera Parentとしておく。
Main CameraをCamera Parentにドラッグし、Camera Parentの子にする。
Main Cameraの位置を調整
Main Cameraを選択すると、Sceneウィンドウの右下にカメラの映像が表示される。これを見ながら、Main Cameraの座標と角度を調整する。
これがゲームで再生される映像
親が動くと、子もついていく
試しに、Camera Parentの座標をずらしてみよう。すると、子であるMain Cameraも同じだけずれる。
子は、親の移動についていく!
つまり、Camera Parentの座標 = ボールの座標としておけば、常にカメラの映像の真ん中にボールが映ることになる。
自分座標=相手座標にするスクリプト
自分(CameraParent)の座標を相手(ボール)の座標と同じにするスクリプトを書く。
Projectウィンドウで「CameraMove」というC#スクリプトを作成し、コードを右のように書こう。
using UnityEngine;�using System.Collections;��public class CameraMove : MonoBehaviour {� // 相手のTransform(位置・角度・大きさ)情報を取得� public Transform move_target;�� // Use this for initialization� void Start () {� � }� � // Update is called once per frame� void Update () {� // 自分の位置を相手の位置と同じにする。� transform.position = move_target.position;� }�}
CameraMoveをアタッチ
書いたCameraMoveをCameraParentにアタッチしよう。(ドラッグする)
アタッチしたらCameraParentを選択してInspectorウィンドウを見ると、CameraMoveコンポーネントのmove_target変数がNoneとなっている。
Sphereをドラッグしてmove_target変数まで持って行こう。すると、Noneが上書きされ、SphereのTransformが変数に入る。
これで基本的な動きはできた!
ゲームを再生し、カメラ映像がボールについていったら成功。カメラが少しずれている場合は、子であるMain Cameraの座標を調整する。
次は、当たるとボールが飛ぶジャンプ箱を作ってみよう。
ジャンプ箱を作る
まず、HierarchyウィンドウのCreateボタンから3D Object > Cubeを選択しよう。名前はJumpBoxとして、土台の先あたりに移動させておこう。
色素材(Material)を作る
白いオブジェクトが増えて、見づらくなってきた・・・ということで、ジャンプ台に色をつけてみよう。
ProjectウィンドウのCreateボタンからMaterialを選択。名前はJumpColorにしておく。これで色の素材が作成できた。
JumpColorを選択して、InspectorウィンドウにあるMain MapsのAlbedoで色を変える。Albedoという文字の右にある白い四角をクリックすると色選択画面が開く。好きな色を選ぼう。
ジャンプ台に色をつける
作成したJumpColorを、JumpBoxオブジェクトにドラッグしよう。すると、JumpBoxに色がつく。
ジャンプさせるための準備
JumpBoxを選択し、Box ColliderコンポーネントのIsTriggerにチェックを入れよう。
これで壁としての機能が無くなり、ボールを跳ね返さないが当たったかどうかは検出するようになった。
ボールをジャンプさせるスクリプト
ProjectウィンドウにJumpBoxというスクリプトを作成しよう。スクリプトは右のように書こう。
OnTriggerEnter()は何かとぶつかった瞬間に呼ばれる。ここに、相手を上に飛ばすプログラムを書いている。
using UnityEngine;�using System.Collections;��public class JumpBox : MonoBehaviour {� // ジャンプする速度� public float jump_speed = 10f;�� // 何かが衝突した瞬間に呼ばれる� void OnTriggerEnter(Collider col){� // ぶつかってきた相手(ボール)のRigidbodyコンポーネントを取得しておく。� Rigidbody rig = col.GetComponent<Rigidbody> ();�� // ぶつかってきた相手(ボール)の移動ベクトルのyを変更する。� Vector3 vel = rig.velocity;� vel.y = jump_speed;� rig.velocity = vel;� }�}
ジャンプ台の完成!
作ったスクリプトをJumpBoxオブジェクトにアタッチして、ゲームを再生してみよう。ボールがジャンプしたら成功!
せっかくだから、ジャンプ台を増やしてみよう。コピーして貼り付けを連打・・・でもいいけど、もっと便利な方法がある。
Prefab(プレハブ)について
JumpBoxを増やす前に、Prefabという仕組みを説明するよ。
SceneにあるGameObjectをProjectウィンドウにドラッグすると、Prefab化することができる。
Prefab本体をドラッグすれば、分身を作るかのように簡単にSceneに複製できる。Prefab本体の値を変更すれば、全ての分身の値も変化する。
これをふまえて、これからJumpBoxを複製するよ!
JumpBoxをPrefab化する
HierarchyウィンドウのJumpBoxをProjectウィンドウにドラッグしよう。これで、JumpBoxのPrefabができた。
JumpBoxを大量生産
ProjectウィンドウのJumpBoxのPrefabを、Hierarchyウィンドウへドラッグすると複製されたJumpBoxが作成される。
座標が重なっているので、移動させておこう。
フィールドを大改造!
土台となるCubeを増やしたり、JumpBoxを複製して長めのステージを作ってみよう!
一度きりの人生なんて・・・
ステージから落ちると永遠に落下し続けるので、リトライができるようにしたい。
リトライを実装する準備として、FileメニューからBuild Settingsを選択する。AddCurrentボタンを押す。
上にMain.unityが追加されていたらOK。
①クリック
②出る
落ちたらリトライするスクリプト
BallMove.csスクリプトに、落ちたら自動でリトライする処理を追加する。
何度でも蘇るさ!
~ version 5.0.1での不具合 ~
リトライ時、Sceneが再読み込みされると画面全体の色が変になる(アプリを出力すると直っている)。気になる人は、Windowメニュー > Lighting > Lightmapsタブ > ContinuousBakingをOFF > Buildボタン で直る。
void Update () {� // 左右キー・上下キーの入力を取得する。� float speed_x = Input.GetAxis ("Horizontal") * speed;� float speed_y = Input.GetAxis ("Vertical") * speed;�� // 自分(ボール)に力を加え、転がす。� this.GetComponent<Rigidbody> ().AddForce (speed_x, 0, speed_y);�� // 落下したらSceneを再読み込みする。� if (transform.position.y < -3) {� Application.LoadLevel ("Main");� }� }
ゴールを作ろう!
ゲームであるからには、目標は必要。というわけで、ゴールを作る!まずは、「ゲームクリア!」みたいなゴール画面から作っていく。
とりあえず作成中のSceneを保存(Control+S)し、FileメニューからNew Sceneを選択しよう。
土台とかボールとか全部消えた!・・・と思うかもしれないが、ちゃんとProjectウィンドウのMain.unityに保存されているのでご安心を。
今回は、ゴール画面用の新しいSceneを作っていく。
「GameClear!!」
ゲームクリアの文字を表示するため、HierarchyウィンドウのCreateボタンからUI > Textを選択する。すると、Textの他にCanvasとEventSystemというオブジェクトも生成される。これらは、文字やボタンなどのUIを表示する上での基本的なオブジェクトなので、自動で生成されている。
Textを選択し、右のように値を変更する。
「GameClear」の文字は好きに変えても良い。
ゲームクリア画面、完成
画面に大きめなGameClearが表示されていたら、成功。
Control+Sを押し、「Clear」という名前で保存しておこう。
保存したら、FileメニューからBuildSettingsを選択し、AddCurrentボタンを押そう。Clearシーンがリストに追加される。
ステージにゴール箱を設置する
Mainシーンのボールがゴール箱に触れたら、Clearシーンに移動する流れを作っていこう。
まず、ProjectウィンドウにあるMainをダブルクリックし、エディタをMainシーンに切り替える。
HierarchyウィンドウのCreateからCubeを作成し、GoalBoxという名前にする。JumpBoxと同じように、GoalBoxのBoxColliderコンポーネントのIsTriggerにチェックを入れておこう。
また、ProjectウィンドウのCreateからMaterialを作成し、GoalColorという名前にしてJumpBoxとは違う色にする。その後、GoalColorをGoalBoxにアタッチする。
ゴールのスクリプト
ProjectウィンドウにGoalBoxというスクリプトを作成する。中身は右のように書く。
JumpBoxよりも単純で、ぶつかったらシーンを移動するという処理のみ。
CubeBoxオブジェクトにアタッチし、衝突時にゲームクリア画面に移動したら成功。
using UnityEngine;�using System.Collections;��public class GoalBox : MonoBehaviour {� // 何かが衝突した瞬間に呼ばれる� void OnTriggerEnter(Collider col){� // シーン移動� Application.LoadLevel ("Clear");� }�}
これでボールころがしは完成・・・?
ボールころがしの基本部分ができあがった。
ただ、四角と丸だけでは物足りないし、色が少ない・・・
そんなあなたにAsset Store!
3Dモデル・Material・エフェクト・音など、ゲームに使える素材が有料・無料で並んでいる。
AssetStoreを開く
WindowメニューからAsset Storeを選ぶことで、AssetStoreが起動する。右上の「Language:English」ボタンを押して、英語から日本語に切り替えよう。
切り替えたら、右上の「ログイン」ボタンを押して、ログインしておこう。(Unityに登録したアカウント)
AssetStore画面
3Dモデルを探してみる
フィールドに飾る3Dモデルを探す。そのために、右側の一覧から「3Dモデル」をクリックしよう。すると、3Dモデルがずらりと並ぶ。
今回は試しに無料のAssetを使いたいので、「以下の項目でソート」の「値段」を選択しよう。すると、無料と書かれたAssetが先頭に来る。
好きな物を選び、アイコンをクリックしよう。
3Dモデルをインポート
Assetのアイコンをクリックすると、詳細・購入画面が出る。今回は無料のAssetを選んだので、左上に「ダウンロード」ボタンがある。これをクリックしよう。
ダウンロードが完了するとウィンドウが開くので、右下のImportボタンを押そう。(Unity5に対応していないAssetの場合、自動変換するか聞かれるので、GoAhead!を押して実行する。)
3Dモデルを配置しよう!
インポートが終わったら、Projectウィンドウに見知らぬフォルダができているはずだ。そこに、今インポートしたモデルが入っている。中を見て、3Dモデルを探そう!物によって違うが、おそらく「Prefab」とか「Model」という名前のフォルダに入っている。
青い箱のアイコンがあれば、それがPrefabだ。Hierarchyウィンドウにドラッグして使おう。
追加された
Prefabをドラッグ
3Dモデルの活用いろいろ
ステージの横に並べたり、形を大きくしたり・・・PrefabにCollider(当たり判定)がアタッチされていれば、障害物として置いてもいいかもしれない(選択時に緑色の枠がでるオブジェクトは、Colliderがある)。
岩を巨大化して、背景にしてみた
選択して緑色なら衝突判定あり!
GetComponent<T>()を使ってみよう
GetComponent<クラス名>()を使えば、他のスクリプトを取得して、中の変数や関数を操作することができる。(クラス名=スクリプト名)
これを使って、ボールの高さを表示するスクリプトを書いてみる。
※ スクリプトやRigidbody(物理演算)・Collider(衝突判定)など、GameObjectにアタッチするものをコンポーネントと呼ぶ。それを取得するから「GetComponent()」、そのまんまの名前だ。
数値を表示するためのTextを作成
HierarchyウィンドウのCreateボタンからUI > Textを選択し作成する。画面の左上にTextを配置しておく。
渡された数値を表示するスクリプト
HeightViewというC#スクリプトを作成し、右のように書く。
スクリプトでは、GetComponent<Text>()でTextコンポーネントを取得している。
その後、先ほどのTextにこのスクリプトをアタッチする。
using UnityEngine;�using UnityEngine.UI;�using System.Collections;��public class HeightView : MonoBehaviour {� Text ui_text;�� // Use this for initialization� void Start () {� // 同じGameObject内のTextコンポーネントを取得。� ui_text = this.GetComponent<Text> ();� }�� // 値を渡すとTextの文字を変える� public void SetHeight(float y){� // Textの文字変更� ui_text.text = "Y=" + y;� }�}
プレイヤーの高さを渡す
BallMove.csに右のように追記する。
これは、Textのオブジェクトにある先ほどのHeightViewコンポーネントを取得し、SetHeight関数を実行している。
using UnityEngine;�using System.Collections;��public class BallMove : MonoBehaviour {� // ボールが動く速度� public float speed = 10.0f;� // 高さを表示するオブジェクト� public GameObject height_text;
// 省略 //
� // 自分(ボール)に力を加え、転がす。� this.GetComponent<Rigidbody> ().AddForce (speed_x, 0, speed_y);�� // 高さを表示するスクリプトにy座標を渡す� height_text.GetComponent<HeightView>().SetHeight(transform.position.y);�� // 落下したらSceneを再読み込みする。� if (transform.position.y < -3) {� Application.LoadLevel ("Main");� }�// 省略 //
追記する部分
高さが表示される
SphereのBallMoveコンポーネントにHeight_test変数が追加されているので、横の四角にTextオブジェクトをドラッグする。
ゲームを再生し、ボールのy軸が左上に表示されていたら成功。
おつかれさまでした!
今回の勉強会で教えるのはここまで。
自分なりの改良を加えたり、他の人が作ったボールころがしで遊んだり、遊ばせたりしよう!新たな発想が生まれるかもしれない・・・