エフアンダーバー

個人でのゲーム開発

Unityの基礎 その4 『コンポーネント』

前回からずいぶんと時間が空いてしまいましたが第四回です。 Unityのバージョンも5.2.3になってしまいましたが、 この記事自体はだいぶ前に書いたため5.1.2時点のものです。 次回からは最新バージョンになる・・・はず。

第四回は流れからわかったかもしれませんが『コンポーネント』です。 プロジェクト、シーン、ゲームオブジェクトときて、 今回のコンポーネントでUnityの構成要素の概要については完結です。

コンポーネント(Component)とは?

コンポーネントは一般人には聞き慣れない言葉かもしれませんが、 プログラマにとってはなじみ深い言葉かと思います。 「部品」という意味です。

前回述べたとおり、Unityにおいて「機能」を有しているのは主にコンポーネントになります。 Unityにおけるゲーム開発とは、様々なコンポーネントを追加し、それらを調整、制御していくことを指します。

コンポーネントは必ずひとつのゲームオブジェクトにくっつけて使用します。 コンポーネント単体で存在することはできません。 このくっつける操作のことをアタッチ(attach)するといい、 ひきはがす操作のことをデタッチ(detach)するといいます。 ちなみに、これはプログラミングで一般的に使用される用語なのでコンポーネントに限った話ではありません (例えば、ゲームオブジェクトに子を設定する操作もアタッチ、分離させる操作はデタッチです)。 また、コンポーネントを複数のゲームオブジェクトで共有することはできません。 同じものが欲しい場合にはコピーして使います。

コンポーネントの編集

コンポーネントは必ずゲームオブジェクトにアタッチしなければならないため、 コンポーネントの編集の際にはまずゲームオブジェクトを選択します。 このとき、複数のゲームオブジェクトを選択すると共通部分に関して同時編集ができます。

編集は主にインスペクタで行います。 Add Componentでコンポーネントを追加した後に、 インスペクタに表示される項目を入力していきます。 通常インスペクタに表示されるのは編集用インターフェースであり、 実際に内部で保存されているものとは違う場合があります。 編集用インターフェースでは物足りない場合には、 インスペクタ右上のメニューからDebugを選択することで保存される値を直接変更できます。 ただし、ここに表示される値を意味も知らずに変更するとゲームが盛大に崩壊する可能性があるので注意しましょう。

f:id:fspace:20150904015509p:plain
Local Rotationは実際にはQuaternionで保存されています。

コンポーネントの編集はシーンビューからもできる場合があります。 インスペクタで編集しづらい場合や値のあたりをつけたい場合にはこちらを利用しましょう。

コンポーネントの実体

コンポーネントの内容はゲームオブジェクト同様、 シーンファイルやプレハブファイルに保存されています。

前々回のシーンファイルの中身です。(再掲)

--- !u!4 &285478060
Transform:
  m_ObjectHideFlags: 0
  m_PrefabParentObject: {fileID: 0}
  m_PrefabInternal: {fileID: 0}
  m_GameObject: {fileID: 285478055}
  m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
  m_LocalPosition: {x: 0, y: 1, z: -10}
  m_LocalScale: {x: 1, y: 1, z: 1}
  m_Children: []
  m_Father: {fileID: 0}
  m_RootOrder: 0

前節のDebugモードのインスペクタの画像に写っているものと同じコンポーネントなので見比べてみるといいかもしれません。 インスペクタに表示されていないいくつかの情報は他のオブジェクトとの関係を示すもので、(多分)Unityとしてはいじってほしくない部分です。 逆にインスペクタにしか表示されていないInstance IDは実行時にのみ使用される情報です。

主なコンポーネント

各コンポーネントの詳細は今後の記事にて順次説明していくつもりですが、 ここでは大まかにコンポーネントの種類について軽く説明します。

レンダリング(描画)関係

カメラ(Camera)

レンダリングで最も重要な要素はカメラです。 あらゆる描画はカメラごとに行われます。

