お疲れ様です。 せいさくしゃです。
前回は、プレイヤーの移動を実装しました。
そして、スクリプトにあらかじめ書かれているコードについての説明をしました。
今回は、前回の続きから実際にプレイヤーを動かすコードを書いていきたいと思います。
今回の目次
前回のおさらい
スクリプトを作った時の説明
前回実装した内容はこちらです。

- プレイヤー用のスクリプトの作成
- プレイヤーの移動操作の実装
以上が前回の実装内容です。
そして、前回説明した内容はこちらです。
- スクリプトファイルの作り方
- 作成したスクリプトにあらかじめ書かれているコードの説明
- Start関数とUpdate関数についての説明
今回は、プレイヤーの移動操作の実装から解説していきたいと思います。
今回の解説
キーボード入力のやり方
入力の仕方ってどうやるんだ?
プレイヤーを移動させるという事は、キーボードやマウス等、何かしらの入力を必要とするのが普通です。
今回は、取り敢えずプレイヤーを動かしてみる、という事を目標としていました。
なので、今回はキーボードを使ってプレイヤーを移動させる方法を採用しました。
プレイヤーの移動操作を実際に組んだコードがこちらです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
private const float MOVE_VEL = 0.05f; //移動速度 // ... 他の処理 ... private void Control() { // 移動操作 Vector3 vel = new Vector3(0.0f, 0.0f, 0.0f); if(Input.GetKey(KeyCode.UpArrow)) { vel.z += MOVE_VEL; } if (Input.GetKey(KeyCode.DownArrow)) { vel.z -= MOVE_VEL; } if (Input.GetKey(KeyCode.LeftArrow)) { vel.x -= MOVE_VEL; } if (Input.GetKey(KeyCode.RightArrow)) { vel.x += MOVE_VEL; } // 移動 transform.position += vel; } |
このうち、「移動操作」とコメントされている部分がプレイヤーの移動の操作を行う部分です。
その中でもキー入力を受け付けているコードはこちらです。
1 |
if(Input.GetKey(KeyCode.UpArrow)) |
このようなコードが4つありますが、これはそれぞれ前後左右のキー入力を受け付けている所です。
この部分について、もう少し詳しく見てみましょう。
まず、「Input.GetKey(KeyCode.***)」の部分で、特定のキーが押されているかを確認します。
この時、「KeyCode.」以降の「***」の部分に確認したいキーを入力します。
キーの種類は、「Z」、「Return」(Enter)、「UpArrow」(上矢印)等があります。
他にも様々なキーコードがあるので、気になる方は公式サイトで調べてみるといいと思います。
因みに、このキーコードの中には、マウスのボタン(?)等も含まれます。
なので、マウスがクリックされたかぐらいは、調べることが可能です。
(ただし、クリックされたマウスの座標等はこのままでは取得できません)
そして、押されていた場合の処理をif文で記述します。
今回は、それぞれ対応した方向への移動量を加算しました。
「Input.GetKey (KeyCode.***)」の関数を使って判定すればいいんだな。
そして、「***」の部分には、判定したいキーのコードを入れればいいんだな。
しかし、場合によってはキーが押された瞬間や、キーを離した瞬間等のタイミングで判定したい事もあると思います。
その時は、「GetKey」関数の部分を次の関数に置き換えてみてください。
キーが押された瞬間を判定するときは「GetKeyDown」関数を使います。
キーを離した瞬間を判定するときは「GetKeyUp」関数を使います。
プレイヤーの動かし方
…で、何をすればいいんだ?
先程、キー入力を受け付ける処理を書きました。
しかし、当然ながらキー入力をしただけではプレイヤーは動きません。
そこで、次は実際にプレイヤーの位置を変える(動かす)処理を書いていきたいと思います。
ここで、一旦今回のコードを確認しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
private const float MOVE_VEL = 0.05f; //移動速度 // ... 他の処理 ... private void Control() { // 移動操作 Vector3 vel = new Vector3(0.0f, 0.0f, 0.0f); if(Input.GetKey(KeyCode.UpArrow)) { vel.z += MOVE_VEL; } if (Input.GetKey(KeyCode.DownArrow)) { vel.z -= MOVE_VEL; } if (Input.GetKey(KeyCode.LeftArrow)) { vel.x -= MOVE_VEL; } if (Input.GetKey(KeyCode.RightArrow)) { vel.x += MOVE_VEL; } // 移動 transform.position += vel; } |
この内、ポイントとなるのは次のコードです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// 移動操作 //(1) Vector3 vel = new Vector3(0.0f, 0.0f, 0.0f); if(Input.GetKey(KeyCode.UpArrow)) { //(2) vel.z += MOVE_VEL; } if (Input.GetKey(KeyCode.DownArrow)) { //(2) vel.z -= MOVE_VEL; } if (Input.GetKey(KeyCode.LeftArrow)) { //(2) vel.x -= MOVE_VEL; } if (Input.GetKey(KeyCode.RightArrow)) { //(2) vel.x += MOVE_VEL; } // 移動 //(3) transform.position += vel; |
- 移動量を表す変数の初期化。
- 移動する大きさと方向を移動量変数へ加算。
- プレイヤーの位置の変更。
主にこの3か所で移動を行っています。
その中でも、プレイヤーの位置の変更は、少し見慣れない言葉があると思います。
ここをもう少し詳しく解説していきます。
まず、前提となる知識を先に説明します。
プレイヤーのようなゲームに登場するオブジェクトは、総称して「GameObject」(ゲームオブジェクト)と呼ばれています。
ゲームオブジェクトは、様々な要素を持っていて、それぞれの要素の事を総称して「Component」(コンポーネント)と呼ばれています。
これを踏まえた上で、プレイヤーの位置の変更を見ていきましょう。
まず、プレイヤーが持っている「transform」コンポーネントを見に行きます。
次に、transformコンポーネント内の「position」(位置)要素を見に行きます。
そして、positionに前の段階で決めた移動量を加算して、位置の変更を行います。
この様に、位置の変更は自身の持っているコンポーネント内の要素を変更して行います。
ここで分かる方もいると思いますが、回転や拡縮も同じようにして変更する事が出来ます。
そして、transform.positionに加算すればいいんだな。
しかし、実は位置の情報にはもう一つ「localPosition」という要素があります。
この2つの違いは、以前軽く紹介した「親子関係」によるものです。
この親子関係の解説は、実際に親子関係を意識する必要が出てきた時に解説していきたいと思います。
なので、申し訳ないですが今回も親子関係の解説は見送らせてもらいます。
単純に位置を変更したい場合なら、今回のpositionを使えば意図したとおりに動くと思います。
逆に、localPositionを使用すると、場合によっては意図していない挙動をする可能性もあります。
なので、慣れないうちはこのpositionを使っていくといいと思います。
これって、普通に数値を使って足すのはだめなのか?
しかし、変数を使うと数値を直接入れるよりもメリットが大きいです。
1つ目は、ぱっと見ただけで数値の意味が理解できる事です。
今は単純な計算なのでまだわかりやすいです。
しかし、さらに複雑になると「この数値は何を表しているか」という事がたまに分からなくなります。
そこで、変数に適切な名前を付けることで、数値の意味が変数名を見ただけで分かるようになります。
2つ目は、数値の修正が簡単な事です。
今回の様に移動量を決めるときに、最初は取り敢えず入れてみて少しずつ調節する、という事もあると思います。
その時今回の場合は、移動量を変更する際に4か所の変更が必要になります。
これを数値で直接記述していた場合は、そのまま4か所の数値を変更することになります。
これでは、変更する際にうっかりミスをしてバグが発生する可能性もありますし、単純に面倒です。
そこで、変数で記述することによって、その変数を修正するだけで全ての箇所の数値が変更されます。
これなら、変更する際のミスをかなり抑えることが出来ますし、修正も簡単です。
この様に、変数を使う事でより便利に数値を扱うことが出来ます。
なので、皆さんも是非積極的に変数を活用していきましょう。
因みに、変数の値を初期値で固定化させたものを「定数」と言います。
また、変数や定数を使わずに、直接記述してしまう数値の事を「マジックナンバー」と言います。
移動関数を呼び出す場所
ここまでで、プレイヤーを操作するコードが一通り記述できました。
後は、このスクリプトをプレイヤーオブジェクトに設定するだけです。
…と言いたい所ですが、ちょっと待ってください。
取り敢えず、今回のコードをもう一度確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
private const float MOVE_VEL = 0.05f; //移動速度 // ... 他の処理 ... private void Control() { // 移動操作 Vector3 vel = new Vector3(0.0f, 0.0f, 0.0f); if(Input.GetKey(KeyCode.UpArrow)) { vel.z += MOVE_VEL; } if (Input.GetKey(KeyCode.DownArrow)) { vel.z -= MOVE_VEL; } if (Input.GetKey(KeyCode.LeftArrow)) { vel.x -= MOVE_VEL; } if (Input.GetKey(KeyCode.RightArrow)) { vel.x += MOVE_VEL; } // 移動 transform.position += vel; } |
もしかしたら、この時点で分かる方もいるかもしれません。
よく見ると、この移動操作のコードは「Control」関数の中で記述されています。
平然と書いてありますが、実はこのControl関数は元々Unityで用意されている関数ではありません。
このControl関数は、私が独自に作った関数なのです。
つまり、このControl関数を呼び出す所がなく、このままでは操作処理を通ることがありません。
そこで、このControl関数をどこかで呼び出す必要があります。
そうなると、具体的にどこで呼び出すかが問題になってきます。
このControl関数は、操作を常にチェックしてほしいので、基本的には常に呼び出されて欲しい関数です。
ゲームの世界でこれを言い換えると、「毎フレーム呼び出されて欲しい関数」という事になります。
つまり、このControl関数は前回解説した「Update」関数の中で呼び出せば良い訳です。
実装は単純ですが、Update内で呼び出すときのコードはこちらです。
1 2 3 |
void Update () { Control(); } |
これで、毎フレームキー入力をチェックして、プレイヤーの操作を行うことが出来ます。
こうすれば、いつでもプレイヤーを動かすことが出来るんだな。
だったら、なんでUpdate関数の中に直接書かないんだ?
しかし、Update関数には毎フレーム呼ばれる処理が他にも必要になる可能性もあります。
その時、全てのコードを直接Update関数の中に書いてしまうと、ぱっと見ただけではどこにどの処理があるかを探す事が大変になります。
そこで、それぞれの処理を別々の関数に分けて書くことで、必要な処理が探しやすくなります。
また、適切な関数名を設定すれば、Update関数の中をぱっと見ただけで何をやっているかが分かるようになります。
この様に、処理内容は殆ど変わらないけど、コードが読みやすくなる工夫をすることは大切です。
もしかしたら、自分のコードを誰かが修正したり、開発の間隔が空いて久しぶりにコードを修正する事が出てくるかもしれません。
その時にコードが読みやすいと、コードの解析が早くなります。
その結果、開発の時間を短縮する事が出来るようになります。
皆さんも、読みやすさを意識してコードを書いてみてください。
オブジェクトへのスクリプトの設定方法
…で、どうやるんだ?
スクリプトの準備が出来たら、プレイヤーオブジェクトに作ったスクリプトを設定します。
因みに、オブジェクトにスクリプトを設定してからスクリプトを書いても構いません。
最終的には変わらないので、好きな順番でやりましょう。
オブジェクトへスクリプトを設定する方法は以下の通りです。

