Persistence

技術メモなど

安定か挑戦か(今後を考える)

昨年の転職活動を振り返りつつ、今後の行動方針をまとめてみます。(その時、自分がどう考えていたかを書き残しておくのって大事ですね。)

振り返り

昨年春頃に、技術系の転職エージェントにお世話になりつつ転職活動をしていました。結果としては条件に合う3社くらいに転職エージェントのサイトを通じてエントリーしてみましたが門前払いといったところでした。後から考えると、全てそこそこ名の知れたベンチャーで、私のような実績もない半端者を雇うわけないですね。

そのエージェントの担当の方に言われたことは、転職活動をするには、会社選びで重要となる4つの要素について優先順位を決めることだということです。その4つの要素とは、仕事内容・報酬・人・付加価値(会社が安定しているかなど)の4つです。これを私の現状に当てはめると次のようになります。

要素 評価
仕事内容 ×:日本でも最大級のシステムを開発/運用しているが、開発はほぼすべて下請けで技術者としてのスキルアップができない。また、私は派遣社員として親会社に派遣されているので、将来的なキャリアパスがない。
報酬 ◯:普通の暮らしをするには困らない程度にはある。子供を国立の大学に通わせることはできるが、私立はゴメン無理ってレベル。
△:いい人ばかり。ただ、安定という"ぬるま湯"に浸かりきっている人が多い。(自分も9年勤めている時点でかなり浸かっている。)
付加価値 ◎:会社としての安定度はかなり高い。また、残業も月平均で10〜20時間と少なく、有給休暇も消化できる。

ということで、現状では「報酬」「付加価値」については概ね満足しているが、「仕事内容」に不満がある。つまり、この状況で転職を考えるということは、現状の優先度としては「仕事内容(技術力)」が一番高いということになります。とは言え、所帯持ちなので報酬や付加価値を今より落とすのもためらわれるため、これらを天秤にかけるのは本当に難しいです。

また、転職するべきか否かをリスクとリターンの観点で評価すると以下の通り。

リスク リターン
転職しない場合 取得できる知識は業務知識ばかりで技術者としてのスキルアップがない。だから歳をとってから会社が倒産したり縮小した場合に外に放り出されたら生きていくすべがない。 高い確率で、定年まで安定した収入を得られる。
転職した場合 今よりもハードワーク(体力的にも精神的にも)になった場合、健康を損なうことになる。その結果、収入も大きく減る。 技術者としてスキルアップすることで、どんなことがあっても技術者として食っていけるようになる。また、より高い報酬が得られる。

ここからは転職しない場合はローリスク・ローリターン、転職する場合はハイリスク・ハイリターンという、すごく当たり前の結論が見えました。もう少し丁寧に言うと、現状のリスクに対する対策が転職なのですが、転職した場合のほうが高いリスクがあるということです。(転職後のリスクが"高い"と評価したことについては後ほど詳しく触れます。実はこれこそがもっとも重要な課題だと今では思っています。)

今後の行動方針

前回の転職活動から1年が経ちました。転職に関しての考え方は変わっていません。条件に合う会社があれば行きたいです。またこの1年で、マイプロジェクトを幾つか遂行したり、他の人のプロジェクトのお手伝いをしたりして、技術的には幾らかレベルアップしました。(まだまだ自信があるとは言えない)。そして今は育児休職中なので、この機会に以下のことにチャレンジしようと思います。

  • 自分の武器を持つ

自分の武器となりそうなスキルといえば、RubyOnRailsです。これを、ちゃんと使えますと証明するためにRailsシルバーの資格を取ります。またその後に、Railsを使ったサイト構築・運営をして実績を作ります。(構築は何度もやっていますが、運営していますと言えるサイトがないので。。。)

  • 体を鍛える

自分が転職に踏み切れない一番の理由は、体調・体力に自信がない事です。そんなこと?と思われるかもしれませんが、私にとっては非常に重要なことです。これさえ解決すれば、もっといろんなことに挑戦できるようになると思います。また、転職活動や仕事をする上でも、"健康に見える"ことは相手にいい印象を与えるために大事ですよね。

  • つながりを大事にする、そして広げる