CGの世界になじみのない人にとってはコンピュータの中なのに何故カメラが必要なのかと疑問に思うかもしれませんが、 カメラは3D空間上に配置したモノをどの場所からどの角度でどれくらいの視野で見ているかという情報の表現です。 3DCGとは言いますが最終的に得たいのは二次元の画像なので、平面に変換するための情報が必要であり、それを持っているのがカメラなのです。

ちなみにカメラは複数作成することもできます。 といってもテレビのように複数の角度からの映像を切り替えるためではなく、 特殊なエフェクトをかけたりする場合に使います。

ライト(Light)

光の色や当たり方によってモノはいろいろな見え方をします。 また、そもそも光が無ければなにも見えません。

ライトは光を表現しますが、光そのものを描画するための機能ではありません。 光がどの位置からどのように発せられているかを表現することで、 モノの見え方をコントロールするためにあります。 光が強く当たっているところは鮮やかな色に、あまり当たっていないところは暗い色に見えますよね。

レンダラ(Renderer)

CGの世界では3D空間上に配置されたモノを特定の形式(主に2Dの画像)に変換することをレンダリング(Render)するといいます (基本的には「描画」=「レンダリング」)。 そして、Unityにおいてレンダリングする主体となるのがレンダラ(Render-er)です (日本語だと何故か「レンダーする」ではなく「レンダリングする」というので少しややこしいですが)。

Unityにおいて目に見えるゲームオブジェクトにはXXXRendererと名の付くコンポーネントがアタッチされているはずです。

物理演算関係

コライダ(Collider)

コライダは衝突する(Collide)もの(-er)という意味で当たり判定を表現します。 ただし、本当に当たっているかどうかを判定するためだけのものなので、 当たったからどうする(例えば、めり込まないようにする)といったところまでは面倒をみてくれません。

基本的に一切動かない場合にはコライダ単体で、 そうでない場合にはリジッドボディと組み合わせて利用します。

Unityには3Dの物理演算と2Dの物理演算があり、 それに対応してコライダも3D用と2D用の二種類があります。 それぞれは独立しているため、3Dのコライダと2Dのコライダの衝突を判定することはできません。

リジッドボディ(Rigidbody)

リジッドボディは剛体を意味します。 剛体というのは高校物理なんかでよく使ったであろう質点に形や大きさの概念が加わったものです。 ただし、どんなに力を加えても変形しないという条件付きです。

といっても、Unityのリジッドボディには形も大きさもありません。 これらはすべてコライダに依存しているためです。 リジッドボディはコライダと組み合わせて使うことでゲームオブジェクトに物理的な挙動をさせることができます。 例えば、衝突時の跳ね返りや回転、空気抵抗や重力の影響などの計算を自動でしてくれます。

コライダ同様、3D用と2D用の二種類があります。

ジョイント(Joint)

ジョイントは関節といった意味で、物理挙動の制約条件を表します。 リジッドボディ同士、あるいはリジッドボディと空間上の点を結びつける役割を果たします。

例えば、球を糸で吊った振り子のようなものを考えてみます。 球は重力に従って落ちますし、叩けば衝撃で飛んでいくといった物理挙動を見せますが、 端点から糸の長さ以上には離れません。 こういった制約条件をリジッドボディに与えるものがジョイントになります。

コライダ同様、3D用と2D用の二種類があります。

UI関係

Unityには新旧二つのGUIがあります(さらには有名アセットとしてNGUIというものもあります)。 古いものはなにかと性能がよろしくないので、今後は何かつくるときには新しい方を使うべきです。

新しいUnityのGUIはマニュアルにはNew UIと書かれていますが、 わかりにくいので一般的にはuGUIと呼ばれています。

キャンバス(Canvas)

キャンバスはUIを配置する場所を設定します。 uGUIでUIを構築する際にはまずキャンバスを作成し、 その下に様々なUI要素を配置していきます。

