個人的にGoogle Playだったりでゲームを遊んでるれいです。
個人開発のゲームで特に目立つ、チュートリアルで指定のオブジェクト(例:育成ボタン)を注目させるときに背景をクリッピングさせる…
アレ、黒背景の画像+透明の丸の切り抜きでやるのはいいんですが・・・なかなか見た目が残念になりやすいです
四角(矩形)にするとそれはそれで見づらい
というわけで、特別な工夫なしに指定のオブジェクトだけ注目させるコードを作りました。
出来栄え
指定のオブジェクトだけを注目させる、かつクリックできるようにしています
2ステップ実現方法
(1)オブジェクトの階層を入れ替えて、背景画像の前面に出す
(2)元の階層に戻す
めちゃくちゃ簡単でした。
それでは実際にコードの使い方を見ていきましょう。
設定
階層構造は以下の通りにします。

背景が画像1と画像2より前面に出ています。
GameObjectには以下で紹介する2つのスクリプトをアタッチし、設定しておきます。

DisplayBackground1Controller.cs
using UnityEngine;
/// <summary>
/// DisplayBackground1シーンの背景Panel制御
/// HierarchyToggleController を使用して、矢印キーで Image1/Image2 の親を切り替える
/// </summary>
public class DisplayBackground1Controller : MonoBehaviour
{
[SerializeField] private HierarchyToggleController hierarchyToggleController;
void Start()
{
if (hierarchyToggleController == null)
{
Debug.LogError("HierarchyToggleController が見つかりません。");
}
}
void Update()
{
if (hierarchyToggleController == null)
return;
// 矢印キー入力で親を切り替え
if (Input.GetKeyDown(KeyCode.UpArrow))
{
hierarchyToggleController.SetActive("Image1");
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
hierarchyToggleController.SetActive("Image2");
}
else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
hierarchyToggleController.DisableAll();
}
}
}
HierarchyToggleController.cs
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 任意のオブジェクトを指定した親に移動して、Z順序を変更する汎用コンポーネント
/// Inspector でキーごとにオブジェクトと移動先の親を設定し、キーベースで ON/OFF を切り替える
/// </summary>
public class HierarchyToggleController : MonoBehaviour
{
[System.Serializable]
public class HierarchyToggleEntry
{
public string key; // キー(例:"Image1", "Image2")
public Transform targetObject; // 親を変更するオブジェクト
public Transform newParent; // 移動先の親(新しい親)
// 実行時に使用(元の親と兄弟順序を保存)
[System.NonSerialized] public Transform originalParent;
[System.NonSerialized] public int originalSiblingIndex;
}
[SerializeField] private List<HierarchyToggleEntry> toggleEntries = new List<HierarchyToggleEntry>();
// キーでエントリを高速参照するための辞書
private Dictionary<string, HierarchyToggleEntry> entryDict = new Dictionary<string, HierarchyToggleEntry>();
// 現在アクティブなキー(null の場合はアクティブなものはない)
private string currentActiveKey = null;
void Start()
{
// 各エントリの元の親と兄弟順序を保存し、辞書を初期化
foreach (var entry in toggleEntries)
{
if (entry.targetObject != null)
{
entry.originalParent = entry.targetObject.parent;
entry.originalSiblingIndex = entry.targetObject.GetSiblingIndex();
// 辞書に追加(キーが重複していないと仮定)
if (!entryDict.ContainsKey(entry.key))
{
entryDict.Add(entry.key, entry);
}
}
}
}
/// <summary>
/// 指定したキーのオブジェクトを親変更状態にする
/// 既に別のキーがアクティブな場合、それを先に Disable する
/// </summary>
public void SetActive(string key)
{
if (!entryDict.ContainsKey(key))
{
Debug.LogWarning($"HierarchyToggleController: キー '{key}' が見つかりません。");
return;
}
// 既存のアクティブなエントリがあれば Disable
if (currentActiveKey != null && currentActiveKey != key)
{
DisableInternal(currentActiveKey);
}
// 指定キーのエントリをアクティブにする
var entry = entryDict[key];
if (entry.targetObject != null && entry.newParent != null)
{
entry.targetObject.SetParent(entry.newParent, worldPositionStays: true);
currentActiveKey = key;
}
}
/// <summary>
/// 指定したキーのオブジェクトを元の親に戻す
/// </summary>
public void Disable(string key)
{
if (!entryDict.ContainsKey(key))
{
Debug.LogWarning($"HierarchyToggleController: キー '{key}' が見つかりません。");
return;
}
if (currentActiveKey == key)
{
DisableInternal(key);
currentActiveKey = null;
}
}
/// <summary>
/// すべてのアクティブなエントリを Disable する
/// </summary>
public void DisableAll()
{
if (currentActiveKey != null)
{
DisableInternal(currentActiveKey);
currentActiveKey = null;
}
}
/// <summary>
/// 内部用:指定キーのエントリを元の親に戻す処理
/// </summary>
private void DisableInternal(string key)
{
var entry = entryDict[key];
if (entry.targetObject != null && entry.originalParent != null)
{
entry.targetObject.SetParent(entry.originalParent, worldPositionStays: true);
entry.targetObject.SetSiblingIndex(entry.originalSiblingIndex);
}
}
/// <summary>
/// 現在アクティブなキーを取得
/// </summary>
public string GetCurrentActiveKey()
{
return currentActiveKey;
}
/// <summary>
/// 指定したキーがアクティブかどうかを確認
/// </summary>
public bool IsActive(string key)
{
return currentActiveKey == key;
}
}
何をしているのか
配置を操作したいオブジェクトを辞書型のような形式で管理します。
指定したキーのオブジェクトについて、前述の通り(1)前面に出す⇔(2)元に戻すを制御しているだけです。
うれしいポイント
・クリッピングとは違い、画面の大きさの違いによる位置ずれを起こしづらいです。
※設定によってはうまく働かない可能性があるのでテストしてください。
・オブジェクトはいくつでも指定可能。多数のオブジェクトがあっても登録すればすべて同じように使えます。
・別のシーンでも1つのコード(HierarchyToggleController.cs)で使える応用性があります。
さいごに
ワイもさっそくゲーム内に導入しよう~また何かあれば書きます( ^^)/~~

