【重要】Away3D 4.0 GoldでColladaの”複数”アニメーションに成功 | Photoshop CC Tutorials
以前にAway3D 4.0 GoldでColladaのアニメーションに成功しましたが
今回はさらに複数アニメーションをすることに成功しました。

ここ数日間、Away3D GoldのDAEParser.asのファイルを読んでいたのですが
複数アニメーションにも対応しているような書き方になっていることが分かってきたので
Colladaファイルを少し加工すればできるのではないかと思い、また独自で編み出してみました。

■操作方法
 十字キーの上下:手を振る
 十字キーの左右:歩く
 地面をマウスドラッグ:カメラ回転
◆【できあがりはこちらをクリック】(要:FlashPlayer11、ビデオカード等GPU搭載PC)
$ピック社長のブログ

モデルはBTAさんのサイトからお借りしました。
■ BTAさんのサイト
http://funsethp.web.fc2.com/

//---------------------------------------------------------------------
// Away3D 4.0 GoldでColladaの複数アニメーションをする方法
//---------------------------------------------------------------------

まずAway3Dのloadersパッケージの中にあるDAEParser.asを開き
下の画像のようにします。
$ピック社長のブログ

$ピック社長のブログ


次にBlenderを使って二つのColladaファイルを作成します。
二つのアニメーションのボーン名が異なっていることにご注意ください。
$ピック社長のブログ

$ピック社長のブログ

次にさきほど作成したColladaファイルを一つのファイル(char.dae)にまとめます。
ただし<geometry>はどちらか一方のもので結構です。
<instance_controller>を含むノードもどちらか一方のものに
<instance_controller>だけを付け加えます。
$ピック社長のブログ

そして最後にさきほど一つにまとめたchar.daeを開き
idをすべて下の画像のように書き換えます。
$ピック社長のブログ

$ピック社長のブログ

$ピック社長のブログ

$ピック社長のブログ

プログラムは下記のようになります。
Main.as
package
{
import away3d.animators.data.Skeleton;
import away3d.animators.SkeletonAnimationSet;
import away3d.animators.SkeletonAnimationState;
import away3d.animators.SkeletonAnimator;
import away3d.animators.transitions.CrossfadeStateTransition;
import away3d.animators.VertexAnimationSet;
import away3d.animators.VertexAnimator;
import away3d.materials.methods.FilteredShadowMapMethod;
import away3d.loaders.Loader3D;
import away3d.loaders.parsers.*;
import away3d.loaders.misc.AssetLoaderContext;
import away3d.bounds.*;
import away3d.cameras.*;
import away3d.containers.*;
import away3d.controllers.*;
import away3d.core.base.*;
import away3d.core.pick.*;
import away3d.debug.*;
import away3d.entities.*;
import away3d.events.*;
import away3d.library.assets.*;
import away3d.library.AssetLibrary;
import away3d.lights.*;
import away3d.materials.*;
import away3d.materials.lightpickers.*;
import away3d.primitives.*;
import away3d.textures.*;
import away3d.utils.Cast;

import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.*;
import flash.text.*;
import flash.ui.*;

[SWF(backgroundColor="#000000", width="600", height="400", frameRate="60")]
public class Main extends Sprite
{
[Bindable]
[Embed(source="../embeds/char.dae", mimeType="application/octet-stream")]
private var ColladaData:Class;

//signature swf
[Embed(source="/../embeds/signature.swf", symbol="Signature")]
public var SignatureSwf:Class;

// tableTexture
[Embed(source="/../embeds/table.jpg")]
private var tableTex:Class;

//engine variables
private var scene:Scene3D;
private var camera:Camera3D;
private var view:View3D;
private var awayStats:AwayStats;
private var cameraController:HoverController;

//signature variables
private var Signature:Sprite;
private var _signature:Bitmap;
private var SignatureBitmap:Bitmap;

//light objects
private var light:DirectionalLight;
private var lightPicker:StaticLightPicker;
private var direction:Vector3D;

//navigation variables
private var move:Boolean = false;
private var lastPanAngle:Number;
private var lastTiltAngle:Number;
private var lastMouseX:Number;
private var lastMouseY:Number;
private var tiltSpeed:Number = 4;
private var panSpeed:Number = 4;
private var distanceSpeed:Number = 4;
private var tiltIncrement:Number = 0;
private var panIncrement:Number = 0;
private var distanceIncrement:Number = 0;

private var char:ObjectContainer3D;

/**
* Constructor
*/
public function Main()
{
init();
}

/**
* Global initialise function
*/
private function init():void
{
initEngine();
initLights();
initListeners();

initialize();
}

private function initialize():void
{
// create ground mesh
var matground : TextureMaterial = new TextureMaterial(Cast.bitmapTexture(tableTex));
matground.shadowMethod = new FilteredShadowMapMethod(light);
matground.lightPicker = lightPicker;
matground.ambient = 0.5;
matground.specular = 0.5;
var mesh:Mesh = new Mesh(new PlaneGeometry(5000, 5000), matground);
mesh.mouseEnabled = true;
view.scene.addChild(mesh);

//Parsers.enableAllBundled();
var context:AssetLoaderContext = new AssetLoaderContext();
AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, loaded, false, 0, true);
var loader:Loader3D = new Loader3D();
loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, complete, false, 0, true);
loader.loadData(new ColladaData(), context, null, new DAEParser());
}