テキスト(Text), イメージ(Image), ボタン(Button), etc.

文字や画像の表示、ボタン等の基本的なUI要素はデフォルトで用意されています。 uGUIではこれらを組み合わせることでGUIを構成していきます。

レイアウトグループ(LayoutGroup)

UI要素の配置位置を決めるにはいくつかの方法があります。 一番シンプルなのは座標値を与える方法ですが、 これはUI要素や画面の大きさが変わったりするといとも簡単にレイアウトが崩れてしまいます。 また親要素との位置関係から決定する方法もありますが、 ひとつのUI要素との関係しか考慮できないため複数要素を整列するようなレイアウトは困難です。

複数のUI要素間でうまく調整しつつ配置を行うためにはレイアウトグループを利用します。 レイアウトグループはUI要素をどのように配置するかという方法を設定します。

基本的なレイアウトはデフォルトで用意されていますが、 複雑かつ柔軟なレイアウトを実現したい場合には自作もできます。

オーディオ関係

オーディオソース(AudioSource)

オーディオソースは音源を意味します。 音を発するゲームオブジェクトにはこのコンポーネントをアタッチし、これを通して音を鳴らします。

オーディオリスナーとの組み合わせにより、 音の発生源と観測点を表現することで音に現実感を出すエフェクト(例えば、遠くの音が小さく聞こえる等)をかけることができます。

オーディオリスナー(AudioListener)

オーディオリスナーは音の聞き手、観測者を意味します。 シーンにひとつだけ設定することで、オーディオソースから鳴った音をキャッチできます。 通常はメインカメラかプレイヤーに対してアタッチします。

特殊なもの

トランスフォーム(Transform)

TransformはUnityにおいて最も重要なコンポーネントです。 Transformはゲームオブジェクトがどの位置にどの向きでどれくらいの大きさで存在しているかを表します。 この情報がなければゲームオブジェクトは動くことができませんし、 そもそもどこにあるのかわからないので描画もできません。

またTransformには親子関係を設定する機能があります。 ゲームオブジェクトがこの機能を借りているのは前回の記事で書いた通りです。

余談ですがTransformは日本語でも滅多に「トランスフォーム」とは書きません。 日本語の「トランスフォーム」はロボットなんかの変形のイメージが強すぎるためかと思います。 「変形情報」というのも少し堅苦しいですしね。

スクリプト

スクリプトはプログラムの一部分を制御するためのちょっとしたプログラム *1 という意味のプログラミング用語で、英語としての意味は台本です。 ゲームオブジェクトがどのように動くべきか指示するものというわけです。

Unityにおいてスクリプトは他のコンポーネントでは表現できない各ゲーム固有の動作、ゲームロジックを表現します。 そしてそれゆえに開発者が唯一プログラミングできるコンポーネントになります。 Unityでの開発はこのスクリプトのプログラミング作業が大半を占めます。

その他

ここで紹介したもの以外にもイベントシステムやキャラクターのナビゲーション、パーティクルシステムにネットワーク関係と様々なコンポーネントがあります。 概要だけでも一度目を通しておくといいかもしれません。

おわりに

なんとなく使用方法は知っているものの「このコンポーネントとはなんだ?」と言われるとかなり難しいですね・・・
なんだかんだでここまでで一番書きづらかったです。

しばらくまとまった時間がとれなさそうなので、続きはしばらく先になるかもしれません。 大したこと書いてないように見えるかもしれませんが、 まとめ系の記事は調べまわることが非常に多いので時間を取られるのです・・・



執筆時のUnityのバージョン:5.1.2

*1:この表現は正確ではないと思いますが、 「スクリプト」という言葉はかなり曖昧でいい加減な使い方をされているため明確な定義を与えることは難しい気がします。 この意味での「スクリプト」と似た意味の言葉に「プラグイン」がありますが、 「プラグイン」は機能の追加、「スクリプト」は動作の制御というイメージです。