Unityに関連する記事です

 以下の内容で順番に実装を進めていきます。

 手順4〜8ではプレイヤーの分身となるキャラの作成、キャラの行動とアニメーションの制御について実装を行います。

 この手順ではキャラの移動範囲についての問題点の検証と改善案を考え、制御を実装します。

手順8 −キャラの移動範囲の制御−
11.キャラが画面外へ移動しないように制御する



新しく学習する内容


・Mathf.Clampメソッド


11.キャラが画面外へ移動しないように制御する

問題点の検証と改善案を考える


 今回のゲームは、キャラを自由に空中移動させて、空中を浮遊させる移動をすることが1つの大きな要素になっています。
空中浮遊については、ジャンプを連続で行うことで実装が出来ています。ですが、現在は、画面外まで移動が出来てしまうのが難点です。
きちんとしたルールのもとで遊ばなければゲームになりません。

 ゲーム画面の左右方向について、あるいは上下方向について、ゲーム画面の中にだけキャラの移動を抑える制御が必要になるでしょう。


<検証動画 左右方向の制限なし>
https://gyazo.com/6bfdd0c5a44ca22944107a070b1c048d


<検証動画 上下方向の制限なし>
https://gyazo.com/32cf49093af2b575f7709112e76e0d9c



問題点と改善案


 キャラが画面外に移動してしまうのが今回の問題点です。キャラの位置をどうやって画面の内側に収まるようにするかを考えていけばよさそうです。

 大きく、2つ方法が考えられます。コライダーを利用して制御する方法と、スクリプトを利用してキャラの位置を参照して制御をする方法です。

 コライダーを利用して制御する方法は、画面の上下左右の画面外の4つの部分に見えない壁用のゲームオブジェクトを設置して、そのゲームオブジェクトにコライダーを持たせておきます。
この方法であれば、キャラの持つコライダーと、この見えない壁の持つコライダー同士の物理的な接触を感知して、キャラをゲーム画面内にとどまらせることが出来ます。

 今回はもう1つのスクリプトを利用してキャラの位置を参照して制御をする方法を実装していきます。
キャラの移動とはすなわち、座標情報の更新のことになります。A地点からB地点へと座標が更新されることにより、移動が行われます。
 
 まずは最初に、Sceneビューにいるキャラを画面内で動かしてみましょう。動かしながら Gameビューでもキャラの位置を確認してください。
Transform コンポーネントの Position X と Y の値がどの値になると、実際のゲーム画面からはみ出てしまうのかをここで確認しておきます。


<検証動画 キャラを画面内に動かして、どの位置まで画面に映る座標なのかを検証する>
https://gyazo.com/64e25c03d9c95f01fca28c44b4260d2a


 Sceneビューの画面中央が x, y = (0, 0) の原点位置となります。ここからXがマイナスになれば左側に、Xがプラスになれば右側に座標が動きます。
つまり座標は、0, 0 の地点を中心軸とした場合、左右は対称的な位置になっています。
例えば、キャラの左端の位置が X = -9.5f だとした場合、右端の位置は X = 9.5f になります。
ということは、いずれかの片側の制限する位置がわかれば、その情報を反転させることによって、反対側の位置情報の制限する位置としても利用できることになります。


<検証動画 座標の対称性>
https://gyazo.com/3c7dc502aa68b617f3b5dd6de035ca4c
 

 以上の検証により、キャラの移動の制限とは、座標の位置を制限・制御することと同義であると言えます。

 この方法を利用して、左右方向と上下方向の移動範囲の制御処理をスクリプトから行うように処理を追加します。


PlayerController スクリプトを修正して、キャラの移動できる範囲を制限する処理を追加する


 宣言フィールドに、移動の制限範囲を設定するための float 型の limitX 変数と limitY 変数を用意します。
値にはそれぞれ、先ほどのキャラの移動範囲として画面に映る制限範囲の情報を代入しておきます。

 なお、スクリプトを読みやすくするために、同じ修飾子同士は並べて宣言するようにしておきます。
今回の変数は private 修飾子の変数ですので、宣言する際にも他の private 修飾子と並べて書くようにすると、グループ分けが出来ます。

 キャラの移動(位置座標の変更)が行われるたび、Mathf.Clampメソッドを実行し、用意しておいた制限座標の値の範囲内に収まっているかを確認します。
収まっている場合には何も処理は行いませんが、もしも座標が範囲外になってしまっている場合には、制限範囲に収めるように座標の制御を行います。


PlayerController.cs

 <= クリックすると開きます。



<Mathf.Clampメソッド 指定値を最小値、最大値内に制限する>


 Mathf.Clamp関数の機能ですが「制御したい指定値を、指定した範囲内の最小値、最大値に収めてくれる」処理になります。

使用例としましては、

制御したい指定値 = Mathf.Clamp(制御したい指定値, 最小値, 最大値);


 今回の場合であれば

  float posX = Mathf.Clamp(transform.position.x, -limitPosX, limitPosX);

 という形で利用していますので、transform.position.x の値を、
最小値が -limitPosX 以下になった場合には -limitPosXの値に、
最大値が limitPosX 以上になった場合には limitPosXの値に制限をしてくれます。

 今回の場合、最小値が左方向の制限値、最大値が右方向の制限値になります。


数値をいれて書くならば
float posX = Mathf.Clamp(transform.position.x, -4.45f, 4.45f);

となります。yの方も処理は同様です。


 この処理の結果を、現在の位置情報として更新するようにしていますので、制限を超えていた場合には、
