Blenderの導入ガイドを書いてみた

Blender 2.60が出ましたね。最近更新ペースが速いです。12月のバージョン2.61では新しいレンダリングエンジンも入るとか。

で、つい勢いでBlender基礎最速マスターというものを書いてみました。タイトルは一時期人気になったプログラミング言語の基礎文法最速マスターシリーズにあやかっています。

Blenderはフルスペックのフリーの3DCGソフトウェアです。Unityとの連携で用いられることも増えていると思うのですが、癖がとても強いことでも知られています。できるだけ短時間でハマりポイントのうち大きなものをカバーできるようにしてみたつもりなんですが、どうでしょうねー。

ブログではなく通常のページにしたのは、また結構長文になってしまったのと、最近ウェブで検索したときに古い情報が出てくることが多い気がするので(数ヶ月前に書いたAIRのエントリももう時代遅れになってしまいましたし……)、固定ページとしてメンテナンスしたほうがいいんじゃないかと。

いざ久しぶりにページを作るとなると、URLを考えるのに困ったりするんですけどね。思い切ってunityというディレクトリを作ったので、そんな感じのものを上げていければいいなと思ってます。

近況としてはわりとUnity漬けですが、Flash 11も気になるところです。

2011年10月22日

Unityで1週間でミニゲームを作ってみた

最近なにかと話題のゲームエンジンUnity。ずっと前から気になっていてちょくちょくいじってはいたんですが、実際にゲームを作ってみたことはありませんでした。そんなところにIGDA日本のUnityのセミナーがありまして、面白そうな内容でぜひ行こうと思ったんですが、Unityをろくに触らないまま遠路出かけるのはもったいないということで、急遽ゲームを1本でっちあげてみました。

ゲームはこちらです。要求スペックはそこそこ高めです。

ちなみにセミナーの内容については「強火で進め」さんのブログにまとめられています。

以下、メイキング的なメモ書きです。

今回、時間がなかったこともあって、「リソースは自作しない」というのを絶対方針にしました。UnityにはAsset Storeという公式の素材マーケットがあるので、主にそこからフリーのものをいろいろ見つくろってきています。背景やトゲ付き鉄球など、全部既製の素材です。

また、プレイヤーキャラクターはMixamoを利用しました。有料ですが、3Dの人体モデルを作成したり、自作のモデルをアップロードしてモーションをつけたりできるサービスです。今回は、Mixamo本家で3Dモデルを作成して$10で購入し、Unityのプラグイン(Mixamo Animation Store)から歩きモーションと立ちモーションをそれぞれ$10で購入しました。しめて$30です。モデリングもモーション付けも自分でやるとものすごく大変な作業ですから、とりあえずこうして解決してしまえるのはとてもありがたいです。

ゲームデザインについてですが、作る直前にUnity上でラグドールの実験をしてまして、ラグドールが吹っ飛ぶのは面白いよねということで(ゲームのバグ動画などでよくありますよね)いろいろ物を投げ込んでぶつけて吹っ飛ばしてやろうと。物理エンジンも活用できるし、見栄えがするのでいいかなと思いました。

吹き飛ぶときの爆発はDetonator Explosion Frameworkを使用しています。Prefabをスクリプト1行で生成するだけで派手な爆発をしてくれるアセットです。ゲームの内容的にはなぜ爆発するんだって感じですが(笑)、一度使ってみたかったので。まあ、特撮などでも意味もなく爆発しますし。このキャラがそういう体質なんでしょう、きっと。

避けゲーということで安直にAvoiderとタイトル決定。たぶん主人公の名前か何かでしょう。タイトル画面は、Adobe Fireworksで適当にプリセットのスタイルを適用して字詰めしてロゴを作成、プレイヤーキャラを配置してライトを当ててできあがり。ちょっとでも動きがないと寂しいので、トゥイーンライブラリのiTweenを使って、ライトのフェードインとロゴの明滅をさせています。ちなみにこのトゥイーンライブラリというのはFlashの世界で生まれて発展してきたもので、簡単に言うと「動き」をライブラリ化したものです。コード1行でオブジェクトをアニメーションさせたりできます。UnityにもFlashのタイムラインのようなアニメーション機能があるのですが、Flash同様、トゥイーンライブラリのほうが楽に動きをつけられる場面が往々にしてあります。iTweenのサイトのExamplesに印象的なデモがたくさんあります。

