Unityを使ってゲームやアプリケーションを開発する際、オブジェクトを非表示にするシーンは多々あります。例えば、ユーザーが特定の条件を満たした時にアイテムを消す、シーンの遷移中にキャラクターを隠す、デバッグ用のオブジェクトを非表示にするなどのケースです。いろいろな方法がありますが、適切な方法を選ぶことで、プロジェクトのパフォーマンスやコードの可読性を向上させることができます。
本記事では、Unityでオブジェクトを非表示にする5つの方法を紹介し、それぞれのメリットとデメリットについて詳しく解説します。
オブジェクトを非表示にする方法
- SetActiveを使う
- Renderer.enabledをfalseにする
- オブジェクトを透明にする
- レイヤーマスクを変更する
- オブジェクトの位置をカメラの視界外に移動する
方法1: SetActiveを使う
最もシンプルな方法は、GameObjectのSetActive
メソッドを使用することです。この方法では、オブジェクト全体を非表示にし、かつ無効化します。
事前に非表示にしておくにはコード不要で、非表示にしたいオブジェクトのインスペクターのチェックを外すだけでできます。
スクリプトから非表示にするのは、1行でできます。
gameObject.SetActive(false);
メリット
- 簡単に使える: 1行のコードでオブジェクトを非表示にできます。この手軽さは、初心者から熟練者まで広く利用されています。
- オブジェクト全体を一括で非表示にできる: サブオブジェクトも含めて非表示になるため、親オブジェクトの管理が楽です。
デメリット
オブジェクトのUpdateやFixedUpdateが呼ばれなくなる
非表示にすると、これらのメソッドも停止します。これにより、オブジェクトの挙動が変わる可能性があります。
子オブジェクトもすべて非表示になる
子オブジェクトもまとめて全て非表示になってしまうので、細かい制御が難しい場合があります。特定の子オブジェクトだけを残したい場合には適していません。
SetActiveで非表示にしたオブジェクトは.Findで取得できない
非表示にしたオブジェクトを取得するには、publicでインスペクターにあらかじめ設定しておくことで対処できますが、数が多くなってくるとそれも大変になってきます。
あらかじめアクティブな状態からFindで取得していれば、非表示になっても取得できます。
ボタンを活用してオブジェクトのSetActiveを変更する方法もあり
ボタンを押したらオブジェクトの表示・非表示を切り替える方法についてはこちらをご覧ください。
方法2: Renderer.enabledをfalseにする
オブジェクトを非表示にするもう一つの方法は、MeshRendererコンポーネントのenabled
プロパティを設定することです。この方法は、オブジェクトの見た目だけを非表示にし、他の機能はそのまま動作させたい場合に適しています。
gameObject.GetComponent<Renderer>().enabled = false;
使用例のスクリプトです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test : MonoBehaviour
{
public GameObject testObject;
void Start()
{
testObject.GetComponent<Renderer>().enabled = false;
}
}
メリット
オブジェクトは存在し続けるが、見た目だけを非表示にできる
ロジックはそのまま動作します。これにより、オブジェクトの物理的な挙動やスクリプトの動作に影響を与えません。
子オブジェクトの描画も制御可能
個別に制御できるため、複数のRendererを持つオブジェクトや、部分的に非表示にしたい場合に柔軟です。
デメリット
- オブジェクトはアクティブなまま: 処理負荷がかかる可能性があります。非表示にしたオブジェクトが多い場合、パフォーマンスに影響を与えることがあります。
方法3: オブジェクトを透明にする
UIオブジェクトを非表示にする場合、CanvasGroupコンポーネントのalpha
プロパティを使用すると便利です。この方法は、透明度を制御することで、UI要素を柔軟に表示・非表示にできます。
UIオブジェクトを透明にする方法
親オブジェクトにCanvasGroupコンポーネントを追加する
非表示にしたい親オブジェクトにCanvasGroupコンポーネントを追加しましょう。
インスペクターから、alpha(透明度)を設定することができ、0で透明になります。
ちなみに、Interactableのチェックを外すことで、ボタンを押したり、スライダーを動かしたりすることができないようになりますので、透明にするときは合わせてチェックを外しておきましょう。
スクリプトから変更する例です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test : MonoBehaviour
{
public GameObject testObject;
void Start()
{
// 透明にする
testObject.GetComponent<CanvasGroup>().alpha = 0;
// ボタンやスライダーを反応させないようにする
testObject.GetComponent<CanvasGroup>().interactable = false;
}
}
メリット
- UI要素の透明度を簡単に制御できる: 視覚的な非表示が可能です。透明度を徐々に変化させることで、フェードアウト効果も簡単に実現できます。
- 他のUI設定(インタラクティブ性など)を一緒に制御可能:
CanvasGroup
を使うことで、UI要素のインタラクティブ性(ボタンの押下可否など)も制御できます。
デメリット
- 非UIオブジェクトには使えない: この方法はUI専用のため、3Dモデルやその他の非UIオブジェクトには適用できません。
- 若干パフォーマンスに負荷がかかる: 透明にするだけなので、オブジェクトは存在し続けます。そのため、大量のUI要素に対して使う場合、パフォーマンスに注意が必要です。
マテリアルを透明にする方法
UIではなく、通常のオブジェクトを透明にするにはこちらをご覧ください。
方法4: レイヤーマスクを変更する
レイヤーマスクを使用して特定のカメラからオブジェクトを非表示にすることもできます。この方法は、複数のカメラを使用するプロジェクトで特定のカメラからオブジェクトを隠したい場合に便利です。
やり方
見えないレイヤーの作成
まずはカメラから見えないレイヤーを作成します。適当なオブジェクトのインスペクターから、Layer > Add Layer…を選択し、レイヤーを作成します。
空いているUser Layerに作成します。名前は適当につけましょう。
戻ってレイヤーを選択すると、先ほど追加したレイヤーが選択できるようになっているので、非表示にしたいオブジェクトにはこのレイヤー設定にしておきます。
カメラの設定
見えなくしたいカメラのCameraコンポーネントのCulling Maskを選択し、先ほど追加したレイヤーのチェックを外しておきます。これでチェックを外したレイヤーはこのカメラから見えなくなります。
もしUIを非表示にしたい場合は、親オブジェクトのCanvasコンポーネントのRender ModeをScreen Space – Cameraに設定し、Render Cameraに対象のカメラを設定するとできるようになります。
スクリプトで設定するには?
スクリプトから非表示にしたいオブジェクトのレイヤーを見えないレイヤーに設定するコードはこちらです。
gameObject.layer = LayerMask.NameToLayer("ここにレイヤー名を入力");
メリット
- 特定のカメラからだけオブジェクトを非表示にできる: マルチカメラシステムに便利です。例えば、プレイヤー視点のカメラからは見えないが、デバッグカメラからは見えるように設定できます。
- マルチカメラシステムに便利: 特定のカメラにだけ表示させたい場合に有効です。カメラごとに異なるレイヤー設定を行うことで、細かな表示制御が可能です。
デメリット
- レイヤー管理が煩雑になる可能性: 多数のレイヤーを使う場合、管理が煩雑になる可能性があります。プロジェクトの規模が大きくなると、どのオブジェクトがどのレイヤーに属しているかの把握が難しくなることがあります。
- カメラごとの設定が必要になる: 複数のカメラでの設定管理が必要です。各カメラに対して適切なレイヤーマスクを設定する必要があります。
方法5: オブジェクトの位置をカメラの視界外に移動する
いっそのこと、オブジェクトの位置をカメラの視界外に移動することで非表示にする方法もあります。
gameObject.transform.position = new Vector3(1000, 1000, 1000);
メリット
- 物理的に見えなくするシンプルな方法: 簡単に実装できます。この方法は、特に一時的な非表示が必要な場合に適しています。
- オブジェクトの状態やスクリプトの動作に影響しない: ロジックはそのまま動作します。非表示にした後も、オブジェクトの物理的な挙動やスクリプトは影響を受けません。
デメリット
- オブジェクトの位置を管理する手間が増える: 大量のオブジェクトを処理する場合は非効率です。位置をリセットする際に、元の位置を覚えておく必要があります。
- 大量のオブジェクトを処理する場合は非効率: パフォーマンスに影響が出る可能性があります。特に多くのオブジェクトを一度に非表示にする場合、この方法は適していません。
まとめ
各方法にはそれぞれの利点と欠点があります。プロジェクトのニーズに応じて最適な方法を選ぶことが重要です。以下に各方法の比較表を示します。
方法 | メリット | デメリット |
---|---|---|
SetActive(false) | 簡単、全体を一括非表示 | Updateが停止、サブオブジェクトも非表示 |
Renderer.enabledをfalseにする | 見た目だけ非表示、子オブジェクトも制御可能 | オブジェクトは残り続けるため、処理負荷 |
オブジェクトを透明にする | フェードイン、フェードアウトができる | マテリアルの場合は、同じマテリアルに設定されているオブジェクトがまとめて非表示になる |
レイヤーマスクを変更 | 複数のカメラを使う時に便利 | レイヤー管理が煩雑 |
位置をカメラの視界外に移動 | 簡単、オブジェクトの状態やスクリプトに影響しない | 位置管理の手間、大量のオブジェクトは非効率 |
実際のプロジェクトでは、これらの方法を組み合わせて使用することもあります。例えば、特定の条件下でオブジェクトを一時的に非表示にする場合にはSetActive
を使用し、UI要素の透明度を調整する際にはCanvasGroup
を使うなど、シチュエーションに応じた適切な方法を選択することが大切です。これにより、プロジェクトのパフォーマンスを最適化し、開発効率を向上させることができます。