2012年3月17日土曜日

非同期で動作する OCUnit (SenTestingKit) を書いてみた

非同期のテストができないのでGHUnitを使っていたのですが、やっぱりCmd+U一発で単体テストが走る便利さがいいなーと思い、ためしにSenTestingKitで非同期のテストができないかやってみたらできちゃったので公開します。

https://github.com/akisute/SenAsyncTestCase

ライセンスはMITライセンスとします。

使い方とか例とかはREADMEを見たりテストケースを見てみたりしていただければ一発でわかるかと思います。あ、もちろんSenTestingKit.frameworkが必要ですよ。

2012年3月4日日曜日

Unity 3.5でバージョン管理をする


およそコンピュータを使った仕事に該当するものでしたら何でも、複数の人物が同時に作業するための何らかの仕組みが必要になるのは、コンピュータを使った仕事に関わっている人でしたら皆ご存知かと思います。特に開発業務といえばgitやhgといったバージョン管理システムの出番になります。そういうわけで今回は Unity プロジェクトでのバージョン管理について一ヶ月間ほどやってみた結果をご紹介したいと思います。


■Unity 3.4以前の場合

そんな暗黒時代のことは忘れましょう。


■Unity 3.5以降の場合

Unity 3.5から新しい仕組みが導入され、 Unity Asset Server というビルトインの ボッタクリ バージョン管理システムを使う以外に、好きなバージョン管理システムを使ってUnityのプロジェクトをバージョン管理することができるようになりました。これを使わない手はありません。まずは公式のガイドを見てみましょう。
http://unity3d.com/support/documentation/Manual/ExternalVersionControlSystemSupport.html

これによると、以下の手順を踏むのが良いようです。
  1. メニューの Edit -> Project Settings -> Editor から、 Version Control の Mode という項目を探し、 Metafiles を選択する。これで外部のバージョン管理システムが導入できるようになります。このチェックを入れると、
    • Libraryディレクトリが重要なメタデータを管理するディレクトリではなくただのキャッシュディレクトリになり、バージョン管理をしなくてよくなる。
    • 新たにAssetsディレクトリ以下のすべてのファイルとディレクトリについて.metaファイルが生成される。
    • 新たにProjectSettingsディレクトリが生成される。
  2. メニューの Edit -> Project Settings -> Editor から、 Asset Serialization の Mode という項目を探し、 Force Text を選択する。この手順はどちらかと言うとおまけです。これを実行すると、ほとんどのAssetファイルがバイナリではなくテキスト形式で保存されるようになり、diffやmergeが行えるだけではなく差分だけをコミットするようになるためバージョン管理システムが扱うデータ量が減ります。
  3. プロジェクト配下のAssetsディレクトリとProjectSettingsディレクトリをバージョン管理システム配下に追加する。それ以外のファイルは追加しなくて良い。
たったのこれだけです。なかなか簡単そうですね!ということで早速やってみました。

・・・ところがぎっちょん、実際にやってみると出るわ出るわ問題の山。


■.metaファイルがどこからともなく勝手に生成される

これが最大の問題です。外部バージョン管理をするためにUnityが.metaという名前のメタファイルをテキスト形式で生成するのですが、コイツがトラブルを起こしまくります。
  • ファイル削除時に.metaを消すのを忘れて、同じ名前のファイルをあとから作成しようとして.metaがぶつかりトラブルになる
  • ファイルも.metaもバージョン管理下から確かに消したはずなのに、なぜか.metaファイルだけが勝手に復活している
  • ブランチを移動すると急に.metaファイルが湧いてきて、ブランチのマージ時に衝突する
