以前書いたエントリーで取り上げたシューティングゲームの製作過程を適当にチュートリアル風味に書いて行きます。こういうの書いてみたかった。
ちなみに僕のプログラミング歴は仕事ではずっと PHP, 趣味では C++(Selene), C#(XNA), Python, JavaScript あたりを適当にいじってました。Unity では C#, Boo, JavaScript が使えますが最初勉強に使ったUnity入門という本では言語が JavaScript だったので今回もそれでいきます。
というわけで作っていきます。Unityちょっと動かした事あるぐらいの人を想定してます。
新しいプロジェクトを作成
Unity を起動して、File -> New Project... を選択し、Create New Project タブを選択、Project Location に適当な名前を入れて Create を押しましょう。testshooting とでもしましょう。
カメラ以外何もない画面が開きます。
各画面の解説とかシーンの操作方法とかは省略します。操作方法とか各画面の解説は Unity のドキュメントが良いです。
自機を作成する
シューティングゲームの自機を作成しましょう。
ただの四角形を動かす
GameObject -> Create Other -> Plane を選択して薄っぺらい四角形を出します。2Dのゲームなんでこの薄いやつでOKです。
Hierarchy に Plane というのができるので名前を Player とかわかりやすいのに変更しておきます。
作成したらこれを選択した状態で Component -> Physics -> Character Controller を選びます。Replace existing component と言われるかもしれませんが気にせず Replace を押します。
Character Controller はキャラクターを制御する為のコンポーネントです。自分で操作するキャラクターをうまい具合にUnityが処理してくれます。
次にこれを動かす処理を JavaScript で書きます。
Project 画面で Create -> JavaScript を選択し、jsファイルを作成します。名前は適当にしときましょう。PlayerControllerとか。
それをダブルクリックして MonoDevelop を起動して以下のように書き込みます。
#pragma strict
// 移動速度
var movingSpeed : float = 5.0;
private var controller : CharacterController;
private var velocity : Vector3;
function Start () {
controller = GetComponent(CharacterController);
}
function Update () {
// 2Dのゲームなので y軸は常に0に設定しとく。
transform.position.y=0;
// 方向キーからの入力を取得
velocity = Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
// 移動速度を入力に掛ける
velocity *= movingSpeed;
// 移動
// Time.deltaTime は前フレームとの時間を返してくる。
// デフォルトでは 60FPS, 1Frame ≒ 0.017sec だが多少誤差が出るので
// その差を吸収する為に deltaTime を使ってやる。
controller.Move(velocity * Time.deltaTime);
}
説明は上記コード内に書いた。書いたら保存してUnityの画面に戻ります。その後 Project 画面からこのスクリプトを Hierarchy 画面の Player にドラッグアンドドロップします。
これで十字キーで移動できるようになりました。上記再生ボタンを押して十字キーで動かしてみましょう。WASD でも動かせます。
自機に画像をつける
このままだととても味気ないので四角形に戦闘機の画像を貼り付けます。画像を作るのは大変なのでフリーで使用できるものを使います。ありがとうございます。
上記リンクから戦闘機素材をダウンロードし、適当なペイントソフトでUnityで使用する画像を作成します。以下のようにアニメーションする画像を一つにまとめます。まとめたらProject画面にドラッグして入れます。
これを先ほど作った四角形に適用します。
オブジェクトの見た目を変えるにはマテリアルを使用します。Project 画面で Create -> Material を選択し、マテリアルを作成します。その後マテリアルを選択した状態で先ほどの画像を Inspector 内の None(Texture) と書いてあるところに放り込みます。
そのままでは画像全部が表示されてしまうので、Tiling の x を 0.5 にして見える範囲を調節します。
さらに、Shader のタイプをデフォルトの Diffuse から Particles -> Alpha Blended を選択します。こうすると png 画像につけたアルファチャンネルがうまく動いてくれます。
作成したらこのマテリアルを Project 画面にある四角形にドラッグして適用します。
自機にアニメーションをつける
このままでは寂しい、というかせっかく画像2つくっつけた意味が無いのでそれを使ってアニメーションさせます。
上記で作成した Player スクリプトを編集し、以下を追記します。
// アニメーションで使う変数たち
var animationInterval : float = 0.1; // 画像を切替えるタイミング
var animationTimer : float = 0.0; // 時間計測用
var animationFlag : boolean = true; // どっちの画像を表示するかのフラグ
function Start () {
(省略)
}
function Update () {
(省略)
// マテリアルに設定したテクスチャーの Offset を変更する事で
// 画像をずらして表示する事ができます。
// それを高速でずらす事でアニメーションを実現します。
// ずらすのが 0.51 と半端なのは画像作成時にちょっとずれたので...。
animationTimer -= Time.deltaTime;
if (animationTimer < 0.0) {
animationTimer = animationInterval;
renderer.material.mainTextureOffset.x = animationFlag ? 0.51 : 0;
animationFlag = !animationFlag;
}
}
Time.deltaTime はここでも登場。よく使うのでしっかり覚えたほうが良いです。自分がUnityの勉強したときの本のサポートサイトに良いページがあったので紹介します。
書籍『Unity入門』 - Unity におけるフレームと Update
スクリプト書き終わったら後再生ボタンを押したら画像が高速で切り替わって表示されると思います。
続く...。
コメント
PlayerControllerに上記コードを入力したらエラーで「Assets/PlayerController.js(15,41): BCE0044: expecting ), found ‘(‘.」
と出てきます。
どうしてですか?
それだけでは原因を特定できませんが、エラーメッセージからすると文法エラーですね。入力した内容を確認してみてください。
velocity = Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
↓
velocity = Vector3(Input.GetAxis(“Horizontal”), 0, Input.GetAxis(“Vertical”));
文字化けしてますね。
指摘ありがとうございます。修正しました。
文字参照がそのまま出ていたようですね。。。
書かれているまま何度も試してみたのですが、
プレイヤーをPlaneで作ったら動作しませんでした。
Cubeで作成すると動作するのですが理由がわからないです。。。
ちなみにPlaneで作成すると”Replace existing component”という質問はでません。
Planeだと動かせないのでしょうか?
こちらUnity4.3で作成しております。
私は自機を Plane で作成したのでできるはずです。何か操作を間違えたか、私の記述にミスがあるのかもしれません。
ただ、2Dのゲームだから2Dっぽく Plane を利用しただけで Cube でも問題ないとは思います。
YAMAGENさんとおそらく同じ現象にハマりましたので、私を含めた初心者の方のために書き込ませて頂きます。
当方の環境(unity 4.3.1)においてPlaneでPlayerを作成した場合、
PlayerのComponentでMesh Colliderのチェックが標準で入り、下記のリマインドは発生しませんでした。
>Replace existing component と言われるかもしれませんが気にせず Replace を押します.
そのため、scriptを追加して再生ボタンを押してもplayerが動かない、という事態になります。
解決策としては、「PlayerのComponentでMesh Colliderのチェックを外し、無効にする」です。
初心者な私はなかなか気付きませんでした。。
カメラの位置設定がされていませんが、2ページ目ではいつの間にかカメラの位置が上方に変わっていませんか?
2ページ目で表示してある画面は Unity Editor 上のものでカメラの設定とは関係ありません。
ゲーム内で利用しているカメラについてはその5で解説しています。
http://loumo.jp/wp/archive/20130218223124/