【Part3】チュートリアルの玉転がし_スクリプト編【Unity勉強】
チュートリアル01 玉転がしゲームで使用したスクリプトについてのメモです。
FixedUpdate
玉を動かす際に使用しました。
Updateが1フレームごとに呼び出されるのに対し、
FixedUpdateは一定時間(デフォルトは0.02秒)ごとに呼び出されます。
フレーム/秒(fps)はコンピュータの処理速度に依存するので、必ずしも一定間隔なわけではないので、
1フレームごとに呼び出されるUpdateは不規則なタイミングで呼び出されることになります。
FixedUpdateはフレーム毎ではなく決められた時間間隔で呼び出されるので、規則的なタイミングで呼び出されます。
物理演算を行うRigidbodyの処理はUpdateではなくFixedUpdate内に書くべきなようです。
逆にInputの処理はFixedUpdateではなくUpdate内に書くべきだそうです。
理由についてはこの方の記事が分かりやすかったです。
Input.GetAxis()
玉を動かすための力をかける方向を制御する際に使用しました。
GetAxis()の引数に"Vertical"や"Horizontal"など(axisNameというらしい)を渡してやることで、
その軸のにおける値を返してくれるようです。
今回のチュートリアルのスクリプトだとこのInputクラスのメソッドをFixedUpdate内に書いていたけど、いいのでしょうか。。。
Component.GetComponen
スクリプト上から、そのスクリプトをアタッチしているゲームオブジェクトのコンポーネントを取得する際に使用しました。
例えば、スクリプトをアタッチしたゲームオブジェクトからRigidbodyコンポーネントを取得したい場合は以下のように
Rigidbody rb = GetComponent<Rigidbody>();
とすることで、Rigidbodyクラスのインスタスの参照を取得することができます。
参照を取得したインスタスから、そのクラスが持つメソッドを呼び出すことができます。
Rigidbody.AddForce
玉を動かすための力を与える際に使用しました。
上記のGetComponetで取得したRigidbodyクラスのインスタスから呼び出し、引数にGetAxisで取得した軸方向の値と、
その値にかける力の大きさを渡してやりました。
例)
rb.AddForce(x軸への力, y軸への力, z軸への力) 他にも、Vector3を引数として利用する方法があったり、力のかけ方の詳細を設定するForceModeを渡すこともできるようです。
OnCollisionEnterとOnTriggerEnter
どちらも衝突判定時に処理を行いたいときに使用しました。
OnCollisionEnterは玉が壁と接触したときに、
OnTriggerEnterは玉がアイテムと接触したときに使用しました。
で、ColisionとToriggerでどう違うのか。
自分も調べて余計に混乱しているのですが、とりあえず、程度の認識で言うと、
「衝突させるオブジェクトのColliderのIs Triggerにチェックが入っているか否か」。
Insperctorビューの〇〇ColliderにはIs Triggerという項目があり、こいつにチェックを入れるとRigidbodyを持ったオブジェクトが接触しても衝突判定を行わなくなります。
接触するけど衝突しないってなんだと思いましたが、ようするにぶつかってもすり抜けるよ、ということのようです。
ただし、OnTriggerEnterのうような、「OnTrigger〇〇」の呼び出しは行われるのでこれらの中に処理を書いてやればオブジェクトが接触対象に触れたときなどにイベントを発生させることができます。
Is Triggerにチェックを入れない場合はRigidbodyを持ったオブジェクトが接触した場合に衝突判定が発生します。
すり抜けずに止まるなり跳ね返るなりするよーってことですかね。
このときに呼ばれるのがOnCollisionEnterのような、「OnCollision〇〇」になります。
Is Triggerにチェックが入っていなくても、ぶつかる側・ぶつかられる側どちらもRigidbodyを持っていない場合は衝突判定は発生しないので注意です。
- 接触するけどすり抜けて、かつなんらかのイベントを発生させたい(アイテムに触れたら回復!とか)ときは、Is Triggerにチェックを入れてOnTrigger系
- 接触したらすり抜けず、かつなんらかのイベントを発生させたい(ぶつかって跳ね返りつつダメージ発生!とか)ときは、Is Triggerにチェックを入れずOnCollision系
・・・で、あってるでしょうか?
詳しい検証を行っている以下の記事を参考に、かなり噛み砕いて解釈しています。
SceneManagement
玉が壁にぶつかったら最初からやり直しという機能をつける際に使用しました。
実際に使ったのはSceneManager.GetActiveScene().buildIndexとSceneManager.LoadScene()です。
SceneManagerは名前の通りシーンを管理するためのクラスです。
SceneとSceneManagerという構造体を持ちます。
・・・やばい、知識が足りてないので後日SceneManagement単体でしっかり調べたいと思ます。
ひとまず今回使用したGetActiveScene()とLoadScene()について。
GetActiveScene()は現在アクティブなシーンを取得します。
チュートリアル内では、アクティブなシーンを取得した後さらにSecne構造体の持つ変数のbuildIndexからそのシーンのインデックスを取得しています。
LoadScene()はシーンの名前あるいはインデックスを引数として受け取り、対応したシーンをロードします。
今回は上記のGetActiveScene().buildIndexで取得したインデックスを渡してロードすることにより、ゲームのリスタート機能を実装しています。
衝突判定とSceneManagementについては後日深掘りが必要ですね・・・。