imog

主にUnityとかの事を書いています

転職活動ログ

こちらの記事は転職ドラフト体験談投稿キャンペーンに参加しています

job-draft.jp

amazonギフト券が欲しいので書くことにした。

転職ドラフト以外も使って就職活動していたので、それらを話しつつ転職ドラフトの話をします。せっかくなので転職活動でこんなところで悩んでこんな解決したよというのも話します。

転職活動開始時

最初は知り合いから紹介された転職エージェントと話しながらいろんな会社に書類を送ったりした。それと並行してリクナビマイナビも登録していたが、これらで受けれる会社は大体エージェントが紹介できたので不要になり退会した。エージェントが紹介できない会社に限っては自分で書類送って受けに行くという感じで進めていた。

ちなみに転職活動の進捗状況はGitlabに「job-hop」というリポジトリ作って管理してた。

f:id:adarapata328:20180830200042p:plain

GitLabにリポジトリを作って管理してた

履歴書とか職務経歴書もここに管理。githubでもよかったんだけど、gitlabはissueにweightを付けられるので何かと便利。 面接で何話したかとかもissueにコメントしてたんだけど、会社によって明らかに文章量が違うので熱量がしっかり形に残ってるのは面白かった。

初期の課題

エージェント経由でも最初はだいぶ高速でお断りされていた。大体理由は二つかなあと思う。

書き慣れてない職務経歴書

転職活動は初めてなので正直なにやればいいの?感はあった。とりあえず履歴書と職務経歴書書いてね見たいな感じでやったけどそれも結構難易度が高く。 特に職務経歴書が難解で、僕の書いた経歴書の例文では「上流で設計を担当しました」「品質管理・テストを担当しました」とかプロダクトの担当範囲をしっかり書きましょうと説明書きがされていたけど別に上流もないしテスト担当だったわけでもないし全部やっとるわみたいなという気持ちになった。とにかく自分のやってきたことを文章にしようとしたときに職務経歴書フォーマットみたいなやつが全然当てはまらなくて完全オリジナル文書みたいなのができてた。

これが良いのか悪いのかみたいなのが見えないのが精神衛生上よくなかった気がする。

業界未経験

エージェントとも話してある程度理解はしていたが、やはり業界未経験が飛び込むのはちょっと大変らしい。

元々WEB業界だったところをゲームで探したので業界未経験という立ち位置になってしまい、結構いくつかの会社は経験が足りないとお断りされたのを覚えている。面接でも「この年齢で新たな職種に飛び込むのはだいぶ勇気が必要だと思われますが」と言われたりした。これは今でも「そんなに勇気いらんやろ・・」と思ってる。

最速だと書類送って20分で落ちた会社がある。バッチが走っているのかと思った。

ただこれは経験の有無だけではなくて、上記の職務経歴書書き慣れていない問題が重なって全く自分のことを伝えらえていなかったんじゃないかなあというのは反省している。

ポートフォリオ作る

この二点が結構問題だったので、業界の人とちょっとご飯食べながら相談した結果、やっぱポートフォリオあった方がいいよねーという話になった。

ポートフォリオとは言えないまでも、実は簡単な実績書いてるページはあった。

adarapata profile

ただこれは殺風景だしなんかゲーム作ってる感がないのでやはりポートフォリオは作った方がいいということで、1日でさっと作った。

https://unityroom.com/games/portfolio

学生時代から遡って作ったゲームを紹介していった。実際に遊べるのは半分くらいだけどとりあえずこれで「ゲーム作れるんやな」感は出せた。

これも一緒に出してから選考通過率が上がったので最初からやればよかったほんと。 最終的には転職エージェント+自分で書類送った企業で合わせて2社内定いただきました。

転職ドラフトの話

転職活動初めて1ヵ月くらいのときに、ドラフト開催の情報がTLに流れてきたのでせっかくなのでちょっとやってみた。

レジュメは結構時間かかった。自分のコアに当たる部分なのでやはり経験だけかいても厳しいなと思い、何故やったか、何を解決したかったかというところに比重を置いた。業務の話になるので書けない内容も多くなるかなあと思ったけど、割と普段からブログで書いたり発表してスライド公開などしていたのでその辺をベースに書いていくと意外と分量は増えた。普段からのアウトプット大事。

