Unityで簡単な2D脱出ゲームを作ってウェブサイトで公開してみよう 〜2D ObjectのSpriteについて +α〜

この記事はだいぶ前に書かれたものなので情報が古いかもしれません
オブジェクトの重なり

この記事を三行にまとめると

やらなくていいことはやらない。やらなければならないことは手短に
2D ObjectのSpriteを使うメリットなくね?
クリックできる範囲を自由に編集できる点はSpriteの方が便利かな
前回UIのImageを使って画像オブジェクトを作成しましたが、画像オブジェクトの種類は他にもあります。その中で一番使われるのは「2D ObjectのSprite」だと思うのですが、本作ではこっちは使いません。今回はその理由をお話したいなと思います。あと座標や原点についても少し。

動画はこちらです。





イベントの有効化

脱出ゲームでは特定の場所をクリックした時に何かしらのイベントが発生することが多々あります。Unity的に言えばこの特定の場所ってのは主にゲームオブジェクトを指すわけですが、オブジェクトをクリックした時にイベントを発生させるための設定方法がUIのImageと2D ObjectのSpriteでは違います。

Spriteのオブジェクトでイベントを有効にするためには「EventSystemオブジェクトの作成」「Physics 2D Raycasterコンポーネントの追加」「Colliderコンポーネントの追加」という3つの設定を行う必要があります。

EventSystemオブジェクトはヒエラルキーで作成できます。前回の画像オブジェクトを作った時と要領は一緒です。

EventSystem

Physics 2D RaycasterコンポーネントはMain Cameraオブジェクトに追加します。インスペクターウインドウの「Add Component」ボタンから追加できます。これに限らず今後も何かコンポーネントを追加したい場合はこのAdd Componentボタンで追加します。

Physics 2D Raycaster

Colliderコンポーネントはクリックしたいオブジェクトで追加します。

Box Colloder 2D

ここでは「Box Collider 2D」というコンポーネントを追加してます。これはクリック範囲を四角に設定するコンポーネントです。他にもいろいろ種類があって、範囲を丸型にすることもできますし、「Polygon Colloder 2D」という自由変形みたいなことができるものもあります。

これでようやくSpriteオブジェクトをクリックした時などにイベントが発生するようになります。EventSystemやPhysics 2D Raycasterは一回設定すればオーケーですが、Colliderはオブジェクトの数だけ設定しなきゃいけないって思うとちょっとめんどいですよね。

UIのImageはこれらの設定が必要ありません。最初からイベントが有効な状態になっています。厳密に言えばEventSystemオブジェクトの追加だけはUIのImageの場合でも必要になるのですが、UI関連のオブジェクトを作成した時にヒエラルキーの中にEventSystemがない場合は自動で作成されるので、あえてこの作業を自分でやる必要はありません。



複数のオブジェクトが重なっている場合

画面の構成によっては一箇所に複数のオブジェクトが重なった状態になることもあります。箱を開けたら中にアイテムが入ってる場合とかドアを開けたら誰か立っているとか(何それ怖い)

この時、箱が閉まっていればアイテムは奥に隠れている状態になると思うのですが、このアイテムにクリックイベントがついている場合に、Spriteだと箱が閉まっていてもクリックができてしまいます。動きとしてはおかしいですよね。箱が開いてないのに中のアイテムが取れちゃったりしますから。UIのImageは奥にあるオブジェクトは基本的にクリックができないので、この不具合は起こりません。

Spriteでこれを防ごうと思ったら箱の開閉に合わせてアイテムの表示・非表示の制御も行なったりしなきゃいけないので、まあそれをやればいいという話ではあるんですが、折木くんも言ってましたからね。「やらなくていいことはやらない。やらなければならないことは手短に」って。

またオブジェクトの重なりに関してなのですが、Spriteはインスペクターの「Order in Layer」や「Pos Z」で順番を入れ替えます。Order in Layerは数値の大きい方が手前、Pos Zは数値の小さい方が手前になります。UIのImageにはOrder in Layerの設定はありません。ヒエラルキーで下にある方が自動的に手前になります。これに関してはどっちの方が便利と一概には言えない気もしますが、少なくとも僕は今までUIのImageを使っていてOrder in Layerに相当する設定がなくて困った経験はないです。



