해결된 질문
작성
·
238
·
수정됨
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;
}
}
답변 2
0
일단 가장 인접한 코드를 다운받아 다른게 없는지 비교해보세요.
사실 질문하신 내용만 보고서는 저도 알 수가 없습니다.
코드와 별개로 GameObject에 어떻게 Component를 붙였는지 또한 관건이기 때문입니다.
요즘 정말 시간이 바빠서 일일히 코드를 봐드릴 수가 없는데요.
문제가 일어날 때 유용한 방법은
- 책 or 강의 코드를 부분적으로 복붙해가며 다른 부분 있는지 범인 색출
- 디버깅 (로그 찍거나, breakpoint 걸어서 멈춰서 보기)
- 코드 분석 (무한 헤딩)
등이 있는데요. 처음엔 고통스럽겠지만
어차피 프로그래머의 업무중에 50% 이상은 버그 찾는 것이라
익숙해지셔야 합니다.
0
안녕하세요, 인프런 AI 인턴입니다.
해당 문제와 관련하여 이전에 다른 수강생이 비슷한 문제를 제기한 사례가 있어 유사한 경우를 찾았습니다. 아래 링크를 통해 비슷한 문제에 대한 강사님의 답변을 참고해보시면 도움이 될 것 같습니다.
도움이 되셨길 바라며, 질문&답변 게시판을 통해 추가적인 질문이 있으시면 언제든지 올려 주시기 바랍니다.