Unityで箱が上下左右に動くまで

Unity3D (http://unity3d.com/)はブラウザで動くゲームプラグインの今のところの本命だと勝手に思っていて、今までもたまに言及してきた。ブラウザ向けゲームプラグイン自体あまり数がないので、どれが本命とかあまりないのだけど。

でも私自身はまだ一回も触ったことがなく、それで言及するのもあんまりだろうと思ったので、さわりだけさわってみた。本当にさわりだけ。箱がキー操作で上下左右に動くものを作った。TL上で@hiz_ (http://twitter.com/hiz_)さんなどに教えていただきながら。

できあがるまで結構とまどうことが多かった。Unityの特徴として、

  • インスタンス (GameObject)に形 (Mesh Filter, Mesh Renderer)やソースコード (Script)を貼りつけて作っていく
  • クラス (Prefab)から作るのではなくて、再利用したいGameObjectができたらそれをPrefabにする

ってのがあるらしく、それを把握するまでが大変。JavaScriptみたいなプロトタイプベースのオブジェクト指向に思想は近いのかもしれない。あとGUIの開発環境なので、どれをどこにドラッグアンドドロップするか、みたいのが最初のうちはよく分からんという問題もある。

でもまあ一応箱が動くまではできたので、その手順を以下に書く。GUI操作を無理やりテキストで書いてるのであまり役にはたたんし分かりにくいけどね。あとあまりマニュアル読まずに独自解釈で適当書いてるのでウソがあるかも。

  • 新規プロジェクトを作る

ファイル一式を置く空のディレクトリを指定する必要がある。パッケージは何もインポートしない方がわかりやすい。

  • メニューから[GameObject]->[CreateOther]->[Cube]として箱を作る

画面中央上の"Hierarchy"に"Cube"というGameObjectが作られる。Hierarchyはそのゲーム内の登場人物一覧が置いてあるところ、だと思う。最初から"Main Camera"っていうのが置いてあるけど、これはその名の通り視点を定めているんだろう。

中央下の"Project"っていうところの[Create]->[JavaScript]でできる。名前は"NewBehaviourScript"に自動的になる。リネームしてもいい。右上の"Inspector"にその内容が表示される。

Inspectorの[Edit]を押すと編集用のウィンドウが開く。最初からUpdate関数が用意されているので、その中に以下のように書く。

function Update () {
	transform.position.x += Input.GetAxis("Horizontal") * 0.1;
	transform.position.y += Input.GetAxis("Vertical") * 0.1;
}

Update関数は1フレに1回呼び出される、よくあるUpdate関数だと思われる。transform.positionがGameObjectの位置。Input.GetAxisでキーやジョイスティックからのXY軸入力が取得できる。

ProjectにあるNewBehaviourScriptをHierarchyのCubeにドラッグアンドドロップ

できあがり。こう書くと簡単だな。ただこの状態だとCubeを出現させたり消したりはできない。ゲーム中にはただこの1つのCubeがあり続けることになる。もしCubeの出現とか消滅とかを制御したかったら、このCubeをPrefab、つまりクラスにして、それを別のスクリプトからインスタンス化した方がよい、はず。

  • 空のPrefabを作る

Projectの[Create]->[Prefab]で"new prefab"っていう空のPrefabができる。

  • CubeをPrefabに貼る

HerarchyのCubeをnew prefabにドラッグアンドドロップすると、このnew prefabがCubeのPrefabになる。なにを言ってんだかよく分からんが、要はCubeの再利用可能な雛形みたいなもんだと思う。詳しくはPrefabの説明 (http://unity3d.com/support/documentation/Manual/Prefabs.html)を読む必要がある。まだ読んでない。

  • Cubeの出現を制御する空のGameObjectを作る

メニューから[GameObject]->[Create Empty]でHierarchyに"GameObject"っていう名前の空のGameObjectができる。

Projectの[Create]->[JavaScript]で"NewBehaviourScript 1"作って以下のように書く。

var cube:Transform;

function Start () {
	Instantiate(cube, Vector3(0, 0, 0), Quaternion.identity);
}

Instantiateっていう関数を使うと、第1引数に与えられるObjectを、ゲーム中の任意の場所に任意の方向で出現させることができる。Start関数はそのGameObjectがシーンに登場したときに一度だけ実行される関数、だと思う。

  • NewBehaviourScript 1のcube変数にnew prefabを貼る

この辺からUnityのワケ分からんところ開始。右下のDefault Referenceっていうところに謎の

 Cube                 None (Transform)

っていうのが出ていると思うが、スクリプトのトップレベルに変数を宣言するとそれがここに表示されるらしい。で、ここにPrefabやGameObjectをドラッグアンドドロップすることで、それをバインドできる。なのでProject内のnew prefab(さっきCubeの雛形にしたもの)をここにドラッグアンドドロップ

  • GameObjectにNewBehaviourScript 1を貼る

スクリプトはHierarchy内のGameObjectに貼られてないと発動しないので、前に作った空のGameObjectであるGameObjectに貼る。

  • Cubeを消す

Hierarchy内のCubeは用済みなのでDeleteキーで消す。というか消さないとゲーム内に残り続けるので邪魔。

  • ついでにCubeが消えるところも作る

せっかくなのでCubeをゲームから消す方法も。NewBehaviourScriptを以下のようにする。

function Update () {
	transform.position.x += Input.GetAxis("Horizontal") * 0.1;
	transform.position.y += Input.GetAxis("Vertical") * 0.1;
	if (Input.GetButtonDown("Fire2"))
		Destroy(gameObject);
}

これでAltキーまたはマウスの右ボタンを押すとDestroy(gameObject)で自分自身を消すようになる。Destroy(this)とするとスクリプトだけ死んでCubeの形は残るので注意。

こんなところ。内容にはだいぶ自信がない。ウソやよりよい方法があったら教えて欲しいです。

まださわりしかやってないけど、Unityはなかなかとまどう環境であることは分かった。慣れればコード量は少なくて済みそうな感じはちょっとある。もうちょっとさわってみれば良さが分かるかなあ。