今は育児休職中でただでさえ人と合うことが少ないので、今までのつながりには積極的につながっていき、更に広がりを増やしていきます。つながりを持つ上で必要なことは、"まずは与える"の精神かなと思います。例えばOSSに貢献したり、便利なものを作って人の役に立ったり。そういうところから人脈を増やしていきたい。

この3つをクリアできた時に、次のステップに移行します!目標は4ヶ月以内!

おまけ

最後に、とても勇気づけられる記事を見つけたので記念に貼ってく。ダニーさんのことはCultureJapanの放送のあたりからずっと見てるけど本当にすごい人。Mirai株式会社、超楽しそう!

www.dannychoo.com

社内勉強会を10回開催して感じたこと

このブログにもいくつかエントリーを書きましたが、昨年下期あたりから社内勉強会を開催していました。途中、開催が途絶えかけた時期もありましたが、なんとか10回まで継続して開催することができました。現在は、私が育児休暇に入ったので主催を後輩に引き継ぎましたが、勉強会を開催して感じたことを残しておきたいと思います。

勉強会の趣旨

私の勤務している会社は、システムを開発・運用していますが、開発はほぼ全て下請けに任せているのが現状です。そのため、開発をしたくて入社した一部の人にとっては開発者としてのスキルアップができないことにジレンマを抱えていました。(私もそのうちの一人)。そういう人を部署の垣根を超えて集めて、切磋琢磨しようというのが勉強会の趣旨です。

良かった点

  • 通常の業務では関わらない部署やグループの人と交流や情報交換ができた。
  • 私と同じようなジレンマを抱えている人が意外と多くいたことが分かった。また、そこまで強い想いではないものの、勉強したいという想いを持っている人もいた。
  • それぞれの人に得意分野があるので、いろいろな分野の知識を得ることができた。
  • 勉強会で発表をすることで今まで自分が理解していると思っていたけど意外と分かっていないということがわかった。
  • 新しいことをするモチベーションを得られた。

見えてきた課題

  • 主体的な人と受動的な人がいる。

主体的な人は、自分の成果をLTしてくれたりするが、受動的な人は「勉強したいので教えてください」スタイルなのでこちらから積極的なアクションを起こさないと動いてはくれない。こういう人に対して「はじめての◯◯」的なことを手取り足取りしてあげるのは、私はあまり好きではない。なぜなら、勉強したいと思っているのならネットで「はじめての◯◯」と検索すれば、ある程度の勉強はできるのだから、自分の仕事ではないと思っているし、やったとしてもすぐに忘れてしまうのがオチだと思っている。

では受動的な人が勉強したいと思っていないのかというとそれは違うと思う。勉強したいという気持ちはあるけど、その先の目標がないから「はじめての◯◯」を検索することすらしないんだと思う。つまり、プログラムを修得することは目標ではなく、あくまで目標を達成するためのツールを得るということなので、受動的な人には目標を立ててもらい、目標を達成するには何が必要かを考えてもらうところから始めてはどうかという仮設を立ててみた。残念ながらこの仮説の検証はタイムオーバーとなってしまい実施できなかった。

何人かにこの話をしたら、肯定的な反応が多かったが、もし別の意見があれば頂きたい。なんとなく、私の考えは本当に良いのだろうかとモヤモヤしている。

勉強会のページ

今までやってきたことや発表したスライドなどはここにまとめている。

github.com

『Rubyによるデザインパターン』を読み終えて

前回の記事で、"まだまだRubyが分かっていない"と思い知らされたので、2年半ほど前*1に購入して積み本になっていた『Rubyによるデザインパターン』を1週間ほどで読みました。

Amazon.co.jp: Rubyによるデザインパターン: Russ Olsen, ラス・オルセン, 小林 健一, 菅野 裕, 吉野 雅人, 山岸 夢人, 小島 努: 本

また、読んだだけではすぐに忘れてしまうので、後から必要なパターンを探し出せるように本書の内容をまとめておきました。

qiita.com

