【Unity】metaファイルって何?
「〇〇.meta」
Git使用時に突如として現れる謎のファイル。
コミットしなかったら、エンジニアの人に怒られるファイル。
一体何者なんだ…。
本記事ではそんな謎多きmetaファイルの正体に迫る…
metaファイルとは
一言でこうだというのが思いつかなかったので、metaファイルの主な特性を箇条書きにしました。
①metaファイルはAssetファイルがインポートされると同時に作成される。
②metaファイルには対応AssetファイルのUnityプロジェクトにおける設定、参照関係が記述、保管される。
③metaファイルにはAssetファイルを識別するためのGUIDが記述されている。
大体こんなもんです。
metaファイルの作成
UnityではAssetファイルがインポートされると同時にそれに対応するmetaファイルが作成されます。「いつの間に!?知らないよ、そんなやつ。」と思うかも知れません。それもそうです。だって、デフォルトではmetaファイルは隠しファイルとなっているので、表示されないんですもん。Gitを使うようになって初めて存在知った!って人が多いのもこのあたりが原因なんでしょう。
ちなみに、メニューバー>ProjectSettings>EditorのVersionControlのModeをVisible Meta Filesに設定すれば、表示されます。
Assetファイルの設定とmetaファイル
Assetファイルの設定は基本的にインスペクターウィンドウ上で行います。metaファイルには対応するAssetファイルの設定が記述、保管されているので、インスペクターウィンドウ上で設定を変更すると、それに合わせて、metaファイルも書き換えられます。
上の画像はインスペクターウィンドウ(画像左)とmetaファイル(画像右)の一部を抜き出したものです。赤い枠で囲んである部分を見てください。どちらもTextureType、TextureShapeと同じ名前です。要するに対応関係にあるので、インスペクターウィンドウの赤い枠の部分を変更するとmetaファイルの赤い枠の部分の数値が書き換えられます。
GUIDと参照関係
metaファイルにはAssetファイルを識別するための固有値、GUIDというものが記述されています。Unityでは、オブジェクト参照時にこのGUIDとFileIDというものを手がかりにします。
FileIDは、local identifier in fileのことであり、ファイル内のオブジェクトを識別するIDです。ファイル内で固有な値であるため、別のAssetファイル内のオブジェクト参照時にはAssetファイルの識別も必要となります。そこで、使用されるのがGUIDです。
以下はとあるスクリプトファイルに対応するmetaファイルです。
2行目にGUID、9、10行目に参照情報が記述されています。
9行目を日本語に訳すなら、「texという変数にはGUIDがf2f994c0d0f9b4a24b4c4615306b56efであるAssetファイル内のFileIDが2800000のオブジェクトから参照した値を格納する。」でしょうか。
metaファイルをコミットしないでプッシュしたら…
metaファイルを一緒にコミットせずにプッシュした場合、Assetファイルの設定や参照関係を引き継いでいないということになります。別の人がプッシュされたものをプルしてプロジェクトを開いても、参照が外れてしまっていたり、画像や音声ファイルの設定が作業前の状態に…なんてことに。
それだけならまだしも、プルした人たちのプロジェクト上にそれぞれ別々のmetaファイルが作成されるというめんどくさい事態も発生します。メインのブランチでやってしまうと修復がめんどくさいです。
このような事態が起こらないように、metaファイルは絶対にコミットしましょう。
【Unity】Spriteをドラッグで動かす【EventSystem】
以前、EventSystemを使ってオブジェクトへのタッチ入力を取得しました。
そのEventSystemを使って今回はSpriteをドラッグで動かします!
実装
手順はタッチを取得したときとほぼ同じです。違うのはスクリプトの中身ぐらいです。
①MainCameraにPysics2DRaycasterをアタッチ
②EventSystemをシーンに配置
③ドラッグで動かしたいオブジェクトに以下のスクリプトとCollider2Dをアタッチ
PointerEventData.positionでドラッグ中のPointer(タッチ位置、マウスカーソルの位置)のポジションを取得できるので、それをオブジェクトのtransform.positionに代入してます。
ただし、PointerEventData.positionはスクリーン座標系なので、ワールド座標系のtransform.positionに代入するには同じワールド座標系に変換する必要があります。また、PointerEventData.positionはVector2なので、こちらで代入するZ位置を指定した方がいいです。じゃないと、思わぬ値が代入されるかもしれないです。本記事では0を代入してます。
実行結果
すごい動くよー!
【Unity】Sprite(Collider2D)の重なりをBounds.Containsを使って取得しようとしたら、思ってたのと違った話
とある案件で「ドラッグで動かしているSpriteが指定したSpriteと重なっているかどうか」を取得する必要があったので
そんなの簡単じゃん。Bounds.Containsを使えばよくね?
と安易な考えで実装を行ったところ、思ってたのと違う!結果になってしまいました。
本記事ではその原因と解決方法について記します。
思ってたのと違う!結果になった実装
はじめはよく考えずに以下のように実装しました。
①シーンに2つのSprite(2DCollider付き)、EventSystemを配置。
②CameraにPysicsRaycaster2Dをアタッチ。
③Spriteの片方に以下のようなスクリプトをアタッチ。
そして実行した結果がこちらです。
Sprite同士(黄緑色の星とテキスト入りのサークル)は重なってないのに、DebugLogで「重なってるよー!」と陽気に叫んじゃってますね。
思ってたのと違う…
なぜ?
思ってたのと違う!結果になった原因
まず、Boundsってそもそも何なのかよくわかってなかったので、調べてみました。
そして、わかりました。
Boundsがオブジェクト(Collider)をピッタリ包む箱である。ただひたすらに箱である。
ということが。
下の画像のカプセルを包んでいる赤い箱がBoundsです。
ピッタリと包んではいますが、箱なので、余白ができてしまってます。
でも、この余白部分もBoundsなんです。
ここでもう一度思ってたのと違う!実行結果を見てみましょう。
赤い枠内がBoundsになります。
ご覧の通り、ドラッグされたSprite(2DCollider)は確かにBoundsと重なってるんです。
スクリプトは間違ってなかった!間違ってたのは私だ!
調べる以前はBoundsはそれを含むSprite(2DCollider)と形状、サイズともに一致するものだと勝手に思い込んでましたが、それは間違いでした。そして、その間違った思い込みのせいでスクリプトの実行結果と自分の頭の中で思い描いていた実行結果との間に誤差が生じたようです。結局、思ってたのと違う!結果になったのは自分の勉強不足が原因でした。
もう一度再確認
・Boundsは箱
・オブジェクトをピッタリと包んではいるが、包むオブジェクトの形状が複雑だと、どうしても余白ができてしまう
思ってたのと違う!結果になったときの解決方法
原因がわかったところで、解決方法を。
Collider2D.OverlapPoint(Vector2 point)
を使いましょう。
pointがCollider2Dと重なっていたらtrueが、
重なっていなかったらfalseが返ってきます。
オブジェクトにアタッチするスクリプトを少し書き換えるだけで、あとは最初にやった手順と同じです。
では、実行してみましょう!
いいですね。こういうのが欲しかった。
結構悩んだ割に解決方法はかなりあっさりでした…
まあ、今回はBoundsについての知識を得られたんでよしとします。
これで、Boundsとも友達!
【C#】配列をシャッフルする【Unity】
割とよく使う気がします。
特にカードゲームを作るとき。
おまけ
上記以外に以下のようにGUIDクラスを使う方法もあります。
GUIDはアセットファイルを識別するための番号のことです。
Unityのアセットファイル全てにこのGUIDが割り振られていて、これをもとにファイルの参照を行なっています。ちなみに特定のアセットファイルのguidはそのmetaファイルを見ればわかります。
GUIDについてはまた後日詳しく書けたら…
【Unity】EventSystemを使ってオブジェクトへのタッチ入力を取得する
スマホアプリを開発する際に必ずやると言ってもいいタッチ入力の取得…
今回はそんなタッチ入力の取得をEventSystemを使ってやっていきます。
Unityのバージョンは2017.4です。
それでは早速やっていきましょう!
① まずは、CameraにPysicsRaycasterをアタッチしてください。
② 次にEventSystemをシーンに配置しましょう。
EventSystemはヒエラルキー上で右クリックして、GameObject > UI > EventSystem
もしくはメニューバーのGameObject > UI > EventSystemでシーンに配置できます。
③ 最後にタッチイベントを追加したいオブジェクトに以下のスクリプトをアタッチしましょう。
オブジェクトにはColliderも必要です。
シーンはこんな感じになってるはず。今回はQuadをタッチオブジェクトにしてます。Quadにはすとーぶと文字が入ったテクスチャをはっつけてます。
これで、すとーぶQuadをタッチすると…
おおー!ちゃんとタッチ取得できてます!
かなり簡単でしたね。
2Dの場合もほぼ同じやり方です。違うのはCameraにPysics2DRaycasterをアタッチすることと、タッチオブジェクトにCollider2Dをアタッチすることだけです。
タップやドラッグの取得もそのうちやってみようと思います。