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プロジェクトを作成した。
見慣れたインターフェイスにどことなく安心感が・・・。
Projectビューにblendファイルを直接放り込んでやろう。
すると下記のようになる。
emilyの右矢印をクリックして展開すると、いくつか知らないものもあるが作成したアニメーションが格納されているのが見える。
ここで、アニメーションに少し手を加えないといけないのでemilyを選択してInspectorビューに表示されたAnimationsボタンをクリックする。
真ん中辺りに表示されているClipsに作成したアニメーションの一覧が表示されているので、Walkを選択する。
すると、下にWalkの詳細が表示されるので、「Loop Time」のチェックボックスにチェックを入れておこう。
その後、下にスクロールしてApplyボタンを押す。
これで歩くアニメーションをループ再生できるようになる。
3D空間にCubeで床を作って、emilyをHierarchyビューに置いてみた。
親オブジェクトはAnimatorを持っているただのGameObjectのようだ。
ただし、Animation Controllerが割り当てられていない。
モデルやアニメーションに必要なものは子オブジェクトとして紐付いている。
・ボクセルモデルのテクスチャを設定
とりあえず真っ白なのが味気ないので、テクスチャを貼って見慣れた姿にする。
blendファイルの中には存在しないみたいなので、MagicaVoxelでエクスポートしたときに出力されたpngファイルをUnityに取り込む。
Texturesフォルダを新たに作成し、pngファイルを取り込んだ。
blendファイルをインポートしたときに作成されたMaterialsフォルダを開いて、中に入っているマテリアルを選択する。
右に表示されたInspectorビューの赤枠をクリックして、先ほど取り込んだpngファイルを選択しよう。
このマテリアルは子オブジェクト(Emily)に設定されているので、それが反映されてテクスチャが表示される。
これでOK。
・Animation Controllerの設定
次にAnimation Controllerを作成する。
AnimationControllerフォルダを作成し、その中にEmilyAnimというAnimation Controllerを作成した。
EmilyAnimを選択した状態でAnimatorビューを開き、Animatorタブを掴んで別枠に表示させる。下の絵はAnimatorビューを右側に持っていった場合。
Projectビューの方で取り込んだBlenderファイルを展開し、中に入っている「Idle」と「Walk」をAnimatorビューの方にD&Dする。
Animatorビューが下記の図のようになっていればOK。
もしWalkの方を先にD&Dした場合には、Walkの方がオレンジになっているかもしれない。その場合はIdleを選択して右クリックし、「Set as Layer Default State」を選択すればいい。
別枠に表示していたAnimatorビューはProjectビューと同じ枠に戻しておこう。
引き続きAnimatorビューで、Transitionを作成する。
Idleを選択して右クリックし、「Make Transition」を選択する。
矢印の先を選ぶようになるので、Walkを指定する。
同じように、WalkからMake TransitionでIdleを指定する。
下記のようになる。
次に、左側の「List is Empty」と書いてある右上の+ボタンを押して、Bool型のアニメーションパラメータを追加する。
walkFlagという名前にした。
現在、アニメーションは基本姿勢のIdle(棒立ち状態)から動かないようになっているので、先ほど追加したwalkFlagを使用してwalkFlagがtrueのときにIdleからWalkへ、falseのときにWalkからIdleへ遷移するように条件を設定する。
IdleからWalkに伸びているTransitionを選択すると、右側のInspectorビューに詳細が表示される。
Conditionsの下にある+をクリックすると、IdleからWalkに遷移する条件を決めることが出来る。今回は最初に表示された「walkFlagがtrueのとき」のままでよいので、これでOK。
次に、WalkからIdleに伸びているTransitionを選択して、同じようにConditionsを追加する。こちらは「walkFlagがfalseのとき」に遷移したいので、右側をfalseにしておく。
ここではもう一つ、ついでに修正しておきたいことがある。
真ん中に表示されているSettingsのところで、WalkからIdleへの移り方が示されているのだが、今のままだとどんな動きになるかというと、「walkFlagがfalseになってから1秒ちょっと経過した頃に直立に戻る」という感じになる。
イメージとしては、プレイヤーがキー入力をやめても1秒ちょっとは手足をばたばたさせる感じになる。これはいかん。
下のIdleをドラッグして左の方へ持って行き、移り変わりの範囲も左の方に設定する。
上の「Has Exit Time」のチェックも外す。
これですぐにIdleへ移るようになる。
ここまでの作業が終わったら、Hierarchyのemilyを選択してInspectorビューに表示されたAnimatorにEmilyAnimをアタッチする。
・ボクセルモデルを動かす
アニメーションさせるための準備は整った。
emilyにCharacter Controllerを追加し、動かすためのスクリプトを作成する。
まず、Character Controllerの追加から。
Add ComponentからPhysics→Character Controllerで追加する。
追加したらコライダーを適当に真ん中に来るように調整する。
次にスクリプトの作成。
新たにScriptsフォルダを作成して、その中にEmilyController.csを作成する。
スクリプトの内容は以下の通り。
// スクリプトここから
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にアタッチする。
早速実行してみよう。
う、動いた・・・!
ちゃんと歩くモーションもループ再生されている。
というわけで、想定していたよりも非常に長くなってしまったが目的達成である。
最後まで見てくれた人も本当にお疲れ様でした。
できるだけ間違いのないよう気をつけたつもりだけども、誤りやわかりにくいところがあったときはごめんなさい。
挑戦してみようと考えている人や同じようなところで躓いている人の参考になれば幸い。
多分もっと効率が良かったり正しいやり方というのがあるのだろうけど、それはまたやる気が溜まったときに調べてみよう。