本書が一貫して伝えていること

  • 良いプログラムを書くには、プログラムの結合度を小さくして柔軟性を高める必要がある。そのためには、「継承よりも委譲を使う」「関心事を分離する」「変わるものと変わらないものを分離する」などをすると良い。
  • 必要になるまで作るな(YAGNIでお馴染み)。
  • パターンの使いどころを誤るな。誤った使い方をしたパターンはよりプログラムを複雑にする。

感想

  • 私のように、Ruby(あるいはオブジェクト指向言語)の継承や委譲、ポリモーフィズムの説明的な知識はあるが、実際にどう使えばよいか分からないという人には非常に参考になりました。
  • 1つ1つのパターンを、最小の実装から徐々にリファクタリングしていくので理解しやすく、フルスタックではなく必要最小限で再利用することもしやすく書かれています。
  • 元祖デザインパターンGoF本をただなぞるのではなく、Rubyの場合はこういう書き方ができるということを説明しているので、「より高度なRubyの機能」や「Rubyらしい書き方とは何か」ということも同時に分かるようになっています。

次のステップ

  • 前回の記事で作ったRubyGemをデザインパターンに当てはめて再構築する。
  • Rubyについてもっと勉強する。特にProcオブジェクトをちゃんと理解する。

*1:私のAmazonの注文履歴による

メディア芸術データベースのラッパーGemを作ってみました

はじまり

数日前、こんな記事を目にしました。

nlab.itmedia.co.jp

なんともすごいデータベースが公開されました。しかも利用規約によると、データベースの情報は自由に使うことができて商用利用もOKとのこと。このデータベースを使って何かのサービスを作ろうと考える人も多いのではないでしょうか。しかし、今のところ情報を取得する手段がサイトから検索するしかないので、データベースの情報をスクレイピングするRubyGemを作ってみることにしました。

メディア芸術データベース

メディア芸術データベース

簡単にサイトの説明と、今回作成したgemでアクセスできる範囲を説明します。

サイトには大きく分類して次のデータがあります。

  • マンガ
  • アニメ
  • ゲーム
  • アート

この中で、今回対応したのは「マンガ」のみ(資料、原画を除く)です。また、蔵書情報など我々が使う上では必要性が低そうな情報は対応していません。

マンガ情報の内容として、次のデータがあります。

  • マンガ単行本作品情報・・・あるマンガの単行本や掲載雑誌などの全体的な情報
  • マンガ単行本全巻情報・・・あるマンガの単行本全巻の情報
  • マンガ単行本情報・・・あるマンガの単行本1巻の情報
  • マンガ雑誌掲載作品情報・・・あるマンガの掲載雑誌全巻の情報
  • マンガ雑誌全巻情報・・・ある雑誌の全巻の情報
  • マンガ雑誌情報・・・ある雑誌の1巻ごとの情報
  • 著者情報・・・ある著者の作品などの情報
  • 資料情報・・・あるマンガの資料の情報
  • 原画情報・・・あるマンガの原画の情報
  • その他情報・・・その他の資料(同人誌など)の情報

また検索方法としては大きく分けて次の方法があります。

  • マンガタイトル検索
  • 雑誌タイトル検索
  • 著者名検索
  • 詳細検索

はじめてのRubyGem

RubyGemを作るのは初めてですが、スクレイピングは得意技なので簡単にできるだろうと軽い気持ちで作り始めました。しかし、このデータベース、サイトもデータも意外と複雑な構造になっていて、gemのインターフェイス設計にかなり悩みました。

例えば、1つの検索方法から得られる結果が1種類だけではなく複数種類が混在している場合があることや、検索の詳細条件がたくさんありインターフェイスとしてどう表現するか、返された値をどのように表現するか、など。

ぱっと思いついたのは、ActiveRecordのようにそれぞれの情報をそれぞれのClassにして、あるデータの小データをメソッドで取得したり、その逆であったり横方向であったり・・といった機能までできればと思いましたが、まずは単純に検索してハッシュデータを取得だけの機能をサイトやデータの構造にそって作ることにしました。(こういう時に、他の人のコードを読むって大事だなと思います。)

Rubyが分かってない

