inosyanのブログ

プログラム、家庭菜園、僕が興味を持ったことを書いていきます

ウルティマオンライン月額課金無料化した記念にjsで画像解析ツールを作成

UO (ウルティマオンライン) との再会

f:id:inosyan:20180418014232j:plain

ウルティマオンライン無料化の記事を読んだ時には「おお!」と心の中で叫びました。そして、しばらくしたら、Mythic Entertainmentからメールが届き、「これはやるしかない!」と思いました。

This mail contains important information on changes to your Ultima Online account.

All Ultima Online accounts that have been closed for more than 120 days can be used to access Endless Journey. The Endless Journey account allows play (with some restrictions) for free without an end date. In addition, all accounts now have access to the Stygian Abyss expansion. More information on the new Endless Journey account type and on the Stygian Abyss expansion can be found here.

UO Team

若い人たちはきっとこのゲームを知らないと思います。名前は聞いたことがあったとしてもプレイしたことがある人は少ないでしょう。私が初めてプレイしたMMORPG(Massively multiplayer online role-playing game = 規模多人数同時参加型オンラインRPG)がこのゲームでした。今から18年ほど前の話です。

そのころはだいぶ流行ってきてたころで、雑誌か何かで知って、MMORPGとはどんなものか体験するためにはじめました。特に知り合いがいるわけでもなかったし、ネットでのコミュニケーションは苦手だったので、いつも一人でプレイしていました。はじめのうちは、ヘイブンという初心者の島からはじまりチュートリアルをこなした後に、どの場所にいくのかを選択する場面になりました。どこに行っていいのかさっぱりわからずにいると、操作を間違ったのか勝手にそうなったのかわからないけど、サーペンツホールドという島に飛ばされました。

そこは毒を持った蛇がうようよいる小さな島でした。後で知りましたが初心者がいく場所ではなかったようです。でも周りは海なので船や魔法がないと他の場所にはいけません。頑張ってスキルをあげようにも敵が強すぎて初心者にはなかなか倒せません。でもなんとか生き延びて、たまに来る上級冒険者が捨てていくアイテム(重量オーバーで捨てたり、上級者には価値が無いものだったり)をせっせと拾い集めてショップで売ってお金をためて、船を買ってようやく島から脱出できました。それがはじめの1ヶ月間のプレイでした。なんてむちゃくちゃなゲームなんだと思いながらも、なんとも言えないその世界観にハマっていきました。

それから1年くらいやってて、仕事がいそがしくなってやめてしまいました。廃人になる前に卒業できてよかったのですが、5年ほど前にまたふと思い立って半年くらいやりました。その時は、なんとマイホームを持つことができました。UOの世界では自分の家を建てて住むことができるのですが、以前は土地不足で家を建てることのできる土地が余っていませんでした。リアルマネー数十万円で取引されている時代もありました。それが5年前では、プレイ人口が減ったからか、どこでも空いているというわけではなかったけど探し回ってやっと空き地に家を建てることができました。でも残念ながらまた仕事がいそがしくなってやめました。

UOをやめることは、つまり月額課金をやめることです。リアルの生活がいそがしくプレイ時間がほとんととれない状況だと、月額課金はもったいないので結局やめてしまいます。でもたまにまたやりたくなります。なので、今回のこのニュースはとても嬉しいです。

いざプレイ

アカウント画面を見てみると、Endless Journey が有効になっていました。 f:id:inosyan:20180418014254j:plain

久しぶりすぎてすっかり忘れています。だいぶたったのでmac版もでてるかと思ったけど、そんなことはありませんでした。ParallelsWindows版のクライアントをダウンロードしました。昔ながらの2D表示のクラシック版と、3D表示のエンハンスド版がありますが、5年前の経験でmac上でエンハンスド版が重くて動かなかったのでクラシック版にしました。macも新しくなったのでもしかしたら動くかもしれませんが、初回起動時のパッチ適用にもエンハンスド版はすごく時間かかった経験があり、いまはすぐにプレイしたいのでリスクを避けました。

f:id:inosyan:20180418014310j:plain

プレイ画面で入れるIDとパスワードは、ブラウザでのアカウント管理画面のそれとは違うようです。メモも残っておらず、おぼろげな記憶をたよりにようやくログインできました。 5年前にプレイした時はどこのシャードだったか、なんとか思い出しました。

