Unityに関連する記事です

干支のシャッフル機能を追加する


 ゲームをプレイしていると、干支同士がうまくつながらないような場面があります。
生成される干支の種類を5種類に絞っていても、ランダムな干支を毎回生成している以上、どうしても避けられない問題です。

 そこで1つの打開策として、干支の位置をシャッフルし、今いる位置からランダムな位置へと移動させることで、膠着した状況を打破できるような設計を考えてみます。

 シャッフル用のボタンを画面下部のUI部分(CanvasのBottomUI部分)を用意し、そのボタンを押すことで干支がランダムな位置へと移動します。

 ロジックとしては、見えないコライダーをゲーム画面内に設置しておいて、シャッフルのボタンを押すと、そのコライダーのスイッチがオンになり
コライダー内にある干支に対して、Rigidbody2DのAddForceメソッドを処理して、空中へと打ちあげるようにします。
ゲーム画面上では、干支の下方向から上方向に向かって風が起きて、浮かび上がっているように表現されています。

完成動画
https://gyazo.com/7557b737aefde69ec4b5e3d9687d5eb0


 このシャッフル機能を、発展2〜3で実装していきます。この手順では、以下の内容を実装します。

 1.Canvas内にShuffleゲームオブジェクトを作成する
 2.Canvas内のBottomUIの子オブジェクトとして空のゲームオブジェクトを作成し、Buttonsに名前を変える
 3.Buttonsゲームオブジェクトの子オブジェクトとして、Buttonゲームオブジェクトを作成し、btnShuffleに名前を変える

 4.Shuffleスクリプトを新しく作成する
 5.ShuffleスクリプトをShuffleゲームオブジェクトにドラッグアンドドロップしてアタッチする 
 6.Rigidbod.AddForceメソッドがどのように作用するか確認する




 新しく学習する内容になります。

・メソッドの引数を利用してアサイン情報を取得する方法
・三項演算子による処理


1.Canvas内にShuffleゲームオブジェクトを作成する


 シャッフルさせるゲームオブジェクトも干支と同じ場所にないと動作しませんので、これをCanvas内に設置していきます。

 Canvas上で右クリックしてメニューを表示し、Create Emptyを選択して空のゲームオブジェクトを1つ作成します。名前を Shuffle に変更します。


ヒエラルキー



 Shuffleゲームオブジェクトをヒエラルキー上で選択し、インスペクターでRectTransformコンポーネントを確認します。普通のTransformコンポーネントになっていたら削除して再度作成してください。
位置についてはCanvasの下部になる辺りに調整します。画像を参考にしてください。

RectTransformコンポーネント




 それでは次に、コンポーネントを2つ追加していきます。

 インスペクターの一番下にある Add Component ボタンを押して、Rigidboby2dコンポーネントを追加します。設定については Gravity Scale(重力)を 0 にして、重力なしの状態にしてください。
他の部分は変更しなくて問題ありません。

Rigidbody2D



 続いてもう一度 Add Componentボタンを押して、CapsuleCollider2Dコンポーネントを追加します。Sceneビューのコライダーを確認しながら、Canvas内に収まる大きさの円を作成します。
位置については干支の配置されている部分と重なるくらいの位置に調整します。Sceneビューの画像を参考してください。

CapsuleCollider2D



Sceneビューでの画像


Sceneビューでの画像


Sceneビューでの画像



Shuffleゲームオブジェクトのインスペクター画像(RectTransformの他に2つのコンポーネントがアタッチされていれば大丈夫です)


 以上の手続きでShuffleゲームオブジェクトは完成です。


2.Canvas内のBottomUIの子オブジェクトとして空のゲームオブジェクトを作成し、Buttonsに名前を変える


 Canvas内に作成済のBottomUIを選択し、その上で右クリックをしてメニューを表示します。
Create Empty を選択して空のゲームオブジェクトを1つ作成し、名前をButtonsに変更します。

 このButtonsゲームオブジェクトは、ボタン用ゲームオブジェクトのフォルダとして利用します。


ヒエラルキー画像


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


ButtonsゲームオブジェクトのSceneビュー画像



3.Buttonsゲームオブジェクトの子オブジェクトとして、Buttonゲームオブジェクトを作成し、btnShuffleに名前を変える


 Buttonsゲームオブジェクトの上で右クリックをしてメニューを表示し、Create => Buttonを選択します。名前を btnShuffle に変更します。

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


 
 btnShuffleゲームオブジェクトを選択してインスペクターを確認します。

 位置と大きさについては、RectTransformコンポーネントのPositionや、Sceneビューの画像を参考して調整してください。

RectTransform


btnShuffleゲームオブジェクト Sceneビュー画像




 つづいてImageコンポーネントを選択し、シャッフル用のボタンの画像を設定します。
無料素材を探してきてインポートして利用してください。
ここでは回転のアイコンを利用していますが、シャッフルというアクションが分かればどんな画像でもよいでしょう。(出来れば、PNG形式の透過性画像がいいです)
他の設定はそのままで問題ありません。


画像設定




 Buttonコンポーネントについては変更ありませんので、アタッチされていることが確認できれば大丈夫です。 

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


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


Sceneビュー画像



 以上でシャッフル用のボタンのゲームオブジェクトは完成です。


4.Shuffleスクリプトを新しく作成する


 シャッフルさせる挙動を実装するために、新しくスクリプトを用意して機能をそちらに記述します。

 Project内の Scripts フォルダ内で右クリックし、Create => C# Script を選択します。名前を Shuffle に変更します。

 それではスクリプトを書いていきましょう。