作り始めてすぐに、Rubyの基本的なことが分かっていない(または忘れている)ことに痛感しました。やっぱりRailsだけやっててもRubyを書けるようにはならないですね。ふだんRailsで使ってるあの機能はどうやって作られているんだろうとか色々と関心が湧いてきました。ソースを見てもらえるとRuby力が低いのがすぐわかると思うので、色々とご指摘を貰えたらと思います。

あと、Rspecを書くのも久しぶりだしRailsでしか書いたことがなかったのでどうしたものかと思いましたが、公開するならさすがに書かないとダメだろうと思い、他のgemのspecなどを眺めながらなんとか書いていきました。これは本当に書いて良かったです。というのも、最初から最後まで色々とインターフェイス設計を試行錯誤していたのでspecがあることで修正漏れが見つけられたのは非常に安心感がありました。テスト大事、テスト大事。

RubyGemsへリリース!

ということでリリースしました。使い方はGithubの方に書いてありますが、詳細なDocument(YARD)は書きませんでした。やっぱりインターフェイスを見なおしてActiveRecordのようにしたいので、書くならその時に書きます。あとは、Travis CIで自動テストさせるようにしました。他にもGithubと連携してくれるツールがたくさんあるので調べてみたら面白そうです。

Unityをいじってみた(その4〜お皿を回転させる技術〜)

これで最後の記事です。

お皿を回転させる技術

このゲームでこだわりたいポイントとして、ターンテーブルの動きをいかに自然に、指の動きに合わせて回転できるかということがありましたので、それについて試行錯誤した実装を説明します。

1.通常時の回転

ゲームシーンでは、何もしない状態で常に一定のスピードでターンテーブルが回転している状態にしておきます。それには、ターンテーブルのGameObjectにRigidbody2Dコンポーネントをつけて、Rigidbody2D.angularVelocityに値を設定します。angularVelocityの単位は角度/秒です。

2.指で回転させる動き

指の動きはTouchクラスで取得します。Touchの状態として、次の4つの状態があります。

  • TouchPhase.Began タッチし始めた時
  • TouchPhase.Moved タッチしながら指を動かした時
  • TouchPhase.Stationary タッチしながら指が動いていない時
  • TouchPhase.Ended タッチし終えて離した時

そして、それぞれの動作は次のとおりです。

BeganとEndedの時は何もしません。

Stationaryの時は、ターンテーブルを指で押さえている状態になるので、ターンテーブルのRigidbody2D.angularVelocityを0にして回転を止めます。

Movedの時は、前のフレームと今のフレームで、ターンテーブルの中心から何度回転したかを取得し、それをRigidbody2D.angularVelocityに回転速度として与えます。また、前のフレームと今のフレームでターンテーブルの回転方向が変わったら、判定処理を行います。

     // 更新前の回転の向き
        float beforeAngularVelocity = discRigidbody2D.angularVelocity;
        // 回転角度を求める
        float deltaAngle = GetDeltaAngle (goDisc.transform.position, touch.position, touch.position - touch.deltaPosition);
        // 回転速度にするために適当な倍率をかけ、回転速度の上限を設定する
        float angularVelocity = Mathf.Clamp (deltaAngle * 25, -500.0f, 500.0f);
        discRigidbody2D.angularVelocity = angularVelocity;

        // Discの回転の向きが変わったら && 一定以上の角度があったら反応する
        if (beforeAngularVelocity * angularVelocity <= 0.0f && Mathf.Abs (angularVelocity) > 10.0f) {
            // スクラッチ音の再生(省略)
            // 判定処理(省略)
        }
 // 3点間の角度を求める
    private float GetDeltaAngle (Vector2 p0, Vector2 p1, Vector2 p2)
    {
        float deltaAngle = GetAim (p0, p1) - GetAim (p0, p2);
        deltaAngle += deltaAngle > 180 ? -360 : 0;
        deltaAngle += deltaAngle < -180 ? 360 : 0;
        return deltaAngle;
    }

    // 2点間の角度を求める
    private float GetAim (Vector2 p1, Vector2 p2)
    {
        float dx = p2.x - p1.x;
        float dy = p2.y - p1.y;
        float rad = Mathf.Atan2 (dy, dx);
        return rad * Mathf.Rad2Deg;
    }

