チームラボのインターンに行ってきた(インタラクティブチーム)

2019/09/02~2019/09/13の2週間、チームラボ株式会社のサマーインターンに参加させていただきました。 そのインターンでのことをまとめたいと思います。 f:id:IKEP:20191022122428j:plain

チームラボ株式会社とは

チームラボは、メディアアートやweb開発、モバイル開発など様々な制作・開発を行なっている会社です。 採用ページなどで見かける「ウルトラテクノロジスト集団 チームラボ」というように、様々な分野のスペシャリストの方がいらっしゃるようです。 インターンで参加できるコースも12コースほどあり、私はインタラクティブチームに参加させていただきました。

チームラボとの出会い

チームラボの名前を知ったきっかけは、2年前参加したVRの国際コンテスト(IVRC2017)に出場した時でした。 このコンテストにチームラボが協賛しており、自分の作品を社員の方が体験していただけたことがきっかけです。 自分は高校生のころ映像制作などの芸術と技術が融合したものを作りたいと思って今の大学に入学したので、チームラボが制作しているメディアアート作品をwebで見たときは「まさに自分が追い求めているもの」と非常に驚いたのを覚えています。

インタラクティブチーム

インタラクティブチームは、このメディアアートなどを制作しているチームです。 一番最初に乗せた写真↑、teamLab Borderlessのビジュアル部分を制作しているのも、このチームです。

インターン応募

インターンの選考は、エントリーシートによる書類選考後、面接でした。 面接は、参加希望するコースの現場エンジニアの方とお話したので、技術話で盛り上がりました。

僕がインターンにいく理由としては、

  1. 会社自体や利用している技術に興味があり、現場を見たい
  2. 将来の就職先として考えている

と大きく2つです。 他に参加したインターンの大体は前者なのですが、チームラボは両方の動機がありました。 だから、どうしてもインターンに行ってみたかったのです。 (実は、今回インターンに参加する前に2回応募しているのですが、2回とも書類選考で落とされています...笑)

インターンの内容

インターンでの内容は初日の日にメンターの社員さんと相談して決めました。 何か作りたいものがあるか、何をしてみたいかなどを話し合い、2週間で制作するものを決めました。 僕の場合、インターンの間にやりたいと思っていたこととして、「シェーダーを使えるようになる!」と言うことを考えていました。 しかし、シェーダーで何を作りたいかがその場で思い浮かばなかったので、開発中のARペイントアプリでも使えそうな、「自作のブラシエフェクトを作ろう!」となりました。 また、VRペイントアプリケーション「Tilt Brush」とかでは、アニメーションをするブラシが少ないと言うことだったので、アニメーションするブラシもできたらいいよねとなりました。 最終的に、「アニメーションブラシエフェクトに凝ったVRペイント」を作ることにしました。

今回のインターンの期間に大きく分けて3つのブラシを作成できました。 最終的な作品がこちら↓

ソースコードこちら

インターンで作ったものを自分の成果物にしていいよとのことだったので、GitHubソースコードは公開しています。

最終日には、インターン生が2週間の成果を発表する機会があったので、その時に発表もしました。 そのスライドも載せときます!↓

インタラクティブチームインターン生としての感想

開発中はほとんど見た目のディテールにこだわることをしており、ブラシの線の太さやペイントスピードなどが変わっても、見た目のディテールに影響しないように調整するのが大変でした。 やはり、世界中から高い評価を受けるアートを作っている会社であるだけに、豊富な技術力やノウハウを持っていることを実感しました。 実装方法に悩んだり勉強したいことがあれば、サンプルプログラムを見せてもらえたり、オススメの本を教えてもらえたりしました。 また、週一で短い時間ですが、インタラクティブチームの勉強会があったり、今やっている仕事の内容や工夫点を共有していたりと、ありとあらゆる場面で学ぶことができる環境だったと思います。 さらに、ランチはインターン生とチームメンバーで行こうとしていただけたため、インタラクティブチームで働くのはどんな感じかといったことから、展示している作品の技術的な話まで様々な話ができ、学べることが非常に多い環境でした!!

チームラボのインターン生としての感想

インタラクティブチームではなくチームラボのインターン生としても非常に楽しい働ける環境でした!

初日と最終日にはインターン生全員と社員さんで懇談会があり、他のインターン生や社員さんと話すことで刺激が多いです。 自分の知らない分野の技術話を聞いたり、チームラボ働いてみてどうかとかなど多くのことを話せました。 一方で自分の技術話も理解してもらえて通用するのも非常に嬉しかったです。

採用チームの方とランチする機会があった時に、前述したIVRCの話ができたのも記憶に残っています。 今年のIVRC予選が、インターン期間中チームラボオフィスの近くで開催されたこともあり、自分が出場した時の話もできました。

インターンの待遇