2D ObjectのSpriteを使うメリット

僕は別にSpriteさんをディスりたいわけではないんですが、もしかしたらそう思わせるような偏った説明になってしまったかもしれません。上記の内容を見る限りだと「2D ObjectのSpriteを使うメリットなくね?」って思いますしね。

じゃあSpriteの方が使い勝手が良い部分ってどこなんだって話なんですが、先ほどチラッとだけ触れた「Polygon Collider 2D」を使うとクリックできる範囲を自由に編集できる点はSpriteの方が便利かなと思います。

例えばこんな画像オブジェクトがあったとします。

どっちが「ブーバ」でどっちが「キキ」だと思う?

この画像の中で灰色の部分だけクリックできるようにしたいみたいな設定はUIのImageだとできません。UIのImageで作った画像オブジェクトは常に画像全体がクリック範囲になります。ほら、基本的に画像って四角じゃないですか。例えば背景が透明なPNG画像とかも、それは画像の中に透明な部分が含まれているというだけで、そこが画像じゃなくなるわけではないと言うか……ちょっと言葉が上手くないですが、ようはUIのImageだとその透明な部分もクリックの対象になってしまいます。だから上記の画像でオブジェクトを作った場合、灰色じゃないところもクリックできることになります。

でもSpriteのPolygon Colloder 2Dなら灰色のところだけをクリックポイントにすることができます。設定も別に難しくはなくて、コンポーネントを追加するとフォトショップの自由選択みたいにUnity側で範囲を形状に合わせてくれます。もしそれが自分の思う通りの範囲になってくれなくても「Edit Collider」ボタンを押せば範囲の編集ができます。オブジェクトどうしが近いと画像の透明部分の一部がかぶってしまうこともあるかもしれないので、この設定が役に立つかもしれません。

僕はSpriteをほとんど使ってないのでメリットがあるとしたらこれくらいかなーと思ってしまうんですが、使いこなしている人からすれば他にも良い点があるかもしれません。だからもしSpriteを使いたいって人は使いこなしている人の情報も参考にしてくれぃ。



CanvasのRender Mode

オブジェクトの重なりの話に戻るんですが、UIのImageには重なりの順番を数値で指定する項目はないけれど、その親であるCanvasオブジェクトには「Sort Order」という設定項目があります。Order in Layerと同じで数値の大きい方が手前になります。だからヒエラルキーでは上にあるんだけど画面上は手前に持ってきたいUIのImageがあるみたいな時に、Canvasオブジェクトを複数に分けてSort orderで手前と奥を入れ替えることは可能です。

ちなみにSpriteとUIのImageを同時に使用している場合、デフォルトの状態だとSpriteはどうやっても手前に来ません。

前回の記事でもゲーム画面には通常領域とCanvas領域があるよって話をしましたが、UI関連のオブジェクトとそれ以外のオブジェクトは存在している場所が違います。画像編集やお絵描き系のソフトを使う人ならレイヤーを思い浮かべてもらえれば分かりやすいかと思うんですけど、あれで言うとSpriteなどのオブジェクトは通常領域のレイヤー(一番下)の中に配置されて、UI関連のオブジェクトはCanvas単位で別のレイヤーの中に配置されるみたいな感じです。それらのレイヤーが重なって一枚のゲーム画面になっているような、そんなイメージ。そしてCanvasどうしのレイヤーは順番を入れ替えることができるけど、メインのレイヤーは常に一番下に固定されているようなものだと思ってください。フォトショップで言うところの背景レイヤーみたいな感じ。

レイヤーのイメージ

図にするとこんなんですかね。Spriteはメインのところに配置されるので、その中でどんなにOrderの数値を上げようがCanvasより上に来ることはないという感じです。

じゃあSpriteをCanvasよりも手前に持ってくるにはどうすれば良いかと言うと、CanvasのRender Modeを「Space Screen – Camera」にすればオーケーです。

Render Mode - Camera

Render ModeをCameraにするとCanvasにもOrder in Layerの設定項目が出てくるので、これでSpriteよりも奥に配置することができます。ついでにRender ModeをCameraにすると「Render Camera」という入力項目が出てくるので、そこにMain Cameraオブジェクトをドラッグ&ドロップすればシーンウインドウで変な位置に表示されていたのも直ります。



