Inflearn brand logo image

인프런 커뮤니티 질문&답변

더머더머님의 프로필 이미지
더머더머

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진

UI 자동화 #2

UI 자동화 #1 - Util.cs의 FindChild함수에서 component.name에 컴포넌트 이름이 뜹니다.

해결된 질문

작성

·

92

·

수정됨

0

component.name에는 T 컴포넌트를 가진 게임 오브젝트의 이름이 와야 하는데, 게임 오브젝트의 이름이 아닌 컴포넌트의 이름이 옵니다. 예를 들면 FindChild<Button>이라면, component.name에 Button이 와, FindChild 함수가 계속 null만 return하는 상황입니다.
(아래에 코드 첨부)

 

코드 문제가 아니라 오브젝트 이름 문제였네요,,ㅠㅠ 해결했습니다 

 

image.png


UIButton.cs

using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public class UIButton : MonoBehaviour
{
    // 타입별로 오브젝트를 저장
    Dictionary<Type, UnityEngine.Object[]> _objects = new Dictionary<Type, UnityEngine.Object[]>();

    [SerializeField]
    TextMeshProUGUI text;

    // Button 오브젝트의 이름들을 enum으로 저장
    enum Buttons
    {
        PointButton,
    }

    enum Texts
    {
        PointText,
        ScoreText,
    }

    private void Start()
    {
        Bind<Button>(typeof(Buttons)); // enum은 Buttons인데, Button 컴포넌트를 가진 오브젝트에 매핑해주세요라는 의미
        Bind<Text>(typeof(Texts));

        Get<Text>((int)Texts.ScoreText).text = "Bind Test";
    }

    void Bind<T>(Type type) where T : UnityEngine.Object
    {
        // 1. 딕셔너리에 enum 요소 수만큼 빈 object 배열 넣어주기
        string[] names = Enum.GetNames(type); // enum값들이 names에 string으로 담김
        UnityEngine.Object[] objects = new UnityEngine.Object[names.Length];
        _objects.Add(typeof(T), objects);

        // 2. 실질적인 컴포넌트(오브젝트) 찾기
        for (int i = 0; i < names.Length; i++)
        {
            objects[i] = Util.FindChild<T>(gameObject, names[i], true);
        }
    }

    T Get<T>(int idx) where T : UnityEngine.Object
    {
        UnityEngine.Object[] objects = null;
        if (_objects.TryGetValue(typeof(T), out objects) == false)
            return null;

        return objects[idx] as T;
    }

    int score = 0;

    public void OnButtonClicked()
    {
        score++;
        text.text = $"Point : {score}";
    }
}

 

Util.cs

using Unity.VisualScripting;
using UnityEngine;

public class Util
{ 
    // go는 최상위 오브젝트 / recursive는 그 자식뿐만 아니라 자식의 자식도 계속 파고들며 찾을건지 여부
    public static T FindChild<T>(GameObject go, string name = null, bool recursive = false) where T : UnityEngine.Object
    {
        if (go == null)
            return null;

        if (recursive == false)
        {
            for (int i = 0; i < go.transform.childCount; i++)
            {
                Transform transform = go.transform.GetChild(i);
                if (string.IsNullOrEmpty(name) || transform.name == name)
                {
                    T component = transform.GetComponent<T>();
                    if (component != null)
                        return component;
                }
            }
        }
        else
        {
            foreach (T component in go.GetComponentsInChildren<T>())
            {
                if (string.IsNullOrEmpty(name) || component.name == name)
                    return component;
            }
        }

        return null;
    }
}

 

답변 2

0

Rookiss님의 프로필 이미지
Rookiss
지식공유자

함수의 조건을 where T : UnityEngine.Component
코드를 component.gameObject.name == name로 수정해보시기 바랍니다.

사실 굳이(?) 이름으로 찾는 경우가 없어서 누락된 것 같네요!

0

안녕하세요, 인프런 AI 인턴입니다.

현재 질문에서 제기된 문제는 Unity에서 FindChild 함수를 사용하여 게임 오브젝트의 이름을 찾고자 할 때, component.name이 아닌, T 타입 컴포넌트의 이름이 반환되는 상황입니다. 이로 인해 함수가 예상과 달리 null을 반환하게 되는 경우가 발생합니다.

이 문제의 원인은 component.name을 사용할 때 발생합니다. Unity에서는 컴포넌트의 name 속성이 해당 컴포넌트를 포함하고 있는 게임 오브젝트의 이름을 가져오는데, 반대로 사용하는 경우엔 컴포넌트 이름을 가져옵니다. 따라서, component.name을 사용하기보다 transform.name을 좀 더 적합하게 사용해야 하는 경우입니다. 이는 FindChild 메서드의 반복문에서 transform.name을 사용하여 이름을 비교하도록 변경할 필요가 있습니다.

유사한 질문 및 답변

아래는 같은 의문점에 대한 유사한 질문이 오간 사례입니다. 이를 참고하시면 도움이 될 수 있습니다:

  • Util.FindChild&lt;T&gt;(gameObject, names[i], true)와 관련하여…
    김지수님의 질문에 대해, “디버깅한 장면에서 _objects 딕셔너리의 Value 값이 \“PointButton{Unity.Engine.UI.Button}\“로 되어 있는 건 사실은 Button Component를 return 했지만 걔는 PointButton꺼야 라는 뜻인가요”에 대한 답변 등이 포함되어 있습니다.

  • FindChild 질문
    dongdong00님의 질문에서 “이 button 컴포넌트를 찾는 건데 컴포넌트의 .name은 붙어있는gameObject의 이름을 따라가니까 PointButton으로 찾을 수 있던거라고 이해하면 될까요?“에 대한 답변 등을 확인할 수 있습니다.

위의 링크들을 참조하여 문제를 보다 이해하고 해결책을 찾으시길 바랍니다. 코드를 수정하고자 할 때, component.name 대신 transform.name을 사용해 보는 일이 가장 직접적인 식별 방법입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

더머더머님의 프로필 이미지
더머더머

작성한 질문수

질문하기