親オブジェクト & 子オブジェクトの扱い ― 要点まとめ

Unityでは、親オブジェクトと子オブジェクトを使うことで、表示や動作をまとめて管理できます。オブジェクトを親子関係にする、切り離す、座標を扱う、生成時に親を設定するなどは、UIや演出、弾管理など幅広い場面で必要となります。本記事では、代表的な操作方法を簡潔にまとめます。

親オブジェクトと子オブジェクトの基本操作まとめ

1) 子を親に付ける(親子関係を作る)

childTransform.SetParent(parentTransform);

親設定&ローカル座標維持

childTransform.SetParent(parentTransform, worldPositionStays: false);
worldPositionStays子の座標
trueワールド座標維持
false親基準のローカル座標になる

SetParent() の第2引数 worldPositionStays は、

親を付けたあと、子の「見た目の位置」を保つかどうか を決めます。

childTransform.SetParent(parentTransform, worldPositionStays: false);
worldPositionStays子オブジェクトの位置がどうなるか
true今の見た目の位置をそのまま維持する(ワールド座標優先)
false親基準の位置に合わせる(ローカル座標優先、見た目が変わることがある)

分かりやすい例

  • true
    位置を変えずに、親の下に入れるだけ→ 見た目が変わらない
  • false
    親の中心へ吸い付くように移動してしまう場合がある→ ローカル位置が優先される

例:UI やエフェクトで便利

  • 敵が爆発するとき爆発エフェクトを enemy の子にしても、位置を維持して再生したい → true
  • アイテムをインベントリスロットへ入れるスロット内の標準位置にそろえたい → false

このように

「見た目を保つ?」 → true

「親基準位置に合わせる?」 → false

と理解すると、直感的に使えます。


2) 子を親から切り離す(Detach)

① SetParent(null)

childTransform.SetParent(null);

ワールド座標は維持される。

② 親側ですべて切り離し

parentTransform.DetachChildren();

※すべての子が root(親なし)になる。


3) Instantiate しながら親を設定

Instantiate(prefab, parentTransform);

位置・回転を prefab のまま保持。

Instantiate(prefab, parentTransform, worldPositionStays: false);

→ 自然にローカル(0,0,0)として設置される


4) 子の取得

① Transform.childCount / GetChild

for (int i = 0; i < parentTransform.childCount; i++)
{
    Transform c = parentTransform.GetChild(i);
}

② 名前で検索(子のみ)

Transform child = parentTransform.Find("ChildName");

③ 階層を見て検索

Transform t = parentTransform.Find("Group/Child");

5) 子を全削除

foreach (Transform c in parentTransform)
{
    GameObject.Destroy(c.gameObject);
}

6) 子を一時的に無効化

child.gameObject.SetActive(false);

7) 子と親の座標系

ワールド座標

transform.position
transform.rotation

ローカル座標(親基準)

transform.localPosition
transform.localRotation
transform.localScale

8) 親基準で移動

transform.localPosition = new Vector3(0, 1, 0);

9) 親と子の座標が勝手に変わる問題

worldPositionStays が関係する。

child.SetParent(parent, worldPositionStays: false);

→ 子は親内で自然なローカルになる(≒0,0,0)


実用サンプル

サンプル1:親から子を切り離して飛ばす

using UnityEngine;

public class DetachShoot : MonoBehaviour
{
    [SerializeField] Transform bullet;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // 親から切り離し
            bullet.SetParent(null);

            // 等速で飛ばす
            bullet.GetComponent<Rigidbody2D>()
                .linearVelocity = Vector2.right * 5f;
        }
    }
}

サンプル2:生成時に親を設定し、2秒後に切り離す

using UnityEngine;

public class SpawnChild : MonoBehaviour
{
    [SerializeField] GameObject prefab;
    [SerializeField] Transform parent;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            var obj = Instantiate(prefab, parent, false);
            StartCoroutine(DetachLater(obj.transform));
        }
    }

    System.Collections.IEnumerator DetachLater(Transform t)
    {
        yield return new WaitForSeconds(2f);
        t.SetParent(null);
    }
}

サンプル3:全子オブジェクトを削除

using UnityEngine;

public class ClearChildren : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.C))
        {
            foreach (Transform child in transform)
            {
                Destroy(child.gameObject);
            }
        }
    }
}

便利Tips

● Transform の親子で座標が崩れる

SetParent(…, false) を使う。

ローカル座標が初期化され、意図通りになることが多い。


● 子が勝手に回転・ズレる

親に Scale ≠ 1 や回転がある場合→ 子も影響を受ける

DOTween のアニメでも影響するため、Visual 親と Logic 親を分けると安全。


● 子を自動で探すが頻繁なら一度キャッシュ

transform.Find() は重い

→ Start() で保持しておく

一覧まとめ(利用頻度順)

種類API説明
親に付けるSetParent(parent)親子関係を作る
親から外すSetParent(null)親子関係を解除
ローカル座標localPosition親基準の座標
ワールド座標positionワールド座標
子の数を取得childCount子の総数
子をインデックスで取得GetChild(index)子を番号で取得
名前で検索Find(name)子を名前で検索
子を削除Destroy(child.gameObject)子オブジェクトを削除
すべて外すDetachChildren()親配下の子を全て外す

よく使われる

SetParent()、localPosition、position

時々使う

childCount、GetChild()、Find()

比較的レア

Destroy(child.gameObject)、DetachChildren()


追加:

「親にまとめて子を制御」する良い使い方

例:

  • 弾を「Bullets」オブジェクトにまとめて階層を見やすくする
  • UI パネル内のボタンを一括無効化
  • エフェクトをまとめて破棄

訪問数 5 回, 今日の訪問数 6回