うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】Component のアクティブを切り替える Scope

Hierarchy に存在するオブジェクトの参照を持っていて、それからインスタンスを作成する場合

生成時には active で終わったあとには disactive にすることがある

   [SerializeField]
    private GameObject _resource;

    private void Create()
    {
        _resource.gameObject.SetActive(true);
        var list = new List<GameObject>();
        for (int i = 0; i < 10; i++)
        {
            list.Add(Instantiate(_resource, transform));
        }
        _resource.gameObject.SetActive(false);
    }

その度に同じような処理を書くのが面倒だったので Scopeにしてみた

public class ComponentActiveScore : System.IDisposable
{
    private readonly GameObject _resource;
    private bool _isChange;
 
    public ComponentActiveScore(GameObject resource)
    {
        _resource = resource;

        // Parent が False で ヒエラルキーでアクティブじゃない場合は
        // インスタンスのないオブジェクトの可能性が高い
        if (_resource.transform.parent == null && !_resource.gameObject.activeInHierarchy)
        {
            _isChange = false;
            return;
        }

        _resource.SetActive(true);
    }
 
    public ComponentActiveScore(Component resource) : this (resource.gameObject)
    {
    }
 
    public void Dispose()
    {
        if (!_isChange)
            return;

        _resource.SetActive(false);
    }
}

これを利用すると先程の処理はこうなる

   [SerializeField]
    private GameObject _resource;

    private void Create()
    {
        var list = new List<GameObject>();
        using (new ComponentActiveScore(_resource))
        {
            for (int i = 0; i < 10; i++)
            {
                list.Add(Instantiate(_resource, transform));
            }
        }
    }

行数は特に変わってないが、 GameObject を気にしなくても良くなった