夜更かし工房

稼げるクリエーターになりたい方へ有益な情報をお届け!

【補足解説付き】Unity公式チュートリアル日本語翻訳【Roll-a-ball tutorial - 2. Moving the Player】

このチュートリアルではプレイヤーとなるゲームオブジェクトを動かしてみます。最初に私たちがこのプレイヤーゲームオブジェクトにどのような挙動を望むのかについて考えてみましょう。

私たちはこの Sphere がゲームエリアを転がり回り、ゲームエリアの端まで行ったときには、落ちないように壁にぶつかって地面の上で停止し、また宙に飛んでいったりもしないことを望んでいます。そして、収集可能なゲームオブジェクトにぶつかったときにはそれを拾うことも必要です。これには Physics (物理法則)が必要です。

Physics を使うためには、ゲームオブジェクトに Rigidbody コンポーネントを追加する必要があります。新しいコンポーネントを追加するためにはまず最初にコンポーネントを追加したい対象であるゲームオブジェクトを選択する必要があります。今回の場合では Hierarchy ウィンドウから Player ゲームオブジェクトを選択します。

f:id:nightowlgames0314:20180909194632p:plain

ゲームオブジェクトにコンポーネントを追加する方法は2通りあります。

1つめは、上部メニューバーから Component > Physics > Rigidbody を選択する方法です。

f:id:nightowlgames0314:20180909194805p:plain

2つめは、Inspector ウィンドウの最下部にある「Add Component」ボタンをクリックして Physics > Rigidbody を選択する方法です。どちらの方法でも選択した Rigidbody コンポーネントが選択した Player ゲームオブジェクトに追加されます。

f:id:nightowlgames0314:20180909195241p:plain

もし Inspector ウィンドウに表示されるコンポーネントの並び順を組み替えたい場合は、各コンポーネントの右上にある歯車マークをクリックして、「Move Up」「Move Down」のいずれかをクリックしてください。

f:id:nightowlgames0314:20180909200004p:plain

コンポーネントの並び順を組み替えることは、私たちのゲームのパフォーマンスには影響しません。しかしながら、ゲームオブジェクト上のコンポーネントに一貫した順序を持たせることは、Project ウィンドウと Hierarchy ウィンドウが整理された状態を維持する、あるいはより良い状態にし続けることで、私たちの開発速度を向上させるために役立ちます。

コンポーネントの名前の位置のバーをクリックすることでコンポーネントビューを折りたたんだり展開したりすることができます。

f:id:nightowlgames0314:20180909202059p:plain

コンポーネントビューの折りたたみと展開を行うたびに、 Scene ビューでそのコンポーネントに関連する Gizmos(位置や向きを示すアイコン)も切り替わることに注意してください。下図のように、Sphere Colider を折り畳むと、Scene ビュー上で Sphere Colider に関連する Gizmos が消失していることが確認できますね。

f:id:nightowlgames0314:20180909202515p:plain

f:id:nightowlgames0314:20180909202528p:plain

今、私たちは Player ゲームオブジェクトが私たちの操作によって動くことを望んでいます。これを行うには、プレイヤーからキーボードを介して入力を得る必要があり、その入力を Player ゲームオブジェクトに適用して、シーン内の球を移動させる必要があります。

これは、Player ゲームオブジェクトに追加するスクリプトを使用して実現します。

まず最初に Projcet ビューに、私たちのスクリプトを保存しておくためのフォルダを作成します。Project ビューの左上部にある Create ボタンをクリックして Folder を選択し作成したのちフォルダ名を Scripts に書き換えます。

f:id:nightowlgames0314:20180909203627p:plain

次は C# で記述された新しいスクリプトを作成します。

新しいスクリプトを作成する方法は下図の通り2通りあります。

f:id:nightowlgames0314:20180909204101p:plain

f:id:nightowlgames0314:20180909204223p:plain

しかし今回の場合、もっと効率的な方法があります。

まず Hierarchy ビューから Player ゲームオブジェクトを選択し、Inspector ビューから Add Component ボタンをクリックして表示されるメニューから New Script を選択します。これはスクリプトの作成と、ゲームオブジェクトへの追加の両方を1回の操作のみで実行してくれます。

f:id:nightowlgames0314:20180909204702p:plain