f:id:inosyan:20180418014324j:plain

キャラ選択画面にいくと、5年前にプレイしていたキャラがみんないました! たしか、家具、道具、薬、巻物、洋服、料理などを作る人と、冒険する人とにそれぞれ役割をわけてた気がするけど、細かいことは忘れています。 まずは思い出すところからはじめようと思います。

スキルやステータスの情報を記録するためのツールを作成

UOにはレベルの概念がありません。その代わりにスキルとステータスがあって、どの組み合わせで成長させるかを選ぶことによって個性が生まれます。また、どれも無限に伸ばせるわけではなく、合計値の上限が決まっているので、組み合わせが重要になってきます。

f:id:inosyan:20180418014343j:plain

f:id:inosyan:20180418014354j:plain

たぶん今後は、昔みたいに取り憑かれたように毎日やるのではなく、たまに気が向いた時にプレイする感じになると思います。そうすると前回どのキャラがどういう状態だったのかを忘れてしまうので、ステータスやスキルを記録したいと思いました。

そのためには、ゲームから情報を取得できなくてはいけません。たぶんエンハンスドクライアントなら簡単にできます。Luaという言語で独自UIを作れるので、情報取得のAPIがあるはずです。でもクラシック版にはその機能はありません。データの保存してありそうな場所を見てみましたが、これはオンラインゲームなので、ほとんどのデータはサーバー上にあり、ローカルにはほぼありません。不正行為のようなこともやりたくありません。そうなると、ゲーム画面に表示されているものが得られる情報のすべてということになりますが、目で見て書き写すのは面倒です。

そこで、画面をキャプチャし、javascriptで解析してみることにしました。昔ならありえない発想ですが、最近のパソコンやjavascriptエンジンの性能を目の当たりにしているので、できるような気がしたのです。やってみたところ、キャプチャ画像を白黒に変換し、アルファベットや数字の画像とピクセルが一致するかどうかを調べて、画像の中に書いてある文字や数字を解析するという、いかにも重そうな処理が全く問題なくできました。

f:id:inosyan:20180418014417p:plain

これが解析結果画面です。ステータスとスキルを一覧できます。デザインはスプレットシートにコピーしやすくするためにあえてUIは装飾していません。

f:id:inosyan:20180418014435p:plain

解析結果をスプレッドシートにコピペしてみました。これで成長の記録はばっちりです。

f:id:inosyan:20180418014449p:plain

ついでにペーパードールというキャラクターの画像を、背景やかばんや巻物などを除いてキャラクターだけをアルファで抜いて切り出すこともできました。

f:id:inosyan:20180418014503j:plain

f:id:inosyan:20180418014514p:plain

javascriptで画像処理も問題なくできました。コンパイル無しで試せるところがとても良いです。プログラムのやる気がわきます。ゲームをきっかけにしたプログラム作成は楽しいしモチベーションを維持しやすいのでおすすめです。jsでの画像処理、もうすこし深掘ってみようと思います。

スニペッチ バージョン0.0.7 リリース & ドキュメント一通り完成

f:id:inosyan:20180303135022p:plain

スニペッチのドキュメントを書いていて、見つかった不具合を修正しました。

バージョン 0.0.7 (2018.3.29) - 「イベント」の「~が押された時」の選択肢「どれかの」にあたる定数 KEY_ANY を追加 - 「調べる」の「ビデオ」の選択肢「モーション」にあたる定数 SENSOR_VIDEO_MOTION を追加 - 「制御」の「~を止める」の選択肢「ステージの他のスクリプト」にあたる定数 STOPTARGET_OTHER_IN_STAGE を追加 - 「制御」の「~を止める」の選択肢「スプライトの他のスクリプト」にあたる定数 STOPTARGET_OTHER_IN_SPRITE を追加 - 「演算」のブロックに「余り」を追加 (書き方の例: 10 % 3) - 「base」を削除したときに落ちる不具合を修正 - 「演算」の「=」のブロックのスニペットが 1 = 1 だったので、正しく 1 == 1 に修正 - 「イベント」の「~ > ~ のとき」のブロックのスニペットに引数が抜けていたので修正 - コスチュームとサウンドの画面で、コスチューム名/サウンド名のラベルが言語切替で切り替わるように修正

