inflearn logo
강의

Course

Instructor

[MMORPG Game Development Series with C# and Unity] Part3: Unity Engine

UI Manager #1

UI_Button 클론이 무한생성

Resolved

314

gml0303091239

7 asked

0

 

UI_Button 클론이 무한생성됩니다.



public class Test : MonoBehaviour
{
    GameObject er;


    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Managers.UI.ShowPopupUI<UI_Button>();
        }
    }
}

아래 코드로 문제가 있어서 화면을 클릭했을 때만 팝업이 뜨도록 위의 코드로 Test 스크립트를 일부 바꿔 봤습니다.

그러고나서 보니까

public static UIManager UI{get{return instance._ui;}} 이 지점에서 계속 다시 Test 파일의

if (Input.GetMouseButtonDown(0)) { Managers.UI.ShowPopupUI<UI_Button>(); }

이 부분으로 가는 것 같습니다. 늘어나는 갯수로 처음엔 한번 클릭했을 때는 한번으로 잘 늘어나는데 그 다음엔 2개가 생기고 그 다음엔 5개..? 규칙을 알 수 없게 늘어납니다

저 요즘 질문 너무 많이하죠..ㅜㅜ 그치만 미워하지 말아주세요 다 기본 3시간은 고민고민하며 노려보다가 보내는거긴해유..하핳..

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    GameObject er ;
    void Start()
    {
        Managers.UI.ShowPopupUI<UI_Button>();
    }

    void Update()
    {
        
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResourceManager
{
    public T Load<T>(string path) where T:Object
    {
        return Resources.Load<T>(path);

    }
    public GameObject Instantiate(string path, Transform parent = null)
    {
        GameObject prefab = Load<GameObject>($"Prefabs/{path}");
        if (prefab == null)
        {
            Debug.Log($"Failed to load prefab : {path}");
            return null;
        }
        return Object.Instantiate(prefab, parent);//Object붙이는 이유는 리소스메니저에 있는 Instantiate를 또 호출하려고 할까봐.
    }
    public void Destroy(GameObject go)
    {
        if(go == null)
            return;
        
        Object.Destroy(go);

    }
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Managers : MonoBehaviour

{
    static Managers s_Instance; //유일성이 보장된다
    static Managers instance { get { Init(); return s_Instance; } } // 유일한 매니저를 갖고온다
    
    ResourceManager _resource = new ResourceManager();
    UIManager _ui = new UIManager();

    public static UIManager UI{get{return instance._ui;}}
    public static ResourceManager Resource{get{return instance._resource;}}
    // Start is called before the first frame update

    void Start()

    {

        Init();
        

    }

    // Update is called once per frame

    void Update()

    {
    }

    static void Init()

    {

        if (s_Instance == null)

        {

            GameObject go = GameObject.Find("@Managers");

            if (go == null)

            {

                go = new GameObject { name = "@Managers" };

                go.AddComponent<Managers>();

            }

            DontDestroyOnLoad(go);

            s_Instance = go.GetComponent<Managers>();

        }

    }



}using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UIManager
{
    
    int _order = 0;
    //팝업 목록을 들고있어야함. 스택 구조으로 관리하기 가장 마지막에 띄운 팝업이 가장 먼저 삭제돼야하니까.
    Stack<UI_Popup> _popupStack = new Stack<UI_Popup>();
    public T ShowPopupUI<T>(string name = null) where T : UI_Popup//T에는 UI버튼이라는 스크립트를 건네고 name에는 팝업프리펩을 건네줄거임.
    {
        if(string.IsNullOrEmpty(name))//이름이 비어있으면 T타입의 이름과 똑같은걸로 넣겠다.
            name = typeof(T).Name;

        GameObject go = Managers.Resource.Instantiate($"UI/Popup/{name}");
        T popup = Util.GetOrAddComponent<T>(go);
        _popupStack.Push(popup);
        return popup;
    }

    public void ClosePopupUI()
    {
        if (_popupStack.Count == 0) //stack을 건드릴 떈 항상 카운트를 체크하는걸 습관화하기
            return;

        UI_Popup popup =  _popupStack.Pop();
        Managers.Resource.Destroy(popup.gameObject);
        popup = null;

        _order--;
    }

}



using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Util
{
    public static T GetOrAddComponent<T>(GameObject go) where T : UnityEngine.Component
    {
        T component = go.GetComponent<T>();
        if (component == null)
            component = go.AddComponent<T>();
        return component;
    }
    public static GameObject FindChild(GameObject go, string name = null, bool recursive = false)

    {

        Transform transform = FindChild<Transform>(go, name, recursive);//<Transform>을 사용하면 FindChild 메서드가 호출될 때 해당 메서드는 Transform 타입의 자식을 찾도록 약속됩니다. 이는 제네릭을 사용하여 메서드를 특정 타입에 제한하는 방법 중 하나입니다.

        if (transform == null)
            return null;

        return transform.gameObject;

    }
    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 childTransform = go.transform.GetChild(i);

                if (string.IsNullOrEmpty(name) || childTransform.name == name)
                {
                    T component = childTransform.GetComponent<T>();
                    if (component != null)
                        return component;
                }
            }
        }
        else
        {
            foreach (T component in go.GetComponentsInChildren<T>(true))
            {
                if (string.IsNullOrEmpty(name) || component.name == name)
                    return component;
            }
        }

        return null;
    }
}

C# unity

Answer 2

0

Rookiss

image
일단 가장 인접한 코드를 다운받아 다른게 없는지 비교해보세요.
사실 질문하신 내용만 보고서는 저도 알 수가 없습니다.
코드와 별개로 GameObject에 어떻게 Component를 붙였는지 또한 관건이기 때문입니다.
요즘 정말 시간이 바빠서 일일히 코드를 봐드릴 수가 없는데요.

문제가 일어날 때 유용한 방법은
- 책 or 강의 코드를 부분적으로 복붙해가며 다른 부분 있는지 범인 색출
- 디버깅 (로그 찍거나, breakpoint 걸어서 멈춰서 보기)
- 코드 분석 (무한 헤딩)

등이 있는데요. 처음엔 고통스럽겠지만
어차피 프로그래머의 업무중에 50% 이상은 버그 찾는 것이라
익숙해지셔야 합니다.

0

communityai8509

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

해당 문제와 관련하여 이전에 다른 수강생이 비슷한 문제를 제기한 사례가 있어 유사한 경우를 찾았습니다. 아래 링크를 통해 비슷한 문제에 대한 강사님의 답변을 참고해보시면 도움이 될 것 같습니다.

도움이 되셨길 바라며, 질문&답변 게시판을 통해 추가적인 질문이 있으시면 언제든지 올려 주시기 바랍니다.

ResourceManager 클래스 관련 질문

1

38

2

몬스터 HP 게이지바 이동

0

24

1

매니저 관련 질문이 있습니다.

0

74

2

비쥬얼 스튜디오에서 unity연결이 없습니다.

0

82

2

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

0

73

2

픽셀 좌표 스크린 좌표

0

58

0

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

0

108

2

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

0

97

1

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

0

103

1

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

0

93

1

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

0

102

1

달리기 애니메이션 에러

0

100

2

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

0

75

1

GetKey 오류

0

132

2

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

0

114

1

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

0

181

6

Animation blending 파라미터 계산

0

77

1

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

0

114

3

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

0

97

2

질문있습니다

0

159

2

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

0

152

3

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

0

94

2

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

0

139

2

유니티6 NavMesh 안되는분들

1

195

1