discRigidbody2DがターンテーブルのRigidbody2Dコンポーネントです。判定処理のため、まず現在の回転速度(回転方向)を取得しておきます。次にGetDeltaAngleメソッドにて前のフレームと今のフレームで、ターンテーブルの中心から何度回転したかを取得します。引数はターンテーブルの中心座標、今タッチしている座標、前のフレームでタッチした座標です。この3点から角度を求めます。後はその角度に適当な調整をかけて角速度にしてdiscRigidbody2D.angularVelocityに設定します。残りは判定処理です。

この「3点の角度を求める」という、おそらく三角関数の基礎なんでしょうが、それが分からず苦労しました。以下のサイトが参考になりました。

参考:【Unity2D】2点間の角度を求める - Qiita

そして壊れる

色々やっていたら、GameObjectがmissing状態になり読み込めない状態になってしまいました。どうやらメタファイルに記録されているゲームオブジェクトのUUIDが変わってしまったために起こる現象らしいです。原因としてはUnity Editor以外のFinderなどでファイルの変更操作を行ったりクラッシュだったり、色々とあるようなので操作は慎重にしてライブラリ管理をちゃんとやらないといけないですね。

参考:Unity開発者が複数人で開発を進める上で覚えておくと幸せになる9つの事 - テラシュールブログ

おわりに

というわけで最後は壊れてしまったのですが、どちらにしても作り直したいと思っていたし、Unity5もリリースされたので新しい機能などもチェックしつつ、次はもっとスマートな設計にしたいと思います。

Unityをいじってみた(その3〜データのダウンロードと保存方法〜)

続きです。実際にゲームを作ることでGameObjectやScriptに関する知識はたくさん溜まりましたが、すべてを書くのは果てしないので、このゲーム独特の内容を書いていきたいと思います。

データの配置と読み込みについて

このゲームは、UIイメージの他に、音源や譜面にBMSデータ(※)を使用しています。主に使うデータとしては、「イメージ画像」「音源(WAV)」「譜面(テキスト)」の3種類になります。※フリーのBeatmaniaクローンゲームのデータ。音源等には著作権があるため、あくまで個人利用。

「イメージ画像」「音源(WAV)」といった素材はUnityのProjectに配置することで、Unityに最適化された状態に変換されるようです。またこの時、ProjectのResourcesフォルダに配置することで、Script側からオブジェクトとして簡単に呼び出すことが可能になります。

一方で「譜面(テキスト)」の場合はUnityで利用する素材ではないため、テキストファイルとして読み込む必要があります。読み込みには.NetライブラリのFileInfoクラスなどを使います。また、Unityはビルド時にアセットを統合してしまうため、実機で実行するとファイルをロードすることができなくなります。統合されたくないデータはProjectのStreamingAssetsというフォルダに配置することで、そのままの状態でファイルをロードできます。

Unity - マニュアル: ストリーミングアセット

データの保存領域について

スマホアプリとしてゲームを配布する場合、データ容量に注意する必要があります。AndroidiPhoneともに、アプリのサイズは最大50MBに制限されています。BMSファイルは1曲で数MB〜数十MBになるため、とてもアプリに含めて配布することができません。そこで、BMSファイルをダウンロードしてアプリ領域以外にデータを保存する領域が必要になります。

1.キャッシュ領域

キャッシュ領域はデータ容量の上限はありませんが、その代わり永続性はありませんので、ゲームデータを保存するのには向きません。

Unity - スクリプティング API: Application.temporaryCachePath

2.永続領域

キャッシュではなく永続的にデータを保存できる領域です。ゲームデータを保存するのにも良さそうです。しかし、iPhoneアプリでここをたくさん使う場合、リジェクト対象となるそうです。

Unity - スクリプティング API: Application.persistentDataPath

3.Asset Bundle

