2012年4月15日日曜日

iphone_dev_jp 東京iPhone/Mac勉強会でしゃべってきた & 反省

昨日開催されましたiphone_dev_jp 東京iPhone/Mac勉強会で1セッションほどお話しさせて頂きました。
http://atnd.org/events/26946

当日の様子がニコ生で配信されていて、現在タイムシフトで視聴することができます。一週間視聴できるので、4/20までですかね。
http://live.nicovideo.jp/watch/lv88663921

このタイムシフト視聴であとから録画されたプレゼンが見られるというのが実に素晴らしくて、具体的には以下のようなご利益があるわけです。
  • 遠隔地の人(今回は大阪の人)が同時に勉強会に参加できる
  • 参加できなかった人があとから当日の雰囲気を見るのに使える
  • 発表者があとから自分のプレゼンを見て反省するのに使える
主催していただいた岸川さん、機材を準備していただいたshachiさんをはじめ運営の方々、ありがとうございます!この仕組が他の勉強会でも流行ればなぁとか思ってます。(自分で主催する気がなくてすんません><)

さてここからは反省会です。タイムシフトのお陰で普段できない「自分のプレゼンはどんな具合だったか」をあとから客観的に見直すことができるので、これは大いに捗るぞと思いちょっと見てみました。2時間30分ちょいぐらいから出てくる一番煩いのが私なのですが。

うん。これはひどい><
ともかく、悪かったところとまぁ良かったんじゃないってところを列挙してみます。
  • 喋るの早すぎ。テンションが上がると更に早くなって困る。
  • 落ち着きなさすぎ。動きがなさすぎるのもつまらないので動くの自体は良いと思っているけれども、動きに変な癖があってそれが煩い。
  • プレゼンの資料で前提知識というか説明が抜け落ちている箇所が多々ある。急ぎで作ったBlocksの資料とかが顕著で、なぜ最初にアプリをクラッシュさせてるのとか説明がない。唐突すぎる。
  • 超テンションで超フランクにやったおかげかツッコミがいただけた、ネタ議論っぽくなったのはすごく良かった。だが、うまく広げられてないのがもったいない。テンパりすぎ。
逆にプレゼンが非常にうまかったsonsonさんやfladdictさんのプレゼンを見て、自分のプレゼンと比較して気づいたところを列挙してみます。
  • 発表に安心感というか安定感というか落ち着きがある。このあたりは場慣れしていきたい。
  • 図の使い方、図による説明の仕方が上手い。直前まで作っていたとか手書きで仕上げたのはやっぱダメですね><
  • デモの回数・実施方法が適切。最もキモとなる1回か2回程度に抑え、あまり資料から離れないため、流れが中断されない。ちょっと自分のプレゼンはコードとデモに逃げすぎたため流れが悪くなっていた。必要であればコードは資料の方に書いておいて流れを切らないようにする(要するに手抜き資料を作ってはならない)

あとはこれを踏まえてどんどん場数を踏んで上達していきたいですね。ということでiOSの勉強会とかで発表者募集している方がいらっしゃいましたら是非宜しければ喋らせてください!

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を試してみて、使用感を書いてみようかと思います。果たしてお値段に見合った効果は得られるのか!?乞うご期待です!