Uni本講座ではUnityで3Dレースゲームの作り方について説明していきます。
今回は第三回となります。
前回の記事 :
前回はプレイヤーを前後に動かしましたが、今回は車を横に動かしてカーブする、速度制限を付けてブレーキをかける、カメラの移動処理などよりゲームらしくなる実装を行っていきます。
では始めていきましょう!
カーレースの車をカーブ(横移動しながら曲がる)処理を作る
まずは横移動(曲がれるように)を作成していきます。
横は横方向の力を与えるのではなく、左右の回転の力(トルク)を与えていきます。では「PlayerController.cs」に追加していきますので、まずは追加済みのコードを見てみましょう。
(・・・は変更のないところを省略しています)
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 34 |
public class PlayerController : MonoBehaviour { ・・・ // 横回転力. [SerializeField] float rotPower = 30000f; ・・・ void FixedUpdate() { MoveUpdate(); RotationUpdate(); } ・・・ // ------------------------------------------------------------ /// <summary> /// 回転処理. /// </summary> // ------------------------------------------------------------ void RotationUpdate() { if( Input.GetKey( KeyCode.A ) == true ) { rigid.AddTorque( - transform.up * rotPower, ForceMode.Force ); } if( Input.GetKey( KeyCode.D ) == true ) { rigid.AddTorque( transform.up * rotPower, ForceMode.Force ); } } } |
まずは「rotPower」という回転力を「SerializeField」で用意します。
そして「FixedUpdate」内で新しく作成する「RotationUpdate()」を実行します。
「RotationUpdate()」は回転力を加える関数です。
1 2 3 4 5 6 7 8 9 10 11 12 |
void RotationUpdate() { if( Input.GetKey( KeyCode.A ) == true ) { rigid.AddTorque( - transform.up * rotPower, ForceMode.Force ); } if( Input.GetKey( KeyCode.D ) == true ) { rigid.AddTorque( transform.up * rotPower, ForceMode.Force ); } } |
回転力を加えるのは「rigid.AddTorque()」で、「AddForce」と同じように加える力と加え方を指定します。
PCキーボードの「A」「D」ボタンを押すことを条件(if文)に、それぞれ左右へ回転力を加えています。
「transform.up」というのは、現在状態での上方向の単位ベクトルです。
Transform Scaleパラメータで車体の大きさ調整
ここで、一旦大きさの調整をします。
各自いい感じに変更しても大丈夫ですが、一部今回使用しているアセットのコースに微妙な段差がある部分があるため、小さくしすぎるとその影響が大きくなる可能性があるので注意しましょう。
ではまず大きさですが、これは単純にHierarchyから「Player」を選択しInspectorの「Transform」の「Scale」を
1 2 |
Player Transform Scale( 0.8, 0.8, 0.8 ) |
にしましょう。コースの幅を考えて少しだけ小さくしました。
車のアクセルに速度制限を付ける
次に速度ですが、今のままだと横転しやすかったりするので「PlayerController.cs」に速度制限を追加していきます。まずは追加したコードを見てみましょう。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
public class PlayerController : MonoBehaviour { ・・・ // 速度制限. [SerializeField] float speedSqrLimit = 200f; // 回転速度制限. [SerializeField] float rotationSqrLimit = 0.5f; ・・・ // ------------------------------------------------------------ /// <summary> /// 移動処理. /// </summary> // ------------------------------------------------------------ void MoveUpdate() { float sqrVel = rigid.velocity.sqrMagnitude; // 前速度制限. if( sqrVel > speedSqrLimit ) return; if( Input.GetKey( KeyCode.Space ) == true ) { rigid.AddForce( transform.forward * movePower, ForceMode.Force ); } // 後速度制限. if( sqrVel > ( speedSqrLimit * 0.2f ) ) return; if( Input.GetKey( KeyCode.S ) == true ) { rigid.AddForce( - transform.forward * movePower, ForceMode.Force ); } } // ------------------------------------------------------------ /// <summary> /// 回転処理. /// </summary> // ------------------------------------------------------------ void RotationUpdate() { float sqrAng = rigid.angularVelocity.sqrMagnitude; // 回転速度制限. if( sqrAng > rotationSqrLimit ) return; if( Input.GetKey( KeyCode.A ) == true ) { rigid.AddTorque( - transform.up * rotPower, ForceMode.Force ); } if( Input.GetKey( KeyCode.D ) == true ) { rigid.AddTorque( transform.up * rotPower, ForceMode.Force ); } } } |
追加箇所は、2つの制限値の変数と移動処理、回転処理の中です。
まず「SerializeField」属性をつけて速度制限値「speedSqrLimit」、回転速度制限値「rotationSqrLimit」を用意し初期値を入れておきます。「SerializeField」を付けることによってUnityのInspectorから値を変更できます。
次に「MoveUpdate()」内を解説します。
1 2 3 4 5 6 |
void MoveUpdate() { float sqrVel = rigid.velocity.sqrMagnitude; if( sqrVel > speedSqrLimit ) return; ・・・ } |
最初の追加部分はこの部分です。
まず「sqrVel」という変数を準備し、「rigid.velocity.sqrMagnitude」を入れています。
ここで「rigid.velocity」というのは、「rigid」というRigidbodyの現在の速度を表すVector3(3次元ベクトル)の値です。
そして、「sqrMagnitude」はベクトルの2乗の長さを表し、今回は速度の大きさの2乗となります。
これが設定したリミットより大きい場合「if( sqrAng > rotationSqrLimit ) 」には「return」、つまりここで処理を終了し、下の処理を行わないようにします。
1 |
if( sqrVel > ( speedSqrLimit * 0.2f ) ) return; |
も同じで「sqrVel」が「speedSqrLimit * 0.2f」以上の場合はここで処理を終了し、それ以降の後ろ移動の処理を行わないようにします。
これで後ろ方向は前よりも小さい速度でしか移動できなくなります。
1 2 3 4 5 6 |
void RotationUpdate() { float sqrAng = rigid.angularVelocity.sqrMagnitude; if( sqrAng > rotationSqrLimit ) return; ・・・ } |
回転速度は「rigid.angularVelocity」で取得でき、それを設定した制限値と比較し、オーバーしたら「return」します。
左右を分ける必要はないのでこの一つでOKです。
カメラの移動処理を作る UnityのLerpメソッドの使い方
現在カメラが暫定的に設定した、車の後ろに固定している状態なので、動きに少し違和感があります。
なのでこれを臨場感のある動きに変更していきます。
まず「Player」の子にある「MainCamera」を外に出して何の子でもない状態にします。そして「Player」のScaleを変更した影響で「MainCamera」のScaleも変わっているので、Inspectorの「Transform」からScaleを( 1, 1, 1 )に変更しておきましょう。
カーレースゲームのテストプレイを行う
では再生して試してみましょう。
横移動、速度制限、カメラ移動を作成したことにより、だいぶレースっぽくなりましたね。
今回の記事は以上になります。
次回はスタート、ラップ数、ゴールなどの処理を作成していきます。
次回の記事 :
コメント