Asset Bundleはアプリ領域にデータを追加保存するようです。ソーシャルゲームなどで一般的に使われているのはこれだと思います。BMSファイルを配布するにはこれが一番良いとおもいきや、Pro版のみの機能ということであえなく断念しました。

参考:【Unity】AssetBundleを使わずに動的にデータを取得するゲームを作る | バイナリ覚書

Asset Bundleもどきを作る

Asset BundleはPro版でしか使えないので、永続領域にBMSファイルをダウンロードして保存し、そこからデータを読み込むことにしました。この場合、iPhoneではリジェクト対象となるのでAndroidだけをターゲットにすることにしました。実装までには次の3つの機能を作成します。

1.ダウンロード

データのダウンロードは、.NetのWWWクラスを使うことで実現できます。ファイルがローカルに存在するか確認し、なければダウンロードします。

     string filename = "bms.zip";
        string path = "file:///" + Application.persistentDataPath + "/";
        string url = "http://localhost/bmsdata/";
        if (File.Exists (Application.persistentDataPath + "/" + filename)) {
            Debug.Log ("Find local file." + Application.persistentDataPath + "/" + filename);
        } else {
            Debug.Log ("Can't find local file, Downloading..");
            WWW www = new WWW (url + filename);
            while (!www.isDone) {
            }
            File.WriteAllBytes (Application.persistentDataPath + "/" + filename, www.bytes);
        }

2.Zip解凍

BMSデータはzip圧縮しているので、ゲームをプレイする前に解凍します。最初は.NetのライブラリのZipFileクラスを使おうとしたのですが、Unityが利用するMonoは.Netの3.5までしか対応しておらず、ZipFileクラスは4.5で追加されたライブラリのため使うことができませんでした。そこで、CodePlexにあったDotNetZipライブラリを使用しました。

DotNetZip Library - Home

外部ライブラリを追加する場合はUnityのProjectに追加するだけでScriptからusingできるようになります。

f:id:bisque3311:20150305223842j:plain

以下はzipファイルから特定の拡張子のファイルだけを解凍するサンプルコードです。ExtractExistingFileAction.OverwriteSilentlyを指定することで、既にファイルが存在する場合も上書きします。

using Ionic.Zip;

        using (ZipFile zip = ZipFile.Read (Application.persistentDataPath + "/" + filename)) {
            zip.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
            foreach (ZipEntry entry in zip) {
                if (Regex.IsMatch (entry.FileName, @"\.(wav|WAV|bme|BME)$")) {
                    Debug.Log ("decompress: " + entry.FileName);
                    entry.Extract (Application.persistentDataPath, ExtractExistingFileAction.OverwriteSilently);
                }
            }
        }

しかしこのライブラリは、Windowsにしか対応していないため、与えられたパスの'\'を'/'に置換するという処理が入っていました。そのため、Macなどの環境ではパス指定ができず読み込みエラーとなりました。(.NetのライブラリなのでWIndowsしか想定していないのは当たり前といえば当たり前ですね)。これをモンキーパッチ的にLinux用に修正されたモジュールがあり、それを使用することでこの問題はひとまず回避出来ました。

DotNetZip Library - View Issue #15236: "Path is empty" when extracting in a linux system.

3.AudioClipの作成

Unityでは音源をAudioClipのインスタンスにして再生します。ダウンロードした音源はWAVファイルなので、これをAudioClipに変換する必要があるため、以下を参考にして実装しました。正直、このレベルになってくると自分の力では相当難しいので、Githubにソースが公開されていて助かりました。

Post Position 【Unity】 WAVファイルからAudioClipを自前で生成するサンプルを作ってみた

以上で、Asset Bundleもどきができました。

できた後で知りましたが、Androidアプリの場合、ダウンロードなどはせずにSDカードに直接データを入れる方法を取るほうが一般的みたいですね。

次に続きます。

Unityをいじってみた(その2〜開発環境とデバッグ〜)

この記事の内容は、Unity4.6時点の内容です。現在、Unity5が公開されていますので、この記事の内容は古い情報となりますが、個人的な記録のために書いています。

前回からの続きです。

作りたいゲームについて

まず目標にしたのが、「スマートフォンで遊べる音ゲーアプリ」にしました。Beatmaniaのスクラッチ部分だけがあり、画面に表示されるターンテーブルをタイミングよく回すゲームです。製作途中の実際の画面はこちら。(非常に音量が小さいです。)

SaraMania 途中経過その1 - YouTube

開発環境について

開発環境について説明します。

  • Unity Editor
  • Xamarin Studio
  • Unity Remote 4
  • iPhone実機
  • Android実機

Unity Editor

Unity EditorはUnityの統合開発環境そのものです。Mac版を使用しています。

Xamarin Studio

Xamarin StudioはScriptを編集するためのエディタです。Windowsを使う場合はVisual Studioを使うのが一般的ですが、Macではデフォルトのエディタが使いにくいのでこれが一般的です。しかしXamarin Studioも使いにくい点があるので、いくつかカスタマイズしました。

1.キーバインド

Xamarin Studioを使う最大のメリットはクラスやメソッドの入力補完が使えることですが、Google日本語入力を使用していたため、そのショートカット(Command + Space)が入力ソースの切り替えのショートカットと被ってしまい使えなかったので、まずは入力ソースの切り替えのショートカットを無効化しました。(普段、Visual Studioを使うのでCommand + Spaceがとてもしっくりくる。)。変更方法は次の通り。

システム環境設定>キーボード>ショートカット>入力ソース の、「前の入力ソースを選択」のチェックを外す。

2.コードフォーマット

Xamarin Studioのデフォルトのコードフォーマットは余分なスペースが多く、Visual Studioに慣れている身にとっては少し気持ち悪いので修正しました。変更方法は次の通り。

Xamarin Studio>Preferences>ソースコード>コードフォーマッティング>C#ソースコードC#フォーマット>編集>White Space で、チェックを外す。

3.エラーハイライト

ビルドエラーや実行エラーが起きた行がハイライトされるのですが、どのシンタックスハイライトを設定してもソースコードにハイライトが被ってしまいとても見にくいです。そんな時はブレイクポイントを設定することで赤背景に白文字になり見やすくなるのでそうしていましたが、ハイライトの色自体を変えることはできなかったので知っている人がいれば教えて下さい。

Unity Remote 4

Unity Remote 4は、UnityEditor上のゲーム画面をiOSAndroidで操作するためのリモートツールです。Touchイベントなども実機と変わらず取得できるので、開発中はほぼこれを使いました。「Unity Remote」で検索すると、一つ古いバージョンのUnity Remote 3も出てくるので間違えないよう。(私は間違えてしばらく3を使っていました。)

iPhone実機

iPhoneの実機でDebug実行するには、XcodeiPhoneの設定(おそらくiPhone Developer Programへの登録)が必要です。おそらくと云うのは、私のiPhone端末は既にそれらの登録を行っていたため、特に困ることなくすんなりできました。実際には何が必要だったのか分かっていません。

Android実機

端末側はUSBデバッグを有効にします。またPC側にはJDKAndroid SDKのインストールが必要です。Android SDKAndroid StudioをインストールするとSDKインストーラもついてくるので、それでインストールすると簡単です。

参考:無償化されたUnityのスマートフォン書き出し機能でお手軽にAndroidゲームを作る方法まとめ | GMOメディア エンジニアブログ

デバッグ方法

Consoleデバッグ

ScriptにDebug.Log("Hoge")でUnity EditorのConsoleにデバッグメッセージが出力されます。

iPhone実機デバッグ

Consoleデバッグ同様のデバッグメッセージが、XcodeのConsoleに出力されます。

Android実機デバッグ

Android SDKのtools(/Developer/adt-bundle-mac/sdk/tools/monitor)にあるmonitor(Android Debug Monitor)に出力されます。非常に大量のデバッグメッセージが出力されるので、フィルタをすると良いです。ちなみに無料版だからか分かりませんが、ものすごい勢いで”profiler is only supported in unity pro”というメッセージが流れ続けてとても見づらいです。Unity5では出なくなっているでしょうか。

参考:Unity - IDEを起動せずにAndroid実機ログを見る方法 - Qiita

次回に続きます。