inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

UI 자동화 #2

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

해결된 질문

152

더머더머

작성한 질문수 1

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;
    }
}

 

C# unity

답변 2

0

Rookiss

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

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

0

인프런 AI 인턴

안녕하세요, 인프런 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을 사용해 보는 일이 가장 직접적인 식별 방법입니다.

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

UI 기능 관련 질문이 있습니다!

0

23

2

픽셀 좌표 스크린 좌표

0

25

0

전체적으로 코드 읽는게 굉장히 오래 걸리네요...

0

66

2

카메라 #2 수업 캐릭터 쓰러짐 해결

0

78

1

플레이어 움직임이 끝날때, 기울어짐 현상

0

80

1

Input 적용과 관련하여 질문 있습니다.

0

72

1

디버그 불가.. Unity에 연결 불가

0

76

1

달리기 애니메이션 에러

0

85

2

오랜만에 게임을 만들다가 사운드 관련해서 뭔가 궁금한게 있어서 봤습니다

0

63

1

GetKey 오류

0

108

2

에셋을 어디에 올려두신지 알 수 있나요?

0

104

1

재귀호출? 오류나는데 왜 이래요 ?

0

167

6

Animation blending 파라미터 계산

0

65

1

newPos와 to지점이 겹쳐져야 하는거 아닌가요?

0

94

3

오브젝트 복제하니까 자꾸 이런게 뜨면서 꺼집니다

0

85

2

질문있습니다

0

142

2

아 이거 소스코드 같은거 없나요?

0

140

3

질문 드립니다. string.IsNullOrEmpty(name)

0

85

2

@Managers 가 씬에 배치되어 있어도 문제가 되지 않나요?

0

133

2

유니티6 NavMesh 안되는분들

1

174

1

Unity6 Unity-Chan Material 마젠타 문제 해결법

7

523

1

GetComponent<Poolable> 질문드립니다.

0

99

2

UI 불러오지 못함

0

116

2

수업자료 다운로드 방법이 궁금합니다.

0

168

2