まずスクリプト名を入力し「Create and Add」ボタンをクリックするか Enter キーもしくは Return キーを押下します。今回はスクリプトを PlayerController と名付けます。チュートリアル動画では C#JavaScript かをここで選択しているのですが、Unity 2017.1b10 で JavaScript が廃止されたため現在の最新バージョンの Unity では言語の選択肢はありません。

f:id:nightowlgames0314:20180909205016p:plain

Unity は PlayerController スクリプトを作成し、コンパイル(人間が書いたコードを機会が理解できる言葉に変換すること)し、選択されていた Player ゲームオブジェクトに追加しました。ただしこの方法で作成したスクリプトは Project ビューの Assets フォルダの直下に配置されることに注意する必要があります。そのため Projcet ビューを整理するために PlayerController スクリプトをドラッグで Scripts フォルダの直下に移動する必要があります。

f:id:nightowlgames0314:20180909210535p:plain

Project ビューでスクリプトを選択している時 Inspector ビューにはスクリプトのプレビューが表示されています。しかしこのテキストをここで編集することはできません。

f:id:nightowlgames0314:20180909210924p:plain

スクリプトを開いてみましょう。これにはいくつかの方法があります。

スクリプトを使ってゲームオブジェクトを検査するときには、Inspector ビューに表示されるコンポーネント(自分で作成した PlayerController スクリプトコンポーネントの一種です)ビューの右上にある歯車マークをクリックして Edit Script を選択します。

f:id:nightowlgames0314:20180909211659p:plain

他の方法としては Project ビューでスクリプトを選択した状態で、ダブルクリックもしくは Inspector ビューに表示されている Open ボタンをクリックする方法です。

f:id:nightowlgames0314:20180909212246p:plain

これにより好きなエディタでスクリプトを開くことが可能です。

f:id:nightowlgames0314:20180909212329p:plain

まず提供されているサンプルコードを削除しましょう。

f:id:nightowlgames0314:20180909215213p:plain

そして考えます。私たちはこのスクリプトに何をさせたいのか。私たちはプレイヤーからの入力を毎フレーム確認して、入力が検知されとき Player ゲームオブジェクトの移動として毎フレーム適用させたい。

私たちはどこで入力を検知して、適用させれば良いのか。2つの選択肢があります。 Update 関数と FixedUpdate 関数です。

Update 関数は毎フレームが描画される前に呼び出されます。そしてゲームのコードのほとんどはこの Update 関数内で実行されることになります。

FixedUpdate 関数は、物理計算を実行する直前に呼び出されます。そしてゲームの物理学に関するコードはこの FixedUpdate 関数内で実行されることになります。

私たちは力を Rigidbody に適用することでボールを動かします。これは物理学です。だから私たちはコードを FixedUpdate 関数内に記述します。

f:id:nightowlgames0314:20180909225906p:plain

私たちが書くべきコードは何でしょうか。私たちはプレイヤーからの入力が必要ですが、それはどうすれば実現するのでしょうか。

MonoDevelop には Unity の API を探すためのショートカットがあります…のようにチュートリアル動画では MonoDevelop エディタから Unity の API を参照するためのショートカットキーについての解説がされているのですが、 現在 Unity で使用されるエディタは MonoDevelop ではなく Visual Studio に移行しているためここの解説は割愛します。ここで表示されるはずだった API については下記リンクにて確認することができます。API とは、ある機能を共有するための仕組みのことです。よく使う機能が API として用意されていればわざわざ一からプログラムを組む必要が無くなります。

Unity スクリプトリファレンス

今回使用する API は下記リンクで紹介されている Input クラスになります。

Input - Unity スクリプトリファレンス

f:id:nightowlgames0314:20180909231331p:plain

Description を読むことで、Input クラスの使い方が理解できます。

Input クラスを使用することで、Input Manager で設定された軸を読み込み、モバイルデバイスのマルチタッチおよび加速度に関するデータにアクセスすることが可能です。今回はモバイルデバイスを含む全てのプラットフォームで、プレイヤーからの入力を取得します。

Description の下の方までスクロールしてみましょう。Input クラスが保持する変数と関数のリストがあります。

f:id:nightowlgames0314:20180909231859p:plain

f:id:nightowlgames0314:20180909231918p:plain