/**
* Initialise the engine
*/
private function initEngine():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;

view = new View3D();
view.forceMouseMove = true;
scene = view.scene;
camera = view.camera;
//setup controller to be used on the camera
cameraController = new HoverController(camera, null, 180, 20, 500, 5);

// Chose global picking method ( chose one ).
view.mousePicker = PickingType.RAYCAST_BEST_HIT; // Uses the CPU, guarantees accuracy with a little performance cost.

view.addSourceURL("srcview/index.html");
addChild(view);

//add signature
Signature = Sprite(new SignatureSwf());
SignatureBitmap = new Bitmap(new BitmapData(Signature.width, Signature.height, true, 0));
stage.quality = StageQuality.HIGH;
SignatureBitmap.bitmapData.draw(Signature);
addChild(SignatureBitmap);

awayStats = new AwayStats(view);
addChild(awayStats);
}

/**
* Initialise the lights
*/
private function initLights():void
{
//setup the lights for the scene
light = new DirectionalLight( 1, -1, 1);
light.ambient = 0.8;
light.color = 0xffffff;

lightPicker = new StaticLightPicker([light]);
scene.addChild(light);
}

/**
* Initialise the listeners
*/
private function initListeners():void
{
view.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
view.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
addEventListener(Event.ENTER_FRAME, onEnterFrame);
stage.addEventListener(Event.RESIZE, onResize);
onResize();
}

/**
* Navigation and render loop
*/
private function onEnterFrame(event:Event):void
{
// Update camera.
if (move) {
cameraController.panAngle = 0.3*(stage.mouseX - lastMouseX) + lastPanAngle;
cameraController.tiltAngle = 0.3 * (stage.mouseY - lastMouseY) + lastTiltAngle;

cameraController.panAngle += panIncrement;
cameraController.tiltAngle += tiltIncrement;
cameraController.distance += distanceIncrement;
}

// Render 3D.
view.render();
}

/**
* stage listener for resize events
*/
private function onResize(event:Event = null):void
{
view.width = stage.stageWidth;
view.height = stage.stageHeight;
SignatureBitmap.y = stage.stageHeight - Signature.height;
awayStats.x = stage.stageWidth - awayStats.width;
}

//animation variables
private var mesh:Mesh;
private var animator:SkeletonAnimator;
private var animationSet:SkeletonAnimationSet;
private var skeleton:Skeleton;
private function loaded(evt:AssetEvent):void
{
if (evt.asset.assetType == AssetType.CONTAINER) {
trace("CONTAINER");
char = ObjectContainer3D(evt.asset);
char.rotationX = 90;
char.scale(50);
char.y = 130;
}
if (evt.asset.assetType == AssetType.MATERIAL) {
trace("MATERIAL");
var material:TextureMaterial = TextureMaterial(evt.asset);
material.lightPicker = lightPicker;
material.ambient = 1;
}

if (evt.asset.assetType == AssetType.SKELETON) {
trace("SKELETON");
skeleton = evt.asset as Skeleton;
}
else if (evt.asset.assetType == AssetType.ANIMATION_STATE) {
trace("ANIMATION_STATE");
var state:SkeletonAnimationState = evt.asset as SkeletonAnimationState;
}
else if (evt.asset.assetType == AssetType.ANIMATION_SET) {
trace("ANIMATION_SET");
animationSet = evt.asset as SkeletonAnimationSet;
animator = new SkeletonAnimator(animationSet, skeleton, false);

//apply our animator to our mesh
mesh.animator = animator;
//animator.autoUpdate = true;
animator.play("default1");
animator.playbackSpeed = 0;

stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp, false, 0, true);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true);
} else if (evt.asset.assetType == AssetType.MESH) {
trace("MESH");
//create mesh object
mesh = evt.asset as Mesh;
}
}

private function complete(evt:LoaderEvent):void
{
AssetLibrary.removeEventListener(AssetEvent.ASSET_COMPLETE, loaded);
evt.target.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, complete);
scene.addChild(char);
}

/**
* Mouse up listener for navigation
*/
private function onMouseUp(event:MouseEvent):void
{
move = false;
}

/**
* Mouse down listener for navigation
*/
private function onMouseDown(event:MouseEvent):void
{
move = true;
lastPanAngle = cameraController.panAngle;
lastTiltAngle = cameraController.tiltAngle;
lastMouseX = stage.mouseX;
lastMouseY = stage.mouseY;
}

//--------------------------------------------------------------------- KEYBOARD

/**
* Key down listener
*/
private function onKeyDown(event:KeyboardEvent):void
{
switch (event.keyCode) {
case Keyboard.UP:
animator.play("default0");
animator.playbackSpeed = 1.5;
break;
case Keyboard.DOWN:
animator.play("default0");
animator.playbackSpeed = 1.5;
break;
case Keyboard.LEFT:
animator.play("default1");
animator.playbackSpeed = 1;
break;
case Keyboard.RIGHT:
animator.play("default1");
animator.playbackSpeed = 1;
break;
}
}

/**
* Key up listener
*/
private function onKeyUp(event:KeyboardEvent):void
{
switch (event.keyCode) {
case Keyboard.UP:
break;
case Keyboard.DOWN:
break;
case Keyboard.LEFT:
break;
case Keyboard.RIGHT:
break;
}
}

}

}


尚、この方法はあくまでも完全独自の方法なので参考程度にしておいてください。