そして、ドキュメントを一通り書きあげました。これで、スニペッチのすべての機能が明らかになりました。 中学生くらいの人を対象に書いたつもりですが、たぶんわかりにくいと思うのでこれから直していきます。

以下が、今回追加したドキュメントです。

計算式の書き方
条件文の書き方
カスタムメソッドで新しいブロックを作る
「ベース」でカスタムメソッドを再利用しよう
コメントの書き方
目的別にコンパイル結果を変える「プリプロセッサ」
こまめに保存し、バージョン管理システムを活用しよう
色コードについて
コマンド一覧 動き
コマンド一覧 見た目
コマンド一覧 音
コマンド一覧 ペン
コマンド一覧 データ
コマンド一覧 イベント
コマンド一覧 制御
コマンド一覧 調べる
コマンド一覧 演算
コマンド一覧 その他

スニペッチの中で私が一番気に入っている機能は、「ベース」です。なぜなら、スクラッチで高度なプログラムを作れる可能性を、この機能は持っているからです。

簡単に説明すると、この機能はプログラムを細かく分解し、再利用する機能です。
作ったものを再利用できるという点では、オンライン版のスクラッチの「バックパック」の機能に似ています。バックパックは作ったものをとっておき、使いたい箇所にコピーする機能です。 https://blog.hatena.ne.jp/inosyan/inosyan.hateblo.jp/entries

ですが、「ベース」は、コピーするのではなく、呼び出すものです。これは、プログラミングでクラスをインスタンス化して使うのに似ています。
実際、スニペッチでベースのメソッドを呼び出すときには new します。

var base = new BaseSample();

function scripts(){
    whenKeyPressed(KEY_RIGHT_ARROW, function(){
        base.sample(true);
    });
    
    whenKeyPressed(KEY_LEFT_ARROW, function(){
        base.sample(false);
    });
}

そして、ベースから、さらに別のベースを利用することができます。つまり、部品と部品をつなげて、さらに高機能な部品「ライブラリ」を作ることができるということです。 ライブラリの開発、共有、利用のサイクルで、さらに高度なアプリを生み出すことができるでしょう。

そもそも、スクラッチで効率を追い求めるのは教育的に良いことなのかどうか、私はプログラマであって教育の専門家ではないので判断できませんが、プログラマの視点で言えば、効率化は当然やるべきことです。「同じコードを2度書かない」「車輪を再発明しない」を実践しようとすればたどり着く結論です。もちろん、学習者が勉強のために何度も同じコードを書いてみることは悪いことではありません。

使っていくと、いろいろ改善したい箇所が出てきました。作品を作りつつ、引き続きスニペッチも改良していこうと思います。

スニペッチのドキュメントを追加しました

f:id:inosyan:20180303135022p:plain

いまスニペッチのドキュメントを書いていますが、いくつか出来たのでホームページに追加しました。まだ足りないので引き続き書いていきます。

コスチューム&サウンド
作品をスクラッチのサイトにアップロードしよう
スクリプトのメソッド
変数、リスト、定数
if文とrepeat文の書き方

それと、スニペッチでスクラッチのゲームを作ってみました。(Flash Playerが必要です)
Star Shooter

githubにソースを上げています。
github

f:id:inosyan:20180319082444p:plain

これについては詳しく説明したいのですが、それはまた次の機会に。

スクラッチ上級者向けのアプリ「スニペッチ」を更新しました

f:id:inosyan:20180303135022p:plain

スニペッチ

スニペッチとは

スクラッチという、子供向けのプログラム言語があります。マウス操作でブロックを並べるだけでプログラムを作れることが大きな特徴で、キーボードの操作に慣れてない子どもたちでも、タイプミスでつまづくことがありません。英語がわからなくても大丈夫です。

ただ、複雑なプログラムを作るためにはたくさんのブロックを並べなけばならず、マウス操作で行うのは大変です。スニペッチは、文字で書いたプログラムをスクラッチに変換するアプリです。

クラッチはWebアプリですが、オフライン用のScratch 2 Offline Editorがあります。これで作った作品をWebにアップロードしたり、Webから作品をダウンロードしてオフラインエディタで続きを作ったりできます。

f:id:inosyan:20180303135058p:plain

