ゴマちゃんフロンティア

気まぐれと勢いで作るUnityゲーム開発日記です

【Unity】CharacterMotor使用時のキャラクター移動を2Dに限定する

time 2016/09/18

というわけで、今回の目標はタイトル通り「CharacterMotor 使用時のキャラクター移動を2Dに限定する」です!

shot2ss20160918121015592

「3Dベースで局所的に2D」は前に一度チャレンジしましたが、キャラクターの移動や敵の行動、オブジェクトの動きなどを全て2D向けに合わせなければなりません。
Unityには2Dモードもありますが、あれは本当に真横から見たドット絵のゲームを作るのに適したもので、3Dゲームで局所的に2Dっぽくするには向かない気がします。
元々3Dを想定して作っていたので、プレイヤーの移動関連はコンポーネントに丸投げで、当たり判定も CharacterController のコライダーをそのまま使っている状態です。

何故こんなことをしたいかと言うと、「場面に応じて2Dと3Dを切り替えたいから」です。
全エリア自由に3次元移動ができる場合でも、カメラワークとステージ構成次第で「2Dっぽいステージ」は出来ますが、画面の手前・奥にどれだけ移動させるかを制御するのが大変です。
所謂「見えない壁」を設置するのが手っ取り早い方法ですが、「行けそうなのに行けない」というのは私的に嫌いな要素です。
それなら特定のエリアだけ2Dにしてしまいたいと言うわけです。

前置きが長くなりましたが、今回はとりあえず自キャラクターの移動制御を2Dに限定させれるようにしてみました!
当たり判定自体は3Dであること、3Dモードにもスイッチできるようにしたいことから、CharacterController + CharacterMotor + PlatformInputController が付いた状態でやります。

移動入力を2D方向へ限定させる方法

CharacterMotorはソースコードが公開されており、C#版を作っている方もいたので、どんな処理をやっているか確認できます。
相応に複雑なので簡単なことではありませんが・・・。

http://forum.unity3d.com/threads/charactermotor-fpsinputcontroller-platforminputcontroller-in-c.64378/

本来は外部的なコンポーネントには手を加えたくないところです。
が、CharacterMotor を Player クラス側からあれこれしても上手くいかないので、(なるべく) 元の動きを崩さないように修正するしかありませんでした。
今回は上記のC#版をインポートして作っているため、既存スクリプトとの重複やメンバのアクセスレベルに注意する必要がありました。
特に「アクセス修飾子が省略されていてprotected扱い」というものが多かったです。

実際にキャラクター移動している部分は UpdateFunction() になります。
その中で「Move our character!」とド直球なコメントが書いてあるあたりを修正します。

// Move our character!
currentMovementOffset.z = 0;
movement.collisionFlags = controller.Move(currentMovementOffset);

「currentMovementOffset」の分だけ CharacterController.Move() で動かしているようなので、その手前でZ軸を0にしてしまいます。

また、上記コードのちょっと上に MovingPlatform に関する処理が書いてあります。
ステージ上に動く足場がなければ問題ありませんが、こちらもZ軸を0にしておきます。

 
moveDistance.z = 0;
if (moveDistance != Vector3.zero)
    controller.Move(moveDistance);

どうでもいい話ですが、ブロックのないif文って個人的に嫌いなんですよね。
ちょっとした処理だとしてもブロック付けてインデントして・・・が見やすいです。

これで移動に関しては2Dっぽくなります!
雰囲気でいえば「スマブラ」や「ロックマンX8」あたりに近いです。

ただし現状では CharacterMotor を直接書き換えた関係上、3Dで動きたいときでも2D方向に限定されてしまいます。
適当にフラグを1つ持たせて制御するのが手っ取り早そうです。

 
// Move our character!
if (invalidMoveZ) {
    currentMovementOffset.z = 0;
}
movement.collisionFlags = controller.Move(currentMovementOffset);

invalidMoveZ というフィールドを定義し、制御してみました!
あとは Player クラスから CharacterMotor を GetComponent() して切り替えたりすれば、移動に関しては問題なさそうですね。

回転方向を2D方向に限定させる方法

現状では PlatformInputController が入力方向にキャラクターを回転させてしまいます。
つまり移動方向は2D限定なのにZ軸 (手前や奥) に振り向くことができます。

空間は3D・移動は2Dのゲームで左右に振り向く際、回転を入れずに瞬時に振り向いているゲームが多い気がします。
2D限定なら手前や奥にキャラクターを向ける必要もないので、当然といえば当然ではあります。
リアリティなんて要らないので、自分もこの方法を取り入れてみました。

ということで、PlatformInputController をいじってみます。
まずは入力方向に一瞬で振り向くようにするため、ConstantSlerp() を修正します。

Vector3 ConstantSlerp(Vector3 from, Vector3 to, float angle)
{
    float value = Mathf.Min(1, angle / Vector3.Angle(from, to));

    if (invalidRotateZ) {
        value = 1;
    }

    return Vector3.Slerp(from, to, value);
}

CharacterMotor と同じように、invalidRotateZ というフィールドを定義して制御します。
Vector3.Slerp() で入力方向に振り向く際の角度を補完しているようなので、第3引数に1を指定すれば瞬時に向き直すようになります。

もう1つ、Z軸に向かないようにするための修正を加えます。
コメント「Set rotation to the move direction」のあたりです。

// Set rotation to the move direction   
if (autoRotate && directionVector.sqrMagnitude > 0.01)
{
    Vector3 newForward = ConstantSlerp(transform.forward, directionVector, maxRotationSpeed * Time.deltaTime);
    newForward = ProjectOntoPlane(newForward, transform.up);

    if (invalidRotateZ) {
        newForward.z = 0;
    }

    if (newForward != Vector3.zero) {
        transform.rotation = Quaternion.LookRotation(newForward, transform.up);
    }
}

newForward が振り向く方向のようなので、これのZ軸を0にすればOKです。
ただしこれだと零ベクトルが渡された場合に奥を向いてしまう上、Unity から警告が出たりしてしまいます。
なので、零ベクトルだったらそもそも LookRotation() を実行しないようにしました。

20160910

これで移動も回転も2Dに限定にすることができました。
GIFアニメーションでは分かりませんが、Z軸に移動入力しても移動・回転が行われていません。

まとめ

そんなわけで、CharacterMotor 使用時の移動方向を2Dに限定させてみました!
キャラクターの動き的にはだいぶ近づいた気がします。

ただし敵は自在に3Dで動いていたりするので、ゲーム的な意味で2Dにするのはなかなか大変ですね。
とはいえ、敵やオブジェクトは RigidBody の Constraint である程度制御できるので、プレイヤーキャラクターの制御よりは楽かもしれません。
今度また挑戦してみます!

今日のイラスト

本ブログのマスコット (?) のシルリスを描いてみました。
メインキャラ3匹のデザインを一新するため、シルリスも新しいデザインを考えているところです。

また、線画でペンタブを使う練習も兼ねていたりします。
パスツールで書くより難しいですが、機械的ではない線が描けるため味が出ます。
ただ影の描き方がだいぶ適当な気もします・・・。

shilriss7

スポンサーリンク

down

コメントする



ツイッター