ただ避けて生き延びるだけではゲームとして単純すぎると思ったので、宝石を取るとスコアが加算されるようにしました。ゲームはプレイヤーに2つ以上のことを同時にさせるといいそうです(参考:社長が訊く『New スーパーマリオブラザーズ Wii』)。というか、Asset StoreにGem Shaderというシェーダがあって、綺麗な宝石モデルも入っていたので使ってみたというのが本当のところで、順序が逆かもしれません。ちなみにシェーダの中身をまったく見てません。ブラックボックスのまま使って(使えて)しまっています。

宝石を取ったときにエフェクトがないと取った感が出ないのでどうしようかと思ったんですが、標準アセットのParticlesパッケージの中にあったFireworksをもうこれでいいやとそのまま使用。あとは、せっかくなのでコンボボーナスをつけたり、宝石を2種類にしてスコアを変えたりしてよりゲームっぽくしてみました。なお、時間が経つと宝石が小さくなって消えるのもiTweenを使ってます。

難易度調整、実はこれが一番時間がかかったかもしれないんですが、NORMALモードとHARDモードを用意するという逃げに走りました。あとカメラアングルは最初もっと低かったんですが、フィールドの上のほうがオブジェクトに隠れて見づらくなり、下のほうばかりをうろうろするプレイになってしまって、あまりに不自然だったので、ほとんどトップビューにしてしまいました。せっかくのキャラクターがよく見えなくなってしまうので躊躇したんですが仕方なしです。タイトル画面のアップでカバーする感じですかね(笑)。それと、プレイヤーキャラの当たり判定は、胴体より下だけにしてあります。

BGMは、一応DTMerなので本来なら自作するべきところなんですが、CubaseのLoopMashのプリセットをちょっといじって書き出してシーンに配置して終わり。宝石を取った効果音もCubase付属音源から適当な音色を探してきて使用。オブジェクトが跳ね返る音は効果音素材CDからです。

と、こんな感じで作ったんですが、ゲーム内容的にも制作工程的にも相当横着してますね。とりあえず見ていただいた方々に面白いと言っていただけたので(ありがとうございます!)いいのかな?と思います。既存のアセットを使いまくってるのはバレバレでしたけど(笑)。

*

さて、こうして短期間で1本でっちあげてみて、Unityのことが以前よりもずっとよくわかったというか、正直、過小評価してたような気がしてきました。すごいゲームエンジンだとは認識していたんですが、ゲームエンジン本体よりも、周辺の文化圏こそが真価だったんじゃないかと。今回、他人のアセットの力を素直に借りようと最初に決断していたとはいえ、素材を探してぽんぽん放りこんで、ちょこちょことスクリプトを書き足すだけで、あっという間にそれっぽいものが組み上がっていくのは、いいんだろうか本当にって感じでした。ほとんどチートのような気もするんですが、実はこれが本来の使い方(のひとつ)なのかもしれません。セミナーの講演の中でもレゴブロック的という話があったように記憶しています。

実のところ、現状のAsset Storeはサーバがかなり重かったりして、お世辞にも使いやすいとは言えないのですが(公式フォーラムのこのスレッドで、Unityの中の人いわくなんとかするそうです)、そのあたりが解決されてアセットの数が増えれば、さらにとんでもないことになりそうな予感がします(なお、ゲームに使用可能な3D素材については他にもTurboSquidなどがあります)。

あと、スクリプトについても、まだ慣れていなくてAPIがあまり身についていないのですが、何か引っかかったらUnity Answersフォーラムで検索すればすぐ答えが出てきましたし、そもそも今回自分で書いたJavaScriptコードが全部で600行ほどしかありません。流暢に書けなくてもどうにでもなる量です。

このスピードとこのコード量で、1人で、仮にも物理エンジンが走り、人体モデルが動くような3Dゲームをでっちあげられるというのは、今までは考えられなかったことなんじゃないでしょうか。3Dゲームを作れるのはナムコとセガくらいみたいな時代もあったと思うんですが、すごいカジュアル化です。Unityが言うには「民主化」とのことですが、ある意味、言い訳ができなくなりつつあるようで、ちょっと怖いなと……まあ、一方で、リソース作りが大変なのは基本的に変わらないとも思うんですけどね。

こうした至れり尽くせりのゲームエンジンに乗っかれるかというのは、特にプログラミングをする人にとって心情的に難しいところもあると思うんですが、自分の場合はどうもメリットのほうが大きそうなので、本気で乗っかってみようかなと考えはじめてます。

とりあえず、もう1本くらい実験作を作ってみたいですね。もうちょっとシーンやスクリプト的に凝った何か。