スニペッチは、このオフラインエディタといっしょに使います。スニペッチでコードを書き、緑の旗(スクラッチの世界では再生を意味する)を押すと、コードが作品ファイルにコンパイルされ、オフラインエディタが起動して作品が読み込まれます。

クラッチと同じブロックが並んでいて、それをコードエディタにドラッグ&ドロップすると、ブロックがコードに変わります。これを繰り返すことで、ブロックとコードが同じ意味だということに気づき、やがてはブロック無しでコードをかけるようになるのです。

また、「スニペッチ」の語源でもあるのですが、繰り返し使う処理「スニペット」を別ファイルにしておき、他のファイルから参照することができます。スクラッチでは、同じ処理を複数のスプライトにコピペすることがよくありますが、そうすると修正する際に複数箇所で行わなければならなくなります。ですが、スニペッチでは共通処理のコードを修正するだけで済みます。

スニペッチの特徴

  • コードエディタ
    • JavaScript風のコード
    • 単語のハイライト
    • コード補完
    • 自動インデント
  • クラッチと同じブロックからコードを作成
  • 共通コードの再利用
  • コードをスクラッチ用の形式にコンパイル

f:id:inosyan:20180303135113p:plain

作ったきっかけ

今から5年ほど前、ネットでスクラッチのことを知り、当時小学生だった娘といっしょにはじめました。スクラッチのイベントに足を運んだり、プログラム教室にボランティアで参加したりもしました。スクラッチのアカウントを作り、子どもたちの参考になればといろいろ作品を作りました。

ある時、スクラッチのファイルの中を見てみたら、JSONとメディアファイルで出来ていることに気づきました。これなら、ブロックじゃなくてテキストで編集できるのでは?と思ったのがはじめのきっかけです。 ブロックとJSON構造の関係を解析して、JSONを手書きで作品を作ってみました。

f:id:inosyan:20180303135133p:plain 「ねこのおさんぽ」

JSONを手書きではなく、普通にプログラム言語で書きたい。そのようなツールがあれば、スクラッチの作品を効率よくつくれるし、娘にも文字で書くプログラムを覚えてもらいたい。そういう思いからスニペッチを作り、2014年11月にはじめのバージョンを公開しました。

ですが、娘はあまり興味をしめしてくれず、スクラッチもあまりやらなくなってしまいました。私もモチベーションが下がり、最近までなにもしていませんでした。

復活した理由

先日、配布していたスニペッチのインストーラーが動かなくなっていることに気づきました。理由はインストーラーの証明書の問題でしたが、この記事「昔作った Adobe AIR のアプリをメンテしようとしたら、リリースビルドが出来ずに苦労した件」に書いたように解決できました。

久しぶりに動かすとちゃんと動き、また昔のようにスクラッチの作品を作ってみたいと思いました。自分で作ったものを褒めるのも変ですが、このまま埋もれさせるのももったいないし、みんなに知ってもらい、役に立ててもらいたいです。

今後の予定

クラッチFlashで作られています。Flashは2020年でサポートが終わることもあり、スクラッチ本家ではReactで作りなおそうとしているようです。

AIRは今後もサポートが続くとアナウンスされているので、AIRでの開発は可能です。ですが、いま仕事でReactをやってることもあり、React + Electron で作りなおしてみたいです。いま流行っている言語で書きたいし、ReactならWebサービスにもできる可能性もあります。

でも、まずはスニペッチのドキュメントをまとめないと、詳しいコーディングの方法をわかってもらえないので、それをやろうと思います。ドキュメントはホームページに掲載していきます。 一人でも多くの人に便利だと思ってもらえるとうれしいです。

f:id:inosyan:20180303135154p:plain

Tokyo HoloLens ミートアップ vol.7 に行ってきました

品川で行われた HoloLensのイベント「Tokyo HoloLens ミートアップ vol.7」 に行ってきました。 会場にはアイボを連れてこられている方もいらっしゃいました。はじめて見ましたが、しぐさが本物の犬みたいでとても可愛いです。

f:id:inosyan:20180219143700j:plain

「HoloLens製カードゲームHADO KARTを現場に導入した話」増田博志@trappleさん

もうこんなサービスが始まっているんですね。乗り物とMRを組み合わせているところが面白そうです。 プロトタイプはLuggieという電動カートを使って作ったそうです。なにもないところから試作品を作って試行錯誤の末にサービス化させるのって大変なことだと思います。