上記の最小値(左方向の制限)と最大値(右方向の制限)の間に収まるように移動範囲が制限されます。

 なおMathf.Clampメソッドにはオーバーロードがあり、引数の型は、float型とint型でそれぞれ利用が出来るようになっています。
Unity公式スクリプトリファレンス
Mathf - Clamp
https://docs.unity3d.com/jp/540/ScriptReference/Ma...


ゲームを実行して動作を確認する


 スクリプトを修正したらセーブし、ゲームを実行してみます。
キャラを移動させてみてください。いずれの方向に移動しても画面内に収まるように移動の制御が出来ていれば成功です。


<実行動画 
https://gyazo.com/7e8bbdb751c9a8a446dfbc8f74ef2e2f


<実行動画◆
https://gyazo.com/a6b15d25d9359c4eb202dee8375ff3fa


問題点の検証と改善案を考える


 最後にもう1つだけ、問題点を確認して、改善しておきます。

 キャラの移動は制限できるようになりましたが、画面の一番上の位置でジャンプボタンを連続で押してみてください。
キャラが落下せずに上空でしばらく待機するような現象が発生していると思います。


<検証動画>
https://gyazo.com/79ae4fa0f31fa779e0990d510bd3b408


 空中を浮遊するルールから考えると、この現象も不具合の1つです。ずっと上空にいるだけでクリアできてしまうからです。

 ジャンプボタンを押すのを止めたら、上空にとどまらずに落下を開始するように改善する必要があります。


問題点と改善案


 通常にジャンプボタンを押して離す動作自体には問題はないはずです。押せばジャンプし、連続で押せば空中浮遊し、離せば落下を始めます。
ではなぜ、画面の上部にいったときだけ、このような現象が発生してしまうのかを考えてみます。

 ゲーム製作で重要なことは、トライ&エラーです。何故エラーや不具合が発生しているのかを発見し、その改善策を考えるためには
何回もデバッグを行っていって、原因を究明する所から始まります。

 ゲームを実行して検証を行っていきます。実行したら、ヒエラルキーで Yuko_Player ゲームオブジェクトを選択し、
インスペクターの Rigidbody2D コンポーネントの中にある Velocity の情報が見れる状態にしてください。

 その状態で画面の一番上までジャンプボタンを押して移動し、そのままその位置でジャンプボタンを連打してみましょう。
VelocityのYの値をよく見ていてください。


<検証動画 Velocityの値を確認する>
https://gyazo.com/bf6fcc9a71a1c519a5af9f4d5b016da1


 通常、Velocity.yの値の値は最大でも 4 前後までしか上昇しません。
そのため、空中にいる間は問題ありませんでしたが、上空でジャンプボタンを連打した場合、Velocity,y の値がずっと上昇し続けています。


Velocity.yの値(10以上になっている)



 画面上のキャラの移動自体は制限されるようになりましたが、Velocity.yの値、上方向への速度ベクトルの値が制限されていないため、
ジャンプボタンを押した分だけ上方向への移動を行おうと処理が動いているためです。
 
 キャラが落下を開始するのは、この Velocity.yの値がマイナスの値の時です(下方向への速度ベクトルが動いている)。

 Velocity.yの値はジャンプボタンを押すのを止めると、Velocity.yの値への加算処理がなくなり、自然とマイナスの値になります。
そのため、ジャンプボタンを押すのを止めることによって、自然落下しているように見えています。地面に接地している間は 0 になります。


<検証動画 ジャンプボタンを1回押して、どのように Velocityの値が動くかを確認する>
https://gyazo.com/ade0163adf03e4d11c4a9720dbf24351


 つまり、ジャンプボタンを連打した分だけ、Velocity.yの値がプラスの方向にどんどんと加算されてしまうため
Velocity.yの値がプラスからマイナスになるまでの時間が長くなり、そのため、画面の一番上でとどまっている現象が発生しています。
 

 ではどのような方法で改善すればよいでしょうか。

 ジャンプを行った際ですが、ジャンプボタンを1回押した際の Velocity.yの値の動きを見てみると、最大でも 4 前後までしか数値は上昇しないようです。
ですが、先ほどは Velocity.yの値が 10 以上の大きな値になっていました。ということは、この Velocity.yの値に上限値を設定すれば、この現象は改善できそうです。

 実際にスクリプトを修正して、処理を追加していきます。


PlayerController スクリプトを修正して、キャラの移動できる範囲を制限する処理を追加する


 Updateメソッド内に、Velocity.yの値を制限する処理を追加します。
Velocity.yの値を 4 前後とのことでしたので、Velocity.yの値の最大値を 5 として制御するようにします。
もしも Velocity.yの値が 5 以上になった場合には強制的に 5 に戻すようにします。


PlayerController.cs

 <= クリックすると開きます。



ゲームを実行して動作を確認する


 スクリプトを修正しましたので、セーブをして、ゲームを実行してみます。

 ゲーム画面の一番上でジャンプボタンを連打しても、Velocity.yの値が先ほどまでのように異常に高い値まで上昇しなくなり、
ジャンプボタンを押すのと止めると落下が始めるようになっていれば成功です。Velocity.yの値の数値とゲーム画面の両方で確認を行いましょう。


<検証動画 _萍未琉貳崗紊妊献礇鵐廛椒織鵑鯱打しても、すぐに落下する>
https://gyazo.com/34034df2516f5e82995e88e58fcb7fcb


<検証動画◆Velocity.yの値が制限されている>
https://gyazo.com/1a83d3dd54974bb964913a7da7bc769b


 以上でこの手順は終了です。

 次は 手順9 −バルーンの作成と制御− です。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

3Dトップビューアクション(白猫風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます