Unityに関連する記事です

 この手順ではインポートしたアセットを利用して2種類目の木の障害物の実装していきます。
このゲームオブジェクトはずっと見えていますが、キャラが一定範囲に近づくと倒れはじめてプレイヤーの進行を邪魔をするような仕掛けにします。

 すべての木を倒すようにするのではなくて、倒れる木、倒れない木を用意することでバリエーションを作り
ユーザーに対して、この木は動くのか、動かないのか、という部分で考える幅をつくり、コース取りの判断をしていただくようにします。


<実装画像 Sceneビュー>



<実装動画 キャラが一定範囲に侵入すると木が倒れる>
https://gyazo.com/9befabacdbb5381bcee7c2096f7c574b


手順14 −木の障害物の実装−

23.木を設置する
24.スクリプトを用意して、木の制御を行う


新しく学習する内容


 ・DOTweenの補間機能と実装例◆ DORotateメソッドー
 ・戻り値の利用
 ・三項演算子による処理


23.木を設置する

1.設計


 今回の障害物は始めから見えているが、近づくと邪魔をするような障害物を設計します。
インポートしたアセット内に雪のかぶった木のゲームオブジェクトがあり、挙動のイメージ的にも合いますので、こちらを障害物として利用しましょう。

 木のゲームオブジェクトはゲーム内の状況に応じて制御を行う必要がありますので、新しくスクリプトを1つ作成して、
それを利用してゲームオブジェクトを制御させます。

 具体的には、一定の距離にペンギンのキャラが近づいたら木を回転させて倒す処理などをスクリプトを使って制御します。

 なおここではモグラのゲームオブジェクトと同様に、障害物としてキャラの滑るのを邪魔する役割を持っていますが、それ以上の役割やルールは設定していません。


2.Obstacles ゲームオブジェクトの子オブジェクトとして、SnowyTree ゲームオブジェクトを作成する


 Obstacles ゲームオブジェクトの子オブジェクトとして、SnowyTree ゲームオブジェクトを作成します。

 雪のかぶっている木のゲームオブジェクトをフォルダから探して、ヒエラルキー上の Obstacles ゲームオブジェクトにドラッグアンドドロップして作成します。
3つありますので、いずれを利用していただいても構いません。

パス
Assets/Snowy_Low_Poly_Trees/Pine_Snowy1.prefab
Assets/Snowy_Low_Poly_Trees/Pine_Snowy2.prefab
Assets/Snowy_Low_Poly_Trees/Pine_Snowy3.prefab


フォルダ



インスペクター画像(Pine_Snowy1.prefab)




 名前を SnowyTree に変更します。


ヒエラルキー画像



インスペクター画像



Sceneビュー画像


 続いて、設定を行います。


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


 SnowyTree ゲームオブジェクトの設定を行います。

 最初にプレファブの状態を解除します。SnowyTree ゲームオブジェクトの上で右クリックをしてメニューを表示し、
Prefab => Unpack Completely を選択します。これでプレファブ状態ではなく、通常のゲームオブジェクトになります。
ヒエラルキーの青いアイコンや名前が黒い状態に戻ります。






 Transform コンポーネントを操作して、位置を調整します。
下記のインスペクター画像や、Sceneビュー、Gameビューも見ながら、適宜な位置に調整してください。
サイズや回転は変更しなくて問題ありません。


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



Sceneビュー画像



Gameビュー画像




 続いて、MeshCollider コンポーネントの Convex にチェックを入れて、コライダーを有効にします。

インスペクター画像



Sceneビュー



 非常に複雑な形状でコライダーが形成されて、この範囲で接触判定を行ってくれるようになります。
ただし、このメッシュ型のコライダーは処理が非常に重いです。

 そのため、例えば、このコライダーを外してCapsuleColliderやBoxColliderで代用することも1つの手法です。
また、無料アセットで、メッシュよりも軽いコライダーを自動的に作成してくれるものもあります。利用してみてください。


参考サイト
kanのメモ帳 様
メッシュに合わせてコライダーを自動作成してくれるSAColliderBuilder【Unity】【アセット】
https://kan-kikuchi.hatenablog.com/entry/SACollide...



 最後に、Rigidbody コンポーネントを追加します。
インスペクターの一番下にある Add Component ボタンを押して、Rigidbody コンポーネントを追加します。

 Use Gravity のチェックを外して重量の影響を受けないようにしてください。

 フラッグのゲームオブジェクトと同じようにFreezeRotation のすべての軸にチェックを入れて
斜面のゲームオブジェクトによって滑ったり、キャラと接触したときに動いてしまわないようにしてください。


インスペクター画像



 以上で木のゲームオブジェクトの設定は完了です。


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


 モグラのゲームオブジェクトと同じように、SnowyTree ゲームオブジェクトの子オブジェクトに「キャラの侵入を判定するための見えないゲームオブジェクト」を追加します。
このゲームオブジェクトにコライダーを用意して、IsTrigger にチェックを入れて、木の前方に配置します。
そしてコライダーの範囲を【キャラの侵入を感知する】範囲として利用します。


実装画像






 手順としてはモグラの侵入判定の方法と同じになりますので、手順を見ずに挑戦してみましょう。



 SnowyTree ゲームオブジェクトの上で右クリックをしてメニューを開き、Create Empty を選択します。
新しい空のゲームオブジェクトが作成されますので、名前を SearchArea に変更します。


ヒエラルキー画像



 Transform コンポーネントを Rotation X を 15 にしてください。こうすることで斜面のゲームオブジェクトと角度が一致します。


インスペクター画像




 コライダーを追加します。
インスペクターの一番下にある Add Component ボタンを押して BoxCollider コンポーネントを追加してください。

 IsTrigger のチェックを忘れずに入れてください

 コライダーの大きさは自由に設計してください。

 前方や横方向に広くするほどキャラの侵入する判定範囲が広くなり、キャラと木の位置が遠い段階で木が倒れるようになり、避けるための難易度は下がります。
逆に小さくすればキャラと木が近い段階で木が倒れるようになるので、避けるための難易度は上がります。

 ここではある程度の標準とする大きさで用意しておいて、広い狭いの個性を出すのはプレファブ化してからの方がやりやすくなると思います。
下記のインスペクター画像は、Sceneビュー画像のコライダーのサイズになります。


インスペクター画像



Sceneビュー画像



Sceneビュー画像



 以上で木のゲームオブジェクトの設定は完了です。


5.ゲームを実行して問題点を修正する


 木のゲームオブジェクトが完成しましたので、まずはゲームを実行してみます。

 キャラを木のゲームオブジェクトに接触させてみてください。一緒に木のゲームオブジェクトが動いてしまいます。


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


 改善するには、IsKinematic のチェックを入れて、キャラが接触しても木のゲームオブジェクトが移動してしまわないようにしてください。





 以上で完成です。


24.スクリプトを用意して、木の制御を行う

1.設計


 SnowyTree ゲームオブジェクトの設定が完了しましたので、このゲームオブジェクトの制御を行うためのスクリプトを作成します。

 どのような制御を行いたいかを、書き出してみます。

 1.キャラが一定の距離に近づいたら、木を倒す

 キャラが一定の距離に近づいたら、という処理と、木を倒す、という処理は1つずつ実装する手順を考えます。
 
 まず一定の距離に、という部分には、先ほど SnowyTree ゲームオブジェクトの子オブジェクトとして作成した SearchArea ゲームオブジェクトのコライダーを利用します。
木のゲームオブジェクトの前方に配置したこのゲームオブジェクトが「一定の距離」として扱うようにします。
そしてこの範囲内にキャラが侵入した状態を「キャラが一定の距離に近づいたら」と判定するように考えてみます。
 これは以前に学習したモグラの侵入判定と同じ手法です。

 その判定が行われて始めて、木を倒す、という処理を実行するように連動させます。

 木を倒す処理は、木の回転情報を操作することで制御できます。
自分で Rotation の値を操作してみましょう。木が倒れる軸があります。

 Unityでは操作したいコンポーネントを事前に操作をして、自分でどんな制御をしたいのか、そのイメージを確認しておくことが出来ますので、
これを必ず行って、「スクリプトを使ってどんなことをしたいのか」を目でみて確認し、ロジックを組む際に役立ててください

 なお、単純に Rotation の値を操作してもよいのですが、その場合、いきなり木が倒れます。移動もそうでしたね。
そのため、ここでも DOTweenの機能を利用して、時間をかけて木を回転させて倒していく処理を実装します。
そうすることにより木がいきなり倒れることはなくなります。

 基本的には、モグラのゲームオブジェクトを制御させた処理を応用することで実装出来ます。

 今回も自分でコメントを書いてみて、処理を実装してみましょう。


2.RotateObject スクリプトを作成する


 宣言フィールドには2つの変数を用意しています。
1つは木を回転させる時間を指定する値で、この時間をかけて木を回転させるようにします。

 もう1つの変数は、「ゲームオブジェクトが回転して倒れているかどうか」を判定するための値です。
この値を判定の条件に利用して、「まだ回転していない(倒れてない)」場合にだけ、回転を行うようにします。
なお、この値を条件式に利用しない場合にはどのようになるか(なぜこの判定が必要なのか)、自分で試してみてください。

 OnTriggerEnter メソッドを利用して、SearchArea ゲームオブジェクトのコライダーに侵入したゲームオブジェクトのうち、
Player タグのゲームオブジェクトのみ判定を行うように制御をします。これを指定しないと斜面のゲームオブジェクトのコライダーにも反応します。
これもモグラのときと同じです。

 Player タグが設定されたゲームオブジェクト(Penguin)のコライダーが侵入した場合、Rotate メソッドを呼び出して木を回転させます。
回転角度は RandomAngle メソッドの戻り値を利用して、ランダムに左右に倒れるようにしています。
戻り値のあるメソッドを実行すると、その処理の結果が呼び出し元に情報として戻されます
これにより、左右のどちらに倒れるか、その都度自動的に変化するようになります。


 以上のように制御することで、一定の距離にキャラが侵入した場合に木を時間をかけて回転させながら倒す制御を行います。


RotateObject .cs

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



3、<DOTweenの補間機能と実装例◆ DORotateメソッドー>


 新しいDOTweenの処理を実装していますので、メソッドの説明をします。

 // Z 軸のみ duration 分の時間をかけて回転。回転角度は RandomAngle メソッドの戻り値を利用して、ランダムに左右に倒れるようにする
  transform.DORotate(new Vector3(0, 0, RandomAngle()), duration);



1.DORotate(Vector3 endValue, float duration, RotateMode rotateMode)

 DORRotate メソッドは指定した時間をかけて回転角度まで最短距離で回転を行います

 第1引数には目標とする回転角度を Vector3 型で指定します。
今回は new Vector3(0, 0, RandomAngle()) でRotation を指定していますので、 Z 軸のみ回転情報を与えられています。

 第2引数には第1引数の回転位置に到達するまでにかかる時間です。float 型で指定します。
今回は duration を指定していますので、duration 変数の値 秒を書けて Z 軸を回転させています。

 第3引数には RotateMode を指定することができ、指定しない場合は RotateMode.Fast が自動的に設定されます。
今回は、RotateMode.FastBeyond360 を指定しています。こちらは、360度を超えた回転角度が指定された場合に、
そのまま 360 度を越えた回転を行うようにするオプション処理です。今回は指定していません。

 これは、第1引数に 360 度を指定した場合、360 = 0 として認識をしてしまい、回転を行わなくなってしまうことを回避するために設定しています。
(RotateMode を 初期設定の Fast に変更して、実際に試してみましょう。)


4.SnowyTree ゲームオブジェクトに RotateObject スクリプトをアタッチして設定を行う


 作成した RotateObject スクリプトが動くように、SnowyTree ゲームオブジェクトにドラッグアンドドロップしてアタッチします。

 アタッチしたら、必ず、アタッチしたゲームオブジェクトのインスペクターを確認しておきます

 RotateObject スクリプトには public 修飾子の変数が宣言されていますので、インスペクター上にその情報が表示されます。
この値の時間をかけて木が回転して倒れるようになりますので、任意の時間を設定してください。ここでは 3 を設定しています。

 なお、0 を指定するといきなり倒れます。


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



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


 すべての設定が完了しましたので、ゲームを実行してキャラを木のSearchArea ゲームオブジェクトのコライダーの中に侵入させてください。
木が回転して倒れれば制御成功です。Sceneビューも合わせて確認しましょう。


<実行動画 キャラが一定範囲に侵入したら木が回転して倒れる>
https://gyazo.com/9befabacdbb5381bcee7c2096f7c574b


<実行動画 木のゲームオブジェクトがキャラに接触しても動かないか確認>
https://gyazo.com/8f6e722fac7cbac455a3c284e70efa5d


 もしも SearchArea のコライダーに侵入できない場合には、IsTrigger のスイッチが入っているかを確認します。
また侵入はできるものの OnTriggerEnter メソッドが実行されない場合には、SnowyTree ゲームオブジェクトに Rigidbody コンポーネントがアタッチされているかを確認します。


6.SnowyTree ゲームオブジェクトをプレファブにする


 挙動に問題がなければ、今後、SnowyTree ゲームオブジェクトを増やしたり、スクリプトから生成させることも念頭に入れて
SnowyTree ゲームオブジェクトをプレファブにしておきます

 Prefabs フォルダに SnowyTree ゲームオブジェクトをドラッグアンドドロップしてプレファブにします。
プレファブにすると、ヒエラルキーにある SnowyTree ゲームオブジェクトがクローンになるため、アイコンと名前が青い色で表示されるようになります。


ヒエラルキー画像



Prefabs/SnowyTree



 その後、プレファブの SnowyTree ゲームオブジェクトを選択して、インスペクターの一番上にある Opne Prefab ボタンを押してプレファブ編集モードにします


インスペクター画像



 Transform の Position の値をすべて (0, 0, 0)にしておいてください。
このとき、Transform コンポーネントの Reset をかけると、設定してある Scale の値も 1 に戻ってしまうため、Position の値だけを 0 にしてください


SnowyTree ゲームオブジェクト プレファブにした際のインスペクター画像



SnowyTree ゲームオブジェクト 編集モード画像



 以上で完成です。


7.<応用 三項演算子を使ってみる>


 三項演算子という処理は、if / else 文の分岐処理を1行で簡潔に記述できる書式です。
ただし、すべての if / else 文を置き換えられるわけでなく、

 (岐処理内部で同じ変数に対して代入処理を行っている分岐処理
 ∧岐処理内部でreturn 文で同じ型の情報を戻す分岐処理

 このいずれかのみ、置き換えることが出来ます。

 今回であれば、RotateObject スクリプトの RandomAngle メソッド内の分岐処理が△乏催します。
こちらを三項演算子を利用することで処理を簡潔に記述することが出来ます。


    /// <summary>
    /// 木の回転角度をランダムに設定
    /// </summary>
    /// <returns></returns>
    private float RandomAngle() {
        int value = Random.Range(0, 2);

        if (value == 0) {
            return 70.0f;
        } else {
            return -70.0f;
        }
    }

 この条件式を三項演算子にして if / else 文を1行にまとめると、次のような式になります。

 ↓

  private float RandomAngle() {
        int value = Random.Range(0, 2);

        return value == 0 ? 70 : -70;
    }



 三項演算子はその名前の通りで、3つの項目があります。

【条件文】 ? 【trueだった場合返す値や処理】 : 【falseだった場合返す値や処理】

 右辺では、この条件式とtrueとfalseの3つの項目を用意して、その結果に合わせて左辺へ値を代入します。


参考記事
Qiita @crazy_traveler 様
参考になる三項演算子



 さらに RandomRange メソッド処理も含めることで、処理自体を1行にすることも出来ます。

  private float RandomAngle() {
        int value = Random.Range(0, 2);
        return value == 0 ? 70 : -70;
    }

  ↓

  private float RandomAngle() {
        return Random.Range(0, 2) == 0 ? 70 : -70;
    }

 これは RandomRange メソッドの戻り値を利用している処理です。




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

 次は 手順15 −ジャンプの実装− です。

コメントをかく


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

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

Menu



技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

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

3D脱出ゲーム(抜粋)

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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