캐릭터의 손에 무기를 배치하려면 보통 손 뼈대를 찾아 그 아래에 해당 무기 오브젝트를 배치한다.
하지만 손 뼈대 위치는 뼈대의 최하위 자식으로 위치하여 많은 캐릭터와 무기를 일일이 처리하려면 번거로움

무기를 배치할 손 뼈대를 찾아 하위에 배치하는 스크립트를 구현

다음과 같이 캐릭터 하위에 Child Name과 같은 이름을 찾아 자식으로 무기를 배치된다.

무기의 Transform은 따로 수정해야 된다.

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
/// <summary>
/// A(캐릭터)의 특정 자식(손 뼈대)을 찾아 아래에 B(무기)를 배치하는 스크립트
/// </summary>
public class WeaponMountManager : MonoBehaviour
{
[Header("Settings")]
public Transform parentObject; // 무기를 넣을 부모 오브젝트
public string childName; // 자식 오브젝트 이름
public GameObject weaponPrefab; // 할당할 무기 프리팹
/// <summary>
/// Inspector의 Mount 버튼을 누르면 호출
/// 1. 입력 값 유효성 검사
/// 2. 재귀 탐색으로 childName에 해당하는 Transform 찾기
/// 3. Prefab 인스턴스화 > Undo 지원
/// 4. target 아래에 무기 마운트
/// </summary>
public void MountWeapon()
{
// 1. 필수 필드 할당 여부 확인
if (parentObject == null)
{
Debug.LogError("Parent Object가 할당되지 않음");
return;
}
if (string.IsNullOrEmpty(childName))
{
Debug.LogError("Child Name이 비어 있음");
return;
}
if (weaponPrefab == null)
{
Debug.LogError("Weapon Prefab이 할당되지 않음");
return;
}
// 2. 부모 오브젝트 아래에서 childName과 일치하는 Transform 재귀 탐색
Transform target = FindChildRecursive(parentObject, childName);
if (target == null)
{
Debug.LogError($"'{parentObject.name}' 아래에 '{childName}' 자식이 존재하지 않음");
return;
}
GameObject instance;
#if UNITY_EDITOR
// 에디터 = PrefabUtility로 인스턴스화 + Undo 기록
instance = (GameObject)PrefabUtility.InstantiatePrefab(weaponPrefab, parentObject.gameObject.scene);
Undo.RegisterCreatedObjectUndo(instance, "Mount Weapon");
#else
// 런타임 = 일반 Instantiate 사용
instance = Instantiate(weaponPrefab);
#endif
// 3. target Transform의 자식으로 붙이고 위치/회전 초기화
instance.transform.SetParent(target, false);
instance.transform.localPosition = Vector3.zero;
instance.transform.localRotation = Quaternion.identity;
// 4. 마운트 완료 로그
Debug.Log($"'{target.name}' 아래에 무기를 마운트 완료");
}
/// <summary>
/// 모든 자식들 중 childName과 일치하는 Transform을 찾아 반환
/// </summary>
Transform FindChildRecursive(Transform parent, string name)
{
foreach (Transform child in parent)
{
if (child.name == name)
{
return child;
}
Transform found = FindChildRecursive(child, name);
if (found != null)
{
return found;
}
}
return null;
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(WeaponMountManager))]
public class WeaponMountManagerEditor : Editor
{
public override void OnInspectorGUI()
{
DrawDefaultInspector();
EditorGUILayout.Space();
if (GUILayout.Button("Mount"))
{
(target as WeaponMountManager).MountWeapon();
}
}
}
#endif