Shuffle.cs


 スクリプト内の StopShuffle メソッド内にある以下の処理は、まだ呼び出し先のメソッドが用意されていないため、現時点ではエラーが出ます。
こちらの部分は、一旦コメントアウトしておいてください。

  // 再度シャッフルボタンを押せるようにする
  //uiManager.ActivateShuffleButton(true);  // コメントアウトしておきます

 次回の発展3内で UIManager のスクリプトを修正した後に、コメントアウトを解除してください。


5.ShuffleスクリプトをShuffleゲームオブジェクトにドラッグアンドドロップしてアタッチする


 Shuffleスクリプトを作成したら、作成してある、Shuffleゲームオブジェクトにドラッグアンドドロップしてアタッチします。
Shuffleゲームオブジェクトを選択して、Shuffleスクリプトをインスペクターにて確認します。
宣言フィールドで宣言している変数が3つ表示されていると思います。いずれも初期値を入力してありますので、数値が 0 でなければそのまま変更せずに問題ありません。


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




 変数の説明です。

 ShufflePowerはAddForceメソッドで使用する、シャッフルする際の力の値です。初期値は 10 です。大きい値になるほど力の係数が上がるため、干支はより高く打ちあがります。

 ShuffleVelocityはシャッフルの速度です。干支に対してシャッフルの速度を使って相対速度を算出し、それをAddForceメソッドにて使用します。
この値も大きくなるほど相対速度が速く(大きく)なりますので、干支はより高く打ちあがります。Xは左右方向への速度、Yは上下方向への速度を表します。
初期値はどちらも 10 です。シャッフルする際にはXに対して -1 か 1 が掛けられて -10 か 10 になることで、ランダムに左右方向が決定されます。

 Durationはシャッフルする時間です。初期値は 1 ですので、1秒間だけシャッフルされます。

 これらの数値は実際にゲームでシャッフルをしながら、調整してみてください。

インスペクター画像


インスペクター画像



<メソッドの引数を利用してアサイン情報を取得する方法>


 他のクラスの情報をクラス内で利用したい場合、その紐づけの方法にはいくつかの手段があります。
private変数内に代入したいのであれば、紐づけしたいクラスがアタッチされているゲームオブジェクトを探して(Findメソッドを利用して)、それからGetComponentする方法、
public変数であれば、インスペクターからゲームオブジェクトをドラッグアンドドロップして事前にアサインしておく方法などです。

 今回Shuffleクラスでは、UIManagerクラスの情報を代入するための変数をprivateで用意しています。
こういった場合にはインスペクターによる事前のアサインができませんが、Findメソッドを利用せずにアサインを取得する方法の1つとして、
メソッドの引数の値にUIManagerクラスを届けてもらう方法があります。


    private UIManager uiManager;    // アサイン情報

    /// <summary>
    /// シャッフルの初期設定
    /// </summary>
    /// <param name="uiManager"></param>
    public void SetUpShuffle(UIManager uiManager) {    // <=  引数でUIManagerクラスが届いている
        this.uiManager = uiManager;                        // それを変数に代入する

        (省略)
    }

 このような手法を用いれば、処理の重いFindメソッドを利用することなく、private変数にアサイン情報を代入することが可能です。
クラス内で利用したい外部クラスの情報は、それをどのように取得するか、という部分で設計を検討することで、このようなやりとりによる値の代入ができます。


<三項演算子による処理>

 
 三項演算子という処理は、if文の分岐処理を1行で簡潔に記述できる書式です。

次のような条件のif文があったとします。

    int value = Random.Range(0, 2);
    
  // シャッフルの方向をシャッフル速度のXに設定(-1 = 左方向、1 = 右方向)
    if(value == 0)
    {
         shuffleVelocity.x *= -1;
    } 
    else 
    {
         shuffleVelocity.x *= 1;
    }

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

  // シャッフルの方向をシャッフル速度のXに設定(-1 = 左方向、1 = 右方向)
    shuffleVelocity.x = value == 0 ? shuffleVelocity.x *= -1 : shuffleVelocity.x *= 1;


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

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

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


参考記事
@crazy_traveler様
参考になる三項演算子
https://qiita.com/crazy_traveler/items/5fb5ec9568e...


6.Rigidbod.AddForceメソッドがどのように作用するか確認する


 ここで実際に、AddForceメソッドによってどのような挙動が実装されているかをデバッグして確認してみましょう。

 デバッグを開始するにあたり、まずはShuffleスクリプト内のUpdateメソッドの処理をすべてコメントアウトします。この部分があるとデバッグができないためです。

 ゲームを実行して、干支を生成します。Shuffleゲームオブジェクトを選択して、CapsuleCollider2Dのスイッチをオン、オフを切り替えてみてください。
OnEnterStay2Dメソッド内に記述しているAddForceメソッドが実行されて、オンの時には干支が空中に浮かび上がって、オフにすると落下するはずです。

 確認が取れたらデバッグを終了しますので、先ほどコメントアウトしたShuffleスクリプトのUpdateメソッドを元に戻しておいてください。


デバッグ動画 Shuffleゲームオブジェクトのコライダーをオン/オフして、どのようにRigidbody2DのAddForceが作用するかを確認する
https://gyazo.com/6f64c7c22674cf8e2f6b7b47f6006d9f


 次の手順では、このオン/オフをシャッフルボタンを用意して切り替えるようにして、シャッフル機能を実装していきます。



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

 次は 発展3 です。

コメントをかく


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

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

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

3D脱出ゲーム(抜粋)

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

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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