- Projectウィンドウから目的のスクリプトのある場所へ移動します。
- Hierarchyウィンドウから設定したいオブジェクトを選択します。
- ProjectウィンドウのスクリプトをInspectorウィンドウ内へドラッグ&ドロップします。
これで、オブジェクトへスクリプトを設定する事が出来ます。
スクリプトの設定は、以前紹介したマテリアルの設定方法と殆ど同じです。
基本的に、オブジェクトへスクリプトを設定して初めてスクリプトは機能します。
なので、忘れずにスクリプトを設定しておきましょう。
今回のまとめ
今回は、主にプレイヤーを動かすためのスクリプトの解説をしました。
今回主に組んだコードは、以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
private const float MOVE_VEL = 0.05f; //移動速度 // ... 他の処理 ... void Update () { Control(); } private void Control() { // 移動操作 Vector3 vel = new Vector3(0.0f, 0.0f, 0.0f); if(Input.GetKey(KeyCode.UpArrow)) { vel.z += MOVE_VEL; } if (Input.GetKey(KeyCode.DownArrow)) { vel.z -= MOVE_VEL; } if (Input.GetKey(KeyCode.LeftArrow)) { vel.x -= MOVE_VEL; } if (Input.GetKey(KeyCode.RightArrow)) { vel.x += MOVE_VEL; } // 移動 transform.position += vel; } |
そして、今回の解説を端的にまとめると、以下の通りです。
- 「Input.GetKey(KeyCode.***)」を使ってキー入力を判定する。
- キー入力判定で決定した移動量を「transform.position」に加算する。
- 作った移動操作関数はUpdate関数の中で呼び出す。
- 作ったスクリプトをオブジェクトに忘れずに設定する。
これで、プレイヤーを簡単に動かすことが出来るようになります。
キー入力は、移動以外にも様々な操作に使うことが出来ます。
なので、決定やキャンセルといった操作も実装可能です。
また、オブジェクトの移動は操作が無くても使うことが出来ます。
なので、敵キャラクターを自動で動かすという事も可能です。
キー入力や移動が使えると、それだけでゲームらしくなります。
なので、まずはキー入力や移動をマスターして、ちょっとゲームらしく動かしてみてはいかがでしょうか。
それでは、今回はここまでにしたいと思います。
お疲れ様でした。