インターンで指導を受けて分かった「活躍する人になる為の心構え」的なものをまとめる

# はじめに
はじめまして。Qiitaで物書きをすることにしました、Kisuiと言います。
現在情報系の修士2年です。

この度、内定を頂き入社を予定しているゲーム会社で、内定者向けインターンシップに参加させてもらっています。
それが1か月経ち、現場であれこれ指導を受け色々と経験が溜まりました。
特に、指導教官が所謂トップエンジニアクラスに該当するほど優秀な人だそうで、交流したり指導を受けることで感覚的に得たものが色々ありまして。

そういうわけで、初心者ながらインターンとして現場に入り気づいたこと、**エンジニアとして活躍する人になる上で必要だと感じた心構え**をメモ書きとして残すことにします。

もし誰かの役に立つのなら幸いです。
それでは、よろしくお願いします。

# 目次
- [特定されない程度の自己紹介](#特定されない程度の自己紹介)
- [ゲーム業界のエンジニアとしてキャリアを積むうえで最初に知るべき(かもしれない)心構え](#ゲーム業界のエンジニアとしてキャリアを積むうえで最初に知るべきかもしれない心構え)
1. [完璧を求めない](#1-完璧を求めない)
1.1. [変数のアクセス修飾子](#11-変数のアクセス修飾子)
1.2. [見えないor気にならないグラフィック](#12-見えないor気にならないグラフィック)
[要するに](#要するに)
2. [身体でコードを書く](#2-身体でコードを書く)
3. [ちょっとキツめの環境に身を置きまくる](#3-ちょっとキツめの環境に身を置きまくる)
4. [失敗を恐れない](#4-失敗を恐れない)
5. [銀の弾丸はこの世に存在しない](#5-銀の弾丸はこの世に存在しない)
6. [新しい技術に物怖じしない](#6-新しい技術に物怖じしない)
7. [遊びでいいので家でも何か関連作業をする](#7-遊びでいいので家でも何か関連作業をする)
8. [無理はしない](#8-無理はしない)
9. [「ゲームエンジニア」ではなく「ゲームクリエイター」になる](#9-ゲームエンジニアではなくゲームクリエイターになる)
10. [高い目標を持ち続ける](#10-高い目標を持ち続ける)
- [まとめ](#まとめ)

## 特定されない程度の自己紹介
軽く済ませます。

### お前は誰や
- 中堅私立大学の情報系修士2年（内部進学者）
- 外部発表は1回だけ経験
- 機械学習を使った研究をしてる

要するに優秀な院生というわけではないです。

### 指導教官とは
- あらゆる部署にアサインされて実装の手伝いをしてた
- 社内で使っているフレームワークの開発者
- ゲームの個人開発をしていてSteamにも出しているらしい（すごい）
- 家でも趣味でアーキテクチャ開発してるらしい（！？）
- 企画もできる（！？！？）
- 3Dモデリングもできる（！？！？！？！？）
- インターンにジョインしたひと月半後くらいに退職し、世界的に有名な某社へ行った

実例を出さないと凄さが伝わらないかもしれませんが、機密事項に関わるかもしれませんのでここでは出しません。


# ゲーム業界のエンジニアとしてキャリアを積むうえで最初に知るべき(かもしれない)心構え
言われた or 感じた順番に書きます。

## 1. 完璧を求めない
これは一番最初に言われました。

例えば以下です。
### 1.1 変数のアクセス修飾子
些細なことですが、最初の最初に指摘された事項なので紹介します。

それまでの自分は、外部からのアクセスをなるべく減らすようにpublic修飾子を使わずやる方法を頑張って考えていましたが、それをやる優先度は低いそうです。**そこに時間を割くよりも、まず動くものを完成させる。** ゲームに限った話ではなく、実務の世界には **「納期」** があるので、ゆっくり(or 正確に)コードを書いている暇なんてないわけです。考えてみれば当たり前のことです。
なので、そういうことをやりたければ、あとで時間に余裕があるときにやる。それを徹底しろと言われました。
### 1.2 見えないor気にならないグラフィック
研修でやった事例を交えて紹介します。

ブロック崩しを作っているとします。
そこで、超高速で飛んでいくボールを作るとします。その時、自分が最初にやっていた壁との当たり判定の実装は以下でした。
（UnityのRigidbodyは使用禁止されているとします）
~~~
public class MyRigidBody : MonoBehaviour
{
    public Vector3 ray_direction;
    public float move_distance;


    private void Start()
    {
        float cache = move_distance;
        Vector3 ray_start_pos = transform.position;
        Vector3 direction = ray_direction;

        while (cache >= 0f)
        {
            RaycastHit2D hit2D = Physics2D.Raycast(ray_start_pos, direction, cache);

            if (hit2D.collider == null)
            {
                Debug.DrawRay(ray_start_pos, direction * cache, Color.red, 1000f);
                break;
            }
            else 
            {
                Debug.DrawRay(ray_start_pos, direction * hit2D.distance, Color.red, 1000f);
            }

            cache -= hit2D.distance + 0.5f;
            ray_start_pos = hit2D.point + ((Vector2)ray_start_pos - hit2D.point).normalized * 0.5f;
            direction = Vector2.Reflect(direction, hit2D.normal);
        }
    }
}

~~~
実際はもう少し調整していましたが、概ねこんな実装をしていました。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1144340/385ba93c-4996-3e6c-e2e1-54c34a1b396b.png)
このように、while文でRayを複数回飛ばして衝突先がなくなるまで移動先を計算し、最後のRayの末端を移動先にするというやり方です。
1フレーム内の移動量が多い場合、その1フレーム内で壁に複数回当たる可能性があります。そのため、1回のUpdate内で反射を複数回呼ぶことができる実装でないと、2回目以降の反射が行われず壁を貫通してしまいます。それを見越した実装なわけです。

この場合移動先は①になります。さて、これを指導教官に見せた際の反応はと言うと、
***
自分「どうですかね？」
**教官「②の位置で止めていいよ。」**
自分「なぜですか？」
**教官「①まで計算する方法にすると、各フレームで壁に当たっている状態が少なくなるから、壁に当たっていることが視認しにくくなる。」**
自分「確かにそうですが、それだと移動が少し遅くなったりして正確な物理演算じゃなくなりませんか？」
**教官「そこまで気にする人はそんなにいないし、気づかない。」**
***
というわけです。これもつまるところ**完璧である必要は必ずしもない**ということの現れです。リアルなゲームですとか、すごく精密な物理演算が必要な場面ではこれくらいやる必要があるかもしれませんが、**「ブロック崩し」はそこまで求めない。** なので不要ということなのでしょうね。

### 要するに

**完璧は悪ではないが、なんでも完璧であることは圧倒的にまずい。** 実装の速度や処理の簡略化という観点で特にそれを指摘されました。


## 2. 身体でコードを書く

主にコーディング速度に関するお話です。先程も書いたように現場には「納期」があるので、何よりも速度が最優先なわけです。そのために、**とにかくコードを書きまくれ**と言われました。必要十分な意識レベルとしては、**「雑談を挟みながらコーディングできること」**。これもよく考えれば当たり前のことですね。アルバイトなどでも担当の業務を延々とこなしていると、意識せずに身体が動くようになるものです。その次元にさっさと到達しろということですね。
ちなみにこの話を指導教官がしてからは、この訓練を狙ってなのかコーディング中に時折雑談を投げかけてくるようになりました。

もちろん意識の話だけではなく、純粋なコーディング速度も上げなければなりません。例えば自分が就活中にポートフォリオとして出したゲームはコーディングに数週間～ひと月くらいかけましたが、指導教官のレベルならば３～４日で仕上がるのだそうです。倍率にして**６～８倍**くらいでしょうか？そのくらいには速くしろということでした。
そのためにも、とにかくコーディングする時間を作ることが必要になります。[3.](#3-ちょっとキツめの環境に身を置きまくる)や[7.](#7-遊びでいいので家でも何か関連作業をする)もこれに通ずるものがありますね。


## 3. ちょっとキツめの環境に身を置きまくる
コーディング時間の短縮も含めて、自分の能力を上げたいのであれば、キツいと思う環境になるべく居ることが良いのだそうです。もちろん自身の体力と要相談ではありますが。

人により異なるとは思いますが、ダラダラしてしまう体質である方は、あえてそういう環境に身を置き「やらなければならない」状況にすることが、能力の向上につながると思います。ここ数年に気づいたことです。




## 4. 失敗を恐れない
****
自分「この場合にはこうした方がいい、っていうのは、何か指標みたいなものとかあるんですか？」
指導教官「 **経験上（こうした方がうまく行ったから）** ですね。」
自分「そう言われてしまうと自分はもう何も言えないんですが…」
指導教官「**そりゃそうだよ。**」
****
何の話だったかはもはや記憶にありませんが、このような受け答えが１回ありました。

要するに、***コーディングは経験による影響が大きい***ということです。そのために、最初から正しいコードを書こうとせず、何度も書き直せ、失敗しろと言われました。[1.](#1-完璧を求めない)に通ずるものがありますね。

ただ、これは企業文化によってそれが許容されるかが変わってくるはずです。自分の入った会社は「失敗を許容する文化」を結構推していましたが、全ての会社がそうとは限らないでしょう。特に大企業になればなおさらです。
ではこれが許容されない文化の会社ではこの経験をどう蓄積していくかですが、これはもう、会社を頼らずに自主活動で経験値を貯めていくしかないと自分は思います。7.とかを実践しろということなのでしょう。


## 5. 銀の弾丸はこの世に存在しない
別プロジェクトからヘルプをしてくださっているエンジニアさんによると、自分の所属含めた直近４つくらいのプロジェクトで利用しているアーキテクチャはすべて異なるそうです。
そのくらいに、プロジェクトにより使う技術もアーキテクチャも千差万別なのだそうです。

これについて指導教官氏は以下のように仰っていました。
***
指導教官「そのコードや技術がもたらす”制約”を意識できるようになるとエンジニアとしての強さが上がる。シニアクラスでも”制約”を意識した実装ができるエンジニアはそんなにいない。」
指導教官「銀の弾丸はない。プロジェクトに応じて技術、アーキテクチャ、”制約”がうまく合う形を作っていくことが要求されますよ。」
***
制約とは何かというと、例えば以下のようなコードがあるとします。
~~~
public class Hoge : Monobehavior
{
    int hitpoint = 0;
}

public class Fuga : Hoge
{
    
    public void Damage(int damage_number)
    {
        hitpoint -= damage_number;
    }
}
~~~
かなり極端に書きましたが、要するに、HPを持つ親クラスと、それを使ってダメージ計算処理をする子クラスに分けられる。つまりオブジェクト指向プログラミングですね。
インターンに入る前の自分であれば疑問にも感じなかったこの書き方ですが、ここに制約が発生します。

この実装における制約とは、***親クラスがhitpointという「体力を取り扱う変数」を持っていることを必ず理解している必要がある***ことです。
その問題点とは、例えばHPに関する処理を足そうとしたときに、***「実装者は、意識を”実装箇所（つまり子クラス）”と”共通部分の内容（つまり親クラス）”の2つに向けなければならない」*** ということなのだそうです。上記では隣り合ってクラスが書かれていますが、これがもし別クラスに書かれていたとして、初見のエンジニアさんが子クラスだけ書かれているファイルを見たとすると・・・いちいち親クラスの実装を確認しに行ったりしなければならないわけです。

そのような***開発者に高カロリーを要求させるような、意識を分散させなければならない実装***には気を付けてほしいということでした。

ではすべての制約が悪かというと必ずしもそうではなく、時と場合、そしてプロジェクトの要件に応じてその制約を構築していくのだそうです。上記の場合ですらも、要件によってはメリットに変わる可能性すらある。ゆえに銀の弾丸はこの世には存在しないということなのでしょう。

とは言え、基本的には制約は可能な限り少ない方が良いらしく、指導教官曰く「多くて１個までに抑えられると良い」とか。


（この辺の説明は自分でも完全に理解できているわけではないです。かなり曖昧な書き方で申し訳ない・・・）

## 6. 新しい技術に物怖じしない

自分の入っているプロジェクトでは、海外では主流になりつつあるが日本のゲーム業界内ではまだあまり利用されていない（らしい）、とあるアーキテクチャを採用しています。それはなぜか。もちろんプロジェクトに合うからという点もありますが、何より***最新技術を常に取り入れる姿勢を作るため***でもあるようでした。
普段からゲームを遊ぶ方であればご存じのことと思いますが、***ゲームに関わる技術の進歩はとにかく爆速です。*** 何を当たり前なことを…とお思いになるかもしれませんが、改めて振り返ってみると、40年前にドット絵と1メガバイトで頑張っていたファミコン時代を基準としても、
- 10年経てばポリゴンによる3D技術が生まれ、 (2D → 3Dという革命)
- 20年経てば常時接続型のオンラインゲームが生まれ、 (オフライン → オンラインという革命)
- 30年経てば携帯電話でゲームができるようになり、 (携帯ゲーム機(を買わないと手軽に遊べない) → 携帯電話(を持てば誰でもゲームができる)という革命)
- 40年経った今となっては、やれ位置情報だVRだNFTだと、新しい遊び方が生まれてきている (ここはなんだろう・・・)

何回革命が起きてんだって話です。
それくらい、***常に新しい物事にアンテナを張り、ゲームに活かすことができるか***がこの業界に入る人間には求められているということなのでしょう。
そんな世界において、新技術に物怖じしていては、絶対にやっていけない気がする。知らないアーキテクチャに触れた経験も相まって、現場にいるとその気をひしひしと感じます。

## 7. 遊びでいいので家でも何か関連作業をする
家で趣味でアーキテクチャを作る指導教官氏程でないにしろ、何かしら興味のあることを自主学習する姿勢は持つべきだと感じました。


<iframe width="560" height="315" src="https://www.youtube.com/embed/-4GjFGjuE9M" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
指導教官氏、自分をこの会社へ導いてくださった人事の方、そして自分が就活時に見ていた上記の「ゲームドライブ就活ちゃんねる」様も、みんな共通して「活躍する人は仕事と趣味の境界線が薄い(ゆえに家でも仕事に関連したことをしている)」と言います。その次元に到達すること、そのためにゲーム開発を楽しいと思えるようになることが、活躍できる人間になる為には必須なのだなと、現場にいて感じました。

裏を返せば、”ゲーム開発を楽しいと思える”ことができなければ、この業界では、生きることはまだしも活躍することは困難ということなのかもしれません。ゲーム業界は狭き門と言われて久しいですが、その根底には「ゲームを作ることが好き」と「ゲームを遊ぶことが好き」の区別がついていない人が多いからのようですね。前者に該当するのであれば、これをこなすことの精神的ハードルは非常に低いのです。大きな差になる点だと思います。

## 8. 無理はしない
これはもうそのままです。体調不良の時は無理せずに休む。指導教官氏もよく頭痛で早上がりしていました。

ただし、前提として、***そもそも無理をしなければならない状況に持っていかないこと***が必須です。
一度、指導教官氏が、社会人として活躍できる人間になる上でのマインドセットをメモ書きしてくださったことがあります。見返してみたところ、そこには
- Forget
- Active
- State
- Teach

の4つが主要事項として書かれていました。上述の話はこれのStateに該当します。健康(Health)、精神状態(Mental)、感情(Emotion)、など、何が起ころうとコントロールして仕事に向かう。それが”無理やり”をそもそも起こさないために常に考えるべきことだと言えそうです。

## 9. 「ゲームエンジニア」ではなく「ゲームクリエイター」になる
これは指導教官氏の特有の考えかもしれませんが、個人的に重要だと感じたので載せることにします。

****
指導教官「エンジニアとしての技術を高めることも確かに大事。でも僕らは『ゲームクリエイター』だから。仕事として与えられた役割だけじゃなくて、ゲームを作るということに意識を向けて、エンジニア以外のこともできるようになるといいと思う。」
上司「『ゲームクリエイター』。良い響きだ。」
****

会社に入ると、基本的には圧倒的成果を出したりしない限りは、いわゆる『歯車』として、与えられた開発の責務を全うすることになるでしょう。ですが、それでは ***「ゲームを作るクリエイティブな職人」としての成長は得られない。*** というような雰囲気でした。実際、自分が入ったプロジェクトは、ヒット作を生み出すことがもちろん最終目的ですが、「若手が実力を伸ばす場所として確立させる」こともまた目的の一つとして挙げられているそうです。

会社に所属していると言っても、「会社員」であると同時に「ゲームを作る人」なわけです。***「ゲームを作る人」がやりたいことは、多少は違えど「誰かに何かの体験を届けること」として収束すると思います。*** そして、それは会社員としてただ目の前の仕事をこなすだけでは到底達成できないということなのでしょう。

そういったやり取りから、エンジニアという立場のもとで漠然と技術を追い続けるだけではいけないということを思い知りました。

## 10. 高い目標を持ち続ける
****
指導教官氏「〇年以内には独立しようと考えてますね～」
自分（目標高杉侍）
****
当時はそんな感想を抱いていましたが、これはもはやこの業界にいるかに関わらず、社会人として意識すべきことなのかもしれません。

指導教官氏。ただでさえ転職して、ある意味現在のゲーム業界で頂点に位置する会社に入ったというのに、そこから先の目標もまたすごく高く設定しているのです。驚かされたと同時に、それを高らかに宣言できるというところがめちゃくちゃカッコいいと感じました。

# まとめ
指導教官氏と初対面の時は「この人が本当にトップクラスのエンジニアなのか？」とか疑ったりもしましたが、もちろん杞憂でした。そんなように、「超絶優秀な方＝凄そうなオーラを放っている」ということが常に正しいとは言えない気が最近しています。

最後まで読んで頂きありがとうございます。上記のように、もしかしたらあなた様の身近にも、普通に見えて凄まじい経歴を辿ってきている方が潜んでいる可能性があります。そういう方を探して社内やグループ内を活動的に冒険すると、どこかで最高の出会いがあるかもしれませんね。