個人的には現在の年収を問われないところが非常にありがたかった。前職を参考というのは本当によくわからない文化だと思う。

指名状況

最終的には7社から指名いただきました。 どれもちゃんとゲームでのお仕事というポジションだったのでありがたや・・と言ってた。そのうち3件辞退して、4件承諾してお話を聞きに行った。ちなみにミクシィもこの中の一つ。転職ドラフトは承諾後のフローは範囲外なのでここからは会社ごとでだいぶ動きが違っていて、通常の面接フローに入ることもあればカジュアル面談したら即内定もらっていたりなどかなり様々だった。指名されるいう形式なので志望理由とか特に聞かれないし、あちらもレジュメを吟味した後なのでしっかり話ができるというのはよかったなあと思う。

指名する理由がきちんと書かれているというのはこちらとしても納得感があり非常によかった。そこで自分がやりたいことじゃないなら最初から辞退できるし。

カジュアル面談で提示額が上がった

個人的にうれしかった話。

ドラフトで指名された企業とカジュアルな面談に行って、雑談してご飯食べて、その後公開してないソースコードを提出したらちゃんとした面接やる前に内定が出て、且つ当初提示された金額を更に引き上げてオファーいただいたことがあった。そこは人事の方もエンジニアで(兼任?)僕のソースコードをしっかりレビューしていただき、コードの良し悪しの話も含め、今後の成長性を評価して適切な額に変更しましたという連絡が来たのだった。ここまでしっかり理由込みでスキル面を評価してもらえたのは他社ではなかったのでかなり感動したのを覚えている。

最終的にはミクシィとその企業で最後まで悩みに悩んで、理由もすべてめっちゃ書いたお断りのメールを送ったらこれまた丁寧なお返事が返ってきたので、徹頭徹尾良い会社だなと思った。今もお会いしたら仲良くさせてもらっている。社名出していいなら出したい。

転職ドラフトの所感

僕自身はドラフトで見つかったのでいいサービスだとは思うけど、楽に転職できる!というサービスではないのでそこの理解は大事かなと思った。あくまでマッチングを目的としているので不相応な会社にいけるわけじゃなさそう。マッチングするためには私はこんな感じですという情報を出さないといけなくて、きちんと客観的に自分の能力とかスキルを判断できる何かが必要。そのためにはやはり定期的にアウトプットしないとなあという気持ちが強くなった。 なので僕は前職より更に会社で学んだことを公開するように意識している。

既に何かしらの武器を持ってる人には大変ありがたいサービスだと思うので、積極的に使ってよさそう。

最後に

転職活動中に色々相談させていただいた方々、本当にありがとうございました。おかげさまで僕は元気にUnityのバグ踏んでます。

社内LT会でキャリアキーノートをやってきた

弊社では隔週で社内LTが開かれている。

adarapata.hatenablog.com

テーマはなんでもいいということなので、今回は前職でやっていたキャリアキーノートをやることにした。

キャリアキーノートとは?というところは次のブログに全て記されている。

blog.hifumi.info

とはいえLT時間は5分なのでかなり端折ることとなり駆け足の発表になってしまった。

speakerdeck.com

5分で話せる内容は本当にごく僅かで、何を話そうかとかなり取捨選択した結果、自分が大事にしているものが見えた気がしないでもない。

周りに流されずに個人で黙々と続けられる人は本当に尊敬しているし自分もそうなりたいけどそれは本当に苦手。とにかく人の影響を受けまくる。後輩にも「周りの影響受けやすいですよね」と指摘されたことはあり、実際その通りだなと自覚しているので、じゃあいい人がいる場所を探した方がいいんじゃない?というのが僕の考え方になっている。転職活動時もその辺に気を使っていたので入ってから後悔も特にはないのだった。

ちなみにスライド内にある阿部さんのゲームは2008年製だけどWin10で動いて感動した。流石.NET Framework

開発方針についての文書を書いていた

色々決めごとをするときは社内にissueなりwikiなり残すのですが、これは外に公開してもいいんじゃない?と思ったので公開します。 今回は「開発方針について」です。

目的

  • クライアントアウトゲーム全体の開発方法、指針を把握する
  • あとから参加した人もスムーズに着手できるようにする

お品書き