f:id:inosyan:20180219143727j:plain
f:id:inosyan:20180219143740j:plain

ホロレンズの頭の上につけるバンド部分は、現場ではよく破損するそうです。私のはまだ壊れてませんが、毎日使うと壊れやすい部品なのかもしれません。

会場でHoloLensを持ってきている人を見ると、バンドを付けてない人が多いです。バンドはなくても後ろの調整ネジで閉めれば落ちてこないので、かならずしも必要ではないのかもしれません。また、バンドがなければそのまま下におろして首にかけることができます。
でも、ネジで締めるとこめかみが痛いんですよね。今日懇親会でピザを食べたときに気づきましたが、ホロレンズつけたまま食べるとこめかみがいたくなります。

f:id:inosyan:20180219143759j:plain

電源アダプターによっては充電されないことがあるそうです。純正のものを使用したほうが無難ですね。バッテリーの持続時間はHADO KARTの場合3時間だそうです。

f:id:inosyan:20180219143814j:plain

ホロレンズおよび観覧者を考慮したシステム構成になっていました。 ホロレンズの開発は、ホロレンズのことに意識が行ってしまいがちですが、観覧する人のことも考えてることも大事ですね。

f:id:inosyan:20180219143834j:plain

開発に使用されたライブラリ - UniRx: Object Pool - BestHTTP: Socket.IO - LeanTween: UWPで使える - Vuforia: WorldAnchor

HoloLensは高いので複数端末での開発は気軽にはできませんが、実際にやったひとの話を聞くと、複数になると直面する苦労もいろいろとあるようです。みんなで同じ座標を共有するためには、原点がどこなのかを揃えなければなりません。 2つのマーカーをそれぞれのHoloLensやiPhoneで読み取っていました。

f:id:inosyan:20180219143848j:plain

「HoloLensで高品質なグラフィックスを実現する」MIRO@MobileHackerzさん

以前、初音ミクが歌舞伎を演じる様子をテレビで見ましたが、その制作の話を聞かせてもらいました。テレビで見てるときは、スクリーンに映っているようにも見えるし、画面に重なっているようにも見えるし、不思議だなと思ってましたが、正解は両方でした。
会場ではスクリーンにプロジェクターで投影したものを上映し、ネットではスクリーンの映像を消して3Dを重ね合わせたものを配信していたそうです。

f:id:inosyan:20180219143914j:plain

でもスクリーンにした映像は、斜めから見ると歪んでしまいます。会場でも立体を表示したいということでHoloLensでの表現を研究しているそうです。 もともとのモデルは17万ポリゴンあったそうですが、HoloLensで動かすために7.7万ポリゴンまで削減したそうです。60fpsを実現するチャレンジはロマンを感じました。

技術メモ - アニメーションは、スキニング計算は重いしモーションが固定なので事前に計算し、全頂点の情報を持つ
- Alembic ImporterはUWP非対応
- Unity上でSkinned meshを1フレームずつコマ送りしてファイルに頂点情報を書き出すツールを制作
- 全頂点分のアニメーションのファイルサイズは 30fps換算で2分33秒のアニメーションが 8.8GB
- 30fpsのデータを補間し60fpsで再生
- IndexとUVは全フレーム共通なのでまとめる
- PositionとNormalだけがアニメーションする
- floatではなく固定小数(-2.0f~2.0fをUInt16Maxで分割) 8.8GB が 2.5GBに削減
- 頂点圧縮はCPUコストがかかるので断念
- 着物の箔押し部分を再現するためMetallic Smoothnessマップに対応
- AmbientOcclusionマップに対応
- 内部はLinearで計算、最終段でGammaに変換
- XRenderViewportScaleを対象物との距離、描画面積などによって値を調整し、60fpsでるように調整

f:id:inosyan:20180219143928j:plain

セットを実際に作ってみるということも大事という話、そのとおりだと思いました。HoloLensは現実とバーチャルが重ね合わさってはじめて一つの表現が完成するものなので、現実のほうもなにか凝ったものを作ってみたくなりました。

f:id:inosyan:20180219143946j:plain

超歌舞伎、興味がわきました。

f:id:inosyan:20180219144000j:plain

