裏鍵.dump

自分用備忘録。内容に脈絡を求めてはいけない。

MagicaVoxel→Blender→Unityでボクセルモデルを動かす⑥(終)

MagicaVoxelで作ったボクセルにBlenderでアニメーションをつけてUnityで動かそう、の6回目。

 

使用するツール

・MagicaVoxel 0.97.4

Blender 2.74

・Unity 5.3.4f1

 

前回はBlenderでボクセルモデルに対して歩く、待機の2つのアニメーションを作成した。

今回はそれをUnityに取り込んで動かす、最終回となる。

もうちょっとなので頑張ろう。

 

・Unityへインポート

Blenderで作成したものをUnityに取り込む。

以前は一旦Blenderでfbxファイルにエクスポートする必要があったのだが、なんと最近のバージョンではBlenderのファイルを直接取り込めるようになっている。すごい。

 

とりあえず今回の作業用に空の3Dプロジェクトを作成した。

見慣れたインターフェイスにどことなく安心感が・・・。

f:id:cores0316:20160727102932p:plain

 

Projectビューにblendファイルを直接放り込んでやろう。

すると下記のようになる。

f:id:cores0316:20160727103228p:plain

emilyの右矢印をクリックして展開すると、いくつか知らないものもあるが作成したアニメーションが格納されているのが見える。

f:id:cores0316:20160727110805p:plain

 

 ここで、アニメーションに少し手を加えないといけないのでemilyを選択してInspectorビューに表示されたAnimationsボタンをクリックする。

f:id:cores0316:20160727142455p:plain

真ん中辺りに表示されているClipsに作成したアニメーションの一覧が表示されているので、Walkを選択する。

すると、下にWalkの詳細が表示されるので、「Loop Time」のチェックボックスにチェックを入れておこう。

その後、下にスクロールしてApplyボタンを押す。

f:id:cores0316:20160727142946p:plain

これで歩くアニメーションをループ再生できるようになる。

 

 

3D空間にCubeで床を作って、emilyをHierarchyビューに置いてみた。

親オブジェクトはAnimatorを持っているただのGameObjectのようだ。

ただし、Animation Controllerが割り当てられていない。

f:id:cores0316:20160727111704p:plain

 

モデルやアニメーションに必要なものは子オブジェクトとして紐付いている。

f:id:cores0316:20160727111939p:plain

f:id:cores0316:20160727112109p:plain

 

 

・ボクセルモデルのテクスチャを設定

とりあえず真っ白なのが味気ないので、テクスチャを貼って見慣れた姿にする。

blendファイルの中には存在しないみたいなので、MagicaVoxelでエクスポートしたときに出力されたpngファイルをUnityに取り込む。

 

Texturesフォルダを新たに作成し、pngファイルを取り込んだ。

f:id:cores0316:20160727113258p:plain

 

blendファイルをインポートしたときに作成されたMaterialsフォルダを開いて、中に入っているマテリアルを選択する。

右に表示されたInspectorビューの赤枠をクリックして、先ほど取り込んだpngファイルを選択しよう。

f:id:cores0316:20160727113919p:plain

 

このマテリアルは子オブジェクト(Emily)に設定されているので、それが反映されてテクスチャが表示される。

これでOK。

f:id:cores0316:20160727114223p:plain

 

 

・Animation Controllerの設定

次にAnimation Controllerを作成する。

AnimationControllerフォルダを作成し、その中にEmilyAnimというAnimation Controllerを作成した。

f:id:cores0316:20160727115043p:plain

EmilyAnimを選択した状態でAnimatorビューを開き、Animatorタブを掴んで別枠に表示させる。下の絵はAnimatorビューを右側に持っていった場合。

f:id:cores0316:20160727115602p:plain

Projectビューの方で取り込んだBlenderファイルを展開し、中に入っている「Idle」と「Walk」をAnimatorビューの方にD&Dする。

Animatorビューが下記の図のようになっていればOK。

f:id:cores0316:20160727120055p:plain

もしWalkの方を先にD&Dした場合には、Walkの方がオレンジになっているかもしれない。その場合はIdleを選択して右クリックし、「Set as Layer Default State」を選択すればいい。

 

別枠に表示していたAnimatorビューはProjectビューと同じ枠に戻しておこう。

 

引き続きAnimatorビューで、Transitionを作成する。

Idleを選択して右クリックし、「Make Transition」を選択する。

矢印の先を選ぶようになるので、Walkを指定する。

同じように、WalkからMake TransitionでIdleを指定する。

下記のようになる。

f:id:cores0316:20160727120851p:plain

 

次に、左側の「List is Empty」と書いてある右上の+ボタンを押して、Bool型のアニメーションパラメータを追加する。

f:id:cores0316:20160727121526p:plain

walkFlagという名前にした。

f:id:cores0316:20160727121746p:plain

 

