はじめに
UnityにはHumanoidという、骨構造を人間として認識させる機能がある。キャラクタのskinデータ1つと、複数のモーションデータを使って、任意のキー入力で切り替える方法についてまとめた。
使用するデータはFBXフォーマットで、Mixamoを使って生成したものである。
なお、アクションゲームのような動きをさせたいのであれば、Mecanim, Third person assetなどを使ったほうがいいとおもうが、これらを使った方法は別稿にする。
環境
Unity 2021.3.10f1
下準備
mixamoで、passive_marker_manモデルを使い、以下のFBXデータを得る。
保存Formatは「FBX for Unity」とする。
motion type | Skin |
---|---|
T-Pose | With Skin |
Standard Walk | Without Skin |
Standard Run | Without Skin |
Run To Stop | Without Skin |
Right Turn | Without Skin |
Left Turn | Without Skin |
Idle | Without Skin |
以下の操作をする。
・Unityのプロジェクトを作り、Assetsに適当なフォルダを作り、さきほどのFBXファイルをいれる。
・新たに、Animator ControllerをAssets内に作成し、ダブルクリックし、Animatorタブを表示する。(ファイル名は初期のままで進める)
・新規にPlaneを作成する。(必須ではない)
asset内のT-Poseのモデルを選択し、RigタブAnimation TypeをHumanoidに変更し、Applyする。
同様の操作をすべてのFBXファイルについて、行う。
骨のデータ、アニメーションデータに加えて、Avatorが追加されているのを確認する。
Skinの含まれるT-PoseのFBXファイルを選択し、MaterialsタブのExtract Texturesを選択し、FBXに埋め込まれているテクスチャを書き出す。
Sceneへの配置
assetからSceneへT-Poseを配置する。
Hierarchy内のT-Poseのモデルを選択し、InspectorのAnimatorのControllerのボックスに、asset内に作成済みのAnimator ControllerをD&Dする。
Animatorウィンドウ内に、Without SkinのFBXデータ(idleなど)をD&Dする。(含まれるアニメションデータのみが入る)
一旦、プロジェクトを再生して、モーションが適用されていることを確認する。
モーションさせ続けたいなら、該当データの「Loop Time」のチェックを入れる。
アニメーションの切り替え
キーボード入力でアニメーションを切り替える方法
Animatorウィンドウで以下の追加をする。
・Parametersタブの+記号からintを選択し、motionという名前で追加する。
・本稿で最初に追加したAssetからidle, walk, run, rightTrun, leftTrunを追加する。
・idleに関しては、set as layer default stateに設定する。
・その他のモーションに関しては、Make Trasitionで矢印を図のようにつなぐ。
モーションwalkへと繋がる矢印をクリックし、以下の設定をする。
・Has Exit Timeのチェックをオフにする。
・Conditionsにmotion, Equals, 1にする。
同様に、モーションrunに関して、以下の設定をする。
・Has Exit Timeのチェックをオフにする。
・Conditionsにmotion, Equals, 2にする。
以下同様に、
rightTrunでは、3
leftTurnでは、4
を設定する。
これで、プログラムのほうでmotionの値を変更すれば、アニメーションが切り替わる仕組みができた。
新規にC#のスクリプトを作成し(ファイル名はデフォルトのままとした)、Hierarchy内のキャラクタにD&Dで割り当てる。inspector内の一番下に追加されているのを確認する。
ソースコードの例は以下。
asdfキーを押すと、motionの値が1,2,3,4になり、アニメーションが再生される。毎フレームmotionを0に戻しているが、アニメーションは1ループ再生されるようだ。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public Animator anim;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
anim.SetInteger("motion", 0);//reset
if (Input.GetKeyDown("a"))
{
anim.SetInteger("motion", 1);
}
if (Input.GetKeyDown("s"))
{
anim.SetInteger("motion", 2);
}
if (Input.GetKeyDown("d"))
{
anim.SetInteger("motion", 3);
}
if (Input.GetKeyDown("f"))
{
anim.SetInteger("motion", 4);
}
}
}
BlendTreeで切り替える方法
検討中。