Input クラスの変数は情報を保持します。例えば touchCount 変数は、そのフレーム内で同時にタップしている指の本数を保持しています。gyro 変数は、デバイスの傾きの角度を保持しています。

f:id:nightowlgames0314:20180909232206p:plain

f:id:nightowlgames0314:20180909232632p:plain

 Input クラスの関数は何をするのでしょうか。私たちのコードの中で Input.GetAxis 関数を記述したらどうなるのでしょう。GetAxis をクリックしてみましょう。

f:id:nightowlgames0314:20180909232915p:plain

Input.GetAxis について見てみましょう。

f:id:nightowlgames0314:20180909233009p:plain

このページに含まれているものは、関数の記述方法、関数の説明、使用方法を見せるためのコードの断片です。Input Manager と Input.GetAxis の詳細については、下記リンク先のレッスンを参照してください。

GetAxis - Unity

今回私たちは、上図で紹介されているコードの断片と非常によく似た記述で Input.GetAxis を使用します。私たちのコードに戻ってコードを記述しましょう。

f:id:nightowlgames0314:20180909234224p:plain

これは、キーボードからの入力をプレーヤーから取得します。

float 型で宣言された変数である moveHorizontal と moveVertical はキーボード上のキーで制御される水平軸と垂直軸からの入力を記録します。

私たちの Player ゲームオブジェクトは Rigidbody コンポーネントを使用し、物理エンジンとやりとりします。プレイヤーからの入力を使用して、Rigidbody に力を加え Player ゲームオブジェクトをシーン内で移動させます。Rigidbody に力を加える方法の詳細については、ドキュメントをチェックしてみましょう。 

Unity - Scripting API: Rigidbody

Player ゲームオブジェクトに力を加えたい場合、何かする必要があります。それでは Rigidbody クラスで使用可能な関数を見てみましょう。

私たちが望むものを見つけるまで説明を読み、今回はAddForceを選択しましょう。

f:id:nightowlgames0314:20180909235620p:plain

これにより Rigidbody コンポーネントに力が加えられ、移動を開始します。リンクをクリックして AddForce 関数の詳細ページを確認します。

Unity - Scripting API: Rigidbody.AddForce

このページでは関数の記述方法を確認でき、使用時には Vector3 型の変数と、Rigidbody に力を加えるための ForceMode の指定が引数として必要であることがわかります。

f:id:nightowlgames0314:20180910000146p:plain

Vector3 とは何でしょうか。Vector3 についてより詳細を学習したい場合は下記リンク先を参照してください。

ベクトル演算 - Unity

f:id:nightowlgames0314:20180910000804p:plain

しかし簡単に言えば、Vector3 は1つの変数内に3つの小数値を保持しています。これにより、X、Y、Z軸のそれぞれに力の値を必要とする3D空間の力のようなものに値を使用したり移動したりすることが容易になります。または、X、Y、Z軸のそれぞれに値を必要とする回転を記述することもできます。全てのドキュメントページはリンクされています。Vector3 をクリックすると、Vector3 のドキュメントページが表示されます。ForceMode、MonoBehaviour、RigidBodyについても同様です。

f:id:nightowlgames0314:20180910001534p:plain

Description の下にあるコードの断片は実際の関数の使用ケースを紹介しています。

AddForce 関数の最初の記述方法の下にある2番目の記述方法に注意してください。Description の内容は一緒です。しかしこの場合は、Vector3 または3つの浮動小数点値を使用して AddForce 関数を使用することができます。

 

f:id:nightowlgames0314:20180910001904p:plain

次に学習するのは、ゲームオブジェクトが様々なコンポーネントを保持したり、参照したりするための方法です。
私たちは PlayerController というスクリプトを書いています。これは私たちのゲームオブジェクトにスクリプトコンポーネントとして追加されています。このスクリプトから AddForce 関数のために Rigidbody コンポーネントを使う必要があります。私たちは PlayerController コンポーネントから Rigidbody コンポーネントにアクセスする必要があります。これを行うにはいくつかの方法があります。しかし今回は、同じゲームオブジェクト上の別のコンポーネントにアクセスすることができる主な方法のうちの1つだけを紹介します。

f:id:nightowlgames0314:20180910003131p:plain

