Unityのゲームで操作キャラクターを切り替える機能

今回はゲーム内に操作出来るキャラクターが複数いた場合に自分で操作するキャラクターを切り替える機能を作成していきます。

ゲームに主人公の仲間がいて、その仲間だと洞窟にいる敵に対して攻撃力が高くなるといった時に、
操作するキャラクターを主人公から仲間へと変更して進めたい時があります。

そんな時に簡単に操作キャラクターを切り替えられるような機能があると便利です。

スポンサーリンク

仲間のキャラクターを作成する

まずは主人公キャラクターの仲間を作成してゲーム内に配置します。

今回はサンプルなので、主人公キャラクターであるEthanをコピーして仲間キャラクターとします。

主人公キャラクターにはすでにCharacterController、Animatorが取り付けられており、キャラクターを動かすスクリプトも作成されているとします。

CharacterControllerは

Unityでキャラクターを移動する為の準備と概要(スクリプトを書く前に)
Unityでキャラクターを移動する為に準備しておく事と、移動させる為に必要な事を考える

キャラクターの移動は

Unityでキャラクターの移動をプログラミングしてみる
キャラクターを移動させる為のスクリプトを作成し、キャラクターを動かす機能を作成します

アニメーターに関しては

Unityのアニメーションの切り替えシステムとスクリプト
Unityのアニメーションを切り替える為のアニメーターの設定とアニメーションの遷移をさせるスクリプトの作成を行います

を参照してください。

主人公と仲間キャラクター

主人公キャラクターをコピーして配置したのが↑の画像です。
キャラクターはそれぞれEthan、Ethan2、Ethan3という名前にしておきます。

3人仲好しキャラクター

配置した状態で動かすと3人同時に同じ動きをしてしまいます。
まぁ・・・これは同じ機能を持ったキャラクターをコピーしたので当然ですね(-.-)

操作キャラクターを変更するスクリプトChangeCharaの作成

そこで最初はEthanだけを操作出来るようにし、Ethan2、Ethan3は操作出来ないようにしてみます。

ゲーム全体を管理するスクリプトを取りつける空オブジェクトScriptを作成し、そこに操作キャラクターを切り替えるスクリプトChangeCharaを取りつけます。

public var nowChara : int; // 現在どのキャラクターを操作しているか
public var chara : GameObject[]; // 操作可能なゲームキャラクター

現在操作しているキャラクターを把握するのがnowCharaの番号になります。

charaには操作可能なキャラクターをインスペクタで設定出来るようにGameObject配列で宣言しています。

Update関数でQキーが押されたら操作キャラクターを切り替えるChangeCharacter関数を呼び出します。

キャラクターの操作が可能なのはコンポーネントのCharacterController、キャラクター移動スクリプトMoveTestが有効になっているからなので、
キャラクターを操作したくない場合はこれらのコンポーネントを無効化します。

途中CapsuleColliderも無効にしていますが、これはキャラクターに取りつけているCharacterControllerのコライダ同士では衝突が出来ない為
キャラクターそれぞれにCapsuleColliderを取りつけ、コライダのサイズをCharacterControllerのサイズと同じにし、IsTriggerのチェックを外しておきます。

キャラクター同士で衝突させる為カプセルコライダを取りつける

CapsuleColliderは↑のようになりました。

キャラクターのAnimatorを無効化しないのは、操作していないキャラクターも何らかのアニメーション(立っている状態でフラフラしてるなど)をさせておきたい為です。

また操作キャラクターを無効にした時にアニメーションが歩いている状態で移動機能が無効化されてしまうと動かないけどその場で足踏みしている状態になってしまうので、
アニメーションパラメータのSpeedを0にして立っているアニメーションへと遷移させておきます。

今回のサンプルでは複数のキャラクターの切り替えは必ず順番で行われるようにしていますが、普通のゲームであれば主人公と仲間の一人など特定の誰かと
操作を切り替えるだけなので操作キャラクターを切り替える場合にもっと単純なスクリプトで実現可能だと思います。

ChangeCharaのインスペクタに値を設定する

これでスクリプトが出来たのでChangeCharaのインスペクタでcharaのSizeを3にしEthanをElement0、Ethan2を1、Ethan3を2にドラッグ&ドロップします。

Unityの実行ボタンを押して確認してみましょう。

キャラクターの操作切り替えが一見うまくいったように見える

↑のように一見うまく出来たあああああああ!!

と思ったら大間違い、2人目のキャラクターを操作してジャンプしている間に3人目のキャラクターに切り替えた場合、
2人目のキャラクターのCharacterControllerとキャラクター移動スクリプトMoveTestを無効化している為に重力が働かず宙に浮いたままになってしまいます。

再度2人目まで操作キャラクターを戻せば重力は働きますが、それまでは重力を無視した超人!という状態が続きます。

ゲームでキャラクターがジャンプ出来なければ問題は出ませんが、なんとなく気持ち悪いので操作キャラクターがジャンプ中に別のキャラクターに切り替えても
前のキャラクターに重力が働くようにしたいと思います。

あとは、例えば操作中でないキャラクターも敵の攻撃を受けるようにしたい場合CharacterControllerのコライダやキャラクター操作スクリプトが必要になります。

なので無効化して操作キャラクターを変更している場合は根本から見直す必要が出てきてしまいます。

そこで、ChangeCharaスクリプトではCharacterControllerや移動スクリプトMoveTestコンポーネントを無効化していましたが、
そうではなくMoveTestスクリプト内でこのキャラクターが操作中であるかどうかのデータcontrollerフラグを作成し、操作中だけ移動の処理が出来るようにします。

操作していない時もCharacterControllerや操作スクリプトを無効化しないChangeChara2スクリプト

MoveTestのcontrollerフラグの設定はScriptに設置したChangeChara2という新しいスクリプトが行う事にします。

まずはScriptのChangeCharaのチェックを外すか削除してください。
その後に新しいスクリプトChangeChara2を作成し取りつけてください。

ChangeCharaとほとんど同じですが、ChangeChara2の場合はMoveTestスクリプトのChangeControll関数を引数を設定して呼び出しています。

MoveTestスクリプトに処理を記述していきます。

他の記事の内容の処理があるので多少見づらいです・・。

private var controll : boolean = true; // 現在コントロール出来るかどうか

キャラクターが操作中であるかどうかのcontrollを宣言し初期状態でtrueにしておきます。

移動の操作が行われるのはcontrollがtrueの時だけになるよう移動処理の部分を条件付きにしています。

ジャンプや攻撃といった処理も操作中のみ出来るようにします。

こうすることで操作中以外の時は重力が働き操作中に別キャラクターに切り替えても地面まで落下します。

CharacterControllerや移動スクリプトMoveTestの無効化はしていないので敵から攻撃を受けた時の処理も追加出来ます。

ChangeChara2のインスペクタの設定値

ChangeChara2のインスペクタは↑のようになります。

それではUnityの実行ボタンを押して確認してみましょう。

操作キャラクターの切り替え機能の完成版

↑のようにジャンプ中に操作キャラクターを切り替えてもちゃんと落下するようになりました。

これでUnityのゲームで操作キャラクターを切り替える機能が完成しました。

操作キャラクター自体が操作中かどうかという情報を持っているので処理が楽ですね。

キャラクターのモデルを変更し、キャラクターそれぞれは同じ操作スクリプトで制御しつつ、Animatorでアニメーションを変更したりするだけでそれぞれの動きをしてくれますから。

こういったところはオブジェクト指向言語のいい所ですね(^^)v