アーキテクチャ


なぜソフトウェアアーキテクチャが必要か

  • 大規模開発、運用にはスケールを見通した設計が必要
    • 秩序なき開発は人間が犠牲になる
  • 設計ルールをその都度作っていくのは大変
  • すでに先人たちが積み上げてきた効率の良い設計が存在する
  • それがソフトウェアアーキテクチャ
  • 一般化されている設計ルールは独自設計より学習しやすい
  • 後から入った人も理解しやすい、むしろそれを前提とした採用もできる

プロジェクトの設計(アウトゲーム)


MV(R)P アーキテクチャ

image


Model

  • いわゆるロジックと呼ばれる部分
  • PureClassであり、MonoBehaviorではない
  • 自身を更新したり、処理結果を返すインタフェースを公開している
  • 自身のパラメータをReactivePropertyで公開もする
  • Modelと一口に言っても内部で分類が色々ある。
  • Presenterを知らない
  • Viewを知らない
  • ユニットテストが書けるようにする

View

  • ButtonやImageなど、画面に表示されるもの
  • MonoBehavior
  • 複数の要素をまとめてViewクラスとするのも可
  • Viewはイベントストリームを持っている
    • クリックされた、選択されたetc..
  • ストリームを公開して、外部から購読できるようにする
  • Viewは外部から情報を更新できるインタフェースを公開している
    • 任意のキャラの情報を表示など
  • Presenterを知らない
  • 自身の情報更新のため、Modelは知っている
    • メンバ変数で持つのは推奨しない

Presenter

  • ViewとModelの間に位置するもの
  • MonoBehavior
  • ViewとModelを知っている
  • Viewのストリームを購読し、Modelに更新をかける
  • Modelの変更ストリームを購読し、Viewに更新をかける
  • Presenterは複数のViewを購読してもよい
    • 大きくなりすぎたら別のPresenterに切り出す

Modelの詳細

Modelは多種多様なので、役割ごとに適切に層を分けないと開発に支障が出る。

  • どこにファイル置けばいいの?と考える時間は少ないほうがいい

逆に層を分けすぎてもそれは分割の手間や思考の時間を奪う

  • スパゲティコードに対してラザニアコードと呼ばれる

MV(R)Pにおいて、モデル下は規約は特に定まっていない。 が、スタンダードな考え方はいくつかある


プロジェクトで考えてるモデルの分け方

  • Model
  • Model/Entity
  • Model/UseCase
  • Model/Repository

Model

  • いわゆるロジックと呼ばれるもの
  • 現状はここに大半いる
  • 色々な役割のクラスが混ざっているので適切な分割は必要

Entity

  • ロジックをほぼ持たないデータのみのクラス
  • キャラクタのパラメータとか
  • 通信のレスポンスオブジェクトとか

Repository

  • リソースを処理する存在
  • リソースのGET,PUT,CREATE,DELETEのイメージ
  • どうやって処理するのかを書く
    • 通信?ローカル?etc...
  • 外部からはリソースがどこに存在するのかは見えない
  • キャッシュ機構を持つのもあり

UseCase

  • ビジネスロジックと呼ばれるもの
  • 「やりたいこと」単位でクラスを作る
    • UserNameChangeUseCase TitleUserLoginUseCase など
  • Presenterは基本UseCaseを使ってモデルを触る

名前変更処理の一例(現在こうなっているわけではない)

image


インゲームのアーキテクチャについて

  • 現状定めていない
  • パフォーマンスチューニングなどが必要になるので、レイヤーの分割が適切に行えないことがある
  • ViewとModelに分割はできるかも?くらいの認識

Rx


ReactiveExtentionsとは


MV(R)PにおけるRxの役割


image

ここの Subscribe OnNext の関係を実装するのがRx


async/await とObservableの使い分け

  • 単純に非同期を待ち合わせたいだけならasync/awaitが簡単
  • それだけじゃない複雑なことをするならObservable
    • 特にイベント処理はObservableのが楽
  • とりさんのスライドで大体かいてる https://niconare.nicovideo.jp/watch/kn3081

DI


Dependency Injection

DIはもはやもうこれ見てもらったほうが早い・・

https://qiita.com/toRisouP/items/b3d3c43db40857ca4ad4


プロジェクトにおける主なZenjectの使い方

  • staticなオブジェクトをなくす
  • 環境によるモジュールの差し替え

staticなオブジェクトをなくす

  • 実体に強く依存するため、差し替えづらい
    • isTestみたいなフラグは持ちたくない
  • ゲームはシングルトンによるstaticが生まれやすいイメージ
    • マスタデータ、サウンドマネージャetc...

これらをDIContainerに管理させることで、疎結合なシングルトンに変更する


環境によるモジュールの差し替え

  • テスト時には通信したくない
  • ローカルと本番でリソース取得先を差し替えるなど

通常だとこれらのフラグ管理などが必要 or 手でDIしなくてはならないが、これらをDIContainerに任せられる


何をBindすべきか

  • あらゆるメンバをBindするとかえって面倒になる
  • 普通にコンストラクタで渡せるならそれのが楽
  • 基本的にはシングルトンだったものが対象
  • Presenter、Viewの層まではやってしまってよい感覚

Model層にContainerを渡さない

  • 上記の通り、コンストラクタで渡せるものは
  • Containerそのものに依存してしまうのはそもそも設計としてよくない
  • Presenterから適切なオブジェクトだけをモデルに渡すのが良い
  • ここは努力目標で・・
public class BadUseCase {
    [Inject] DiContainer container;  // UseCaseがcontainerまで気にするのはおかしい

    public void Foo() { 
        var foo = new BadFoo(container.Resolve<Bar>());
    }
}
public class BadUseCase {
    private Bar bar;  // 素直に受け取る

    public BadUseCase(Bar b) { bar = b; }

    public void Foo() { 
        var foo = new BadFoo(bar);
    }
}

テスト


テストいろいろ

プロジェクトで書けるテストは2種類 - ユニットテスト - UIテスト

なぜ書くのか?


ユニットテストはどのくらい書く?

  • 基本的にモデルはすべてユニットテストが書けると考えている
  • 作成したメソッドのテストは書いてほしい
  • タスクの完了条件に「テストを書いている」を足したい
  • 現場の状況で書かない判断はしましょう

テストでよくある質問

Q.仕様変更はしょっちゅう起こるし、その都度落ちたテストを書き換えるのは手間では?

A.確かに手間です。が、どう落ちたのかが可視化されるのは大きなメリットです。影響範囲がある程度わかれば修正もやりやすくなるので結果的には開発速度は上がると考えます。


テストでよくある質問

Q.テスト書く時間をかけすぎて辛い。

A.テストが書けない理由を掘り下げることが大事です。

  • 何をテストしたらいいかわからない => そのクラスに何をしてほしいのか明確になっていない?
  • テストのための準備が多くて書きづらい => 1クラスの依存関係が多すぎる?
  • テストの構文がわかってない => ググるぞ!

コードレビューについての文書を書いていた

色々決めごとをするときは社内にissueなりwikiなり残すのですが、これは外に公開してもいいんじゃない?と思ったので公開します。 今回は「コードレビューの導入する」というやつです

なぜコードレビューをするのか

大きく二つの効果があると思っています

コードの品質を保つ

一人でコードを書いたときに、それが対応として適切であるかどうかを判断するのは結構難しいです。 基本的には機能を実装するとき、以下の三つについて確認する必要があると考えています。

  1. コードの書き方が適切であるか
  2. 解決方法が適切であるか
  3. 修正箇所以外の影響への対応は適切であるか

下に行くほど考えるべき領域が広くなっていきます。 領域が広くなるほどに一人で対応できる難易度は上がっていくため、漏れが発生し不具合が起きてしまいます。 特に3に関しては自分が予想だにしていないところに影響を与えるなどありがちです。 これを防ぐためにテストコードを書いたり、レビューにより他人の視点、知識から問題を発見していくことが重要になります。

コードの属人化を減らす

ゲームは特に専門性の高い部分が多く、この部分はこの人以外対応できないという問題が発生しがちです(属人化)

短期開発における属人化は速度が出せるので有効ですが、長期の開発においての属人化はボトルネックになりがちです。 これを回避するためには全員がある程度コードを把握しておく必要があります。 コードレビューは自分が把握していないコードを見る有用な時間です。 品質を保つためのレビューだけではなく、自身がコードの内容を把握するためにレビューしていく習慣をつけることで属人化に対処できると考えています。

どうやっていくのか

PRのマージは2人のapprovedを必須にする

  • 2人のapprovedを確認して、自分でマージしてもらいます。(書いた人が取り込みたいタイミングを理解しているはずなので)
  • 人数は暫定です。多いか少ないかはやってみて動的に変えていこうと思います。
  • 2人approvedもらえたら、そこからいつマージするかはPR出した人にお任せします。状況に応じてもっとレビューを求めるのも問題ありません。

スクリプトファイルのみの変更はレビュー不要

  • エンジニアが目視で見ても判断つかないため
  • レビュイーがUIテストなどが通ってるかは確認しましょう(いずれ自動化)
  • 「レビューポイント」のところにレビュー不要な理由を書きましょう(シーンファイルのみのためetc..)

インゲーム・アウトゲーム関係なく2人をランダムにレビュアーにする(ランダムな仕組みは後から作る)

  • 属人化を防ぐため
  • リード的な人のレビューを必須にするとボトルネックになってしまうため
  • この人に見てもらわないと不安!みたいなシチュエーションの場合はその都度その旨書いて指定する

レビューを優先する

  • レビューが終わらないのでマージできない!という状況を防ぐために、レビューを優先!という共通認識を持ちたい
  • 忙しすぎてレビューが本当に無理!ということになったらタスクの積み方から一旦見直す

レビュイー(PR出す側)に意識してほしいこと

PRの粒度を意識する

PRのコミット粒度を小さくすることを心がけていきましょう。 体感ですが、スクリプトファイルの変更が二桁突破するともう辛くなります! コミット粒度を小さくするためには、エンジニアタスクの適切な分解が必要になってきます。

例えば「APIからとってきた情報を表示する新規の画面の追加」というタスクがあるとしたら、それは以下のタスクに分解できます。

  • 画面に表示する情報を持つモデルを作成する
  • 新規のAPIと通信をするメソッド実装
  • 新規画面の追加(データは決め打ちのモック)
  • 画面にモデルの情報を表示するように繋ぎこむ

これらをまとめてやってしまうと肥大化してレビューしにくいので、適切な分割を心がけましょう、

背景が伝わるように文章を書く

PRから背景が伝わるように文章を書いていきましょう。 なぜこのPRをやるのか、どのように解決するのか、特にどこをレビューしてほしいのかなのかがハッキリすればレビュアー側の負担を減らすことができます。JIRAチケットのURLを貼るのもいいでしょう。 前職では以下のようなテンプレートを採用していました。これに近いものを用意しようかと考えています。

https://gist.github.com/adarapata/40ec5f66e0c348a639a1aa6cb519aee6

レビュアーに意識してほしいこと

HRTの原則を守る

「レビューはBARで語らうように」という名言があります。レビューとは相手のやったことに対してコメントするので、ともすれば相手を傷つけてしまうような悪い空気になってしまいます。それが発生しないように謙虚(Humility) 尊敬(Respect) 信頼(Trust) の気持ちをもってコメントしましょう。

HRTの原則 ~ソフトウェア開発はバーでしっとり語り合うように ~

http://blog.livedoor.jp/lalha/archives/50496623.html

なぜを書く

「良い」「悪い」という基準は主観的な言葉なので、どういう観点から良い、悪いを判断したのかを書くように心がけましょう。

悪い例:「ここはBのようにしたほうが良いと思います」 いい例:「ここはBのようにするとネストが減り可読性が上がりそうです」

わからないところは質問していく

レビューは品質の保証だけでなくレビュアーが要件を理解する場でもあります。なので、こうしたほうがいいというコメントだけではなくて「このコードは何をしているんですか?」みたいな自身の理解を深めていくのも目的です。 なのでこの辺りがわからない、というのもどんどんコメントしましょう。

褒める

めっちゃええコードやんと思ったらそういうコメントもどんどんしてください。

テストコードについての文書を書いていた

色々決めごとをするときは社内にissueなりwikiなり残すのですが、これは外に公開してもいいんじゃない?と思ったので公開します。

今回は「Unityにテストコードを導入する」ときの文書です

なぜテストコードを導入するのか

往々にしてプロダクトの要件は常に変化します。一ヵ月前の仕様が変わることも珍しいことではありません。仕様が変わればコードの修正は必要です。つまり、コードは必ず変化するという前提で書く必要があります。

コードが変化すると、その周辺のコードに少なからず影響を与えます。場合によっては全然関係ないと思っていたところに飛び火することもあります。それらを予め人間がすべて把握するのは経験則からくる職人技に近いものなので、非常に難易度が高いです。

テストコードを書くと、変更を加えた際に起きる影響をある程度可視化してくれます。 プロダクトの規模が大きくなるほど開発速度は落ちていきますが、テストコードはその減速率を下げるのに役立ちます。

テストコードを書くメリットは以下の2点です

品質を把握する

テストそのものが品質を上げてくれるわけではありません。テストコードは現状のプロダクトの品質がどんなものなのかを可視化してくれます。この部分が適切に動いているのか、この部分に変更を加えるとどうなるのか、など。品質の可視化は機能追加、リファクタリングの判断材料となり、素早い意思決定が行えます。

テストがないコードは品質が悪いのではなく品質がわからないので、どこを直すべきか、どこの処理を手厚くすべきかという判断が難しくなり、結果的に開発効率が落ちてしまうと考えています。

精神的障壁の排除

影響範囲の見えないコードの修正はメンタル的によろしくないです。 根本原因を解決すべきとわかっていても、影響範囲が見えない場合、リスクを減らし最小工数で抑えるために一旦場当たり的な対応を取りがちです。これはもちろん有効に働く場合もありますが、上記のネガティブな理由から選択すると、未来で同じ問題にぶつかってしまいます。

テストコードにより影響範囲が可視化されていると、根本原因の解決はどのくらいの影響を与えるのかというのがある程度見えることで「なんだか大変そう・・」という精神的障壁を超えた上で判断ができるようになります。

導入するためには?

テストコードを書くためには、ビューとロジックが分離されている必要があります。(そうしないとめっちゃ書きづらい) これは別issueのMV(R)Pアーキテクチャ導入 #1125 によって実現できると考えてます。

また、シングルトンはテストするのが非常に面倒です。 refs シングルトンパターンの誘惑に負けない

この問題は、シングルトンをやめて依存性の注入(DI)を行うことで解決できます。UnityだとZenjectというライブラリが有名です。

ユニットテスト

Unityに依存しないPure Classのテストです。これはEditModeテストを導入します。実はいくつか実装済みです。 - 例 xxxxx

Zenjectを導入した場合、バインド処理が必要になるのでZenjectに付属の ZenjectUnitTestFixture を継承して書く

refs - Unity で ユニットテストをする http://blog.kakeragames.com/2016/02/17/unity-test-unit.html

インテグレーションテスト

MonoBehaviorなどUnityに依存したコードのPlayModeテストを書く。やり方はもうちょっと詰めていく。

unity-uitestというライブラリがあったのでこれを使えばアウトゲームのシーンUIの自動テストは書けそうな気がするが要調査

FaceRigとボイスチェンジャーでバーチャルの肉体を手に入れた

30手前の男性二人がチャットでボイチェンで美少女声出してキャッキャしてたら肉体も欲しいなという気持ちになり、FaceRigを購入しておばあちゃんの肉体を手に入れた

無駄にバーチャルの肉体で配信できる環境を整えてしまった。

しかしそうなると今度は身体を動かしたいなという感じになってきたので誰か僕にHTC VIVEを買ってください。

社内LT会に参加してきた

社内でLTやろうぜ!という流れができたので参加してきた。

お昼に行われるやつで、なんと1000円相当の弁当が出るコスパ高いLT大会だった。今回は牛たん御膳を選択。

僕は最近やってたUnityのでモッククライアントの実装など話していた。

speakerdeck.com

前回話したテストの延長で、通信が絡むユニットテストの解決方法を探すという感じのお話。 これはいずれ汎用的に使えるやつとして公開したいなーというお気持ち。

その他にもC++の黒魔術があったりとバラエティ豊かな発表だった。

www.slideshare.net

C++ => C プリプロセッサらしい。

全員基本的になんだかヤバそうなスキルを備えていて聞いてて飽きない話ばっかりだったので、こんな感じで表に出していけるような空気になっていけばいいなと思う。