2011年7月19日

AIR+FlashDevelopでブラウザ・PC・Android・iPhone一挙開発

そもそもAIRって何なんでしょうか?(芸術以外で)

Adobeのページを読むと、Adobe Integrated Runtimeの略称で、”a cross-operating system runtime”などと書いてあるんですが、どうやら最近のAdobeの方針として、Flash等で作ったものがアプリケーションとしてどこでも動く、いわゆるWrite Once, Run Anywhereな実行環境を整備しようとしているようです。そのためのランタイムがAIRという理解でいいのかなと。自分の印象だと、どうもFlash自体がJavaに近い方向に向かってるみたいですね。

ちなみにAdobeはゲーム方面にも力を入れはじめているようで、Flash 11以降で、GPUを用いた3D描画や、ゲームコントローラのサポートが予定されているようです。

さて、AIRでは、以下のようなアプリケーションを開発できます。

  • iOS(iPhone, iPod touch, iPad)アプリ
  • Androidアプリ
  • WindowsやMacにインストールするアプリケーション

ActionScriptで書いたプログラムが、ブラウザで表示するFlashとしてだけでなく、各プラットフォームのアプリケーションとして配布できるのはすごくお得そうに見えます。あちらではAndroid SDKでJava、こちらではiOS SDKでObjective-Cというのは大変ですから。JavaScriptは? というのはちょっと今回は置いといて(笑)。

要は、FlashでiPhoneアプリだろうがPCゲームだろうが作れるよ!ってことです。

AIRアプリケーションは、Adobeが無料で配布しているFlex SDKとAIR SDKを使って作成できます。今回の趣旨ですが、フリーのActionScript用統合開発環境であるFlashDevelopと、ちょっとしたバッチファイル群を使って、ひとつのソースコード群から各プラットフォームのアプリケーションを手軽にビルドできないものかと試行錯誤してみました。

前置きが長くなりました。動くものをということで、こちらが今回のサンプルです。まだ癖が強い環境ですので、いろんなAPIを軽くテストするような感じになっています。

さしあたって、Flash版をクリックして見ていただくのがいいかと思います。この気楽さがウェブアプリのいいところですね。

iOS版については、配布するにはApp Storeに登録するしかなく、こんなテスト用プログラムでは審査を通りませんので公開できません。代わりにiPhone 4で動かしている様子を撮影しましたのでご覧ください。

FlashDevelopプロジェクトはこちらです。

FlashDevelopは4.0.0以降を使用します。2011-06現在、4.0.0はまだベータ版なのですが、3.3.4では駄目なので……不具合など不安な場合は正式版になるまで待ってください。ベータ版はこちらで配布されています。また、iOS版のパッケージングにはiOS Developer Programへの加入が必要です(ここを読むと、もしかしてMacがなくてもなんとかなるんでしょうか?)。

プロジェクトの簡単な説明と、そのあとAIRの所感にも触れたいと思いますが、その前に回り道になる人が出ないよう2点ほど。

ここではフリーソフトのFlashDevelopを使っていますが、AdobeのFlash Professional CS 5.5Flash Builder 4.5では正式にマルチプラットフォーム書き出しができます。高価ですが、なにしろ公式サポートなのでずっと楽です。Flash Builderの体験版を試してみたところ、インストールして数分でiPhoneとAndroid実機での実行までできました。

ADC MEETUP ROUND 01 発表資料「Flashによるマルチデバイスアプリ開発ワークフロー」 | ClockMaker Blog

また、iOSやAndroidのパッケージングについて、すでにエントリを書いている方々がいらっしゃいます。Adobe公式のドキュメントなども非常に詳しいです。まずこちらで基本的な手順を確認したほうがいいかもしれません。

AIR2.7でAIR for iOSを試してみた | ton-up blog – とんぶろ
FlashDevelop4ビルド版でAIR for Android(ver 2.7)のセットアップメモ | alt

Adobe AIR * Adobe AIR® アプリケーションの構築
Adobe AIR * モバイルデバイス向けの AIR アプリケーションの開発

iPhone/iPadアプリ開発の扉を開くAdobe AIR 2.6とは(1/3) – @IT

*

というところで、ようやくプロジェクトファイルについてです。通常のFlashDevelopプロジェクトにいくらか手を加えてあります。使いかたとしては、

  1. FlashDevelop上でSWFファイルをビルドする
  2. 証明書などを用意
  3. build.batまたはbuild.bat debugを実行してAIRアプリケーションとしてパッケージング(ipa、apk、air、exeファイルの作成)

