【入門編】世界よ、これが本当の Unity 講座だ(1)

続編の「【入門編】世界よ、これが本当の Unity 講座だ(2)」はこちらをご覧下さい。

前書き

 みなさん初めまして、Japanリージョンゲーム事業本部 技術・編成部 開発基盤グループのどらです。直近では新規タイトルの開発に入り込み、課題感の吸い上げ、技術ノウハウの横展開などを目的とし、業務を行っています。

 

 今日は、みなさん最近よく聞くであろう「Unity」について、社内の勉強会で発表した資料を元にして主に入門者の方々向けの記事を書かせて頂こうと思います。

 

 この記事の目標は、みなさんに Unity の原理原則を理解して頂くという事です。いわゆるメンタルモデル(物事が概念としてどういうものかという理解)を構築する事を目的としますので、メニューがどうとか、操作がどうだとかと言った細かい事はあまりご説明しません。

 何故その様な方針にしているかと言いますと、原理原則さえ理解していればどういった事ができるのか、何をしなければいけないのかは自ずと分かってくるはずで、単純に「これはこうやるものなんだ」という応用の効かない暗記ではなく、自分の頭で考えられる糧となってくると考えているからです。

 

 ちなみに記事のタイトルがやや挑戦的なものになっていますが(笑)これは最近私がハマっている League of Legends というオンラインゲームに関してニコニコ動画で配信をしている人の動画のタイトルの真似です(笑)面白いので是非見てみて下さい(【jungle編】世界よ、これが本当のLOL講座だ)。

 

 もとい、この記事は全2回の構成を想定しており、第1回目の今回は概念の理解に重点を置き、第2回目の次回は実際に Unity を触って少しだけ動くものを作ってみようと考えています。

 

 第1回目の流れとしては、以下の様に大きく2つを学んでいく形となります。

  • まず “Unity とは” のセクションで Unity ってそもそも何なんだっけ、位置づけは?といった所を整理する。

  • その後、“Unity でゲームを作るには” のセクションで実際に Unity を利用してゲームを作ろうと思ったら何が重要な要素になってくるのかについて理解する。

 

 それでは、実際に Unity について学んでいきましょう。

 

目次

  • Unity とは

    • ゲームエンジン概観

    • ゲームエンジンとしての Unity

    • 他ゲームエンジンとの比較

  • Unity でゲームを作るには

    • Unity のオブジェクト構造とその作り方(Editor)

    • 描画システム(3D / 2D)

    • プログラミングの技術(設計 / 言語)

 

Unity とは

 Unity とは、いわゆる「ゲームエンジン」です。ゲームエンジンとはなんぞや、何ができるのか、他にはどんなゲームエンジンがあるのか、それらと比べた時に Unity はどのような位置づけなのかについて、まずは見ていきましょう。

ゲームエンジン概観

 ゲームエンジンとは、下記の様な要素を備えた「ゲームを作るための統合開発環境」です。これがあればゲームを作れますね、というツールキットの様なものです。

  • 3D/2D 描画

  • サウンド再生

  • ユーザーインターフェース管理

  • マルチプラットフォーム対応

  • データ管理・作成ツール

  • そして当然これらがプログラマブル

 なお、何故上記の要素を主要な要素としてリストアップしたかと言うと、ゲームとは結局人間との対話によって成立するものなので、それぞれ下記の様な人間とのやり取りの中での重要な役割があると考えているためです。

  • 3D/2D 描画→視覚

  • サウンド再生→聴覚

  • ユーザーインターフェース管理→触覚(インタラクション)

  • マルチプラットフォーム→多くの人にやってもらう

  • データ管理・作成ツール→楽にゲームを作る

  • プログラマブル→様々なゲームを作る

 あれ?嗅覚は?味覚は?といった所もあると思います。ただ、このあたりは将来的に森のダンジョンに入ると森っぽい匂いがするなどの進歩もあるのかもしれませんが今はそういったデバイスも消費者レベルで浸透していないのでいったん置いて話を進めます。

 

 ここで触れたデータ管理・作成ツールは一般的にエディタ(レベルエディタ)と呼ばれたりするので、覚えておいて下さい。

 

 ちなみに上記に挙げた主要な要素以外にも、細かく挙げると下記の様な機能もあり、それぞれもなかなか奥深い分野となっています。

  • 物理シミュレーション

  • アニメーション

  • パーティクル

  • ネットワーク(通信対戦)まわり

  • メモリ管理(確保・解放)

  • リソース管理

  • デバッグ用のツール

  • 等々...
中山さん_1.png

ここで挙げた様な機能を全て自前で実装しようとなるとこんなに分厚い本が書けてしまうくらいのノウハウが必要になってきます。これはただ「いや、ちょっとこんな感じのゲーム作りたいだけなんですけど…」という場合には辛いものがありますよね。そこで、既存のものが使えるならば使ってしまって積み上げた方が楽だよね、というのがゲームエンジンです(Unity ちゃんあんな見た目ですがやってくれている事は実はすごいんですヨ)。

ゲームエンジンの一例としては、下記の様なものが挙げられます。

  • ミドルウェアとして公開・販売されているもの

    • Cry Engine / Crytek

    • Unity / Unity Technologies

    • Unreal Engine / EPIC GAMES

    • Cocos2d-x / OSS

    • Adobe AIR / Adobe Systems

      • 元々ゲーム作るために作られたのかと言うと微妙ですが

  • ゲームメーカーが独自に開発・利用しているもの

    • Panta Rhei / カプコン

    • Crystal Tools / スクウェア・エニックス

    • NUライブラリ・NUCCシステム / バンダイナムコゲームス・サイバーコネクトツー

    • ヘッジホッグエンジン / SEGA

 ゲームを作る側からすると、一つのプラットフォームに絞りたくない、どうせ作るならマルチに出したいというビジネス的要求もあるので、マルチプラットフォーム対応も意外と大事になってきます(たいていのゲームエンジンではサポートしている)。

 

 また、ゲームを組み立てていく段階で「すぐに確認できる」事が開発速度にインパクトが大きいため、プレビュー機能や簡単に修正ができるエディタも重要な評価ポイントになり得ますし、他のユーザーが作成した部品や素材を再利用しやすいかどうか、ドキュメントやフォーラムなどのコミュニティの充実具合も日々の開発には地味に効いてきたりします。

ゲームエンジンとしての Unity

 まずは、Unity 公式サイトからの引用ですが、以下の図を見て下さい。

※Source: McKinsey report to be released September 2014 とあるが、出稿時点で見つけられなかったのでどういった調査かは不明(出典:Unity - Fast Facts http://unity3d.com/public-relations)

※Source: McKinsey report to be released September 2014 とあるが、出稿時点で見つけられなかったのでどういった調査かは不明(出典:Unity - Fast Facts http://unity3d.com/public-relations

 ゲームエンジンのマーケットシェアで 45%(最も近い競合は 17%)、メインの開発ツールとして Unity を開発に利用しているデベロッパは 29%、メインではないにしろ利用しているデベロッパは 47% となっており、相当数のデベロッパが Unity を利用している事が分かります。弊社でも実際にいくつかのタイトルの開発に利用しています。

他ゲームエンジンとの比較

 ではゲームエンジンとしての Unity を見た時に、他のゲームエンジンと比べてどの様な特徴があるのでしょうか。

  • Pros

    • アセットストアでの豊富な機能拡張

  • Cons

    • 尖った性能

    • ソースが見れないが、ドキュメントがイマイチな事がある 

 先ずは Unity の優れている点として、アセットストアでの豊富な機能拡張が挙げられます。アセットストアにはユーザーが自分で作成したプログラムの部品や 3D の素材などを登録して公開・販売する事ができ、他のユーザーはその部品を簡単に利用する事ができます。この仕組みによって、車輪の再発明を防ぎ、効率の高い開発を行う事ができます。実際に、製品の開発に活用されているものもあります。対抗馬の一つ、Unreal Engine も最近アセットストア(Market Place と呼ばれている)が開設されましたが、私が調査した段階では登録数はまだまだ少なく、これからの発展に期待、というイメージでした。

 

 次に Unity が(場合によっては)劣っている点として、尖った性能が出し辛いという事が挙げられます。Unity はゲームエンジン本体のソースコードが公開されていないため、何らかの機能に尖った性能を出したい、例えば描画のプロセスに手を入れて高速化したいと思っても改善する事が難しいという特徴があります。また、プログラムのソースコードが見れない割にドキュメントが分かり辛かったりする事がある点もデメリットと言えるでしょう。

 

 その他、Unity ならではの特徴ではないとは言え、ゲームエンジンならではの特徴について軽く触れておきます。

  • 拡張可能で実行時での値の変更も可能な Editor

  • 3D が初心者でも扱いやすい

  • マルチプラットフォームに対応している

    • iOS / Android / BlackBerry / Windows Phone / Web / Mac / Win / Xbox / PS3 / PS4 / PSVita / etc…

 Unity は先ほど軽く触れたレベルエディタが充実しており、レベルエディタで実行ボタンを押すとそのままゲームを実行できます。また、エディタでゲームを実行した状態で内部の値を変更する事もでき、一時的に見栄えを少し変えて試してみる、といった事が比較的簡単にできます。さらに、便利にゲーム画面を編集するための機能拡張を自分で作る事もでき、効率化を図る事ができます。

 

 また、3D のゲームを作る事が予め想定されているので、初心者でもあまり複雑な操作をしなくてもとりあえず 3D のゲームを作る事ができます。ただし、パフォーマンスを上げたり、複雑な描画をしようとするとそれなりの作業は必要になります。

 

 加えて、Unity はマルチプラットフォームに向けたゲーム開発が行えます。画面の解像度やアスペクト比が違う可能性がありますし描画の方法も使えるもの・使えないものがあったり CPU やメモリにも差異は当然あるので全てが同じプログラムで動くという訳ではありませんが、プログラムをうまく組む事でその辺りの差異を吸収して大きくプログラムを変更しなくても動作できるものは作りやすい形になっています。

 

 ただし、上記に挙げた様な機能は Unity に限った事ではなく、最近の 3D 対応のゲームエンジンであればほぼカバーされている場合が多いと言えます。

 

 また、ざっくりと他のゲームエンジンの特徴を一覧してみましょう。

 ここまでが、ざっと Unity とはどんなものなのか、という前提の確認でした。それでは、次に実際に Unityでゲームを作ろうと思ったらどの様な要素が重要になってくるのかを見ていきましょう。

 

Unity でゲームを作るには

 これまで Unity で開発を行ってきた経験上、実際に Unity でゲームを作ろうとした時に、およそ下記の様な要素が重要と言えると考えています。

  • Unity のオブジェクト構造とその作り方(Editor)

  • 描画システム(3D / 2D)

  • プログラミングの技術(設計 / 言語)

 ただ、これらを全て解説していこうとすると膨大な記事になってしまうので、今回は一番上の「Unity のオブジェクト構造とその作り方(Editor)」にフォーカスしてお伝えしていこうと思います。

 

Unity のオブジェクト構造とその作り方

 では実際に Unity でのゲームの作り方を見ていきますが、何はともあれゲームは

  • 何かモノがあって

  • それを人が受け取って(見て)

    • 聞くなども実はありますが一旦無視

  • 人が何かする(画面に触る)と

    • 喋るとか、振るなどもない訳ではないが一旦無視

  • モノが変化する

  • という流れを何らかのルールに従って繰り返す

というものと言えると思います。そこで、これらを Unity 上で実現する方法をざっとおさらいしていきましょう。

 

何かモノがあって

 基本的には、「モノとして存在するものは GameObject というものに置き換えて考える」というのが Unity の流儀です。例えば、ゲームのキャラクターや宝箱といったものです。

 これらに「どういう振る舞いを持たせるのかが Component である」という考え方をします。例えば、どう見えるのか、どう動くのか、触ったら何が起きるのかといった事です。
全体像.png

 上記の図では GameObject にいくつかの Component が保持されている形が見てとれますよね。これが Unity での世界の作り方の基本です。さらに言うと、GameObject は内部に GameObject を保持する事ができ(厳密に言うと Transform がその役割を担っている)、入れ子の構造を構築する事が可能です。例えば、キャラクタが剣を持っている、という形は入れ子の構造で表現できそうです。

 また、GameObject を配置する空間は Scene(シーン)と呼ばれ、これで大まかな画面の切り替わりを制御します。例えばダンジョン1用のシーン、ダンジョン2用のシーン、といったイメージで、これらは読み込みの単位として別物になります。あまり大量の GameObject を配置したシーンを作ると切り替えに時間がかかるので注意が必要で、これを緩和するテクニックもあるのですがここでは詳しくは省略します。

それを人が受け取って(見て)

 シーンを実際に画面に映し出すのは Camera コンポーネントの役割です。どこから何をどう見た絵にするのかを決めるために Camera も GameObject にアタッチされた形でシーン上に存在します。

 また、カメラは複数にする事もでき、GameObject にタグを付け、それをカメラに指定する事でそれぞれに映って欲しい対象の GameObject 達を絞り込む(カリング)する事もできます。

人が何かする(画面に触る)と

 さて、ここまでで「何かモノがあって」「人が受け取って(見て)」という所までは分かりました。では「人が何かする(画面に触る)」場合にはどの様な動きになるのでしょうか。

スクリーン上のどこかを触ったとしても、それは 3D 空間を 2D に投影したもを触ったという事でしかありません。なので、2D のどこかを 3D のどこかに変換してあげる必要があります。これがいわゆる「逆透視変換」という作業です。

 実際に変換する時には、左図の様にレーザー光線(Ray と呼ばれる)を視点から 2D の面に投射し、3D 空間に存在している GameObject を串刺しにするイメージですが、これはゲームエンジンとしての Unity がサポートしていますので小難しい計算などをする必要はありません。

 実際には Unity の内部にはコライダという GameObject が Ray に当たるかどうかを定義する様な Component もあるのですが(コライダがなければ Ray に当たった事にならないのでタッチされた事にならない)、先ずは概念として上記の様な処理が行われているんだな、という理解ができていれば大丈夫です。
 

突然の前提確認

 いきなりですが、ここから先は少し専門用語が多くなってきますので、3D についての基礎的な前提知識の確認をしてみましょう。3D の描画は、おおまかに下記の様なイメージです。

  • 3次元の座標上の点を結んだ線で表現した面をたくさん集めて、

  • その面に絵を貼り付ける付ける事で、

  • 立体的な形と絵柄を表現している。

 ここで言うところの、

  • 3次元の座標上の点=頂点(バーテックス)

  • 頂点の集まりの最小単位=ポリゴン(だいたい三角形)

  • ポリゴンの集まり=メッシュ

  • メッシュを物体として意味のある形にしたもの=モデル

  • メッシュに貼り付ける絵=テクスチャ

  • メッシュのどこにテクスチャのどこを対応させるか=UV マップ

  • どういう光がどっちにさしているのか=ライティング

  • メッシュとかテクスチャとかライティングを元にどう描画するかを決めるもの=シェーダー

  • テクスチャとシェーダーに関する設定をひとまとめにしたもの=マテリアル

 と、言う事ができると思います。この辺りの用語を抑えた上で、さらに Unity でのオブジェクト構築の方法を見ていきましょう。

 

モノが変化する

 では実際にモノを変化させる方法について見てみましょう。変化させるといっても色々あります。

  • どういう絵柄・形なのかを変える

    • 絵柄=テクスチャ

    • 形=モデル(メッシュ)

  • どういう光がどう射してどう反射しているのかを変える

  • 位置・大きさ・回転を変える

 状態を変化させる、あるいは聴覚に作用するサウンドを変化させるという話もあるのですが、まずは説明を簡略化するために視覚的な分野にフォーカスしてみます。

どういう絵柄・形なのかを変える

 どういう絵柄・形なのかを変える方法としては、下記の様なものが考えられます。専門用語が色々書いてあって「むむっ」となると思いますが、その時は「突然の前提確認」の章を読み返してみて下さいね。

  • 絵柄を変える

    • テクスチャを変える

      • そもそも差し換える

      • UV マッピングを変える

    • シェーダーで描画の仕方を変える(フラグメントシェーダー)

      • 柄は一緒なんだけど色を変えるとか

  • 形を変える

    • アニメーションでモデルの形を変える

      • いわゆるボーンアニメーション

    • シェーダーでモデルの形を変える(バーテックスシェーダー)

      • モデルを形作るポリゴンの形自体を変える

 例えばキャラクターが剣を振る、といった動作はキャラクタの形が変わっているのでこのあたりの方法が使えそうです。

 

どういう光がどう射してどう反射しているのかを変える

 どういう光がどう射してどう反射しているのかを変える方法としては、下記の様なものが考えられます。

  • どういう光が、どう射して

    • 種類(向く方向と範囲)

      • ディレクショナルライト

      • ポイントライト

      • スポットライト

      • エリアライト

    • 光源の位置

    • 光の強さ

    • 光の色

  • どう反射しているのか

    • シェーダーの計算式を変える

    • シェーダーに与える値を変える

      • ノーマルマップを変える

      • バンプマップを変える

 例えば自分のまわりだけ明るくなる松明を持つ、などは光の当たり方が変化しているのでこのあたりの方法が使えそうです。ノーマルマップやバンプマップなどの言葉はかなり専門的なので解説は省きますが、興味がある方は調べてみて下さい。

位置・大きさ・回転を変える

 位置・大きさ・回転を変える方法としては、下記の様なものが考えられます。

  • Transform コンポーネントの値を変更する

    • 物理エンジンに任せる

      • 重さや弾性係数、摩擦係数などのパラメータを指定しておくとよしなに動かしてくれる

    • アニメーションエンジンに任せる

      • ルートモーションという仕組みで、3D オブジェクトのアニメーションに Transform 情報を更新させる事ができる

    • 自前で Transform の情報をプログラムから変更する

      • 特殊な動きをさせたい時や動的に生成したオブジェクトなど

  例えば、投げたボールが放物線を描いて飛んでいき、地面に落ちてバウンドする、などは物理法則に従った動きになりそうなのでこのあたりの方法が使えそうです。

上記の流れを何らかのルールに従って繰り返す

 さて、ここまでで「何かモノがあって」「それを人が受け取って(見て)」「人が何かする(画面に触る)と」「モノが変化する」という所までは分かりました。次にこれらの流れを「何らかのルールに従って繰り返す」という所を考えてみたいと思います。

 

 ゲーム空間が変化するルールを作るには、自分で「Component を作ってそこで定義する」必要があります。繰り返しになりますが、「GameObject がどう振る舞うのかを定義するのは Component」です。

 Unity の場合は Component の動作は C#、JavaScript、Boo などのプログラミング言語を使って記述する事になり、MonoBehaviour というクラスを親に持つ子クラスを作るという形になります。このあたりの詳細は書き出すとキリがありませんので(笑)、いったん概要だけの理解にとどめます。

 

 さて、Component で記述するという事は分かりましたが、実際どうやって書いていけばよいのでしょうか。Unity は可変フレームのリアルタイム処理になっていますので、それを意識して記述していかなければなりません。

 

 リアルタイム処理とはその時(から一定の期間の中で)起きている事を随時計算し、それを画面に反映していく処理形式で、一般的には秒間30回から60回更新する事になります。これがいわゆるフレーム(更新)レートで、30FPS や 60FPS と呼ばれたりします(厳密には処理の回数と描画の回数は別になったりする場合もあります)。

 

 可変フレームとは、前回の更新から次回の更新は一定時間で行われる事は保証されないという形です。つまりAフレームからBフレームまでは0.1秒だったとして、BフレームからCフレームは0.3秒になる可能性があるという事です。

 

 秒間30回〜60回も更新されるという事はとても細かい単位で「変化」させていく事になりますよね。Unity は内部で「今から更新しますよー何かを変えるなら変えて下さいねー」というタイミングを用意してくれていますので、それが伝えられた段階で自分で変化させる量を決めていく事になりますが、この時利用されるのが「前回の更新からどれだけ時間が経過したのか」という情報になる Time.deltaTime です。例えば、1秒で1m移動するのであれば0.1秒では10cm移動する事になります。この場合の0.1秒が Time.deltaTime から取得できるという訳です。

 

 なお、「今から更新しますよー」というタイミングには下記の様なものがあります。

  • Update=フレーム更新処理が走る時に呼ばれる

  • LateUpdate=Update が実行された後に呼ばれる

  • FixedUpdate=一定時間に一回呼ばれる

 この様なタイミングを適材適所で利用し、更新していきます。詳しくは、「イベント関数の実行順 / Execution Order of Event Functions」などをご参照下さい。

この様な形で Component を作り、GameObject に追加する事で、独自のルールを持った GameObject を作る事が可能になります。  

この様な形で Component を作り、GameObject に追加する事で、独自のルールを持った GameObject を作る事が可能になります。

 

Congratulations

 おめでとうございます!ここまで読んで下さった方は、

  • 何はともあれ、ゲームは…

    • 何かモノがあって

    • それを人が受け取って(見て)

    • 人が何かする(画面に触る)と

    • モノが変化する

    • を何らかのルールに従って繰り返す

 を実現する方法が全て分かりました! …う、うん、少なくとも概念の上では分かったはずです!(笑)

あとは、実際に Unity を触って実践するのみ、そこは次回のお楽しみという事でお待ち下さい!!^^

 

続編の「【入門編】世界よ、これが本当の Unity 講座だ(2)」はこちらをご覧下さい。