徳島ゲーム開発ごっこ 技術ブログ

ゲームを作るために役に立ったり立たなかったりする技術を学んでいきます!

【Unity】GameObjectがどのシーンにあるのかがプロパティ経由で取得できることを今更ながら知ったんだ

 悪魔の証明という言葉あります。
 「悪魔はいる」という主張を証明するには、悪魔をつれてこればいいですよね。
 でも「悪魔はいない」という主張はどう証明すればいいのでしょうか。
 この世のありとあらゆる場所を調査し、悪魔がいないということを確認する必要がありますが、現実的には不可能なのです。

 これはプログラムでも同じことが言えますね。
 「こういう機能はない」と高々に主張しても、それを証明するのは難しいのです。

 というわけで今回は、以前私が「GameObjectがどのシーンにあるかを判定する関数がないので、試行錯誤の末に出来た」という記事を投稿したんですが、
 結論として、どのシーンかを判定するプロパティがあった、という自らの調査能力の低さが露呈することになったお話です。
f:id:urahimono:20180625172240p:plain


この記事にはUnity2018.1.5f1を使用しています。
.Netのバージョン設定には.Net4.x (4.6相当)を使用しています。

GameObjectがSceneプロパティを持ってた!

 以前僕は、このような記事を書いたんですよ。
www.urablog.xyz

 指定したGameObjectがどのシーンにあるかを、いろいろな手を使って判定しようとしているんですよ。
 それでね、最近スクリプトリファレンスをいろいろみていたら、こんなプロパティを見つけたんですよ。

docs.unity3d.com

 GameObjectが持ってんだよ!
 sceneプロパティという、どのシーンにあるかの情報をな!!

 マジか……。
 えっ、このプロパティ最近出来たの?
 と思いスクリプトリファレンスを見返してみると、少なくともUnity5.3の時代からありやがる!
 自分の記事を見てみると、「この記事にはUnity5.6.0f3を使用しています」と書いているあるから、「そのときにはドキュメントに書いていなかった」といういいわけも出来ねえ。

 いやまあ聞いてくださいよ。
 SceneManagerは以前から結構調べていて、シーンに関する処理はSceneManagerが基本持っているはずだという考えが僕にあったんですよ。
 そしてSceneManagerが、指定したGameObjectがどのシーンにあるかを判定する関数がない以上、そんな処理は無いんだと決めてつけてしまったんです。
 そりゃ無えわな。
 GameObjectが所属しているシーンのプロパティ持ってるんなら、わざわざ判定する処理なんかは!

 というわけで上記の記事を見て、無駄に長い判定処理を作ってしまった方には申し訳ない。
 sceneプロパティを使えばあっさりわかるのでそちらをご利用くだされ。

 しかし、誰からもこの点を指摘されないところ見ると、
 僕の人望の無さと、このブログのアクセス数の低さが露呈するなぁ……。

 とういわけで、僕の方でも使ってみましょうか、sceneプロパティ。

SceneComponent.cs

using UnityEngine;

public class SceneComponent : MonoBehaviour
{
    private void Awake()
    {
        Debug.LogFormat( "Awake() 僕は「{0}」。シーン「{1}」に所属しているよ。", gameObject.name, gameObject.scene.name  );
    }

    private void Start()
    {
        Debug.LogFormat( "Start() 僕は「{0}」。シーン「{1}」に所属しているよ。", gameObject.name, gameObject.scene.name );
    }

} // class SceneController

f:id:urahimono:20180625172258p:plain
f:id:urahimono:20180625172310p:plain

Awake() 僕は「GameObject 1」。シーン「SceneA」に所属しているよ。
Awake() 僕は「GameObject 2」。シーン「SceneB」に所属しているよ。
Start() 僕は「GameObject 1」。シーン「SceneA」に所属しているよ。
Start() 僕は「GameObject 2」。シーン「SceneB」に所属しているよ。

 ああ、簡単だよ。
 長尺で書いたあの記事はなんだったのか。

DontDestroyの場合はどうなんの?

 一応、前回の記事でもやったように、DontDestroy()を使ってシーンの所属が無い場合も調べておきましょうか。

SceneComponent.cs

using UnityEngine;

public class SceneComponent : MonoBehaviour
{
    private void Awake()
    {
        Debug.LogFormat( "Awake() 僕は「{0}」。シーン「{1}」に所属しているよ。", gameObject.name, gameObject.scene.name  );

        // これで僕のシーンはシーン移動しても消えないぞ!
        DontDestroyOnLoad( gameObject );
    }

    private void Start()
    {
        Debug.LogFormat( "Start() 僕は「{0}」。シーン「{1}」に所属しているよ。", gameObject.name, gameObject.scene.name );
    }

} // class SceneController

f:id:urahimono:20180625172330p:plain
f:id:urahimono:20180625172341p:plain

Awake() 僕は「GameObject 1」。シーン「SceneA」に所属しているよ。
Awake() 僕は「GameObject 2」。シーン「SceneB」に所属しているよ。
Start() 僕は「GameObject 1」。シーン「DontDestroyOnLoad」に所属しているよ。
Start() 僕は「GameObject 2」。シーン「DontDestroyOnLoad」に所属しているよ。

 シーン情報がDontDestroyOnLoadに変更されているね。
 ああ、良かった良かった。

 しかし、僕の調査能力もたかがしれているなぁ。
 調査兵団にでも入って、調査能力を上げる努力をしようかなぁ。