となります。なお、Androidプロジェクトでは、FlashDevelopのビルドで実機での実行・デバッグまでできるようにしてあります。それぞれ詳しい手順については、README.txtをご覧ください。

ソースコードの共有

FlashDevelopでは通常ひとつしかないプロジェクトファイル(*.as3proj)ですが、複数用意することで、ひとつのソースコードからそれぞれのプラットフォーム向けのビルドを行っています。プロジェクトは、Projectパネルでas3projファイルをダブルクリックして簡単に切り替えられます。当然ですが、プロジェクトのプロパティやライブラリの登録などはそれぞれ独立していますので、変更した場合に忘れないよう注意が必要です。as3projファイルはXMLファイルですので、どんな情報を保持するファイルなのか、テキストエディタなどで見ておいたほうがいいでしょう。

条件付きコンパイル

プラットフォームによってコンパイルされるソースコード内容を変更するために、ActionScriptの条件付きコンパイルを用いています。

ActionScript 3.0 の条件付きコンパイル – akihiro kamijo

FlashDevelopでコンパイル定数を設定するには、プロジェクトのプロパティ、Compiler OptionsタブのCompiler Constantsを開きます。MY_CONFIG::PLATFORMとMY_CONFIG::AIRを設定し、以下のようにビルド・実行するコードを変更しています。

config namespace MY_CONFIG;

MY_CONFIG::AIR {
	...
}

if (MY_CONFIG::PLATFORM == "iOS") {
	...
}

条件付きコンパイルではなく、Capabilitiesなどの参照でなんとかなることも多いかもしれません。

アプリケーション記述ファイル

Adobe AIR * AIR アプリケーションプロパティの設定
Adobe AIR * モバイルアプリケーションプロパティの設定

AIRアプリケーションをパッケージングするときに必要な設定ファイルです。プロジェクトのルートにapplication.xmlを配置するとFlashDevelopのProjectパネルのボタンから設定ウィンドウを開けるので、ここに配置して全部のプラットフォームで共有しています。

アプリケーションアイコンについては、全部のプラットフォームで使用するサイズのアイコンをまとめて設定してしまっています。

	<icon>
		<image16x16>icon16.png</image16x16>
		<image32x32>icon32.png</image32x32>
		<image36x36>icon36.png</image36x36>
		<image48x48>icon48.png</image48x48>
		<image72x72>icon72.png</image72x72>
		<image57x57>icon57.png</image57x57>
		<image114x114>icon114.png</image114x114>
		<image128x128>icon128.png</image128x128>
	</icon>

こうすると、使用されないアイコンまでパッケージに含まれ、パッケージの容量がやや増えてしまいますが、まあ気にしないでいいのではないかと(富豪的パッケージング)。各サイズのアイコンは、バッチファイルでImageMagickを使用してひとつのicon.pngからまとめて作成しています。

*

モバイル版AIRを試してみて気づいたことです。

解像度

スマートフォンのディスプレイ解像度は多種多様です。が、デフォルトでは、Flashがアスペクト比を保ったまま画面の内側からフィットするようにステージをスケーリングしてくれますので、ゲームなどではこれに任せて、物理的な解像度についてはあまり気にしなくてもいいのかなと思います。Flashが元来ベクターグラフィックスに強いのも幸いしています。ただし、ディスプレイのアスペクト比の違いが問題になります。たとえば、iPhone向けにステージサイズを640×960に設定したSWFを、Galaxy Sの480×800の画面で表示すると、ステージの上下が余分に表示されてしまいます。

この対策は3つ考えられると思います。

  • DisplayObject.maskでステージ内のみ描画するようマスクを設定する
  • ステージの外部をオブジェクトで覆い隠す
  • アスペクト比にあわせて表示要素を外にずらす

マスクを使うのが楽なのですが、やはり描画にマスク判定が入ると重いのか、端末や描画モードによってはパフォーマンスがかなり落ちてしまいます。iOSのCPUモードではフレームレートが半減することもありました。2番目、3番目の組みあわせになるでしょうか。

なお、StageScaleMode.NO_SCALEを設定すると、物理解像度の座標系で描画できるようになります。詳しくはこちらのページに解説があります。

複数の画面サイズ向けのモバイルFlashコンテンツのオーサリング | デベロッパーセンター

StageScaleMode.NO_BORDERというものもあります。こちらは外側から画面にフィットしてくれます。

CPUモードとGPUモード