「Unityを使わずHoloLensアプリを作ってみた」河原田清和さん

優れたミドルウェアのおかげでHoloLensアプリの開発は難しくありません。誰でも簡単に、プログラムが書けなくても作ることができます。しかしそこに依存するあなたは自分をエンジニアと胸を張っていえますか?

UE4は結局今の段階では速度を出すのは厳しく、DirectXは速度があがる可能性があるという結論でした。 効率を考えるとミドルウェアを使うのが現実的だと思います。ですが、仕組みを知るため、DirectXからHoloLensに出してみる工程に一度触れてみることはありだと思います。

f:id:inosyan:20180219144018j:plain

技術メモ(DirectX)
- 必要なもの
- Visual Studio 2017 - HoloLens Emulator
- テンプレートからプロジェクトを作る
- Visual C++ -> Windowsユニバーサル -> Holographic から Holographic DirectX 11 App を選択
- ビルドしてHoloLensへ転送
- ここをいじればいろいろできる
- コンテンツ初期化、シェーダー読み込み
- インプットイベントハンドラ
- SpinningCubeRenderer:CreateDeviceDependentResources()内の
- Vertex/Pixelシェーダーファイルのロード、作成
- 頂点フォーマットを定義
- キューブモデルを生成(8頂点をプログラム内に記述)
- 頂点バッファ、インデックスバッファを作成
を改造する


会場の端で、私の作ったアプリ Window Breaker のデモをさせていただきました。
見に来ていただいた皆様ありがとうございました。いろんな方との交流ができてよかったです。 持参したHoloLens以外はなにも用意してなかったので、デモなのかどうかわかりずらかったですね。次回は「デモやってます」くらいのプレートは用意します。

f:id:inosyan:20180219144039j:plain

次回も都合がつけば行きたいです。

次回イベント
HoloLens MeetUp Vol.8
日程: 2018 4/21(土)
時間: 13:00~18:30
会場: 日本マイクロソフト株式会社

昔作った Adobe AIR のアプリをメンテしようとしたら、リリースビルドが出来ずに苦労した件

Flash Builder x AIR

f:id:inosyan:20180218104818p:plain

Adobe AIR は、一つのソースコードから様々なOSやデバイス向けのアプリを作れる仕組みです。
そして、Flash Builder は、Adobeが開発したデベロッパー向けのアプリで、FlashAIRの開発が行えます。Flashで開発してた頃はメインで使っていました。数年前まではAIRを使って、デスクトップアプリ向けやモバイル向けに、いろんなゲームやツールを作ってました。

昔作ったairアプリがインストールできなくなってしまった

ふと、昔作ったアプリのインストーラーである、拡張子 .air ファイルをクリックすると、

Sorry, an error has occurred.
The application could not be instlled because the installer file is damaged. Try obtaining a new installer file from the application author.

というエラーが出ました。

f:id:inosyan:20180218104851p:plain

ネットの情報では、このエラーはインストーラーを作ったときの証明書が古いと出るそうで、たしかにインストーラーをコンパイルしたのは今から数年前で、その証 明書を作ったのはそれから更に数年前なので、かなり古いです。

再ビルドしようとしたらエラーが出た

それなら新しく証明書を作りビルドしなおせば良いと思い、そうしようとしたところ、こんどは、

Error creating AIR file:Could not generate timestamp: Operation time out

というエラーが出ました。

f:id:inosyan:20180218104909p:plain

調べて見ると、これは、Flexの使っている Java 6 が参照しているタイムスタンプサーバがいまは動いてないのが問題で、Java 7 か 8 に上げれば解決するそうです。
Fixing the ‘timestamp’ error when packaging an AIR app for desktop

Javaのバージョンをあげる

マシンにはすでに Java 8 が入っています。ところが、Flash Builderは古いバージョンのJavaを参照しているので、新しい方を参照するように直す必要があります。 macでの対処法はここに書いてあったので、このとおりにやってみました。 Running Adobe Flash Builder on Win and Mac with Java 7/8 (UPDATED)

まず、ターミナルで、Javaのバージョンを調べます。

java -version

私の環境では、このように返ってきました。

java version "1.8.0_71"

このバージョンをメモしておき、次のコマンドのJavaのバージョンjdk1.8.0_71のところは、自分の環境のものに置き換えて実行します。

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_71.jdk/Contents/Home

