Unityに関連する記事です

 ここからの手順では2回にわけて、ゴール地点の作成ゴールした際のゲームクリアの判定について実装していきます。
ここではゴールした際のゲームクリア判定とキャラの制御を実装します。

<実装画像 Gameビュー>



<動画 Sceneビュー>
https://gyazo.com/67e45fb124c4ec7020bd33fb4e72d68f


手順10 −ゴール判定とキャラの制御を実装−

15.ゴール地点に侵入したらゲームクリアの判定を行えるようにする
16.ゲームクリアの判定に伴ってキャラの速度を減速して停止させるとともにキャラの移動も出来ないように制御する


新しく学習する内容


 ・Tag の設定
 ・OnTriggerEnterメソッド
 ・実数を変数に変える


15.ゴール地点に侵入したらゲームクリアの判定を行えるようにする

1.設計


 ゴール地点を通過(侵入)した、という単語をプログラム化していく手順です。

 ゴール地点を通過したら、という問いかけをプログラムで制御を行うには、「ゴール地点を通過しているかどうか」という情報を作るところから始めます。
この情報はキャラが管理することが望ましいですから、キャラがゴール地点を通過したのか、あるいはまだ通過はしていないのか、という情報を持つことが必要になります

 こちらは bool 型で情報を管理できるようにします。isGoal という変数を用意して、false = ゴール地点を通過していないtrue = 通過した、というように切り替えるようにすれば
この変数を参照することで、「ゴール地点を通過したら」という条件を表現することが出来るようになります


 ゴール地点との通過の判定ですが、ゴール役の GoalSet ゲームオブジェクトに、Box 型の Collider を新しく用意します。
このコライダーにキャラのゲームオブジェクトにアタッチされているコライダーが侵入したら、それを「ゴール地点を通過した」と判定するようにします

 コライダーだけではどのゲームオブジェクトのコライダーに侵入したのか判定が難しいので、GoalSet のコライダーのゲームオブジェクトには Tag を設定します。
これはゲームオブジェクトの分類を行うとともに、判定時に特定の Tag かどうか、という方法で利用できます。


2.PlayerController スクリプトを修正する


 すでに作成されている PlayerController スクリプトを修正します。
設計の手順で説明を行いましたように bool 型の isGoal 変数を用意します。
この値の真偽値ゴール地点を通過した判定値として利用することで、ゴール地点を通過した状態を作り出しています。
新しい変数を作成する際には「どんな目的のために必要か」を考えるとよいでしょう。

自ずと変数の名前も、その「目的」に即した名称を考えていくようになります。

 ゴール地点を通過した際の判定には、Unityが最初から提供してくれている、OnTriggerEnter というメソッドを利用します。
これは IsTrigger のスイッチが入っている他のゲームオブジェクトのコライダーと、このスクリプトがアタッチされているゲームオブジェクトのコライダー
(つまり、Penguin ゲームオブジェクトにアタッチされている Capsule Collider)とが接触して通過(侵入)した際に、自動的に呼び出されるメソッドです。

 このように、ある一定の条件を満たした際に自動的に呼び出されるメソッドのことをコールバック・メソッドといいます。


PlayerController.cs

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



 スクリプトを修正したらセーブを行い、PlayerController スクリプトがアタッチされている Penguin ゲームオブジェクトのインスペクターを確認します。
新しく宣言した変数は private 修飾子であるので表示されませんので、いままで同じ情報のみ表示されていれば問題ありません。


Penguin ゲームオブジェクト インスペクター画像




3.<OnTriggerEnterメソッド>


 Unityの Collider クラスの持つメソッドの1つです。
このメソッドが記述されたスクリプトのアタッチされてるコライダーを持つゲームオブジェクト(キャラ)が、他のコライダーを持つゲームオブジェクトを通過した際に接触(侵入)判定を行うメソッドです。

 このスクリプトがアタッチされているゲームオブジェクトのコライダーの中に、侵入したゲームオブジェクトがある場合、その情報を Collider 型で取得し、メソッド内で利用できる状態にしてくれます

 通常コライダーを持つオブジェクト同士は接触し停止しますが、いずれか片方のゲームオブジェクトのコライダーの IsTrigger のスイッチがオンになっている場合、
コライダーを持つゲームオブジェクトを通過(侵入)することができます。その際に、このメソッドが侵入判定を行います。

    // IsTriggerがオンのコライダーを持つゲームオブジェクトを通過した場合に呼び出される、コールバック・メソッド
    private void OnTriggerEnter(Collider other) {

        // 侵入したコライダーのゲームオブジェクトの Tag が Goal なら(それ以外の Tag ならば以下の処理を行わない)
        if (other.gameObject.tag == "Goal") {
            Debug.Log("Goal");

            // ゴール地点を通過した状態にする
            isGoal = true;

            Debug.Log(isGoal);
        }
    }

 侵入判定はコライダーであれば反応してしまうため、何も制限をかけないと、例えば斜面のゲームオブジェクトのコライダーにも反応してしまうため、それでもゴールの判定が発生してしまいます。
そのため多くの場合は今回の実装例のように、Tag などで侵入判定を行うゲームオブジェクトを制御して利用をします。


参考サイト
Unity公式スクリプトリファレンス
OnTriggerEnter

https://docs.unity3d.com/ja/current/ScriptReferenc...


4.GoalSet ゲームオブジェクトの子オブジェクトとして、GoalCollider ゲームオブジェクトを作成する


 GoalSet ゲームオブジェクトの上で右クリックをしてメニューを開き、3D => Cube を選択します。
Cube ゲームオブジェクトが作成されますので、名前を GoalCollider に変更します。


GoalCollider ゲームオブジェクト ヒエラルキー画像



GoalCollider ゲームオブジェクト インスペクター画像



GoalCollider ゲームオブジェクト Sceneビュー画像とGameビュー画像



5.GoalCollider ゲームオブジェクトに Tag を設定する


 Unity ではゲームオブジェクトに1つだけ、 Tag(タグ) という参照ラベルを割り当てることが出来ます。
例えば、複数の同じ目的のゲームオブジェクト(例えば敵)に Emeny という Tag を付けたり、
逆に、単一の情報として特定するためにペンギンのゲームオブジェクトに Player という Tag を付けたりすることが出来ます。

参考サイト
Unity公マニュアル
タグ
https://docs.unity3d.com/ja/current/Manual/Tags.ht...


 GoalCollider ゲームオブジェクトを選択し、インスペクターの名前の左下にある Tag の設定を変更します。
左クリックすることでプルダウンメニューが表示されますので、一番下にある Add Tag を選択します。

 任意の文字列を Tag として登録できますので、+ ボタンをおして、Water を登録してください。


Tag の追加



 もう一度、GoalCollider ゲームオブジェクトを選択して、同じように Tag の設定を選択すると、登録した Goal のTagが追加されていますので、
Untagged(Tag なし)の状態を Goal に変更してください。


<手順動画 Tagの設定>
https://gyazo.com/7dedf65a70c4d4afa7d1517eb618845a


GoalCollider ゲームオブジェクト インスペクター画像



6.GoalCollider ゲームオブジェクトの設定を行う


 3つの手順がありますので、順番に設定を行います。

 最初に、ゲームオブジェクトの大きさと位置を変更します。

 このゲームオブジェクトは、ゴール地点を通過した際に判定を行うためのゲームオブジェクトです。
つまり、フラッグのゲームオブジェクトのすぐ後ろ側から設置するようになります。

 両端にあるフェンスのゲームオブジェクトの位置までゲームオブジェクトの X 軸を広げます。
また Y 軸もフラッグの高さと同じ位に広げます。Z軸は厚さになりますが、ここは変更しなくても問題ありません。

 Sceneビューや下記のインスペクター画像を参考にして調整してください。


GoalCollider ゲームオブジェクト インスペクター画像



Sceneビュー画像



Sceneビュー画像



Gameビュー画像




 続いてコライダーのコンポーネントを追加します。インスペクターの一番下にある Add Component ボタンを押して BoxCollider コンポーネントを追加してください。
自動的にゲームオブジェクトと同じ大きさになりますので、確認してください。同じ大きさのコライダーになっていれば問題ありません。
この範囲が実際にキャラのゲームオブジェクトとの判定を行う範囲になります。

 大きさが問題なければ、IsTrigger のスイッチにチェックを入れてオンの状態にしてください。
このスイッチがオンでないと侵入するコライダーになりません。(オフだとコライダー同士が接触して侵入できません)

 また、PlayerController スクリプトに用意した OnTriggerEnter メソッドも、IsTrigger がオンのコライダーに侵入した場合にしか動きません


GoalCollider ゲームオブジェクト インスペクター画像



Sceneビュー画像
&ref(-s.png)



Sceneビュー画像



Gameビュー画像





 最後の MeshRenderer コンポーネントのスイッチを外してコンポーネントをオフの状態にします。
こうすることでゲームオブジェクトを描画する機能がオフになるため、見えないコライダーを持つゲームオブジェクトを作成できます。


GoalCollider ゲームオブジェクト インスペクター画像



Sceneビュー画像



Gameビュー画像




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


 ゲームを実行して、キャラを滑らせていきます。ゴール地点の後ろ側に配置してある IsTrigger にチェックの入っている Box Collider コンポーネントに対して
キャラのゲームオブジェクトが侵入して Capsule Collider が接触したとき、PlayerController スクリプトに追加した OnTriggerEnter メソッドが自動的に呼び出されます。

 この処理の中では、Goal の Tag を持つゲームオブジェクトに侵入した際に、isGoal を true にして重複判定を防ぐとともにゴール地点を通過した状態を作り出します
このように bool 型を利用することでゲーム内に特定の状況・状態の設定をゲーム内の仕組みとして組み込むことが出来ます。

 また Debug.Log メソッドがありますので、Console に、ゴールの文字と、isGoal の値(true) とが表示されれば、制御は成功です。


<実行動画>
https://gyazo.com/c5e3b0d7c7567d17add78d356bc210aa

 これで、ゴール地点を通過した情報は判定できるようになりました。
現在、ゴール地点を通過してもキャラの速度は減速せず、またずっとキャラの移動操作が行える状態になっています。

 続いては、ゴール地点を通過したという条件を元にして、キャラの速度を徐々に遅くて停止させて、またキャラの移動を行えなくするための制御を行います。


16.ゲームクリアの判定に伴ってキャラの速度を減速して停止させるとともにキャラの移動も出来ないように制御する

1.設計


 PlayerController スクリプトに isGoal 変数を用意したことによって、OnTriggerEnter メソッド内の処理に合わせて
この値が変化するようになり、ゴール地点を通過しているか、まだ通過していないか、という状態を管理できるようになりました。

 この手順ではこの情報を利用して、以下の3つの制御を行います。

 1.【ゴール地点を通過している場合には、キャラの速度を徐々に低下させる】
 2.【ゴール地点を通過している場合で、かつ、キャラの速度が一定値よりも低下した場合には、キャラを停止させる】
 3.【ゴール地点を通過している場合には、キャラの移動を行えないようにする】

 どのようにすれば、上手く isGoal 変数を利用して、上記の制御を行えるか、ロジックを考えてみてください。

 日本語をプログラム化するときには、ロジックを組む、という言葉を使います。
物事を論理的に考えて、どのような制御の組みあわせを作ることによって、実装したい処理を実現できるようしましょう。

 ロジックを記述する際には、いきなりプログラムを書くのではなく、ここかな? という部分に、日本語のコメントを用意します
その上で、その日本語の処理をプログラム化していきます。こうすることで処理の内容を考えながらロジックを構築することが出来ます。
また、処理が完成した場合にもそのままコメントが有効になるため、処理の確認も容易に行えます。

 キャラの速度を下げるには、どの値を制御すればいいのか、速度の情報を制御するとした場合、継続的な処理が必要なのか、
継続的な処理を作るとしたら、FixedUpdate メソッドがいいのか、Update メソッドがいいのか。

 一度にすべてのことをやろうとはせず、処理を1つずつ掘り下げていき、徐々に全体の処理を考えていくようにします。
 

2.PlayerController スクリプトを修正をする


 先ほど作成した isGoal 変数などを利用して if 文の条件式に利用します。
新しく用意する変数はありません。

 if 文内には return キーワードを利用することにより、処理を実行させないための制御機能を実装出来ます。
今回であれば、ゴールした後にはキー入力などの処理を実行させないように処理を追加しています。

 return の処理は、処理を制御したい場所をよく吟味した上で、どのような制御が出来るのかを考えて作成するように心掛けます。
例えば FixedUpdate メソッド内に return 文を記述した場合、その処理よりも下に Move メソッドなどがあれば、それらが制御の対象となります。
そうすることで、色々な場所(各メソッド内に個別)に return を記述せずに済むためです。

 まずはコードを記述する前に、自分の考えた処理を該当の箇所に日本語でコメントしてみてください。
その上で処理を書いてみましょう。どのような値を制御すればいいのかをイメージすることが大切です。


PlayerController.cs

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


 スクリプトを修正したらセーブを行います。

 変数の追加はありませんので、インスペクター上での変更点はありません。


Penguin ゲームオブジェクト インスペクター画像



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


 ゲームを実行してゴール地点を通過してみてください。キャラの速度が徐々に下がって一定速度よりも下がった場合には停止します。
また、ゴール地点を通過したら左右方向のキー入力を行ってもキャラが移動しないように制御されていれば制御成功です。


<実行動画>
https://gyazo.com/9d4057bf302677fcef312856aea82221


4.<応用 実数を変数に変更する>


 PlayerController スクリプトの 右辺の部分には、0.985f や 2.5f というように実数が記述されています。
こういった記述をリテラル表記といいます。リテラル表記はわかりやすい反面、一切融通が利きません。常に固定値として処理が動くためです。

 これらを変数に変更して、現在のリテラル表記の値を代入して利用するように修正してください。

 宣言する際の修飾子は private で、変数名は自由で問題ありません(用途に見合った名前にしましょう)。
代入処理、条件式の比較処理を行うためには左辺と右辺の型が同じである必要があります。


PlayerController.cs 参考例

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


 スクリプトを修正したらセーブします。

 新しく宣言した変数は private 修飾子であるので、インスペクターには表示されません。
いままでと同じ情報のみ表示されていれば問題ありません。



 ☆,函△離螢謄薀詆週の部分を変数に変更したら、値も変更してどんな挙動になるかを確認しておきましょう
このように自分で処理を変更することで、スクリプトによってどのようにゲームの挙動が変化するかをつかめれば、コード上の処理をイメージしやすくなります。


<例 ☆◆,留κ佞涼佑鯤儿垢靴疹豺(見えやすくするためにフェンスは非表示にしています)>

2.0f
https://gyazo.com/3ff58b30e8bc2f8b12001e9199e503da

2.5f
https://gyazo.com/c1660bf33f2acccdf0f9d8431326dfdd


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

 => 次は 手順11 −障害物の準備− です。

コメントをかく


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

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

Menu



技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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