モバイル版AIRには、CPUモードとGPUモードの2つの描画モードがあり、アプリケーション記述ファイルのrenderModeでどちらを使用するか指定します。GPUモードのほうが速そうに思えますが、端末や描画内容によってまちまちで、正直よくわかりません。AIR 2.6と2.7で特性が大きく変わったりもしているようですし、各種ベンチマークをまとめて取るプログラムを作る必要があるかもしれません。サンプルではAndroid版はGPUモード、iOS版はCPUモードでパッケージしています。

GPUモードではDisplayObjectのフィルタが使えない等いろいろな制限があります。制限事項がこちらのページにあります。

Adobe AIR * 一般設定

ちなみに今後、モバイル版AIRでもMolehillのハードウェア3D APIが使えるようになるそうですので、そうなるとGPUモードを重用するようになってくるのかなと思います。

あと、このエントリを書いている最中に、AndroidのGPUモードに不具合らしいものを見つけました。cacheAsBitmapをtrueにすると、アプリを中断して復帰するときに表示が化けるようです。フィルタを設定しただけでもtrueになるので要注意です。

互換性と実行速度

実際、ActionScriptコードがどれくらい動いてくれるのかですが、こいつ、動くぞ!って感じです(笑)。SiONでMMLが演奏できたり、Away3D Liteで3Dモデルが表示されたりするほどですから、大抵の処理は問題ないんじゃないでしょうか。つまり、ActionScriptの豊富なコード資産がそのまま使えるということです。

ただ、パフォーマンスについてはスマートフォンのCPUパワーなりです。サンプルの「Sound (SiON)」でLoad Complex MMLで呼び出せる曲(超手前味噌ですみません……)がGalaxy Sではほぼ正常に鳴ってますが、iPhone 4では処理が追いつきませんでした。上の動画で音が途切れている様子がわかりますのでご覧ください。

また、描画についてはかなり軽い描画内容でしか高フレームレートが維持されず、すぐ30fps以下になってしまいます。個人的には60fps大好き人間なのでつらいところですが、このあたりについてはランタイムの最適化が進むか、あるいは時間が解決するというやつで、今後数年でスマートフォンの性能が上がれば大丈夫なんじゃないでしょうか。

あと、細かな制限があるようで、例えばiOSではActionScriptを含んだSWFをLoaderやEmbedで読み込めないようです。ipa-debugターゲットで読み込もうとすると、”Uncompiled ActionScript”というエラーメッセージが出ます。

また、ipa-app-storeターゲットでは何も表示されず、以後の読み込みがすべて失敗します。うっかりActionScript入りSWFを読み込んでしまうことは多そうですから、割と地雷の予感……。

それからGalaxy SでMP3の再生開始に間があります。「Sound (MP3)」でSEボタンを押して確認できますが、ゲームの効果音の再生に支障がありそうです。iOSでは瞬時に鳴ります。

タッチパネルの判定

スマートフォンの小さい画面にウェブページと同じサイズでボタンを表示すると、なかなかタップできないことがあります。ボタンを大きくしてもいいですが、当たり判定だけを大きくする方法もあります。実際、サンプルではBackボタンの反応が悪かったので、タッチパネルの場合だけひとまわり大きい透明な矩形をaddChildして判定を広げてみました。このテクニックは使いでがあるんじゃないかと思いました。

// タッチパネルなら当たり判定を広げる
if (Capabilities.touchscreenType == TouchscreenType.FINGER) {
	var rect:Rectangle = backButton.getBounds(backButton);
	rect.inflate(10, 10);

	var touchArea:Shape = new Shape();
	var g:Graphics = touchArea.graphics;
	g.beginFill(0xFF0000, 0);
	g.drawRect(rect.x, rect.y, rect.width, rect.height);
	g.endFill();

	backButton.addChild(touchArea);
}

リモートデバッグ

最初、実機でのデバッグのやり方がわからなかったのですが、

  • SWFをDebugビルド
  • Androidではapplication.xmlでandroid.permission.INTERNET権限を許可しておく
  • adtでパッケージングするときに -connect [FlashDevelopが動いているPCのIPアドレス] オプションをつける
  • FlashDevelopのデバッガを Debug > Start Remote Session で待機させてから
  • 実機でアプリを起動

というようにすればいいようです。iPhone、AndroidともにFlashDevelopのデバッガでステップ実行が可能です。

iOSでのテストが手間

iOSのパッケージングがとにかく遅いです。SandyBridgeのCore-i5 2500K機で、今回のサンプルのパッケージングに1分30秒かかっています。また、パッケージしたアプリを実機に転送するのにiTunesを使うのですが、「同期」ボタンを押して、転送が完了するまでさらに1分30秒近くかかります。ビルドの間にラーメンができます。パッケージングのほうは、最適化をしないipa-debug-interpreterターゲットを使えば数秒で終わるんですが(実行速度がだいぶ遅くなります)、実機への転送はiOSがクローズドなため改善されるとも思えず、困ったものです。Flash Builderでもipaファイルを自分で転送するように指示する表示が出ます。

Androidならパッケージング、転送、起動全部込みで10秒かかりませんので、Androidでのテストが基本になりそうです。

それと、アプリケーション記述ファイルのversionNumberを変更しなければiTunesでアプリを更新できません。どうしても変更を忘れてしまうので、versionNumberを0.0.1増やすPerlスクリプトを作ってパッケージングの際に自動的に呼び出すようにしています。

Flexフレームワーク

まだFlashDevelopでは試していないのですが、モバイル版のFlexフレームワークを使えば、一般的なスマートフォンのアプリケーションのようなユーザーインターフェースを作成できるようです。TitaniumjQuery Mobileみたいな感じですかね。

Flash Builder 4.5でAndroidアプリを作ってみた – @IT
Android女子部が初体験 Flash Builder 4.5で作るAIR for Androidアプリ(1/4):CodeZine

View and ViewNavigator – Flex SDK – Adobe Open Source
Understanding Flex Mobile View and ViewNavigator : Mihai Corlan

制限事項

AIRの制限ですが、現状ではスマートフォン固有のAPIにアクセスできないため、アプリ内課金や、iOSのGameCenterなどが使えません。といっても、この辺は公式フォーラムでどうにかしてと言ってる人が大勢いるので、すぐになんとかなるんじゃないかと思います(笑)。現時点でも、かなりトリッキーな方法で実現している方もいるようですが。

こちらのエントリで、AIR for Android/iOSでできないことが簡単にまとめられています。

hi-posi Blog Archive AIR for Androidでできない事。

Androidへのインストール

AndroidでのAIRアプリケーションの実行にはランタイムが必要です。

AIRアプリケーションを初めてダウンロードして起動するとき、ランタイムがないということで上のようなダイアログが出て、「インストール」をタップするとマーケットのAIRダウンロードページにジャンプします。このとき最初のAIRアプリケーションは終了してしまいますので、AIRをインストールしてから再度起動する必要があります。一度入れれば問題ないのですが、ちょっとしょっぱいなーと思います。

そして、「250,000超件のダウンロード」ということで、これがAIR for Androidの現在の利用状況ということですかね?

パッケージの正体

パッケージングして完成したairファイル、ipaファイル、apkファイルは、実はどれもZIPアーカイブです。拡張子をzipに変更すれば展開できますので、最終的にいったいどういうファイルが作られたのか、のぞいてみるといいかもしれません。

いまさら情報かもしれませんが、バイナリの先頭に「PK」が見えたらたぶんZIPです。

コード署名証明書

WindowsにAIRアプリケーションをインストールしようとすると出てくるおなじみの警告ダイアログ。最近はネイティブアプリケーションへの風当たりが厳しいですね。

発行元不明をなんとかしたければ、自己署名ではなく、ちゃんとしたコード署名証明書が必要です。国内で個人を対象に発行してもらえるのはグローバルサインだけのようですが、高すぎるんですがどうにかなりませんか……。ちなみにインストールするときだけでなく、「プログラムのアンインストールまたは変更」でも発行元がUNKNOWNになってしまって結構目立ちます。

困ったら

やはりまだまだ発展途上の環境なので、謎の現象がいろいろ起きます。特にスマートフォンで疑わしい挙動に出くわしたら、Adobeのフォーラムやバグデータベースに当たるといいのではと思います。

まとめ

さて、下準備にだいぶ手間がかかりましたし、今のところ人柱度も相当高めですが、これで一応、ブラウザだろうがデスクトップだろうがiPhoneだろうがAndroidだろうが、APIを調べまわったりせず、同じ手順で何かを動かせるわけです。自分としてはかなり気が楽になったなと思います。必要が生じればネイティブなSDKに切り替えればいいわけですしね。タッチパネルで何か実験しようと思ったらすぐActionScriptで書けますし、比較的パフォーマンス要求のないアプリなら、全プラットフォームで同時リリースなんてこともできるかもしれません。

これからのFlashのアップデート、特にゲームコントローラのサポートにも夢が膨らみます。最近はJavaScriptがトレンドですが、個人的にはFlashとももう少し長いつきあいになりそうな気がしています。

今後の課題としては、どうすればモバイルで描画パフォーマンスが出るか、あと今回はAndroid MarketやApp Storeでリリースするところまで行ってませんので、そのためのアプリを何か考えないといけないなと。

そうそう、デスクトップ版AIRで、簡単に透明ウィンドウにできるのも面白いです。application.xmlのtransparent周りを変更してみてください。

久しぶりのエントリが思いもかけず長くなりました。日頃ウェブの情報にお世話になりっぱなしですし、こういうアウトプットもしておかないとということで。ひとまず置いて実制作に戻りたいなと思います。

2011年6月27日

iPhone/iPad用ピアノアプリを作りました

どうもApp Storeが混乱しているようで状況がさっぱりわからないんですが、もう公開状態だと考えていいんでしょうか、これ……。

というわけで、このところ作っていたiPhone/iPad用のピアノアプリ「Live Piano」がon saleとなったようですのでお知らせします。ダンパーペダル、リバーブ搭載です。矩形波も鳴るのでゲーム音楽にも好適です。詳細およびApp Storeへのリンクはこちら

鍵盤については、iPadよりも、むしろ小さいiPhoneできちんと演奏できるようにと調整しました。たとえば当たり判定の大きい黒鍵などです。それについては演奏デモ動画を作らなければ……こんなに早く公開されると思わなかったので、準備がまだできてません。Stay tuned!って感じでひとつ。

(追記)やっとというか、専用ページにデモ動画を公開しました。動画制作に慣れてなかったり、アプリに不具合が見つかって修正版の審査がなかなか通らなかったりで時間がかかってしまいました。開発の経緯なども書いてありますので、よろしければどうぞ。

2010年4月2日

Flashでジョイスティックを使う実験

Flashはブラウザゲームのすぐれたプラットフォームですが、ジョイスティックが使えないのが欠点のひとつです。一方、新興のゲームプラットフォームにUnityがあります。こちらのプラグインはまだほとんど普及していませんが、ジョイスティックに対応しています。

FlashにもUnityにも、それぞれブラウザのJavaScriptとの連携手段が用意されています。それなら、Unityからブラウザを介してFlashにジョイスティックの状態を送れば、Flashでもジョイスティックが使えるんじゃ? と思いついたので、実際にやってみました。

ジョイスティックの状態を送る一連のプロセスについて。まずUnity側からです。Unityでは、物理デバイスの入力を整理・抽象化して、それぞれ名前をつけて扱うようになっています。メニューの Edit > Project Settings > Input にその設定があります。今回はひとまず生データを送りたいので、レバーの軸とボタンを一通り登録します。レバーのデッドゾーン(Dead)もゼロにしておきます。

気分の問題ですが、遅延を少なくするために、Unityの最大フレームレートを上げておきます。

function Awake()
{
	Application.targetFrameRate = 300;
}

次に、ジョイスティックの状態の変化をブラウザに毎フレーム送信します。ブラウザとの通信についてはUnity Web Player and browser communicationに説明があります。Application.ExternalCall()でHTML内のJavaScriptを呼び出すことができます。実際のスクリプトとしては以下のようになります。

var axes = new float[9];

function Update()
{
	for (var i = 1; i <9; i++) {
		var position = Input.GetAxis("Axis" + i);
		if (axes[i] != position) {
			axes[i] = position;
			turnOnLed();
			Application.ExternalCall("axisHandler", i, position);
		}
	}

	for (i = 0; i < 16; i++) {
		var buttonName = "Button" + i;
		if (Input.GetButtonDown(buttonName)) {
			turnOnLed();
			Application.ExternalCall("buttonHandler", i, 1);
		}
		if (Input.GetButtonUp(buttonName)) {
			turnOnLed();
			Application.ExternalCall("buttonHandler", i, 0);
		}
	}
}

ちょっとしたテスト兼演出として、関数を呼び出したときにLEDが点灯するようにしました。

function turnOnLed()
{
	GameObject.Find("Led").SendMessage("TurnOn");
}

次にHTMLです。Flashの埋め込みにはSWFObject 2.2を使用しています。Unityから呼び出されたJavaScriptの関数axisHandlerとbuttonHandlerが、ExternalInterfaceで登録したActionScriptの関数を呼び出します。

var attributes = {
	id:"Flash"
};
swfobject.embedSWF("Game.swf", ...);
...
<script type="text/javascript">
	function axisHandler(no, position) {
		document.getElementById("Flash").axisHandler(no, position);
	}

	function buttonHandler(no, state) {
		document.getElementById("Flash").buttonHandler(no, state);
	}
</script>

ExternalInterfaceは、ローカルファイルシステムではセキュリティのため動作しません。ローカルにApacheを立ててそこでテストするのが簡単です。また、ExternalInterfaceはいろいろ罠があって、ちょっとしたことで動かなくなることが多いようです。今回もそれでなぜかIEでだけ動かず、しばらくはまったんですが、教訓としては、SWFObjectのtest suiteから始めるのがいいと思います。

ここの”Browser communication test page”がブラウザとの通信のサンプルです。test suiteというだけあって動くことが保証されていますので、このサンプルがサーバ上できちんと動くことを確かめてから少しずつ書き換えていくのがいいんじゃないでしょうか。

Flash側では、以下のようなクラスを作ってコールバック関数を登録し、メッセージを受け付けます。

package
{
	import flash.external.ExternalInterface;

	public class Joystick
	{
		public static const AXIS_MAX:int = 9;
		public static const BUTTON_MAX:int = 16;

		private var axes:Vector.<Number> = new Vector.<Number>(AXIS_MAX);
		private var buttons:Vector.<int> = new Vector.<int>(BUTTON_MAX);

		function Joystick()
		{
			if (ExternalInterface.available) {
				ExternalInterface.addCallback("axisHandler", axisHandler);
				ExternalInterface.addCallback("buttonHandler", buttonHandler);
			}
		}

		public function axisHandler(no:int, position:Number):void
		{
			axes[no] = position;
		}

		public function buttonHandler(no:int, state:int):void
		{
			buttons[no] = state;
		}

		public function getAxis(no:int):Number
		{
			return axes[no];
		}

		public function isButtonPressed(no:int):Boolean
		{
			return (buttons[no] == 1);
		}
	}
}

これでUnityからFlashまでジョイスティックの状態が伝わるようになりました。

ちなみに、いったんここまで作った後で、逆の方法に思い当たりました。つまり、UnityからFlashにジョイスティックの状態を流し込むのではなく、FlashからUnityにジョイスティックの状態を問い合わせるやり方です。もしこちらができれば、通信量も間違いも少なく好ましいでしょう。が、ブラウザからUnityの関数をSendMessageで呼び出したときに、戻り値が取得できないので断念しました。

さて、これで、「Unityのプラグインがインストールされていればジョイスティックでも操作できるFlash」ができました。アクロバティックなやり方ですが、信じがたいことにIE8、Firefox 3.6、Google Chrome 4それぞれでXbox360コントローラなどを使って普通に操作できるようです。特にアナログレバーを動かすとかなり頻繁にメッセージが送られるのでもつだろうかと心配だったんですが、レスポンスは悪くないし、CPU使用率もたいして上がりません。作る前はデータの間引きなども考えていたんですが、必要なさそうなのでやっていません。

で、実用性はどうかというと、微妙かなと思ってます。まず、ブラウザゲームでジョイスティックを使う文化がないですよね。それに、ジョイスティックを使いたい人はすでにJoyToKeyなどを使っているはずです。アナログレバーが使えるという違いはありますが、Flashゲームはまずマウスとキーボードで遊べるように作りますから、ゲームにアナログレバーの必要な操作を持ち込むわけにはいかないでしょう。そもそも、ジョイスティックを使うゲームなら最初からFlashではなくUnityで作れよという気もします。

あと、1つのウェブページに2つの標準でない技術を使うことになるので、それなりにリスクがありそうです。Unityの出力するHTMLファイルも結構複雑ですし(ちなみにコメントで説明が書かれているので読んでおくのがおすすめです)、環境によっては不具合が発生するかもしれません。導入には結構ためらうものがあります。

もしUnityのプラグインがある程度普及すれば(20%くらい?)メリットのほうが大きくなるかもしれません。また、いずれにせよFlashでジョイスティックを使う方法ができたということで、ウェブではなく、どこかへの展示用のFlashなどでしたら役に立つかもしれません。

……ということで、どうもひたすら微妙な感じ。こんな変態的なことをさせる前に、そもそもAdobeがFlashでジョイスティックをサポートしてくれたらいいんですけどね……。ゲーム志向にするとか考えてるならその辺検討してほしいなあ。

2010年2月10日

トップページ
プロフィール

はてなブックマーク
wonderfl