Pivot

画像オブジェクトには「Pivot」や「Anchors」という、原点の位置を設定するための項目があります。

Pivotはオブジェクト自身の原点の位置です。デフォルトだとオブジェクトの中心(X、Yが共に0.5)に設定されています。この時、インスペクターに表示されるPos XやPos Yは、位置座標の原点からこのオブジェクトの中心までの距離を表します。Pivotの設定範囲は0〜1です。

例えばここでPivotのXとYを両方0にすると原点の位置が左下に移動します。つまりPos XやPos Yは位置座標の原点からオブジェクトの左下までの距離に変わります。反対にXとYを両方1にすると原点の位置が右上に移動するので、Pos XやPos Yが座標の原点からオブジェクトの右上までの距離に変わります。

動画ではクッションの原点を中心から左に移動させているので(Xだけ0にした状態。Yは0.5)、Pos Xだけが変化していますね。

ウェブ業界の人がたまにサービスをピボットしましたとか言うんだけど、あれって意識高い系のワードなんかな



Anchors

位置座標に関するデフォルトの原点は、親がいないオブジェクトの場合は画面の中心、親子関係にある子オブジェクトは親オブジェクトの中心に設定されています。Anchorsはこの位置座標の原点に関する設定項目です。Pivotと同じで設定範囲は0〜1です。

動画の例だとクッションはソファの子供なので、原点の位置はソファの中心にあります。つまりクッションのPos XやPos Yはソファの中心からクッションの中心までの距離ということになりますね。先ほどクッションのPivotを(0, 0.5)に変えたことでPos Xの数値が変わりましたが、この数値はソファの中心からクッションの左中央までの距離です。

AnchorsをX、Y共に0にすると座標の原点が左下になります。今回で言うとPos XやPos Yがソファの左下からクッションの左中央までの距離になるってことですね。反対にXとYを1にしたらソファの右上からクッションの左中央の距離になります。動画の中ではXだけを0にしているのでPos Xだけが変化してソファの左中央からクッションの左中央までの距離になっています。

小学生の頃に水泳のリレーでアンカーを努めたのが人生のピークだったかもしれない






今回はここまでっすね。

そういや僕が前の会社にいた時、若いベンチャー企業の集まりみたいなのが何度かあったんですけど、会話の中でたまに「サービスをピボットしました」ってワードを言う人がいたのよね。ウェブサービスの運用が思うようにいかなくて方向性を変えましたみたいな意味なんですけど、ピボットって一般的なビジネス用語なんかいな? 「ローンチしたサービスが思うようにマネタイズできていないので、新たにアサインしたメンバーとブレストやランチミーティングを重ねた結果、サービスをピボットするってことでコンセンサスが取れました。リソースも問題なさそうだから景気付けにソープなランドにでも繰り出そうって話になりまして、この後めちゃくちゃフィックスしました」みたいな使い方するのか? ちょっと何言ってるか分からない。

まあそんな話は置いといて、次回はテキストオブジェクトの使い方を見ていこうと思います。画像と同じくらい、テキストもよく使うと思うしね。

ただテキストに関してはちょっと思うところがありまして……僕の作ったゲームはどうやら海外からのアクセスが結構あるみたいで、だから日本語が分からないと謎が解けないゲームばかりなのもあれだなって思ってるんですよ。他の方が作ったゲームもいろいろやらせてもらっているんですが、中には文字がほとんど出てこないものもあるんですよ。パスワードを解く時に出てくる数字くらいなもんで、テキストのヒントがなくても解けるように作られているんですね。海外の脱出ゲームもそんなのが結構多くて、英語が全然分からなくても解けるような作りになっていたりします。こういうゲームの作り方もあるんだなあと、いろいろ勉強させてもらっておりやす。

僕もいずれはそういう、テキストが不要なゲームも作ってみたいなーと密かに思っていたりしまして……できれば今年中には一つ作ってみたいです。今んとこ完全にノーアイデアですが、もし完成したら気が向いたらで良いんで遊んでもらえると嬉しいっす。

それじゃ、次回もよろしくお願いしゅーべると。



本シリーズの記事の一覧はこちら
Unityで簡単な2D脱出ゲームを作ってウェブサイトで公開してみよう 〜エピローグ〜
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください