Unityでhd2d(3d背景で2dキャラクターを動かせる方式)備忘録その2ー2Dキャラクターを3D平面上で動かす

要するにペーパーマリオとかオクトパストラベラーしたい!って人向け

参考動画

以下2つのYoutube動画を参考に作成した。

「TOP DOWN MOVEMENT in Unity!」…よく見る2Dマップ上で2Dキャラを動かすためのアニメーション設定について詳しく解説してある。


「Paper Mario Style 2.5D Movement in Unity (Tutorial)」…ペーパーマリオ寄り。正面に進むグラフィックと左右に進むグラフィックが同一であったり、左右切り替え時に画像が紙のように回るエフェクトが追加されている。ジャンプ時の挙動もかわいい。


どちらも英語だが自動翻訳があれば(なんならなくても)十分。
よりペーパーマリオのような動きに近い方がよければ「Paper Mario Style 2.5D Movement in Unity (Tutorial)」の説明と同じように設定すればい。

ここでは、「前後左右に進むアニメーション設定を行った2Dイラスト」を3Dマップ上で動かすために、どのような設定を行ったのかについて記録する。

注意

ここで紹介したスクリプトでのキャラクターの動きは、カメラ基準ではなくグローバル座標基準になっている。
したがって、カメラの向きを変えると前に進ませたいのに後ろに行ってしまう、という状態になってしまう。
対策を現在調査中(3Dキャラクターの例はたくさん見つかったが、2Dキャラクターを動かす場合の例が見つかっていない)。

平面の準備

まずはキャラクターを歩かせる平面を準備。

キャラクターの動きが分かればなんでもいい。

歩行グラフィック素材の準備

自前のものがある人はそれで。なければフリー素材を配布しているサイトからダウンロードしてくる。
今回は上下左右の動き、idle状態等も作れそうな以下の素材をダウンロードしてきた。

「やさぐれひよこ素材」置き場さん
スプライトシートフルパックがよさそう。

歩行グラフィック素材の分割処理

早速Unityに読み込む。
エクスプローラーから直にゲームプロジェクト内のアセットフォルダに入れた。
(場所は C://Users/ユーザー名/プロジェクト名/Assets という感じの人が多いかな)

これを一枚一枚分ける作業をUnityにやってもらう。
この画像を選択し、Inspectorを表示させる。

以下のように設定を行う。

項目名
Texture Type Sprite(2D and UI)
Sprite Mode Multiple
Pixels Per Unit 手持ちの画像に合わせる※
Mesh Type Full Rect
Compression None

※今回のやさぐれひよこは、32×32ピクセルのアニメーション画像が18パターンある。1つのアニメーション画像あたり何ピクセルかを聞かれているので、この場合は32を入力する。
ドット絵素材を利用する場合は、Filter Modeを「Point(no filter)にするといい。

ここまで入力したら、右下にあるApplyを押し、続いてInspector上にあるSprite Editorを押す。

このような画像が現れるので、左上のSliceを押す。
AutomaticのままSliceを押してうまくいくパターンもあるけど、ない場合はGrid by Cell Size等からピクセル数を入力して良しなに分割してもらう。

Sliceを押したあと、歩行グラフィックデータの隣に右矢印マークが出ている。
これを押すと分割された歩行グラフィックデータを一覧で確認できる。

キャラクターをシーンに入れる

キャラクター画像をシーンに入れる。

まずHierarchy上の空欄を右クリックして、空オブジェクトを作成する。これに分かりやすいように何か名前(ここではPlayer)を付ける。

続いて先ほど分割した歩行グラフィックデータから、適当な1枚を選んでHierarchyに追加する。これにも何か名前を付ける(ここではSprite)。

ここで、SpriteをPlayerの子オブジェクトとする。
位置調整は後程行うが、より扱いやすいように、PlayerとSpriteのTransformの値を右クリックしてリセットする。

キャラクターを物理的に扱えるようにする

単純にRigidBodyとColliderを追加するだけ。

追加するのは空オブジェクトであるPlayerの方。
PlayerのInspectorから、Add Componentを選択し、
RigidBodyCapsule Colliderを追加する。

ここでPlayerの位置調整をInspectorのTransform等から行い、下図のようにする。
Spriteは勝手についてくるのでいじらなくていい。

RigidBody,Collider共に大きさを歩行グラフィックに合わせる。
また、RigidBodyのFreeze Rotationのx,y,zすべてにチェックを入れる。

スクリプト作成

キャラクターを歩行させるためのスクリプトを組む。
Unityの適当なフォルダに「Script」フォルダを作成し、新規C#ファイルを作成した。スクリプト名は「PlayerMovement」とした。
冒頭の参考動画で紹介されていたものとほとんど同じ構成だが、3Dマップに適応させるために一部改変した。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{

    public float moveSpeed =5f;
    //RigidbodyをtheRBと定義
    public Rigidbody theRB;
    public Animator animator;
    Vector3 movement;

    // Update is called once per frame
    void Update()
    {
        //x軸の移動はHorizontal(左右方向キー等)から取得する
        movement.x = Input.GetAxisRaw("Horizontal");
        //z軸の移動はVertical(上下方向キー等)から取得する
        movement.z = Input.GetAxisRaw("Vertical");

        animator.SetFloat("Horizontal", movement.x);
        animator.SetFloat("Vertical", movement.z);
        //移動速度決定フロー。sqrMagnitudeは距離計算に使用されるらしい
        animator.SetFloat("Speed", movement.sqrMagnitude);
    }
    void FixedUpdate()
    {
        //theRBの移動後の位置を決定するための式
        theRB.MovePosition(theRB.position + movement * moveSpeed * Time.fixedDeltaTime);

    }
}

ここまで書いたら保存し、Unityに戻る。作ったスクリプトをPlayerに追加する。

こうなればOK。

theRBにPlayerを追加。Speedはデフォルトで5になっているがお好みで変えて、実際に動かしてみる。
アニメーションはしないものの(エラーが出てると思うがここでは気にしなくてよし)、無事に動けば成功。

各アニメーションの作成

前後左右に移動している際のアニメーションパターンを作る。
Unity上部メニューWindow → Animation → Animationを選択し、アニメーションタブを出現させる。

Createボタンを押すと、何やら保存しろと言われるので作業しやすいフォルダ(例えば歩行グラフィックと同じフォルダ)に「Walk_down」と名付けて保存する。

先ほど分割した歩行グラフィックデータの中から、正面向きに歩く画像をドラッグ&ドロップでAnimationタブのタイムラインに並べる。

あくまで例。本当にお好みでいい。

ここで一度SpriteのInspector内「Sprite Rendeler」のチェックを外し、Hierarchy上のPlayerをクリックした後に、Animationタブの再生ボタンを押すと、アニメーション挙動がシーン上で確認できる。
チェックは後で戻すのを忘れずに。

他のアニメーションに関しても同様に作成する。
Animationタブ内のWalk_downをクリックし、Create New Clipという選択肢を選ぶ。
Walk_up,Walk_right,Walk_left,Idle等の名前を付けてアニメーションを作成する。

アニメーター設定

アニメーション設定時に自動的に作成されたアニメーターファイルがあると思うので、それをダブルクリックする。

上図でいう「Player」。

Animatorタブが開くので、ここで編集を行う。
自動で作成された、アニメーションの名前が付いたState(オレンジと灰色のやつ)は使わないので削除する。

空白右クリック → Create State → Emptyにより、新たなStateを作成する。名前を「Idle」とし、InspectorのMotionに先ほど作った「Idle」用アニメーションを設定する。

続いて、Animatorタブ内のParametersタブを選択し、+ボタン → Floatを選択する。これを3回繰り返し、それぞれ

  • Horizontal
  • Vertical
  • Speed

と名付ける。

できたら、Animatorタブ内の空白で右クリック → Create State → From New BlendTreeを選択する。出てきたものをダブルクリックする。


こういうのが出てくると思うので、これをさらにクリックしてInspectorを表示させる。

項目名
BlendType 2D Simple Directional
Parameters Horizontal,Vertical

と設定できたら、右下の+マークからAdd Motion Fieldを4回押す
設定は下図のように行う。アニメーション名は自分で作ったものに合わせよう。

ここまでできたらAnimatorタブのBaseLayerに戻り、
Idleを右クリック → Make Transition → 作ったBlendTreeにつなげる
出てきた矢印をさらにクリックし、

項目名
Has Exit Time チェックを外す
Transition Durations 0

とする。
加えて、Conditionsの右下の+マークを選択し、Speed/Grater/0.01と設定する。

同様に、作ったBlendTreeからもIdleに矢印を繋げて、同じ設定を行う。
ただし、ConditionsについてはSpeed/Less/0.01とする。

アニメーションの適用

ここまでできたらシーンに戻り、
SpriteにAnimatorコンポーネントを追加する。
Controller欄に、先ほど作成したアニメーターファイルを追加する。

続いて、Playerのスクリプトコンポーネント上のAnimator欄で、Sprite(Animator)を選択する
もしかしたら自動でAnimatorコンポーネントがPlayerオブジェクトに追加されているかもしれないが、これは消していい。

完成

カメラ等もろもろ見やすいように設定したら動かしてみる。
ちゃんとアニメーションできていたらOK。平面でやってみたが、Terreinでも動かせる。