ナウい「LWF」
こんにちは、WG基盤開発部ゲーム基盤チームの何です。内製プロダクトチームを陰から支える仕事をしています、チーム名を噛みやすいのが玉にキズ。最近はLWFをメインにフロントエンド周りのお・も・て・な・しをしています。滝川クリステルさん大好きです。
『GREE Advent Calendar 2013』15日目では ナウい「LWF」 と題しまして、LWFが最近どのように使われているのかを社内の活用例と共に紹介したいと思います。今更聞けないLWFの豆知識を始め、現場の開発で役立てているアシストツール、LWFの最新の事情についても触れていこうと思います。死語だらけの記事ですが、これを読んであなたもナウいLWFの世界へLet's Dive!
LWFの簡単なおさらい
「LWF」- Lightweight SWFとはFlashコンテンツから変換したデータをマルチプラットフォームで再生可能にするアニメーションエンジンです。昨年オープンソースプロジェクトとしてリリースされ、現在グリー内の様々なプロダクトで活用されております。
技術の概要などは過去にもEngineers' Blogの記事で紹介され、昨年末にはLWFにフォーカスしたTechTalkも開催されました。最近ではクリエイターの間でも徐々に浸透し始め、Creators' Blogの記事を始め様々な開発者の方のブログなどでも取り扱ってくれています。今も継続的に更新されており、パフォーマンス、対応環境共に日々進化しています。
また、ナウい話題としましては「LWF for C++」が先週から公開され、同時にCocos2D-xやiOS UIKitで使うためのRendererも一緒にありますので、さらに幅広い環境で利用できるようになりました。
Why LWF?
グリー社内では、「探検ドリランド」を始め様々なプロダクトでLWFを導入していますが、LWFを使用するメリットとしましては
- 多くのクリエイターにとって親しみやすいAdobe Flash CS6 及び CCを使い制作することができる
- 同一ソースでHTML5, Unityを始め複数環境の多様な描画方式に対応している
- スマートフォンゲームコンテンツの開発にフォーカスしている
が挙げられます。
実際クリエイターがオーサリングしたアニメーションをコンバートし、エンジニア側でその出力データを表示させるだけなので、餅は餅屋で制作工数を大幅削減することができます。幅広く使われているFlashで制作できるのでクリエイターの学習コストも抑えられ、HTML5で使う場合なら実行環境に合わせてレンダリング方式をも選択できるので、パフォーマンスチューニングも行いやすいです。
気になるパフォーマンス関連につきましてはこちらの記事で競合技術とのパフォーマンス比較などについて取り上げています。その後も更なる高速化が実現されて、現状ここまでパフォーマンスが上がっています。
WebGL版パフォーマンスサンプル、Canvas版パフォーマンスサンプル
弾幕すらヌルヌル動きます。
弾幕サンプル
また、端末依存のバグの対処ノウハウが多く、多くの端末や実行環境をサポートしているのも魅力的です。ブラウザ向け以外にもUnity版などでネイティブ環境への導入もできるため、実質的に一回作ったFlashコンテンツをブラウザ/非ブラウザの両方に出力できるのも便利です。
上記を踏まえつつ、新しい機能やイベントを実装する際に短い時間で導入できることから、昨年から複数プロダクトにて活用されています。
LWFの開発効率を上げるナウい方法
しかしいきなりLWFを使うといっても、まだまだ新しい技術なのでやや心もとない感じを受けるかと思われます。そこで以下ではグリー社内で使われている、LWFを導入する際に使っているアシストツールやそれらの活用法についてご紹介します。未経験の方が躓きやすいポイントや落とし穴の多くをスマートに解決できます。
LWFS
まずそもそもどうやってLWFフォーマットへ変換したらいいのか、変換したファイルのプレビューはどうすればいいのかが大きな問題になってくるのですが、これらの問題を華麗に解決してくれるのがLWFSです。LWFSはLWFを変換、プレビューできるビューワーで、必要な素材をディレクトリに配置するだけで、LWFフォーマットへの変換に加え、各種レンダリングモードでのプレビューをブラウザ上で行えます。社内ではLWFの変換作業はほぼすべてLWFSで行っており、テストツールとしても活用しています。
LWFSについては過去の記事でも取り上げられており、Windows/Mac/Linux、各環境で動作しておりますので以下からぜひダウンロードしてお試しください。
LWF Loader
LWF Loaderは共通的なアニメーション設定など重複しがちなパラメータなどをすべて引き取り、必要の部分だけユーザに指定させ、LWFを最小限の努力で楽に使うために作られたWrapperです。既存コードを大幅に短縮できる上、必要な機能をひと通り内包していますので、社内でも広く使われております。
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 |
window.addEventListener("DOMContentLoaded", function() { window.requestAnimationFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) { window.setTimeout(callback, 1000 / 60); }; })(); (function(){ LWF.useCanvasRenderer(); var stage = document.getElementById("lwf-test"); var cache = LWF.ResourceCache.get(); var current_time, from_time; function calc_tick() { current_time = Date.now() / 1000.0; tick = current_time - from_time; from_time = current_time; return tick; } cache.loadLWF({ "lwf": "test.lwf", "prefix": "", "stage": stage, "use3D": false, "useBackgroundColor": true, "onload": function(lwf){ lwf.setFrameRate(24); var main = function(){ lwf.exec(calc_tick()); lwf.render(); window.requestAnimationFrame(main); } window.requestAnimationFrame(main); } }); })(); }); |
通常の場合、LWFを再生するためには上記のようにパラメータを細かく設定する必要があるのですが、LWF Loaderを使えば以下のようにシンプルに実装可能です。
1 2 3 4 5 6 7 8 9 10 11 |
var setting = { lwf: "test.lwf", prefix: "", privateData: {} }; var lwfLoader = new window.LwfLoader(); window.addEventListener('DOMContentLoaded', function() { var element = document.getElementById('lwf-test'); lwfLoader.playLWF(element, setting); }); |
先日オープンソースプロジェクトとしてリリースされ、サンプルやAPIドキュメントも公開しました。上記のLWFSと組み合わせて使うのがオススメです。
LWF Loader 紹介
LWF Loader ドキュメント
Gruntを活用する
LWF Loaderの使用に必要なunderscore.jsを始め、各チーム内で様々なフロントエンド開発用のjsファイルやその他のライブラリを読み込んでいる場合が多く、ファイル管理やデプロイする際のjsファイルのminificationなどの手順を自動化するためにGruntを導入しています。
一例ですが、このような感じで使っています
Gruntプラグイン | 内容 |
grunt-contrib-jshint | jsコードの品質チェック |
grunt-contrib-concat | 複数jsファイルのconcatenation |
grunt-closure-compiler | jsファイルのminification |
grunt-lodash | underscore.jsと互換性があるライブラリ |
LWF関連の更新があった際に、簡単にテスト/リリースできるように関連タスクを自動化させています。
その他のグリーにおいてのGrunt活用事例につきましては先日のAdvent Calendar記事をご覧ください。
Jenkinsを活用する
クリエイターがリソースをエンジニアに引き渡したあとに
- コミットされた素材はいつのタイミングで変換すればいいのか
- 変換したあとの管理はどうするのか
- そもそも正しい素材が送られてきているか
など様々な小粒タスクに直面することが多いのですが、ケアレスミスが起こりやすい部分なのでJenkinsで自動化してミスを防ぎます。一例ですが、JenkinsジョブにリモートのLWFSを連動させ、素材がコミットされる度にLWFSで変換し、専用ディレクトリへ出力するというプロセスを取っています。コミットされた素材の中身を素早く確認するため、更新がある度にスクリーンショットを自動で撮って、即時に表示して比較する手法を採用しているチームもあります。
ナウい「LWF for C++」
せっかくなので先日公開されたナウい「LWF for C++」を簡単に紹介します。
HTML向けのJavaScript版、Unity向けのC#版に続き、その他native環境向けのC++での実装になります。標準描画環境としてCocos2D-xのRendererが提供されている以外に、iOS UIKitで動せるRendererも公開されています。使い方はどちらも大変シンプル:
Cocos2D-x Renderer
LWFデータをnodeとして扱うだけであとはすべてCocos2D-xの文法に従います。
1 2 3 4 |
LWFNode *lwfNode = LWFNode::create("sample.lwf"); SpriteBatchNode *batch = SpriteBatchNode::createWithTexture(lwfNode->getTexture()); batch->addChild(lwfNode); this->addChild(batch); |
iOS UIKit Renderer
StoryboardにLWF Viewを置いてパラメータを設定するだけで再生ができます。UIKit Rendererは現在CocoaPodsで提供されていますので、既存のXcode projectへ追加する際も下記のPodfileを準備してpod install
するだけで大変お手軽です。
1 |
pod 'LWF/UIKit' |
どちらのRendererでも再生に使う素材は従来のLWFファイルを使い回せますので、すでに「LWF for HTML5」を触ったことがある方は手軽に試せると思います。また、ゲームエンジンとして使いやすいように、「LWF for C++」ではLuaをサポートしています。HTML5版と同じく外部スクリプトから制御できるようになっておりますので、ぜひぜひご活用ください。
参照ページ
LWF for C++
LWF for C++: Cocos2D-x Renderer Sample
LWF for C++: UIKit Renderer Sample
CocoaDocs: iOS UIKit Objective-C LWF API Reference
まとめ
当初はドキュメントやサンプルも乏しく、とっつきにくいイメージを抱かれていたLWFですが、ドキュメントの整備も進み、LWF LoaderやLWFSといったツールも充実してきています。LWFを採用したプロダクトも次々とリリースされていて、ノウハウも徐々に溜まりつつありますので、少しでも導入コストが高いイメージを払拭できていればと思います。
数多ある競合技術とは細かい差はあるものも、LWFでは「オーサリングのしやすさ」と「パフォーマンス」を両方考慮し、もっともバランスのいい実装を提供していると自負しております。2Dゲームの制作に関わってる方、スマートフォンブラウザで少しでも滑らかにアニメーションを提供したい方はぜひ一度お試しください。
明日は鈴木晃一さんの番です! Check it out!