今回は人型キャラのアニメーションクリップをスクリプトで作成する方法を紹介したいと思います。
使い方としてはゲーム上で動くキャラを録画するのではなくモーションとしてアニメーションクリップにしたいだったり、モーションキャプチャーをゲーム上で行いそのデータでアニメーションクリップを作成したいなどを想定しています。
まず作成するにあたりクリップに必要な情報はなにか知る必要があります。
その情報とは
どのオブジェクトの何がどの時間にどんな値なのか
ということです。
たとえば1秒の手の動かすアニメーションでは
手(オブジェクト)のlocalPosition.x(何)が0秒(時間)に1(値)
手(オブジェクト)のlocalPosition.x(何)が1秒(時間)に2(値)
という情報があればlocalPosition.xをうごかすアニメーションに必要な情報は取得完了ということになります。ここではlocalPosition.xだけで例を出しましたが、他の値も動かしたいのであれば他の値もそれぞれ取得します。
上記の情報を格納するものを
AnimationCurve(アニメーションカーブ)といいます。
そしてこのアニメーションカーブのなかのどの時間にどんな値の部分を
keyframe(キーフレーム)といいます。
これをUnity上で見ると
こんなかんじで
赤枠がAnimationCurve(アニメーションカーブ)
青枠がkeyframe(キーフレーム)になります。
アニメーションカーブにキーフレームをどんどん足していくと一つの要素のアニメーションが完成します。
公式では
AnimationCurve 時間の経過をとおして評価される Keyframes の集合を保存します。
keyframe アニメーションカーブでの単一のキーフレームです。
図があるとなるほどとなりますよね。
ということで知識が充実してきたところでスクリプトの例を出して終わりたいと思います。
詳しい情報はスクリプトに書きますね。
スクリプト作成
今回のスクリプトでは適当な値で1秒のアニメーションを作っています。
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class animetest : MonoBehaviour
{
private AnimationClip _clip;
private Animator _animator;
[SerializeField]
private Transform _unitychan;
private Transform _leftHand;
private string _path;
private AnimationCurve handPosXCurve;
private AnimationCurve handPosYCurve;
private List<Keyframe> keyframesPosX;
private List<Keyframe> keyframesPosY;
void Start()
{
_animator = _unitychan.GetComponent<Animator>();
_leftHand = _animator.GetBoneTransform(HumanBodyBones.LeftHand);
_path = FindPath();
handPosXCurve = new AnimationCurve();
handPosYCurve = new AnimationCurve();
SetKeyframes();
AddKeyframe();
FindPath();
SetAnimationCurve();
ClipSave();
}
private void SetKeyframes()
{
keyframesPosX.Add(new Keyframe(0, 0));
keyframesPosX.Add(new Keyframe(1, 1));
keyframesPosY.Add(new Keyframe(0, 2));
keyframesPosY.Add(new Keyframe(1, 3));
}
private void AddKeyframe()
{
for (var i = 0; i < keyframesPosX.Count; i++)
{
handPosXCurve.AddKey(keyframesPosX[i]);
}
for (var i = 0; i < keyframesPosY.Count; i++)
{
handPosYCurve.AddKey(keyframesPosY[i]);
}
}
private string FindPath()
{
string objectPath = _leftHand.name;
Transform parent = _leftHand.parent;
while (parent != null)
{
objectPath = parent.name + "/" + objectPath;
parent = parent.parent;
}
return objectPath;
}
private void SetAnimationCurve()
{
_clip.SetCurve(_path, typeof(Transform), "localPosition.x", handPosXCurve);
_clip.SetCurve(_path, typeof(Transform), "localPosition.y", handPosYCurve);
}
private void ClipSave()
{
AssetDatabase.CreateAsset(_clip, "Assets/CreateAnime");
AssetDatabase.Refresh();
}
}
間違っていたらすいません。たぶんなんかわすれたけど最後にないかつけないと滑らかに動かないような気が・・・
一応確認のためにクリップをほぞんできるようにしています。エディター上でだけですけどね。
今回は左手を動かすというパターンを作りましたが、これを基盤につくれば全身でできます。またキーフレームも最低限しか用意していませんがたくさんつくるといい感じになります。
モーションキャプチャー中にキーフレームを作成しまくって、これでくりっぷを作成するとすばらしいアニメーションが出来ることでしょう。