スクリプトで Rigidbody コンポーネントへの参照を保持する変数を作成し、この参照を Start 関数で設定します。リファレンスに記述されているコードの断片を見てみましょう。rb と名付けられた Rigidbody 型の変数が public で宣言されています。これは私たちがアクセスしたい Rigidbody コンポーネントへの参照を保持するための変数です。

f:id:nightowlgames0314:20180910004155p:plain

Start 関数内で GetComponent<Rigidbody> という記述によって rb と名付けられた変数に参照がセットされています。この記述は、このスプリクトが追加されているゲームオブジェクトに追加されている Rigidbody が1つだけなら、その参照を見つけて返します。Start 関数内のすべてのコードは、スクリプトがアクティブである最初のフレームで呼び出されます。これは多くの場合、ゲームの最初のフレームです。

最後に FixedUpdate 関数内で、ゲームオブジェクトに取り付けられた Rigidbody コンポーネントに、rb という名称の変数を介してアクセスして rb.AddForce 関数を使用します。

f:id:nightowlgames0314:20180910005313p:plain

したがって、私たちのスクリプトでは、参照を保持する変数を作成するために専用の Rigidbody rbを記述する必要があります。Start 関数には、rb = GetComponent <Rigidbody>と書く必要があります。FixedUpdate 関数では、Rigidbody.AddForce の最も単純な書き方を使用しましょう。単に Vector3 を使用するもので、私たちのコードから ForceMode を省略して ForceMode をデフォルトのままにします。

つまり私たちのコードには rb.AddForce(Vector3)だけを書けば良いです。

f:id:nightowlgames0314:20180910010408p:plain

2つの浮動小数点値を Vector3 の値にするにはどうしたらいいでしょうか。Movement という新しい Vector3 変数を作成しましょう。これは、X、Y、およびZで構成される新しいベクトル3に等しくなります。X、Y、Zの値は、ボールに追加する力の方向を決定します。

f:id:nightowlgames0314:20180910010835p:plain

X の値は水平を意味する moveHorizontal を代入します。これにより、左右のキーがボールを左または右に動かす力を加えます。

Y の値は高さを意味します。私たちはボールを上下には動かしたくはないので 0 を入力します。

Z の値には moveVertical を代入します。

f:id:nightowlgames0314:20180910011421p:plain

今度は、rv.AddForce(動き)としてVector3の値であるMovementを使用します。

スクリプトをセーブして Unity に戻ります。Unity のフッタやコンソールにエラーの表示がないかどうかチェックします。 

Play ゲームオブジェクトに Rigidbody コンポーネントを追加しておきます。

私たちが書いたスクリプトを試してみましょう。

ゲームを再生すると、Input Manager のキー設定を使用して、ボールがシーン内を移動します。しかしとても遅いです。これは遊ぶには遅すぎますが、基本的なコンセプトの学習としては100%です。

テストをやめるために Play モードを離れてください。

私たちのコードに戻り、ボールの速度をコントロールするツールを作ってみましょう。私たちは、私たちの動きに何らかの値を掛ける必要があります。

その値をスクリプトに入力するだけでも済みますが、変更や修正が必要な場合はいちいちスクリプトエディタに戻り、スクリプトの値を変更してから再コンパイルする必要があります。これには時間がかかります。

解決策は、スクリプトに public 変数を作成することです。speed と名付けられた public 変数を作成します。スクリプトに public 変数を作成することで、この変数は Inspector ビューに編集可能なプロパティとして表示されます。public 変数を使用すると、エディタですべての変更を行うことができます。

Movement に speed を掛けます。

f:id:nightowlgames0314:20180910013558p:plain

エディタの中から動きの値を制御できるようになりました。これらの変更を保存してUnityに戻りましょう。Unity エディタに戻ると、Player Controller スクリプトに speed プロパティが追加されているのがわかります。

f:id:nightowlgames0314:20180910013741p:plain

Speed の値を100にしてゲームを再生してみましょう。今度は動きが早すぎましたね。しかし、修正を加えるのも速いです。 再生モードを終了し、値を10に変更して再生してみましょう。良くなりましたね。

おめでとう。私たちは自分のキャラクターを動かせるようになりました。次の課題ではカメラの移動方法について学習しましょう。