主要な原因はUnityが空のディレクトリから.metaファイルを生成しているためです。 以下のようなケースで、中身が空のディレクトリというのは容易に生成されてしまいます。
gitの場合
gitはディレクトリをバージョン管理対象に含めないため厄介なことになります。通常はgit pull時にmerge/rebaseが実行され、その際に空になったディレクトリは削除されるのですが、merge/rebaseの最中に衝突が発生したりすると問題が大きくなります。merge中に裏でUnityが動いていると空ディレクトリの.metaがその場で生成されて、考えるだけでも恐ろしいことになったりします。
通常はこれで問題ないのですが、merge/rebase時に衝突が発生していて、裏でUnityが動いていたりすると酷いことになるみたいです。
hgの場合
hgはgitと同様にディレクトリがバージョン管理対象外なのですが、hg update時に空になったディレクトリをきちんと削除してくれます。これはupdateがworking directoryの中身を指定されたリビジョンの状態にするから、という認識です。gitと違いpullやupdate時にmerge/rebaseを実行しないためトラブルになりづらいのか?などと考えてますが実際に苦労したわけではないのでよくわかりません。おそらくgitよりはトラブルになりづらいとは思います。
1および3にupdateすると、きちんとFolderやOtherFolderが削除されてくれます。いい感じ。
svnの場合
ディレクトリもバージョン管理の対象にするので問題ありません。以下の図を参照。
r2のような削除の仕方をするとFolderが残ってしまうためFolder.metaが生成されてしまうのですが、普通はディレクトリを消したときはr4のような削除の仕方になるので問題がないはずです。
また中身が事実上空なディレクトリ(すでに使われていない.metaしか入っていないディレクトリなど)が亡霊みたいにさまよっていて延々と自身の.metaを書き出し続けたり、善意で予め作っておいた空ディレクトリが.metaを吐き出していることを知らずコミットされては削除されを繰り返していたり、二人が同時にディレクトリを削除しようとして片方のコミットが衝突して結果が壊れてしまったりなど、枚挙に暇がありません。

元ファイルを移動したり削除した際に.metaを消さなくてはいけないというだけでも極めて面倒で、相当なトラブルになりました。そもそもがUnityを使っているプロジェクトのメンバーが全員バージョン管理システムに慣れていないため、とりあえずバージョン管理システムのGUIツールがいうがままに変更を全部コミットするだけという具合の運用に。.metaだけが延々と残って衝突が繰り返されるという悲惨な状況が発生してしまうこととなりました。これはUnityのせいではなくメンバーがバージョン管理の考え方を正しく理解していないのが問題なのでツールは何を使っても発生しうるのですが、.metaがなければここまで問題は拡大しなかったと思います。

いっそignoreしてしまいたいぐらいなのですが、この.metaにファイルごとのメタ情報が全て詰まっているため、当然ignoreするとプロジェクトがブッ壊れます。これはひどい><

本家のドキュメントで例にされているのがgitでもなくhgでもなくsvnであるあたりを見ると、なんだかsvnで動作させることしか考えてなさそうな印象です・・・


■.unityファイルがマージできない

.unityファイル自体はテキスト形式にできるのですが、中で使われているAssetのIDがちょっと触れただけでものすごい勢いで変化したり、他人の環境では別の値になったりするため、殆どの場合マージできません。iOSプロジェクトのxcodeprojファイルみたいな感じです。こればかりはマージを諦めるしかありません。


■まとめ

最初はgitを使って管理をしていたのですが、上記に挙げたような問題が多発しまくって回らなくなってしまいました。別のバージョン管理システムを使うことも検討したのですが、そもそもメンバーのバージョン管理に対する知識が足りていない上に.metaが存在する以上hgやsvnに変えても問題が根本的に解決しそうにないと判断し、結局社長に頼んでAsset Serverを購入して試してみることになりました。がっかしです>< ですがAsset Serverならば.metaを使わないでバージョン管理できるので問題を根本的に解決できそうです。

逆に言えば.metaに気をつければそれ以外の箇所ではgitでもあまり問題になりませんでした。バイナリを大量に扱うため重いのではないかと懸念されていましたが、github経由ででも問題なくpush/pull出来る程度の重さにしかならなかったです。ということで.metaとうまく付き合えるチームメンバーが揃っているのであれば、Asset Serverなしでも十分やっていけるのではないかと思いました。