チームラボのインターンインターンの経験だけでなく、待遇も非常に素晴らしくありがたいものでした。 まず、インターン期間中は時給1000円が発生しており、お給料がもらえます。 (他のチームは実務やってるとこもあるけど、インタラクティブチームは実務してないのに....。感謝感激😂)

また、交通費、宿泊費も全額支給してもらえます。 特に宿泊に関しては、インターン開始前日から最終日翌日まで、オフィスまで徒歩10分のホテルをチームラボ側で予約していただけました。 そのため、初日の朝早くや最終日の深夜に新幹線に乗ることもなく、初日前日にゆっくり行ったり、最終日翌日に観光したりもできました。

また、インタラクティブチームインターン生としてはめちゃくちゃ嬉しいteamLab Borderlessの見学会もありました。 自分が今(インターンで)いる場所はこの作品が生み出されている場所だということ、自分が学んでいるその先にこのような作品を作れる可能性があること、などを考えたら鳥肌が立ちましたね 笑

まとめ

一言でいうと、「クリエイティブに没頭できる最高の2週間」という言葉が全てを物語っていると思います!! 様々な人と出会い交流しつつも、自分の専門を深め非常に多くのことを吸収できる環境が整っていると思いました。 何より、自由に好きなことで働けるということが実感しました。 もっとこの環境でいたかったと心の奥底から思うほど、チームラボのインターンに参加できてよかったです! チームラボのみなさま、インターン生のみなさま、ありがとうございました!!m( )m

敵対的生成ネットワークをまじめに勉強して実装してみた2 ~CycleGAN~

前回、概念から数学的なことも含めてGANについて説明しました。 今回はCycleGANにフォーカスを当てます。 f:id:IKEP:20191022103139p:plain CycleGANの論文より

CycleGANとは

画像から画像への変換が可能なGANの一種です。 こういった画像to画像の変換にはpix2pixのように、データセット画像がペアになっているのが普通です。 「入力画像に対して画像変換を行うとこういう画像になる」という風に、入力画像群と変換目標画像群をペアにして与えます。

しかし下の画像のようなペアではないものでも、CycleGANは画像間のスタイル変換が行えます。 なので、上の画像のように現実的にペアの画像を用意することが難しいものが対象でも画像変換が可能です。 (馬とシマウマを全く同じ構図、背景、姿勢で写真を取るのはほぼ無理ですよね?)

f:id:IKEP:20191022104223p:plain:w300

工夫点

ペアの画像の場合は入力画像と変換目標の画像間のピクセルごとの差分を利用する(MSEやMAE)などで、学習を進めることができます。 しかし、今回はペアでないものを対象とするための工夫がなされています。 それは、2つのGenerator(G, F)を用意し、Gで変換したものをFで変換した時に、元の画像に戻るかという設計です。 ドメインXの画像群の画像xをGによってドメインYの画像群のような画像y^に変換。 その後、y^をFでXへと変換した画像x^が、xとどれだけ異なっているか利用しています (数学的にいうと、X→Yの写像GとY→Xの写像Fがあり、Xの画像xを入力した時、x-F(G(x))の値を小さくする、ということ)。 これが、Cycle Consistency Lossと言われています。

f:id:IKEP:20191022104715p:plain

損失計算

損失関数は以下のようになっています。

f:id:IKEP:20191022105557p:plain

で、Cycle Consistency Lossがどれかというと、上式の3項目です。 内容は以下

f:id:IKEP:20191022105753p:plain

画像ドメインX, YそれぞれのCycle Consistency Lossの和です。 L1ノルムなので、ただピクセル間の差分を見ているだけですね。

そして、残りの1, 2項目は以下のようになっています。

f:id:IKEP:20191022110058p:plain

GeneratorがDiscriminatorを騙せたかどうかということです。 これは、普通のGANとAdversarial Lossと同じなので、説明は割愛します。

λは、Cycle Consistency LossとAdversarial Lossの割合を決めるハイパーパラメータで、論文の実装では10で実装したとなっています。

実装してみた

てことで、内容は理解したのでChainerを使って実装してみました。 実装したコードはこちら。 データセットは公開されているものの2つ(馬↔︎シマウマりんご↔︎みかん)と、オリジナルで作成したものを利用しました。 オリジナルは、ポケモンモンスターボール↔︎マスターボールの変換です。 google-imagedownloadを使って、Google画像検索で出てくる画像を使いました。(そこから明らかに違う画像は人力排除...)

f:id:IKEP:20191022111131p:plain

f:id:IKEP:20191022111109p:plain

f:id:IKEP:20191022111142p:plain

学習結果

馬↔︎シマウマ

f:id:IKEP:20191022111335p:plain

りんご↔︎みかん

f:id:IKEP:20191022111447p:plain

モンスターボール↔︎マスターボール

f:id:IKEP:20191022111540p:plain

