i-school - パーティメンバーからリーダーを切り替えて操作できるようにする

設計

 
前提としまして、【複数用意したプレイヤーキャラクターをボタンで変更する】という教材を終了している必要があります。
もしも終了していない場合には、クラスを作成しつつ、記事を抜粋しながら処理を実装していってください。



 プレイヤーキャラクター(以下、キャラ)を複数用意して、中央の位置(リーダーの位置)に選択されたキャラを配置し、操作できるようにします。

実装動画
https://gyazo.com/d61e06af574480dc367b7f7de86c0f25

 この教材では、キャラのまとまりをパーティ、パーティ内のキャラをメンバー、メンバーの中で操作できるキャラをリーダーと定義します。
 また、リーダー以外のキャラをリーダーキャラに追従させる処理は含まれていません。


 ヒエラルキー上、あるいはゲームの実行と同時にキャラを生成し、複数のキャラをゲーム内に用意します。
これらをメンバーとして管理する変数をChangeCharactersクラスに用意しておきます。

 リーダーとなるキャラはGameDataに用意してあるcurrentCharaNumber 変数をそのまま適用します。

 リーダー変更ボタンを用意し、押すとcurrentCharaNumberの値が1つ増えるようにしておきます。
そしてこの値を次のリーダーの番号として利用します。(使用キャラ = リーダーキャラの図式の方が分かりやすいためです。)

 流れとすると、以下のようになります。
リーダー変更ボタンを押す => GameDateのcurrentCharaNumberが変更される => 変更された値を用いてChangeCharactersクラスのリーダー変更メソッドを処理する => カメラの追従対象を変更するメソッドを処理する

実装手順と技術


 以下の順番で実装を行います。クラスそのものがない場合には、前の記事を参考にしながら作成をしてください。
なお書いてはありませんが、Canvas内にリーダー変更用のボタンを1つ作成し、適宜な位置に配置しておいてください。

1.ChangeCharactersクラスを修正する。
2.MainCameraControllerクラスを修正する。
3.UIManagerクラスを修正する。

 処理の全体的な流れは先ほど提示させて頂いた通りです。基本的には、前回学習した内容の応用です。
学習できる技術としましては、以下の通りです。

・配列のディープコピー

1.ChangeCharactersクラスを修正する。


 パーティメンバー管理用の変数を新しく配列で用意します。またStartメソッドを修正して、キャラを追従するカメラの位置を設定します。(そのため、カメラのStartでの設定処理を廃止します。)
またリーダー変更用のメソッドを用意し、ボタンが押されたときに呼ばれるようにします。

ChangeCharacters.cs


 ヒエラルキー上にメンバーとなるキャラが存在している場合には、そのキャラをteamMenber変数にすべて登録してください。
事前に登録しないでゲーム実行と同時に探す場合にはStartメソッドのコメントアウトしている部分を使ってください。

 画像は事前に登録しているものです。



<シャローコピーとディープコピー>

 配列などの情報はクラスとして扱われます。そのため、イコール(a[i] = b[i])での処理は、コピーされた値ではなく、参照された値がコピーされます。
これはシャローコピーといって、参照している元の値に合わせて変化する値になります。上記の例でいえば、b[i]の値が変わると、それに合わせてa[i]の値も変化してしまいます。

 今回実装したい処理の中には、シャローコピーしていたのでは実現できない処理がありました。それはキャラの情報と、直前の位置情報の2つです。

 新しい情報が上書きされると同時に、参照元である値も変化してしまうため、こういった場合にはシャローコピーでは対処が出来ません。

 そのため、ディープコピーという機能を利用します。こちらは、参照ではなくて、参照元の情報を構造を含めて完全にコピーをする方法です。
この方法ですと値は参照型ではなく、この値自体を変化させない限りは、新しい情報として保持することが出来ます。
つまり、b[i]の値が変化したとしても、ディープコピーして作成したa[i]はその値を参照することがなくなりますので、コピーしたときの情報を保持しています。

 この配列のディープコピーの機能を利用して、キャラの情報や位置情報を保持することで、前にいたリーダーと同じ位置に次のリーダーも配置することが可能になっています。

 ディープコピーについては、こちらの記事も参考にしてみてください。
侍エンジニア塾
【C#入門】配列をコピーする方法(一部の範囲指定、高速コピーも解説)
https://www.sejuku.net/blog/40212



2.MainCameraControllerクラスを修正する。


 【1】でも述べましたように、Startメソッドでのキャラとカメラの位置の設定を廃止しています。

 代わりに、SetUpCharaメソッドにoffsetを設定する処理を追加しています。これにより、リーダーの変更があった場合にも、次のリーダーとのoffsetを設定しなおすことで
以前のリーダーの位置と同じ地点でカメラを設置することが出来ています。

MainCameraController.cs


3.UIManagerクラスを修正する。


 リーダー変更ボタンが追加されましたので、ボタンコンポーネント用の変数を作成しています。
こちらに、ボタンが押された際、リーダー変更処理を呼び出すためのOnClickLeaderChangeメソッドを登録しています。 

UIManager.cs


 スクリプトの修正が終了したらUIManagerゲームオブジェクトのインスペクターを確認します。Buttonコンポーネントのアサイン情報が追加されていますので
リーダー変更ボタンをヒエラルキーからドラッグアンドドロップしてアサインしてください。




 以上で終了です。ゲームを実行して参考動画のようになれば完成です。
デバッグ内容としましては、リーダー変更の処理、カメラの位置がリーダーに追従、リーダーだけ操作できる、という部分を確認してください。

応用 リーダーの切替ボタンを2つにする

 
 現在はリーダー変更ボタンが1つですので、リーダーの順番を送ることでしか変更ができません。
これをボタンを2つにして、キャラ変更と同じように、リーダーの順番の送ったり、戻したりして変更できるようにしてみましょう。

 ChangeCharactersクラス内のコメントにヒントがありますので、参考にしてながら実装をしてみてください。


ディープコピー参考サイト
memberwiseclone
https://docs.microsoft.com/ja-jp/dotnet/api/system...