複数のアニメーションを付ける

提供: socialakiba wiki
移動: 案内検索

ポーズをつけてキーフレームを打つ作業

Mannx3.blend.png

メッシュはObjectモードにする。 表示はテクスチャに。

アーマチャ(ボーン)はPoseモードにする。 Armature のプロパティで X-Ray にチェックする(作業しやすい)。

フレーム数は1から30くらいにする(長いとめんどうなので)。

Mannx3.blend2.png

Default を Animation に。

左側に Dope Sheet と F-Curve というパネルが出る。

Mannx3.blend3.png

一番下の赤丸の右隣を Rotation にしておく。 これはキーを回転だけに打つという意味。 自動でキーを打てるがやめておいたほうがいい。

1フレーム目に移動して、 念のためにすべてのボーンにキーを打っといたほうがよい。 Armature を Poseモードで全選択(Aキー)したあと、Iキー(キーを打つ)。

フレームを動かしながら、 個別にボーンを回転させてキーを打ち、ポーズを付けていく。

キーフレーム、F-Curve、Dope Sheet のフレームのレンジを適当に広げたり縮めたりするとよい。

Mannx3.blend4.png


Mannx3.blend5.png


Mannx3.blend6.png

F-Curveで適当に動きを修正する。 ループ再生できるようにカーブの最初と最後で傾きを合わせるとよい。

移動はGを押して右ドラッグ。

Dope Sheetでもキーを移動したりできるがめんどくさい。

Mannx3.blend7.png

Dope Sheet を Action Editor に切り替える。

Dope Sheet はあまり使わない。 Action Editor にすると、 今のアニメーションが ArmatureAction という名前になっていることがわかる。 念のためこの名前の隣のFを押しておく。


Mannx3.blend8.png

ArmatureAction をコピーして ArmatureAction.001 を作る。 Fのとなりの+を押すだけ。 Fも押しておく。

F-Curve をいじって二つ目のアニメーションを作る。

Mannx3.blend9.png

Action Editor で ArmatureAction と ArmatureAction.001 を切り替えながら、 二つの動きが別々に登録されているかどうかを確認する。

ここまでうまくできたらいったん保存する。

※ よどみなくやるとだいたい成功しますが、 二つの動きが同じになったり部分的に混ざったりします。 そんなときはやり直し。 こまめにセーブ。

action editor で余計なアクションを削除したいときは、 アクションを選択した状態で Shift を押しながら×を押すと消える。

0フレーム目のポーズはいじらないこと。 Three.js の仕様か何かよくわからないが、全体のポーズが0フレーム目のポーズの影響をうける。 原因は今のところよくわからない。

Three.js の書き出し

ここからは Javascript が関わってくる。

Three.js 形式でエクスポート。

書き出したJSONファイルをテキストエディタで開いて確認(書き換える必要はありません)。

最初の部分

{

	"metadata" :
	{
		"formatVersion" : 3.1,
		"generatedBy"   : "Blender 2.7 Exporter",
		"vertices"      : 350,
		"faces"         : 348,
		"normals"       : 350,
		"colors"        : 0,
		"uvs"           : [243],
		"materials"     : 1,
		"morphTargets"  : 0,
		"bones"         : 19
	},

マテリアルの部分

	"materials" : [	{
		"DbgColor" : 15658734,
		"DbgIndex" : 0,
		"DbgName" : "Material",
		"blending" : "NormalBlending",
		"colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
		"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],
		"colorEmissive" : [0.0, 0.0, 0.0],
		"colorSpecular" : [0.5, 0.5, 0.5],
		"depthTest" : true,
		"depthWrite" : true,
		"mapDiffuse" : "mannxx.png",
		"mapDiffuseWrap" : ["repeat", "repeat"],
		"shading" : "Lambert",
		"specularCoef" : 50,
		"transparency" : 1.0,
		"transparent" : false,
		"vertexColors" : false
	}],

マテリアルは配列になってるけど普通は一つしかありません(materials[0]しかない)。

   "MapDiffuse": "hogehoge.png" 

という行がないときはうまくマテリアルにテクスチャが割り当てられてません。 がんばりましょう

ボーンのアニメーションの部分

Three.js のエクスポーターのオプションで skeletal animation にチェックが入ってない場合には、チェックを入れる。

  "animations" : [{"name":"ArmatureAction","fps":24,

とか

{"name":"ArmatureAction.001","fps":24,"

などという行が含まれていれば、 アニメーションもちゃんと書き出せています。

HTML に js と png を読み込んで動かしてみる

OrbitControl.js と BlendCharacter.js も同じフォルダに入れます。

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/threejs/r67/three.min.js"></script>
<script src="OrbitControls.js"></script>
<script src="BlendCharacter.js"></script>
<style>
#canvas {
	width: 600px;
	height: 400px;
	float: left;
}
#sidebar {
	width: 100px;
	height: 400px;
	float: left;
}
</style>
<script>
var scene, camera, controls, renderer, mesh;

var init = function() {
	var canvas = document.getElementById('canvas');// 描画要素
	var width = canvas.clientWidth;
	var height = canvas.clientHeight;
    
	scene = new THREE.Scene();

	camera = new THREE.PerspectiveCamera(15,  width / height, 1, 10000);
	// 視野角度 fov、アスペクト比 x/y、クリッピング手前、クリッピング奥
	camera.position.z = 2000;// カメラの位置
    
	controls = new THREE.OrbitControls(camera);// カメラの操作
	controls.target = new THREE.Vector3(0, 0, 0);

	scene.add(new THREE.AmbientLight(0xffffff));// 環境光
	var directionalLight = new THREE.DirectionalLight(0xaaaaaa, 3);// 平行光
	directionalLight.position.set(0, 3, 1);// 光源の位置
	scene.add(directionalLight);

	mesh = new THREE.BlendCharacter();
	mesh.load( "mannx3xx.js", start );

	renderer = new THREE.WebGLRenderer();
	renderer.setClearColor('#777777', 1);// 背景色
	renderer.setSize(width, height);// 描画領域の大きさ
	canvas.appendChild(renderer.domElement);
}

var start = function(){
	mesh.position.set(0, 50, 0);
	mesh.scale.set(50, 50, 50);
	mesh.animations['ArmatureAction'].loop = false;
	mesh.animations['ArmatureAction.001'].loop = false;
	scene.add(mesh);
	animate();
}

var animate = function() {
	requestAnimationFrame(animate);
	//mesh.rotation.y += 0.01;
	var stepSize = 0.05;
	mesh.update(stepSize);
	THREE.AnimationHandler.update(stepSize);
	renderer.render(scene, camera);
}
$(function(){
	$('#action0').click(function(){
		mesh.play('ArmatureAction', 1);
	});
	$('#action1').click(function(){
		mesh.play('ArmatureAction.001', 1);
	});
});
</script>
</head>
<body>
<div id="canvas"></div>
<div id="sidebar">
<button id="action0">ArmatureAction</button>
<button id="action1">ArmatureAction.001</button>
<script>
init();
</script>
</body>
</html>

   mesh.load( "mannx3xx.js", start );

ここでJSON形式のメッシュ(テクスチャとアニメーション付き)を読み込んでいる。 適当にファイル名を直す。

   mesh.play('ArmatureAction', 1);

というのは ArmatureAction というアニメーションを重み1で再生するという意味。

   mesh.animations['ArmatureAction'].loop = false;

というのは、Three.js のアニメーションはデフォルトでループ再生になっているので、 ループしないようにしている。


action editor でアクションの名前(ArmatureAction とか ArmatureAction.001 とか)を変えたときは該当する箇所を書き換える。