モンスターボール↔︎マスターボールでいい感じのやつを集めてみました↓。 特に左上がMマークが作成されてるので、ちょっとびっくりしました。

f:id:IKEP:20191022111705p:plain f:id:IKEP:20191022111714p:plain f:id:IKEP:20191022111726p:plain f:id:IKEP:20191022111745p:plain

感想

ペアデータなしでここまでの画像変換ができるのは、かなり感動です。 論文の画像を見る限りではもう少しクオリティが高そうだったので調べると、今回実装したコードは学習安定化のテクニックを入れていなかったので、それが原因かなと思います。 でも、楽しむ分にはなかなかな精度が出てるのでいいんじゃないでしょうか(^ ^)

参考

CycleGAN - Qiita

"CycleGAN"の論文解説と"GAN"の補足

[DL輪読会]Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks

敵対的生成ネットワークをまじめに勉強して実装してみた

敵対的生成ネットワーク(Generative Adversarial Network, GAN)を使うことになったので、いろいろ勉強しました。せっかくなので、備忘録として勉強したことをまとめておきたいと思います。これから、GANを勉強する方の参考にでもなればと思います。

 

GANとは

Generative Adversarial Network(日本語では、敵対的生成ネットワーク)と呼ばれるディープラーニングを用いた生成モデルの一種です。

GeneratorとDiscriminatorという二つのニューラルネットから構成されており、二つを敵対させながら学習を進めることで、高精度なデータを生成することができるようになります。

よく、説明される例を挙げると、偽札屋と警察の関係に似ています。偽札屋(=Generator)は警察(=Discriminator)が本物と誤判別する偽札を作る。警察は、与えられたお札が本物の紙幣なのか、偽札なのかを見分けられるように学習する。警察の判別能力が向上すると、偽札屋はより本物そっくりな偽札を作らなければならず、偽札屋が本物そっくりな偽札を作れるようになると、警察はより高度な判別能力が必要となります。これを繰り返すと、偽札屋は徐々により高度で本物そっくりな偽札を作る方法を学ぶことができます。

このように、GeneratorはDiscriminatorを騙せるように、Discriminatorは与えられたデータが本物か偽物かを正しく見分けられるようにとお互いが敵対することで、最終的にGeneratorが本物そっくりな高精度なデータを生成できるようになるというのがGANの考え方です。

f:id:IKEP:20191002172641p:plain

上図がGANの概念図です。潜在変数(VAEなどを勉強すればわかりやすいが、ここでは乱数と思ってOK)をGeneratorに入力し、偽物データを生成。DiscriminatorはGeneratorが生成した偽物データか本物のデータを受け取り、それが本物なのか、偽物なのかを判別、判別結果を出力します。

データとして画像を扱う場合は、GeneratorとDiscriminatorは大体、畳み込みニューラルネットワーク(CNN)がベースとなっています。

 

 

GANの学習

GANの損失関数は以下の通りです。

f:id:IKEP:20191006151705p:plain

Dは0~1を返すDiscriminatorモデルの出力、GはGeneratorの出力(偽物生成データ)、zは潜在変数、xは本物データです。P_dataとP_zは確率分布でxとzがそれぞれの確率分布から生成されるとしています(詳しくは後述の「GANの数学的な考え方」)。
 

GANの学習アルゴリズムは以下の通り(GANの論文より引用)です。

 

GANの数学的な考え方

ここでは、GANの学習についてもう少し踏み込むために、GANの数学的な位置づけについて述べます。

前述したとおり、GANはディープラーニングを用いた生成モデルの一種です。ここでいう生成モデルとは、「データの生成過程を数理的にモデル化したもの」ということです。そして、数理モデルは確率分布によって表されます。つまり、何らかのデータは何らかの確率分布によって生成されると言えます。

簡単な例としてサイコロを考えます。サイコロを振った時に出る数字は、1~6どの面も1/6の確率です。これはつまりサイコロは、1/6の確率で1の目が、1/6の確率で2の目が...といったように、1~6すべての事象が1/6の確率である一様分布を確率分布とする生成モデルであると言えます。このように何らかのデータは何らかの確率分布によって生成されるといえることがわかると思います。

当然、Generatorはデータを生成するため、Generatorは暗黙的に何らかの確率分布を持っていると言えます。もちろん、学習に使う本物のデータ群も何らかの確率分布を持っていると言えます(上記の損失関数でいうところのP_data)。この本物データ群の確率分布にGeneratorの確率分布をできるだけ近づけていくというのが、GANの数学的な考え方です。

ここで損失関数を展開して計算します。

f:id:IKEP:20191006154129p:plain

展開したところで、Gを固定してDの最適解について考えます。

ミニマックス問題なので、Dの最適解はVを最大化します。Vを最大化するには積分の中身を最大化すれば良いです。P_tとP_gは確率なので0~1、Dも0~1なので、積分の中身の式は、要は下のような上に凸なグラフになります。上凸なグラフの最大点が確率の割合でずれるだけと考えれば、Dで微分してやればいいです。

