Unity を手に入れる
Unity は商用のゲームエンジンですが、基本的な機能を備えた無料版が提供されています。無料版には小規模ゲーム開発に必要なほとんど全ての機能が網羅されており、開発したゲームの Windows 版 / Mac 版 / Web Player 版を無制限に出力できます。
まずは Unity のダウンロードページから無料版を取得し、お手持ちの Windows / Mac にインストールしましょう。
本チュートリアルはこの無料版を用いて進めていきます。
必要動作環境
- Windows XP SP2 またはそれ以降の Windows(サーバー版を除く)
- Mac OS X - インテル CPU、Leopard 10.5 以降>
- 64MB 以上の VRAM、4つ以上のテクスチャーユニットを搭載するビデオカード
(詳細は 動作環境 をご覧ください)
Unity の統合開発環境
Unity をはじめて起動すると、下記のような画面が現れます。
これが Unity の統合開発環境で、スクリプト制作以外のほとんど全ての作業をここで行なうことができます。
-
シーン/ゲームビュー
シーンビューには製作中のゲーム世界(シーン)が表示され、自由な位置・角度から眺めることができます。ゲームのプリビューを開始すると、ゲーム内カメラによる描写に切り替わります。
-
インスペクターパネル
シーンの中で選択肢中のオブジェクトが持つ属性を表示・編集するためのパネルです。属性には座標やメッシュといった見た目上のものから、衝突判定や物理制御に冠するパラメーターなどもあり、その他ユーザー定義のものもここに表示されます。
-
ヒエラルキーパネル
シーン内に存在するオブジェクトの一覧が表示されます。編集中のシーン内でオブジェクトをコピー/ペーストしたり、適切な名前をつけて整理することもできます。
-
プロジェクトパネル
製作中のプロジェクト(ゲーム全体)に含まれるシーン、スクリプト、グラフィックやサウンドなどのデータ、その他のリソースがファイル単位で表示されます。ここに出来合いのスクリプトセット、アートアセット、シェーダーなどを「パッケージ」単位でインポートすることもできます。
始めてのプロジェクト作成
それでは、「ブロック崩し」のゲームプロジェクトを開始しまししょう。メニューバーのから、を選択すると、新しいプロジェクトを作成することができます。(この手の操作は今後 と表記します)
プロジェクトの名前を決めると、次にどのコンポーネントをインポートするかを決めるダイアログが表示されます。今回は空っぽの状態からスタートしますので、何も選択せずに次へ進みましょう。
Main Camera オブジェクトだけが配置された、空っぽのシーンが出てきましたか? これは仮のシーンになっていますので、でシーンに名前をつけましょう。ここでは「TheGame」という名前で保存します。プロジェクトパネルに同名のシーンファイルが現れたら OK です。
これでゲームの入れ物ができあがりました。
シーンパネルの基本操作
オブジェクトの配置・選択・編集を行なう上で、最も多くの操作を行なうのがシーンパネルです。シーンを把握するためにカメラの操作をマスターすると、その後の作業が楽に進められます。
シーンパネル上でマウス右ボタンを押しながらドラッグすると、カメラの角度を自由に動かせます。また、ホイールでカメラの前進・後退、ホイールをクリックしながらドラッグで上下左右にパンできます。マウスを右クリックしながらキーボードのWSADを押すことでも操作できます(FPS 風の操作)。
シーンパネルの右上にある「x y z」と書かれた 3D アイコンを操作することでもカメラを回転させることができます。どれかの軸をクリックすると、その軸に沿った平行投影の絵を得ることもできます。パースペクティブビューに戻すには、3D アイコン中央の立方体をクリックします。
ウィンドウ上部にあるメディアプレーヤーライクなアイコンの再生ボタンを押すと、編集中のシーンが実行され、ゲームビューが表示されます。
とはいえ、まだ何も配置されていません。さっそく中身を作って行きましょう。
必要なパーツを配置しよう
今回制作する「ブロック崩し」の世界を構成する基本要素は、操作可能なラケット、直線運動をするボール、破壊対象となるブロック、そしてそれらの移動可能範囲を決める四方の壁となるでしょう。
これらのものは、Unity に最初から組み込まれている基本の 3D メッシュを配置して構成することができます。後々、より凝った 3D モデルに置き換えるとしても、まずは単純な立方体や球体のゲームオブジェクトを配置し、全体の枠組みを作ってみましょう。
世界の枠組みを作る
はじめに、四方に「壁」を配置してゲーム世界の範囲を決めます。と選んで、
シーンに立方体を追加しましょう。
追加された立方体は 1辺の長さが 1.0 で、適当な位置に配置されるので、調整が必要です。立方体を選択して、インスペクターパネルに目を向けます。
インスペクターパネルには、選択した立方体の位置・姿勢情報(Transform)が表示されています。Position が位置、Rotation が回転、Scale が大きさです。各項目の数値を入力することで狙った位置、大きさに変更することができます。
まず、Position の各項目を 0 として、立方体の位置を原点とします。次に、Scale の X に大きな数値(ここでは仮に 20 とします)を入力して、立方体を X 方向に引き伸ばします。これを壁の 1辺としましょう。
続いてヒエラルキーパネルに注目しましょう。今しがた編集した立方体が「Cube」という名前でリストアップされています。これを右クリックしてを選択しましょう。複製が作られます。
今度は、作成した複製の Transform を編集し、Scale X を 1 に、Scale Z を 30 程度にします。こうして Z方向に伸びる棒状にし、Position の X を -10、Z を 15 程度にして左側の壁にします。
これで底面と左側面の壁ができました。今度はそれぞれをインスペクターパネル上でまた複製・移動して、上面の壁と右側面の壁を配置しましょう。これで世界の枠組みは完成です。簡単ですね。
カメラと照明を配置する
XZ平面上に世界の枠組みを配置しました。次に、これをゲームカメラが適切に捉えられるようにしましょう。
ヒエラルキーパネルで Main Camera を選択すると、シーンビュー上に小さなプレビューが出てきます。これが実際のゲーム画面に捉えられるイメージです。これが良い感じになるように、シーンビュー上でカメラを移動させます。
シーンビュー上のオブジェクト操作モードは、ウィンドウ上部のツール選択ボタンで選びます。デフォルトでは移動操作モードとなっていますので、カメラを回転させるときは回転操作モードボタンを押してから、シーンビュー上で操作しましょう。
カメラは良い感じに配置できましたか? プレビューを見ると、とても暗いことがわかりますね。これは、シーンに照明が配置されていないためです。とりあえず明るくするために、
を選択して、光源を導入しましょう。
これでシーンが明るく照らされるようになりました。もう一度 Main Camera を選択すると、プレビューが明るくなったことを確認できます。
操作の対象を配置する・ラケットとボールを配置
プレーヤーの操作対象となるラケットも、形としては立方体で表現できます。先ほど作成した四方の壁と同じ要領で、適当な位置に細長い立方体を配置しましょう。壁の高さと合わせるため、Transform の Position Y座標を 0 にすることを忘れないよう注意します。
今度は
として球体を配置します。エディター上で置く場所はとりあえずの初期位置となりますので、ラケットのすぐ上が良いでしょう。大きさは初期状態の直径 1 でかまいません。
ボールを大きくするとゲームの難易度が簡単に、小さくすると難しくなりそうです。お好みで調整しても面白いかもしれません。
以上で、破壊対象のブロック以外のゲーム要素の配置が(とりあえず)完了しました。いよいよ、中身の制作に移ります。
はじめてのスクリプト
配置したオブジェクトを動作可能にするには、いくつかの方法があります。
スクリプトで動きを完全に制御することもひとつの方法ですが、Unity に組み込まれた物理エンジンにあやかって、等速直線運動や放物線運動等の自然動作はエンジンに任せるのも良いアプローチです。
今回の場合、ブロック崩しのボールは直線運動をすれば良いため、物理エンジンに挙動を任せるのがよさそうです。
ラケットに関しては、ユーザーの操作に反応する部分はスクリプトで制御しますが、壁面やボールとの衝突判定等を正面から実装すると大変なので、そこは物理エンジンに任せることにしましょう。
ボールに物理特性を与える
先ほど配置した球体のゲームオブジェクトは、単に静止しているだけの存在です。物理オブジェクトとして運動できるようにするには、このゲームオブジェクトに Rigidbody(剛体)のコンポーネントを追加する必要があります。
球体を選択した状態で、と選択していきましょう。Rigidbody コンポーネントが追加され、この球体は物理オブジェクトになりました。
これをそのまま実行すると、ボールは虚空に向かって落ちていきます。重力が働いているためです。それでは困るので、インスペクターパネル上の Rigidbody 項目の(重力を使用する)からチェックを外します。
また、ボールは XZ平面上だけを移動すれば良いので、Constraints(制限)項目を開き、(位置を固定)の Y要素にチェックを入れます。また、回転する必要もないので(回転を固定)の全要素をチェックします。
さらに、ボールの運動は等速直線運動を想定しているため、運動抵抗を与えないようにします。これは、項目を 0 にすることで実現できます。
これで、ボールの動きに適切な制限を加えることができました。
ボールに初速を与える
ボールが正しく動作することを確認するため、スピードを与えましょう。ここでスクリプト(とても簡単なもの)を導入します。
プロジェクトパネル上でコンテキストメニューを開き、と選択。新しいスクリプトがプロジェクトに追加されますので、名前を「BallContoller」とでもしましょう。これをダブルクリックすると中身を編集できます。
生成されたスクリプトには、はじめから Start() と Update() という関数が記述されています。これらは Unity のスクリプトにおける基本的な関数で、Start() はオブジェクトが動作開始するタイミングで 1回呼ばれ、Update() はフレームの更新時に毎回呼ばれる仕組みになっています。
ここでは初速を与えるため、動作開始時に 1回だけ呼ばれる Start() 関数を使いましょう。以下のように記述します。
var Speed = 20.0;
function Start () {
rigidbody.AddForce(
( transform.forward + transform.right ) * Speed,
ForceMode.VelocityChange );
}
最初の行では、ボールの速度を示すユーザー変数を宣言しています。関数スコープの外で宣言することで、インスペクター上に露出させることができ、微調整が便利になります。
Start() 関数の中では、ボールに追加した Rigidbory コンポーネントのメソッドを呼び出し、初速を与えています。
AddForce メソッドに与えている第 1 引数は 3次元ベクトルです。transform.forward はボールの正面(Z方向)、transform.right はボールの右方向(X方向)を示す単位ベクトルで、これらを足して Speed を掛け合わせることで右斜めのベクトルを得ています。第 2引数は力の加え方を指定するフラグで、ここでは質量を無視して指定の速度をいきなり与えることを指示しています。
さて、シーンビューでボールを選択して、プロジェクトパネルから「Ball Contrller」スクリプトをインスペクターパネルにドラッグアンドドロップしましょう。これで、このスクリプトがボールに関連付けられます。
これを実行するとボールが勢い良く動き出しますが、壁面にぶつかって止まってしまいます。何がいけないのでしょうか?
ボールのバウンド
Unity の物理エンジンにおいて、デフォルトではオブジェクトがバウンドしないようになっています。これは、物理オブジェクトに適切な Physic Material(物理マテリアル)を与えることで変更できます。
プロジェクトパネル上でコンテキストメニューを開き、と選択しましょう。
新しい物理マテリアルができますので、名前を「Perfect Bounce」とでもしましょう。
これを選択すると、インスペクター上に物理マテリアルの要素が出てきます。重要となるのはという要素です。これを 1 とすることで、オブジェクトに完全弾性を与えることができます。また、Friction Combine と Bounse Combine をそれぞれ Minimum と Maximum に設定しておきます。
続いてシーンビュー上でボールを選択します。インスペクターパネルの Sphere Collider コンポーネント内、項目に、作成した物理マテリアルをプロジェクトパネルからドラッグアンドドロップしましょう。
これでボールが跳ねまわるようになりました。
ラケットを操作可能にしよう
ゲーム開発において、ユーザー入力をどう扱うかの問題は度々頭を悩ませることですが、Unity では非常にスマートなソリューションが用意されています。
Unity ではキーボードやジョイスティック、マウスの入力などを抽象化した入力モデルを用意しており、水平垂直の方向入力、ジャンプや攻撃といったボタン入力を直感的に扱うことができます。を選ぶと、インスペクター上で入力コマンドと軸・ボタンの設定を見たり、編集することができます。
実例を見るのが早そうです。プロジェクトに新たなスクリプトを追加して、「RacketController」と名づけましょう。そして、Update() 関数の内容を次のようにします。
var Accel = 1000.0;
function Update () {
rigidbody.AddForce(
transform.right * Input.GetAxisRaw( "Horizontal" ) * Accel,
ForceMode.Impulse
);
}
ボールに使ったスクリプトに似ていますが、フレームごとに毎回呼ばれる Update() 関数に記述することで、常時駆動型の関数となっています。
関数内では Rigidbody コンポーネントのメソッドを使って、ラケットに加速度を与えています。注目点は、Input.GetAxisRaw( "Horizontal" ) という部分。この関数により、水平方向(Horizontal)のユーザー入力を -1 ~ 1 の正規化された範囲で取得しているのです。
ユーザー入力はキーボードによるものでも、ジョイスティックによるものでもかまいません。その細部は Unity の Input Manager によって管理されています。
ここでは第 2引数に ForceMode.Impulse を指定しています。こうすると与えた力は質量を考慮して動作に反映されますので、ラケットの動きに一定の慣性が働く感じが得られるようになります。
ラケットの操作性は加える力の大きさと、ラケットの質量・抵抗によって変わってきますので、プレビューしながら良い感じに調整していきましょう。
まとめと次回のテーマ
ここまでのチュートリアルで、ラケットを操作してボールを跳ね返すことができるようになりました。
Unity におけるゲームオブジェクトやコンポーネント、物理エンジンの扱いやユーザー入力の処理方法など、基本的な部分を理解することができましたが、まだゲームというには程遠い状態です。ボールの挙動も、ラケットとの当たり具合によって変になることがありますね。どうしたらよいでしょうか?
次回は、破壊可能なブロックを追加したり、ゲームルールを構成して、きちんと遊べる形に仕上げていきましょう。