お父さんです。
先日行われた勉強会、ひよこの会で発表してきた「トゥイーンの再利用」についてまとめました。 僕自身、トゥイーンの再利用についてまだあまり有効な活用方法を見いだせておらず、いちおうずっと気になってた方法をまとめるだけの発表でしたが、仕事の時短術やクオリティアップにお役に立てれば幸いです。
Flashには昔から(たぶんFlash8とかの旧モーショントゥイーンの時代から)トゥイーンを再利用する方法が幾つか用意されてあり、その後になって新モーショントゥイーンの機能も追加されたこともあって本当にたくさんのトゥイーンの再利用方法が用意されています。
僕はトゥイーンの再利用そのものに有効な活用方法を見いだせないままずっと放置していたのですが、これを機会に調べられるだけ調べてみました。
仮にこんなすばらしいモーションを作ったとします。このすばらしいモーションを出来るだけ後生にまで伝えたい、素材を変えてモーションだけ再利用したい!
そんな願いを叶える方法です。
いちおうほとんど全て新モーショントゥイーンを対象に説明していますが、僕も今回やっと新モーショントゥイーンちょっと触った程度なので、旧モーショントゥイーンの再利用方法についても一番最後に説明をしておきます。
1:コピー&ペーストして再利用
一番簡単な方法がこれだと思います。
モーションガイドを選択した状態で右クリックして
「モーションをコピー」を選びます。
これでモーションがクリップボードにコピーされましたので、次は
別の素材を選択して右クリックから
「モーションをペースト」するだけでOKです。
2:モーションプリセットに保存して再利用
クリップボードにコピーしただけでは、このすばらしいモーションは保存されません。
何度も何度も、繰り返し再利用したいモーションはこのプリセットに保存する方法を使うといいかと思います。
モーションを選択して右クリック
「モーションプリセットとして保存」
プリセットに名前をつけろと言われるので、世界であなたのモーションだけの素晴らしい名前をプレゼントしましょう。
保存したモーションはメニューの「ウインドウ」→「モーションプリセット」からいつでも呼び出せることが出来ます。
自分が保存したモーションの他にも、「デフォルトプリセット」といってAdobeがあらかじめ用意した使いどころの難しい僕のモーションよりもずっと素晴らしいプリセットもあります。
ちなみに、モーションプリセットの具体的な保存場所は、
Macだと
/Users/<ユーザー名>/Library/Application Support/Adobe/Flash CS5/ja_JP/Configuration/Motion Presets
winだと
C:\Users\<ユーザ名>\AppData\Roaming\Adobe\Flash CS5\ja_JP\Configuration\Motion Presets
あたりにあるのではないでしょうか(Winは未確認)。
adobe系のこういったユーザー定義ファイルの保存場所は覚えておくと何かと便利です。
3:AS3のコードとして再利用
実用的かどうかはまだ未知数なのですが、僕が一番おもしろいなと思ったのがこれです。
モーションをActionScript3.0のコードに変換してしまう方法です。
モーションを選択後右クリックで「as3.0にモーションを書き出してコピー」
これで今選択したモーションがクリップボードにActionScriptのコードとしてコピーされました。
試しにタイムラインにアクションスクリプトをペーストしてみましょう。
任意のタイムラインを選択してアクションパネルを開きます。
そこでおもむろにペーストしてみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | import fl.motion.AnimatorFactory; import fl.motion.MotionBase; import fl.motion.Motion; import flash.filters.*; import flash.geom.Point; var __motion_kao_5:MotionBase; if (__motion_kao_5 == null ) { __motion_kao_5 = new Motion(); __motion_kao_5.duration = 35 ; // Call overrideTargetTransform to prevent the scale, skew, // or rotation values from being made relative to the target // object's original transform. // __motion_kao_5.overrideTargetTransform(); // The following calls to addPropertyArray assign data values // for each tweened property. There is one value in the Array // for every frame in the tween, or fewer if the last value // remains the same for the rest of the frames. __motion_kao_5.addPropertyArray( "x" , [ 0 , 5.96283 , 12.2405 , 18.8772 , 25.9359 , 33.4796 , 41.634 , 50.516 , 60.2874 , 71.1639 , 83.2892 , 96.5736 , 110.379 , 123.662 , 135.795 , 146.678 , 156.446 , 165.326 , 173.477 , 181.017 , 188.073 , 194.706 , 200.98 , 206.95 , 188.338 , 169.716 , 151.072 , 132.439 , 113.806 , 95.1561 , 76.5351 , 57.9093 , 39.2788 , 20.6491 , 2 ]); __motion_kao_5.addPropertyArray( "y" , [ 0 ,- 12.4844 ,- 24.8276 ,- 36.9843 ,- 48.9072 ,- 60.5021 ,- 71.7026 ,- 82.3267 ,- 92.1163 ,- 100.674 ,- 107.31 ,- 111.064 ,- 111.069 ,- 107.324 ,- 100.691 ,- 92.1305 ,- 82.3435 ,- 71.7214 ,- 60.5223 ,- 48.9285 ,- 37.0062 ,- 24.8498 ,- 12.5067 , 0 ,- 0.258063 ,- 0.404897 ,- 0.470401 ,- 0.473853 ,- 0.429182 ,- 0.347192 ,- 0.237801 ,- 0.111154 , 0.0184064 , 0.120505 , 0 ]); __motion_kao_5.addPropertyArray( "scaleX" , [ 1.000000 ]); __motion_kao_5.addPropertyArray( "scaleY" , [ 1.000000 ]); __motion_kao_5.addPropertyArray( "skewX" , [ 0 ]); __motion_kao_5.addPropertyArray( "skewY" , [ 0 ]); __motion_kao_5.addPropertyArray( "rotationConcat" , [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]); __motion_kao_5.addPropertyArray( "blendMode" , [ "normal" ]); __motion_kao_5.addPropertyArray( "cacheAsBitmap" , [ false ]); // Create an AnimatorFactory instance, which will manage // targets for its corresponding Motion. var __animFactory_kao_5:AnimatorFactory = new AnimatorFactory(__motion_kao_5); __animFactory_kao_5.transformationPoint = new Point( 0.500000 , 0.500000 ); // Call the addTarget function on the AnimatorFactory // instance to target a DisplayObject with this Motion. // The second parameter is the number of times the animation // will play - the default value of 0 means it will loop. // __animFactory_kao_5.addTarget(<instance name goes here>, 0); } |
なにやらぞわーっとスクリプトが貼り付けられました。
今自分が作ったモーションがActionScriptに変換されたことが分かります。
あとは動かしたいインスタンスにインスタンス名をつけてやって(今回は「icon」とつけました)
39行目の箇所の
1 | // __animFactory_kao_5.addTarget(<instance name goes here>, 0); |
こうなってる箇所のコメントアウトを外して、addTargetの一番目の引数に先ほどの動かしたいインスタンスのインスタンス名を入れてやります。
1 | __animFactory_kao_5.addTarget(icon, 0 ); |
いろいろごちゃごちゃと書かれていますが、ほとんどが動きの定義ばっかりで、実際に実行しているのはこの最後の一行だけです。
この機能、まだ調べたわけではないのであれなんですが、憶測では結構低レベルのAPI叩いてるっぽくて、うまくオレオレモーションライブラリと組み合わせるとお気に入りの軽い動作が出来るんじゃないかとほくそ笑んでます。
4:XMLとしてモーションをコピーして再利用する
今までは新モーショントゥイーンでの再利用方法だったわけですが、最後にもう一つ、旧モーショントゥイーンでも使える再利用の仕方も調べてみました。
それがこのXMLとしてモーションをコピーして再利用する方法です。
クラシックトゥイーンでモーションを作ったら、タイムライン上でコピーしたいフレームを全選択しておいて
「コマンド」→「XML形式でモーションをコピー」を選びます。
これでモーションがXMLの形式でクリップボードにコピーされました。
これをどう使うのかというとActionScriptで使用しますのでタイムラインアクションを出してみましょう。
そこでクリップボードのXMLを変数に入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | var motion_xml:XML = <motion duration= "30" xmlns= "fl.motion.*" xmlns:geom= "flash.geom.*" xmlns:filters= "flash.filters.*" > <source> <source framerate= "24" x= "97" y= "178" scalex= "1" scaley= "1" rotation= "0" elementtype= "movie clip" instancename= "kao_5" symbolname= "kao" > <dimensions> <geom:rectangle left= "0" top= "0" width= "80" height= "80" > </geom:rectangle></dimensions> <transformationpoint> <geom:point x= "0.5" y= "0.5" > </geom:point></transformationpoint> <keyframe index= "0" tweensnap= "true" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "7" tweensnap= "true" x= "88.80000000000001" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "15" tweensnap= "true" x= "190.3" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "25" tweensnap= "true" x= "317.2" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "29" tweensnap= "true" x= "367.95" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> </motion> |
ぞわーっとコードが増えましたが、XMLコピペしたぶん長いだけなので、実質は
var motion_xml:XML =
て書いてペーストしただけです。
さらに続けて
1 2 | var motion:Animator = new Animator(motion_xml, icon); motion.play(); |
こう書き足していきます。
Animatorコンストラクタの引数にそれぞれ、XML、動かしたいインスタンスのインスタンス名を入れます。
CS5などのアクションパネルでコード補完が効いていれば必要なimportも自動で行ってくれるはずなので、最終的にはこうなっているはずです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | import fl.motion.Animator; var motion_xml:XML = <motion duration= "30" xmlns= "fl.motion.*" xmlns:geom= "flash.geom.*" xmlns:filters= "flash.filters.*" > <source> <source framerate= "24" x= "97" y= "178" scalex= "1" scaley= "1" rotation= "0" elementtype= "movie clip" instancename= "kao_5" symbolname= "kao" > <dimensions> <geom:rectangle left= "0" top= "0" width= "80" height= "80" > </geom:rectangle></dimensions> <transformationpoint> <geom:point x= "0.5" y= "0.5" > </geom:point></transformationpoint> <keyframe index= "0" tweensnap= "true" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "7" tweensnap= "true" x= "88.80000000000001" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "15" tweensnap= "true" x= "190.3" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "25" tweensnap= "true" x= "317.2" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> <keyframe index= "29" tweensnap= "true" x= "367.95" > <tweens> <simpleease ease= "0" > </simpleease></tweens> </keyframe> </motion> var motion:Animator = new Animator(motion_xml, icon); motion.play(); |
ちなみにモーションとは関係ないですが、変数にXMLを入れる場合は「ダブルクオート(”)」などの引用符は付けないです(ASが内部にパーサーを備えているのでXMLの開始タグと終了タグを理解するため)。
まとめ
モーションの再利用について今回改めて調べてみて、いろいろな方法があることがわかりました。
他にも「XMLとして保存、読み込み」とか「モーションを特殊ペースト」など僕がまだまだわからない方法もありますが、うまいこと使いどころを考えていくとなかなかに便利なのかなという気もします。