f:id:IKEP:20191006155201p:plain

微分してやると

f:id:IKEP:20191006154906p:plain

これが0になるDが最適解なので、式を整理してやると最適解は

f:id:IKEP:20191006155043p:plain

となります。

 

次にこれを代入してGの最適解を考えると、

f:id:IKEP:20191006155758p:plain

となり、最適なDのもとでのGの最適化は、Jensen-Shannonダイバージェンスの最適化に相当するということになります。

Jensen-Shannonダイバージェンスを軽く説明すると、2つの分布が距離としてどれだけ異なるかを測る尺度です。そして、最小値は2つの分布が等しい時で0になります。

つまり、Gの最適解ではVを最小化するのでPtとPgは等しく、V=-log4となります。よって、損失関数のGの最小化はPgをPdataに近づけることに相当し、本物データ群の確率分布にGeneratorの確率分布をできるだけ近づけていくことになるのです!

以下、イメージです(GANの論文より引用)。

f:id:IKEP:20191006160734p:plain

ちなみに、Dの最適解

f:id:IKEP:20191006160554p:plain

は、0.5となり本物と偽物を五分五分でしか見分けられないということになります。

 

 

実装してみた

以上のことをDCGANとして実装してみました。

GANの論文自体は、ネットワークの構成について一切述べていないので、DCGANを使いました。DCGANはGenerator、DiscriminatorをそれぞれFCNで実装したものです。

実装コードはこちら

 データセットgoogle-images-downloadを使い、Google画像検索で出てくるマリオの画像を使いました。ダウンロードした画像から個人目線で、マリオだけが写っている画像を手作業で抽出しました。その後、256*256pxに変換しています。

f:id:IKEP:20191006162129p:plain

 

 

学習結果

個人的にいい感じで生成されていたのを抽出してみました。

f:id:IKEP:20191006162410p:plain     f:id:IKEP:20191006162420p:plain

f:id:IKEP:20191006162431p:plain       f:id:IKEP:20191006162441p:plain

初めてGANをやったので驚きです!!

もう少し綺麗な画像を出して欲しいけど、まあとりあえずここまでで 笑

 

 

参考

http://mizti.hatenablog.com/entry/2016/12/10/224426

https://qiita.com/triwave33?page=2

https://elix-tech.github.io/ja/2017/02/06/gan.html

https://qiita.com/kenmatsu4/items/b029d697e9995d93aa24

https://qiita.com/FrontPark/items/a591ad680dbb2589d4ba

https://www.slideshare.net/masa_s/gan-83975514

https://qiita.com/kzkadc/items/f49718dc8aedbe8a1bee

https://qiita.com/hideki/items/4de4928236ca15152c18

https://qiita.com/kilometer/items/5be635edefeadaca9281

NAKEDのインターンに参加してきた

8/5~8/15まで約2週間、株式会社ネイキッド(Naked Inc.)の実務インターンに参加させていただきました。

そのインターンで学んだこと、感じたことなどをまとめたいと思います。

 

株式会社ネイキッドとは

NAKEDは、空間全体を演出するクリエイティブカンパニーです。

具体的には、映像による空間演出やインスタレーションプロジェクションマッピングなどを行っています。これらの業界で有名なのは、チームラボとかですね。

元々はドラマのタイトルバックや、ミュージックビデオとかの制作を行っていたそうですが、最近は上記のような空間演出系のこともされているようです。

 

 

インターンに参加したきっかけ

僕は大学に入ってからプログラミングにハマり、色々開発・制作をしていますがVR・AR系の開発を結構しています。VRといえばHMDというのが今の時代だと思いますが、HMDの映像は3DCGです。さらに、ユーザーの行動によって映像が変化するのが普通なため、インタラクティブ3DCGです。僕自身もそういったHMDの映像を作っていました。その後、インタラクティブアートに出会い、自分がやっているVR/ARという分野に近いインタラクティブ3DCGによって、幻想的な空間が作り出せることを知り、いつか現実空間とコンピュータ世界の空間の境界を超えた作品を作ってみたいなと思っていました。

そんな中、テレビCMで興味深いものを目にしました。石原さとみさんが出演している、フレアフレグランスのCMです。

このCMの演出が面白いなと思い調べて見たら、花が舞うのは映像編集ではなくインタラクティブプロジェクションマッピングだったのです!

で、これを作っているのがNAKEDでした。NAKEDについて調べてみるとインターンシップを募集しており、

プロジェクションマッピング、AR(拡張現実)といった既存の表現にとどまらない空間を創造していきます。
映像表現がモニターのフレームを越えてリアルな空間に広がって行くにつれ、多様なデバイスをコントロールしたり、新しい表現の追求のために、それを実現するツールを生み出す技術が必要とされています。 

と記述がありました。僕は「これだ!」と思い、すぐにインターンシップの応募をしました。 

 

 

インターン選考

流れとしては、エントリーシート提出→面接→採用と一般的なものでした。

エントリーシートは、大学などの基本情報に加えなぜNAKEDのインターンに参加したいかを書いたと思います。

面接はSkypeで行っていただけました。NAKEDのインターンになぜ参加したいか、自分の経歴や経験はどんなものか、インターンで何を学びたいかなどありきたりな質問でした。

面接したその日のうちにインターンシップ採用のメールをいただきました。

テクニカルディレクター(メディアアートプログラマー)として参加することになりました。

 

 

業務内容

NAKEDは、大きく分けてblue、green、redの3チームに 別れており、blueが事務や企画(?)など、greenが映像の制作やインタラクティブ機能の作成など、redがNAKEDの核となるシステムの開発を行う、といったように別れているようです。

僕はredチームで働きました。概要としてはgreenチームの人が簡単に制作をできるようにするシミュレーションシステムの開発や、既存映像ツールでは制作困難なものをグラフィックプログラミングによって制作可能にし誰でも簡単に使えるツールにするなどを行いました。

 

 

インターンで学んだこと、感じたこと

  • オブジェクト指向のコーディングをもっと学ぶべき
    • インターフェースやイベントなど、オブジェクト指向の特性や能力をもっと生かしていくべき。そうすることで、クラス間の依存関係を薄めることや、機能拡張性、修正容易性が大幅に向上する!
      オブジェクト指向のコーディングをもっと学ぶには、既存の各クラスやメソッドを積極的に利用すべし。リファレンスを軽く眺めるのも1つの手。既存のものを利用すると、バグも少なくなり(リファレンスなどがあるため)誰にとってもわかりやすい。
    • 汚いコードは読むだけで一苦労と痛感。結局何をしているかが伝わらないこともある
    • クラスを分けることで頭の中も整理できる
      • 各クラスの役割を明確に定めることで、そのクラスで何を担当すべきか、データをどのように扱うが変わってくる。
  • 様々な視点から書いたコードを観察する
    • エンジニアでない人が使うツールの作成を行ったために、どうすれば使いやすいか、人的なミスをなくし自動化できるかを、かなり考えた。
      それにより、将来的に機能拡張をするときにどんなことが考えられるか、必要なデータがない時の処理やエラーハンドリングをどうするかなど、普段とは異なった視点からコードを観察できた
  • コーディングとリファクタリングを短いスパンで回す
    • コーディングをして一段落したら、放置せずに出来るだけ早くリファクタリングをすべき。コードが膨大になってしまうと、理想的な設計にするのは不可能だと思う。できるとしても、ほぼ作り直し
  • 勝手に自分の中のフィルターを作らない
    • グラフィックの動き・綺麗さ、既存アルゴリズムの使用による限界など、「現状の手段では難しい」とか、「こんなものかな」など、現状に満足しないようにすること。何か少しでも気になるところがある場合は、何らかの解決手段を探し検討すべき。
      それが、繊細なところまでこだわりぬく事につながり、素晴らしい作品作りには不可欠である
    • 繊細な調整や、処理負荷を考えられるのはエンジニアのみ。すなわちこだわり抜くことができるのもエンジニアにしかできない醍醐味。
  • グラフィックプログラミング、GPGPUは面白い!
    • パラメータ1つで出てくる絵が大きく変わることもあり、奥が深い
    • GPGPUによって多量並列実行が可能であるため、膨大な量のシミュレーションが可能
      →圧倒的な映像美をプログラミングで魅せれる

 

 

感想

コーディングに関しては、ほぼ自分で考え自分で思ったことばかりを書きましたが、やはり他の人にとって読みやすくするなり、他の人が使いやすいものにするなりと、他人を意識することで、良いコードが身についていくと思いました。

また、グラフィックプログラミング、グラフィックエンジニアリングの面白さを実感しました。想像している通りになるまでこだわり抜くこと、CGに関する知識や様々なツールを利用することで、未知なるものを生み出すことができると感じました。

僕もいつの日か、誰もみたことのない未知なるものを生み出してみたいものです...。

 

株式会社Aimingのインターンシップに行ってきた

3/25 ~ 3/29までの1週間、株式会社Aimingのエンジニアインターンに参加させていただきました。

今回はそのことについて書きます。

 

Aimingとは

Aimingはオンラインゲームの企画からプロデュース・開発・運営までを行なっているゲーム会社です。

制作タイトルで有名どころだと剣と魔法のログレスなどがあります。剣と魔法のログレスは運営元は株式会社マーベラスとなっていますが、開発はAiminigが行なっています。

f:id:IKEP:20190331172111j:plain

 

 

インターンに参加したきっかけ

大きく分けて2つ理由があります。

プロの現場でコードを書いてみたい

私は前々からインターンに参加し、プロのエンジニアの現場を体験したいと思っていました。Aimingインターンに参加する1ヶ月ほど前に任天堂のインターンに行きましたが、プログラミングはしていません。なので、実際にコードを書くインターンに行きたいと思っていました。また、コードを書くのは個人でもできますが、自分の周りにCG関連のコーディングに強い友人がいないため、プロの現場なら学べるのではないかと思ったからです。

 

Webの知識を活かせるゲーム開発をしてみたい

私はアルバイトで開発の仕事をしていますが、そこでWeb系の知識をある程度身につけました。

一方、私の興味のある分野がVRやCG関連であるため、ゲーム会社のインターンをしてみたいと思っていました。今の時代、多くのゲーム会社がスマホゲームを作っています。そして、そのほとんどがオンラインゲームです。しかし、それらのゲーム会社のインターンの募集を見るとほぼすべて、クライアントとサーバ側でカリキュラムや日程が分けられています。しかし、Aimingインターン募集の時点でそういった区別がありませんでした。

実際に会社でオンラインゲームを開発するなら、私はお互いのことをある程度理解しておくべきだと思います。そうすれば、お互いのことを考えた開発ができます。Aimingはゲーム開発のみではなくWeb技術なども含む、技術的多様性のあるインターンを体験できると思ったからです。

 

 

インターンの内容

私が参加した回だけかもしれませんが、インターン生は私1人でした。しかし、チーム開発の手法を教わり、擬似的に実行していました。その中で社員さんからのアドバイスやフィードバックを受けつつ、ひたすら開発を行なっていました。

制作物としては、ドイツの2人対戦型のボードゲームガイスター」をオンラインゲームとして作りました。ユーザの作成&ログインからゲームルームの作成&参加、対戦相手とのマッチング、対戦準備処理、ゲーム操作、ゲーム状況の更新&提示、勝敗判定までオンラインゲームの基本となるものを一通り作成し、独自にオリジナル拡張機能の作成もさせていただきました。

最終日にはコードレビューを行なっていただき、これから自分が改善していくべき課題やプロのゲームエンジニア目線の考え方などを教わりました。

 

 

インターンで学んだこと・学ぶべきと感じたこと

いかなる時もコーディング前の設計を大切に

今回のインターン生が私1人だったこと、開発速度を向上しインターンでもっと学びたいという思いから、私はコーディング前の設計を軽視してしまいました。結果、複雑な処理の実装時にどうやって作るべきかを悩んでしまいました。そして、無理くりな手法で実装したことで、コードが汚くなり、挙動も不安定なシステムになってしまい、後々修正する羽目になりました。

チーム開発の時は設計をしないと、チーム全体での実装方針が決まらないため、設計はきちんと行なっています。しかし、私は1人開発の時に開発速度を優先することにより、設計を軽視する側面があることに気づきました。今回のように開発速度を優先して設計を軽視しても、修正作業が入ってしまい、結果全体で見たときの開発速度は落ちてしまいます。

1人の開発でもチーム開発と同じです。1人開発はいわば、「過去の自分、今の自分、未来の自分とのチーム開発」なのです。

 

常に綺麗なコードを書こう。プロのコードは綺麗だよ。

  • 設計の話と絡む話ではありますが、設計がしっかりすれば綺麗なコードを書けるはずです。
  • 実装方法に悩んだ時は、すぐに無理くりな方法を実装しないようにすべき。周りに相談したり、より良い方法がないかを調べるようにする。
    結果、チームメンバーのコードのより深い理解につながるし、新たな技術の習得にもつながる。
  • 綺麗なコードを書くことは結果として、開発速度の向上や、機能拡張をする時にも役に立つ(長いスパンで考えた場合だけでなく、短いスパンの場合でも)
  • コピペをしない。コピペをすると、その機能に最適な処理でない可能性が高い
  • デフォルトで用意されている機能がないかを調べる。すでに用意されているものがある場合、自分で作るのは時間の無駄&他人は理解しづらい。一番理解しやすいのはコードを書かないこと!(この辺はリーダブルコードにも書いてあったような気が...)

 

オブジェクト指向型言語ならではのコーディング手法を身につける

  • MVCモデルを意識し、きっちりと処理を分ける。
    Viewは極力データを持つべきではない。
  • オブジェクトごとに細かくクラスを分け、機能拡張を容易に行えるコーディングを心がける
  • Unityの場合、何でもかんでもMonoBehaviourを継承するのをやめ、Unityの機能を本当に必要とするものにのみ継承すべき。こうすることで、Unityを使わないプロットフォームでの開発に利用できる。ロジック系のクラスは特に。
  • オブジェクト指向エクササイズのススメ」の9つのルールなどを参考に
  • ReactiveXとかは非常に便利

 

重たい処理を極力避ける 

  • ゲームはパフォーマンスが大事なので、CPUや, GPU, メモリのことを考えたコーディングを心がける
  • どれが重たい処理なのかを理解し、使うべき時を考える。初期化時に行なったり、本当に必要な時にのみ使用する。少なくとも、ループする関数では使わない。チリも積もれば山!
  • デフォルトで配置しておくオブジェクトを少なくする。多いと、データの読み込みに時間がかかってしまう。必要な時にコードから生成しよう
  • 定期的に、どこか重い処理がないかを確認しよう。

 

定期的に振り返ろう 

KPTというプロジェクト振り返り手法を学びました。

Keep: よかったこと、これからも続けていきたいこと

Problem: 悪かったこと、今後はやめること

Try: Problemをなくすために具体的にこれから行うこと

これらを書き出し、短いスパンで定期的に振り返りを行うことで、プロジェクトの改善を加速することができるそう。

参考:

【徹底解説】正しい「KPT」が仕事の成果を生み出す!進め方のコツ、現場の事例を紹介 | SELECK [セレック]

 

 

感想

 自分の周りにはCG関連に詳しい友人がいないので、なかなか他人にコードを見てもらう機会がありません。そんな中、今回のインターンで自分のコードを見てもらったことで、自分のコードの何がダメで何が良いのかが明確になりました。

個人開発では絶対に経験できないことを学べたので、非常に良い体験でした。

 

 

 

VR作品「I AM MAN」がISCA2018で佳作賞を受賞しました

研究室の実習の1つとして、VRコンテンツを作成して、INTERNATIONAL STUDENTS CREATIVE AWARD 2018 (ISCA2018)に応募することになりました。応募するとノミネート作品として選出され、本大会に招待されました。さらに、本大会では佳作賞を受賞しました。

今回はその制作過程を書きます。

 

INTERNATIONAL STUDENTS CREATIVE AWARD 2018とは

INTERNATIONAL STUDENTS CREATIVE AWARD(ISCA)は大阪で開催されている、国内、国外の学生を対象とした国際的なクリエイティブアワードです。作品を募集し、表彰するだけでなく、若い才能を発掘し、社会や海外との交流を提供し、人材育成に貢献しているそうです。

国内映像部門、海外映像部門、デジタルコンテンツ部門と3部門あり、私はデジタルコンテンツ部門に応募しました。

今年は国内172作品、海外121作品、計293作品の応募があったそうです。

f:id:IKEP:20181211165150j:plain

 

企画

実習の一環なので、VRコンテンツということは決まっていました。

そこで、VRでできたら面白いと思うアイデア(キーワード)を出していきました。

ある程度アイデアを出した後それらを見ていくと、「充電器(充電される感覚)」、「腕からビーム」、「アイアンマン」、「壁破壊」「体が重くなる」といったキーワードがありこれらを融合した物を作ったら面白いのではないかと....

とりあえず、これらを組み合わせてメンバーにプレゼンしたのが↓

f:id:IKEP:20181209194920p:plain

f:id:IKEP:20181209194951p:plain

この後、先生や他のメンバーからの意見を受け考えた具体的な実装案が↓

f:id:IKEP:20181209195409p:plain

(企画時にニンテンドーラボ ロボットキットが販売されたこともあり、少しゲーム性の参考にしました 笑)

 

最終的な作品の企画としては、

「体験者がパワードスーツを着たヒーローになって、飛んでくる障害物をパンチやビームで破壊していく」というものになりました。

そして体験者の行動量に応じてパワードスーツのバッテリー量が増減し、それと連動して実際に自分の体が重くなったり、パワードスーツが充電され実際に電気が流れるような感覚を提示するといったようなものを実装することにしました。

 

 パワードスーツのアイデアがアイアンマンからきていることから、作品名は「I AM MAN」(アイアムマン)にしました(ダジャレやんけ.....笑)

 

制作

企画は6月ごろに行っていました。7月はテスト期間であったため全然活動できず、8月から制作を始めました。

ISCAの前に、大学としての展示が9月初旬にあったので、約1ヶ月の制作の制作でした。

1ヶ月の成果がこちら↓

 

 

 

僕はメインプログラマを担当したので、Unityによるゲームの実装全てと感覚提示デバイス群との通信を担当しました。

 

そして大学の展示で初披露

f:id:IKEP:20181210180145j:plain

f:id:IKEP:20181210180206j:plain

多くの方に体験してもらい楽しんでいただけた一方、改善点も多く見つかりました。

 

大きな改善点としては...

- 感覚提示デバイス

・感覚提示デバイスの着脱に時間がかかる

・激しく動いた時にデバイスがずれる、外れるなど

・体を回転させた時に、デバイスのコードに体が絡まる

 

- ゲーム性

・初心者にはゲームがむずすぎる

・パンチのタイミング、パンチ出来たのかがわかりにくい

・操作法がわかりにくい

 

などが挙がりました。

そして本番のISCAに向けて1ヶ月ほど、ブラッシュアップを行いました。

僕が担当したゲーム性については、

 

チュートリアルモードの作成によって、操作性やパンチのタイミング、ゲームレベルに慣れるように

・パンチのヒットがわかるように、スコアの表示&エフェクトの修正

・デバイスのコードに体が絡まらないように、ゲームのアルゴリズムの修正

 

などを中心に大まかな改善を行いました。

そして完成!!

 

 

 

 

システム構成

全体のシステム構成は以下のようになっています。

f:id:IKEP:20181215143234p:plain

 

自作ハードウェアの構造はこんな感じ

・関節制御デバイス(空気圧人工筋肉)

f:id:IKEP:20181215143456p:plain

 

・靴型デバイス

f:id:IKEP:20181215143546p:plain

 

ゲームとハードウェアの通信や、大きな負荷をかけるのに苦労しました...

 

 ISCA本大会に参加

準備日も含めて3日間で開催されました。

1日目は、準備で終わり。

 

2日目は、朝の開場前に審査員の方々へのプレゼンから始まりました。

体が重たくなるという感覚提示を行い、それをゲームと連動させる。

体験者が何も意識しなくていいように自然に感覚提示を行う。

ソフトウェアとハードウェアの利点、欠点を補い相互作用を考えた設計工夫

などをアピールしました。

f:id:IKEP:20181211174019p:plain
f:id:IKEP:20181211174101p:plain

 

数時間後、佳作賞を受賞しました🎉

審査員の方からは、「非常にチャレンジングな作品だった」とのこと。

おそらく、「ゲーム進行によってプレイヤーが不利になっていく新しいゲーム性」や、VR分野で困難な部類の、重力強化」に挑戦したからだと思います。

 

授賞式の後は、映像部門の作品上映を行ったり、参加者で交流会をしたりして2日目が終わりました。

3日目はずっと展示を行っていました。

 

「I AM MAN」を制作&ISCAに参加してみて

真っ先に思ったのは、私たちはゲームのグラフィック完成度が低いと思いました。他の方の作品はどれも高グラフィックでかつ、個々人の「思い」が込められていました。

ゲーム部分の制作を私一人が担当だった(他に担当できる者がいなかった)ことから、グラフィックについて深く話せなかったことが反省点ですね。

作品制作において、グラフィックはそれだけで評価に値する要素だと思うのでもっとクオリティを上げれるようにしたいです。

 

また、作品に「思い」を込めることが、自分の作品を見てくれた人を魅了すると身を持って感じました。私自身、今までの作品に「思い」がこもっていないということではないですが、その「思い」の大きさが違うなと感じました。

例えば、障がい者の方のためだったり、何かを知ってもらいたいとか、自分の個性を埋め込んだり...

私も作品を通して、誰かを魅了しその人の原動力となる作品を作っていきたいと、心から思いました。

 

まだまだ、ISCAで得たものは多いですが書ききれないのでこれくらいに...笑

今回の受賞で満足せずに得たことをバネにして、これからもさらに上を目指していきます!

最後になりましたが、関係者のみなさま、体験していただいた方々、ありがとうございました。

UnityでGitHubとGit LFSを使ったバージョン管理初期設定まとめ

Unityで扱うデータサイズは(画像や音声などがあって)大きいため、UnityのプロジェクトをGithubでバージョン管理するのは、ちょっとめんどくさい印象がありました。

新しいプロジェクトを作るときは、いつもいろいろ調べながらGit管理のセットアップをしています。

いちいち調べるのがめんどくさくなったので個人的にベストだと思った、新規Unityプロジェクトのgit管理初期設定をまとめておきます。(あくまで個人的なまとめです)

 

  1. Unityでプロジェクト作成
  2. Unityの「Edit」→「Project Settings」→「Editor」で以下を設定
  3. ブラウザでGitHubにアクセスし、新規のリポジトリ作成。readme, gitignore, gitattributesはまだ加えない
  4. ターミナルで 「git init」
  5. ターミナルで 「touch README.md」
  6. READMEの内容書き込み
  7. ターミナルで 「touch .gitignore」
  8. gitignoreに以下書き込み
  9. ターミナルで 「git lfs install」
  10. ターミナルで 「touch .gitattributes」
  11. attributesに以下書き込み
  12. ターミナルで 「git add .」
  13. ターミナルで 「git commit -m "メッセージ"」
  14. ターミナルで 「git remote add origin <ブラウザで作成したリモートリポジトリのurl>」
  15. ターミナルで 「git push origin master」

 

これで、容量が大きいファイルはGit LFSによって、Large File Storageに保存され、unityプロジェクトがgit管理できます。

あとは開発していくのみ💪

 

 

参考:

Git LFS