現在、アニメーションは基本姿勢のIdle(棒立ち状態)から動かないようになっているので、先ほど追加したwalkFlagを使用してwalkFlagがtrueのときにIdleからWalkへ、falseのときにWalkからIdleへ遷移するように条件を設定する。

 

IdleからWalkに伸びているTransitionを選択すると、右側のInspectorビューに詳細が表示される。

Conditionsの下にある+をクリックすると、IdleからWalkに遷移する条件を決めることが出来る。今回は最初に表示された「walkFlagがtrueのとき」のままでよいので、これでOK。

f:id:cores0316:20160727122939p:plain

 

次に、WalkからIdleに伸びているTransitionを選択して、同じようにConditionsを追加する。こちらは「walkFlagがfalseのとき」に遷移したいので、右側をfalseにしておく。

f:id:cores0316:20160727123317p:plain

ここではもう一つ、ついでに修正しておきたいことがある。

真ん中に表示されているSettingsのところで、WalkからIdleへの移り方が示されているのだが、今のままだとどんな動きになるかというと、「walkFlagがfalseになってから1秒ちょっと経過した頃に直立に戻る」という感じになる。

イメージとしては、プレイヤーがキー入力をやめても1秒ちょっとは手足をばたばたさせる感じになる。これはいかん。

 

下のIdleをドラッグして左の方へ持って行き、移り変わりの範囲も左の方に設定する。

上の「Has Exit Time」のチェックも外す。

f:id:cores0316:20160727125417p:plain

これですぐにIdleへ移るようになる。

 

ここまでの作業が終わったら、Hierarchyのemilyを選択してInspectorビューに表示されたAnimatorにEmilyAnimをアタッチする。

f:id:cores0316:20160727130607p:plain

 

 

・ボクセルモデルを動かす

アニメーションさせるための準備は整った。

emilyにCharacter Controllerを追加し、動かすためのスクリプトを作成する。

 

まず、Character Controllerの追加から。

Add ComponentからPhysics→Character Controllerで追加する。

追加したらコライダーを適当に真ん中に来るように調整する。

f:id:cores0316:20160727132643p:plain

 

次にスクリプトの作成。

新たにScriptsフォルダを作成して、その中にEmilyController.csを作成する。

f:id:cores0316:20160727133010p:plain

スクリプトの内容は以下の通り。

// スクリプトここから

using UnityEngine;
using System.Collections;

public class EmilyController : MonoBehaviour {

    CharacterController controller;
    Animator animator;

    Vector3 moveDirection = Vector3.zero; // 移動方向計算用
    float gravity = 9.8f;                 // 重力
    float speedZ = 3.0f;                  // 進行方向の速度

    // Use this for initialization
    void Start () {

        // 必要なコンポーネントを取得
        controller = GetComponent<CharacterController>();
        animator = GetComponent<Animator>();
    }
    
    // Update is called once per frame
    void Update () {

        // Inputを検知して前に進める
        if (Input.GetAxis("Vertical") > 0.0f)
        {
            moveDirection.z = Input.GetAxis("Vertical") * speedZ;
        }
        else
        {
            moveDirection.z = 0;
        }

        // 方向転換
        transform.Rotate(0, Input.GetAxis("Horizontal") * 3, 0);

        // 重力分の力を毎フレーム追加
        moveDirection.y -= gravity * Time.deltaTime;

        
        // 移動実行
        Vector3 globalDirection = transform.TransformDirection(moveDirection);
        controller.Move(globalDirection * Time.deltaTime);

        // 移動後接地していたらY方向の速度はリセット
        if (controller.isGrounded) moveDirection.y = 0.0f;


        // 速度が0以上なら歩きフラグをtrueにする
        animator.SetBool("walkFlag", moveDirection.z > 0.0f);

    }
}

// スクリプトここまで

 

簡単に説明すると、上入力でモデルが向いている方向に移動し、左右入力で向きが変わる。ジャンプは無いけど一応自由落下するようにしている。

そして、上入力があるときはアニメーションを切り替えるwalkFlagがtrueになり、歩くアニメーションが再生される、というもの。

スクリプトを保存したら、emilyにアタッチする。

f:id:cores0316:20160727141033p:plain

 

 

早速実行してみよう。

f:id:cores0316:20160727144028g:plain

う、動いた・・・!

ちゃんと歩くモーションもループ再生されている。

 

 

というわけで、想定していたよりも非常に長くなってしまったが目的達成である。

最後まで見てくれた人も本当にお疲れ様でした。

できるだけ間違いのないよう気をつけたつもりだけども、誤りやわかりにくいところがあったときはごめんなさい。

挑戦してみようと考えている人や同じようなところで躓いている人の参考になれば幸い。

 

多分もっと効率が良かったり正しいやり方というのがあるのだろうけど、それはまたやる気が溜まったときに調べてみよう。