人生ゲーム漬けなダメ人間のBlog

ページ内情報

プロフィール

ページ内検索




カレンダー
  12345
6789101112
13141516171819
20212223242526
2728293031  
<< August 2017 >>



月ごとで検索


カテゴリーで検索




最近の日記一覧

コンテンツ

【Away3D】Flashで3D表示ができるようになったお

色々書きたいけど使い方は結構量があるので、次の週末あたりにかければ。
とりあえず完成品とソースコードを晒しておきます。

一般的には Class で読み込むケースが多いみたい
でも、Flash CC で且つ Class化 しない方法で
今回は書いてみました。

これ以外にも3Dデータをコンバートする際に
ハマりどころがあったりと、アーティストが使うには
結構敷居が高いところが多かったです。

自分の場合は以下のフローで対応してます。

ToyStudio(.x Export) → Unwrap3D(.AWD Export) → AwayBuilder

これでもカメラやライトが一切ついてこなかったりと、
結構クセのある代物なので Unity ちゃんみたいな幻想は
あまり抱かないほうが良いかもしれません。

とはいえ、使いこなせれば
Flash との親和性は驚くくらい高いので、
次のバージョンアップに期待しても良いかもしれません。

完成品



3D表示の部分

import away3d.core.base.*;
import away3d.containers.View3D;

import away3d.animators.*;
import away3d.animators.data.*;
import away3d.animators.nodes.*;
import away3d.animators.states.*;

import away3d.cameras.*;
import away3d.lights.*;

import away3d.library.AssetLibrary;
import away3d.library.assets.AssetType;
import away3d.loaders.Loader3D;
import away3d.loaders.parsers.*;

import away3d.errors.*;
import away3d.events.AssetEvent;
import away3d.events.AnimationStateEvent;

import flash.events.Event;
import away3d.events.LoaderEvent;
import away3d.entities.Mesh;
import away3d.animators.transitions.CrossfadeTransition;
import away3d.core.partition.LightNode;

//諸々指定
var loader:Loader3D = new Loader3D();
var _camera:Camera3D;
var _light:DirectionalLight;

var _mesh:Mesh;
var _skeleton:Skeleton;
var _animator:SkeletonAnimator;
var _node:SkeletonClipNode;

//アニメーションのフェードアウト係数設定
var _stateTransition:CrossfadeTransition = new CrossfadeTransition(0.5);

const NORMAL_ANIM:String = "cube_wait";
const ACTION_ANIM:String = "cube_jump";

//何度も使う場合は先に埋め込む
//埋め込むとwebで呼び出すものがswfだけで済むようになるが、代わりにアセット管理が面倒にもなる
[Embed(source="../resource3d/test_CubeAnim_scene.awd",mimeType="application/octet-stream")]
var cube_3d:Class;


//Viewとsceneとcamera定義
var View:View3D = new View3D();
var scene  = View.scene;

View.backgroundColor = 0xDDDDDD;

//View開始(先にリスト登録しないとプロパティが引けない模様)
addChild(View);

trace("start: "+ loader);

//パーサ定義
AssetLibrary.enableParser(AWD2Parser);

//ロードイベント
loader.addEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete );
loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete );

loader.loadData( new cube_3d() );


//アセットも読み終わったら表示開始
function onResourceComplete(event:LoaderEvent):void{
	
	loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete );
	
	//表示スケールの調整
	loader.scaleX *= 10;
	loader.scaleY *= 10;
	loader.scaleZ *= 10;	

	//登録
	View.scene.addChild(loader);
}


function onAssetComplete(event:AssetEvent):void{
	
	//forEachの如く呼び出されたアセットをひたすら潜って拾う模様。変な処理を書くと悲劇になるので注意w
	AssetLibrary.removeEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete );	
	
	trace(event.asset.name +" : "+ event.asset.assetType);
	
	if (event.asset.assetType == AssetType.CAMERA){
		
		_camera = event.asset as Camera3D;
		
		//読んできたカメラをアタッチする
		View.camera = _camera;
	}
	
	if (event.asset.assetType == AssetType.LIGHT){
		
		//マテリアルにLightPicerとShadowLight設定がないと反映されないので注意
		//陰影は概ねDirectionalでつくが影マップはバイポリゴンで算出なので綺麗ではない
		_light = event.asset as DirectionalLight;
		
		View.scene.addChild(_light);
	
	}
	
	if (event.asset.assetType == AssetType.MESH){
		
		_mesh = event.asset as Mesh;
		
		addEventListener(Event.ENTER_FRAME, onEnterFrame);
	}
	
	if (event.asset.assetType == AssetType.SKELETON){
		
		_skeleton = event.asset as Skeleton;
		
	}
	
	if (event.asset.assetType == AssetType.ANIMATOR){
		
		_animator = event.asset as SkeletonAnimator;
		
		//再生
		_animator.play(NORMAL_ANIM);
		
		trace("Read end: "+ loader);
	
	} else if (event.asset.assetType == AssetType.ANIMATION_NODE){
		
		_node = event.asset as SkeletonClipNode;
		
		if (_node.name != NORMAL_ANIM) {
			
			_node.looping = false;
			
			//シーンに永続させないといけない系のイベントの模様遷移時消し忘れ注意
			_node.addEventListener(AnimationStateEvent.PLAYBACK_COMPLETE, onPlaybackComplete);
		}
		
	}
}

//カメラの調整

function onEnterFrame(event:Event):void{
	
	View.render();
	
}

//アニメーション切替え

function ChengeAnim():void{
	
	//再生(オフセット指定しないと適当なところから再生しようとする。酷い仕様だこれw)
	_animator.play(ACTION_ANIM,_stateTransition,0);
	
}

function onPlaybackComplete(event:AnimationStateEvent):void
{	
	//自分のステートがアクティブかとうかを一旦みないといけないらしい。無いとうまく動かない。
	if (_animator.activeState != event.animationState)
	return;
	
	_animator.play(NORMAL_ANIM, _stateTransition,0);
}

UI表示の部分

import flash.utils.Dictionary;
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.TimerEvent;
import flash.utils.Timer;
import fl.transitions.Tween;
import fl.transitions.easing.Back;


var timerObj:Timer;

var menu_Dic:Dictionary = new Dictionary();
var txt_format:TextFormat = new TextFormat();

menu_Dic["btn_onMenu"] = new btn_onMenu();
menu_Dic["btn_txt"] = new TextField();

//テキスト設定

txt_format.size = 28;

menu_Dic["btn_txt"].width = 180;
menu_Dic["btn_txt"].defaultTextFormat = txt_format;
menu_Dic["btn_txt"].mouseEnabled = false;

//表示設定

menu_Dic["btn_onMenu"].x = 20;
menu_Dic["btn_onMenu"].y = 20;

menu_Dic["btn_txt"].x = menu_Dic["btn_onMenu"].x + 10;
menu_Dic["btn_txt"].y = menu_Dic["btn_onMenu"].y + 10;
menu_Dic["btn_txt"].text = "あくしょん!";

addChild(menu_Dic["btn_onMenu"]);
addChild(menu_Dic["btn_txt"]);

//シンプルボタンがシンプルすぎるので制御をいれる

menu_Dic["btn_onMenu"].addEventListener(MouseEvent.CLICK,onBUTTON_fnc);

function onBUTTON_fnc(event:MouseEvent):void{
	
	ChengeAnim();
	
	//アニメーションにタイムをもたせて待ち時間を返す
	//待ち時間が完了したときの処理は TimerEvent 側に書いてあげる
	
	var my_time = onButtonAnim(menu_Dic["btn_onMenu"]);
	
	timerObj = new Timer(my_time,1);
	timerObj.addEventListener(TimerEvent.TIMER_COMPLETE,_mouseEvent_END);
	timerObj.start();
	
}

function _mouseEvent_END(event:TimerEvent):void
{
	menu_Dic["btn_onMenu"].mouseEnabled = true;
	
	timerObj.removeEventListener(TimerEvent.TIMER_COMPLETE,_mouseEvent_END);
}

function onButtonAnim(btn_obj:Object):int {

	//二度押し防止の処理です。終わったらタイマー側で必ず戻してあげましょう。
	
	btn_obj.mouseEnabled = false;//解除忘れ注意!
	
	//x,yのアニメーション指定
	
	var btn_tween_x:Tween = new Tween(btn_obj,"x", Back.easeIn, btn_obj.x + 6, btn_obj.x + 0, 0.3, true);
	var btn_tween_y:Tween = new Tween(btn_obj,"y", Back.easeIn, btn_obj.y + 6, btn_obj.y + 0, 0.3, true);
	
	//待ち時間を返す
	
	var times:int = 1200;
	return times;

}




| ここな | 制作 | comments(0) | trackbacks(0) |


<< 【bloGirls】真瑞さんアップデート | main | 【Away3D】3Dコンテンツ表示の手順をまとめてみた >>



Comment











Trackback
url: http://kurobee.kokona.lomo.jp/trackback/1038030

その他情報

管理者ページ / RSS1.0 / Atom0.3 / Powered by ロリポブログ

無料ブログ作成サービス JUGEM
(C) 2017 ブログ JUGEM Some Rights Reserved.