次のコマンドはroot権限が必要です。これもJavaのバージョンを自分の環境のものに置き換えて実行します。これは、私の環境では失敗しましたが、このパスにフォルダをつくればいいのでFinderから手動で作っても大丈夫です。

sudo mkdir –p /Library/Java/JavaVirtualMachines/jdk1.8.0_71.jdk/Contents/Home/bundle/Libraries

続けてこのコマンドを実行します。これもJavaのバージョンを自分の環境のものに置き換えて実行します。

sudo ln -s /Library/Java/JavaVirtualMachines/jdk1.8.0_71.jdk/Contents/Home/jre/lib/server/libjvm.dylib /Library/Java/JavaVirtualMachines/jdk1.8.0_71.jdk/Contents/Home/bundle/Libraries/libserver.dylib

上記JAVA_HOMEに設定したパスの一つ上に Info.plistというファイルがありますが、これをテキストエディタで開くと

<key>JVMCapabilities<key>
<array>
    <string>CommandLine</string>
</array>

の箇所があるので、array の中に2行追加します。

<key>JVMCapabilities<key>
<array>
    <string>JNI</string>
    <string>undledApp</string>
    <string>CommandLine</string>
</array>

そして、Flash Builderのアプリ "/Applications/Adobe Flash Builder 4.7/Adobe Flash Builder 4.7.app" のところまで行き、右クリックでコンテキストメニューを開き、Show Package Contents で中身を見ます。更に奥の階層の中の、Contents/MacOS/Adobe Flash Builder 4.7.ini をテキストエディタで開きます。このファイルまでのフルパスは、
/Applications/Adobe Flash Builder 4.7/Adobe Flash Builder 4.7.app/Contents/MacOS/Adobe Flash Builder 4.7.ini
です。 そして、このファイルの最後の行に、

-Djava.library.path=../../../eclipse/plugins/com.adobe.flexide.nativelibs_4.7.0.349722/os/macosx/:../../../eclipse/plugins/com.adobe.flexide.amt_4.7.0.349722/os/macosx/:../../../eclipse/plugins/com.adobe.flexbuilder.utils.osnative_4.7.0.349722/os/macosx/

を足します。念のため事前にこの相対パスが存在するか確かめてみましたが、私の環境では大丈夫でした。

そして、これが大事ですが、マシンを再起動 してください。Flash Builderを再起動しただけでは変更が反映されません。

最新のAIR SDK を昔のやり方で入れようとして失敗

実は、Flash Builder を Java 8 で動くようにしただけでは、Timestampの問題は解決しませんでした。調べてみると、SDKを最新にしたら直ったという報告があったので、最新を入れてみることにしました。

ですが、AdobeSDKは4.6が最後のバージョンで、その後オープンソース化されて、いまは Apache Flex SDK という名称に変わっていました。 ちなみに、SDKAdobeが開発していた時代は FlexAIR は別々に配布されていて、zipを解凍したものを、Flexのフォルダの中にAIRのフォルダの中に混ぜて使っていました。混ぜたフォルダをアプリの sdks フォルダの中に置き、Flash Builderの プロジェクトのプロパティの Flex Compiler から Configure Flex SDKs を選んで、そのフォルダを読み込めば利用できます。

まず、今回の問題はAIR書き出し時の問題なので、最新の AIR SDK 28.0 をFlex4.6に混ぜてみました。しかし、Timestampの問題は解決しません。

AIR SDKのバージョンがあがったので、アプリ名-app.xml名前空間

<application xmlns="http://ns.adobe.com/air/application/3.1">

のバージョンの部分を

<application xmlns="http://ns.adobe.com/air/application/28.0">

に変えました。しかし、今度は、その名前空間が認識できないというエラーが出て、ビルドできません。

最新のFlex SDK を昔のやり方で入れようとして失敗

Flex SDKも最新にしないといけないことに気づき、sdkをzipで落としてきて入れようとしたら、Flash Builderがそれをうまく読み込んでくれませんでした。エラーメッセージを見るといろんなファイルが足りないようです。おそらく著作権などの問題が絡んでいて一緒に配布できないのでしょう。一つずつ入れて行こうとしましたが、 ant を使って解決できると書いてあったので試してみました。ですが、うまくいきませんでした。