個人的にUnityでバージョン管理をする際におすすめする外部バージョン管理システムはsvn、可能であればPerforceです。git/hgのようにブランチを主体とするバージョン管理システムはブランチを切り替えた瞬間に.metaに殺されるケースが多々あるため、ブランチの使用そのものが非推奨となり、力が発揮できません。mergeについてもバイナリファイルやmergeできないテキスト形式のファイルが多くて結局意味がない気がします。どうしても分散VCSを使いたい!というならhgをお勧めします。ブランチ切り替えは常にupdate -Cすることで対応できるかなと。bazaarはわからないのでノーコメント。gitはpull時の衝突の最中に裏でUnityが動いていて大爆発するケースがあったのでやめておいたほうが良いです。hgなら少なくともpull/update時に爆発することはないはずですからね。

次はAsset Serverを試してみて、使用感を書いてみようかと思います。果たしてお値段に見合った効果は得られるのか!?乞うご期待です!

スタイラスペンの先端を保護する画期的な方法を思いついた


iPadなどのタブレット端末向けにスタイラスペンを持ち歩いていると、先端が破損してしまったり書き味が悪くなってしまったということはありませんか?最近のスタイラスペンの先端は繊細なシリコンゴムでできているものが主流で、持ち運びの最中に強い力がかかったりしてしまうと書き味が悪くなってしまうのです。そこで今回ご紹介したいのが、 Bamboo Stylusにマジックラッションペン No.300のキャップがジャストフィットする ってことなんです。こうやって写真のようにラッションペンのキャップをBamboo Stylusにつけてしまえば、持ち運んでいる最中にペン先が痛むことがありません!

Bamboo Stylusはクリップが取り外せるので、書いている最中はこんなふうに後ろにキャップが付けられます。


これで随分とペン先の劣化に悩まされることがなくなりました。これから発売される高級スタイラスは先端保護のためにキャップを付けて欲しいなぁと思った次第です。



■以下完全に余談: こんなことを思いついた経緯

もともと私は以前からiPad向けのスタイラスマニアで、よさそうな新製品が出るたびに買っては買っては試し、気に入ったものはポケットに入れて常に持ち歩くようにしています。
参考: http://akisute.com/search?q=スタイラス

その中でも特に書き味が素晴らしく、気に入っているのがBamboo StylusとSu-Penです。

B004XF0FQWWacom iPad/IPad2/iPhone4対応 描画、ポインティングに最適なタッチペン Bamboo Stylus CS-100/K0
ワコム 2011-05-27

by G-Tools
B005VCL6AKiPad/iPhone用スタイラスペン Su-Pen P101M-AS
7knowledge

by G-Tools

しかしながらこの2本はどうも先端の耐久性が他の製品にくらべて今ひとつなのか、ポケットに入れて持ち歩いているとどんどんペン先が劣化してしまうのです。まず最初にSu-Penが一月程で書けなくなってしまいました。TwitterでぼやいていたらSu-Penの担当の方に迅速かつ丁寧な対応をいただき、初期不良交換までしていただいたのですが、新しいペン先もやっぱり一月でダメになってしまいました。ものすごく丁寧な対応をしていただいたのになんかすみません>< Bamboo Stylusも三ヶ月ほどでペン先が死んでしまうため、こちらは購入後ペン先を2回も交換しています。これは悲しい。

そんな具合でスタイラスのペン先の劣化に悩まされていたある日、会社に落ちていた鉛筆と鉛筆キャップを見てふと思いついたのです。 そうだキャップを被せれば良いじゃん と。よくよく考えたら市販のペンは全てペン先にキャップが付いているかノック式になっていてペン先が収納できるようになっているんですよね。どうしてスタイラスにペンキャップがないのかと。早速東急ハンズの文房具コーナーにダッシュしてそこら中のペンのキャップを引剥して Bamboo Stylusに付けてみました。その結果たったひとつだけBamboo Stylusにジャストフィットするペンキャップが見つかったのです。それがマジックラッションペン No.300!

B000W9FK5Y寺西化学工業 マジックラッションペン No.300 黒
寺西化学工業

by G-Tools

まさかこんな所で1960年代から続くロングセラー製品と最先端技術が融合するとは!