SDK Installer を使ったらSDKを最新にできた

いろいろ探していたら、SDK Installer を見つけました。なんと今は、インストーラーを使ってSDKをインストールできるようになっていました。

f:id:inosyan:20180218104930p:plain

これを使って、SDKを最新にすることができました。

でもFlash Builderが不安定、パッチをあてて解決

その後、ビルドしようとすると、

Error: Comparison method violates its general contract!

というエラーが頻発し、うまくビルドできませんでした。 解決法を探していたら、 この記事 Error: Comparison method violates its general contract! の対処法 を見つけました。Flex SDKのバグのようで、その対処のパッチを作ってくれていたので、それを使わせていただいたところ、見事解決しました。

そして、無事、airアプリをビルドすることができるようになりました。

まとめ

今回はかなり大変でしたが、まとめると、Timestamp問題を解決するためには、これらが必要でした。

  • Flash BuilderをJava 8で動くように設定する
  • ApacheSDK Installerを使って FlexAIRSDKを最新にする
  • アプリ名-app.xml名前空間を最新のAIRのバージョンに書き換える
  • Flex SDKのバグに対処するためのパッチをあてる

Flashはもう2020年に終了が決まっていますが、AIRはどうもその後もまだ続くようです。 Flash Playerのサポートは2020年末で終了、ただしAdobe AIRは継続の方針

せっかく最新の環境にできたので、もうすこしやってみようかなと思いました。

複数のUnityのバージョンを管理できる「Unity Hub」

f:id:inosyan:20180209000726p:plain

Unityのベータ版のダウンロードサイトを見ると、ベータ版のインストーラーの隣に「Unity Hub」というものが並んでいました。

f:id:inosyan:20180209000757p:plain

スクリーンショットは Unity 2018.1.0b5 ですが、2/8の時点では Unity 2018.1.0b6 です。

説明にはこうあります。

Now available in Beta, Unity Hub simplifies how you find, download, and manage your Unity Editor installs and view all your Unity projects. It will also help you discover features to help you get started faster - such as the new Templates feature.

便利そうなので、早速インストールしてみました。

インストールすると、こんな画面が開きます。

f:id:inosyan:20180209000811p:plain

インストールしたばかりの時はまだ何も入ってないので、No versions available now と表示されています。

Beta Releases を選ぶと、ベータ版がダウンロードできます。

f:id:inosyan:20180209000830p:plain

ダウンロードしたバージョンは、On my machine に追加されます。

f:id:inosyan:20180209000845p:plain

左のメニューから Official Releases を選ぶと、安定版の
- Unity 2017.3.1f1
- Unity 2017.2.1f1
- Unity 2017.1.3f1

がリストアップされ、それぞれダウンロードできます。それ以前のバージョンはここには出てきませんが、On my machine の画面の 「+Locate a Version」 ボタンで、既にインストール済みのバージョンをリストに加えることができます。

f:id:inosyan:20180209000901p:plain

さらに、リストアップされたアプリ名の右の…をクリックすると出て来るポップアップメニューで、デフォルトで起動するバージョンを選択できるようです。

f:id:inosyan:20180209000916p:plain

上部メニューの Projects で、最近開いたプロジェクトの一覧が見れます。プロジェクトのパスの横には、そのプロジェクトを編集したUnityのバージョンが表示されています。
いままでは、まず適切なバージョンのUnityを起動しておいてからプロジェクトを開く必要がありましたが、Unity Hubからプロジェクトを選べば、適切なバージョンのUnityで開いてくれます。
また、プロジェクト名の右の…で開くポップアップメニューで、どのバージョンで開くのかを選択できます。

f:id:inosyan:20180209000937p:plain

新しいバージョンは通知欄からインストールできます。

f:id:inosyan:20180209000952p:plain

古いバージョンで作られたプロジェクトを保守したり、バージョンの違う複数のプロジェクトを同時に開発する際には便利ですし、気軽にベータ版を試せるのは嬉しいです。

アセットストア向けの開発は、最終成果物のアップロードを行なったバージョンがサポート対象バージョンになるため、できるだけ古いバージョンのUnityで動作確認するのですが、複数バージョンを使い分けできるUnity Hubは重宝します。これからはデフォルトで使うことになりそうです。