인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

Inflearn Community Q&A

No author

This post's author information has been deleted.

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

UI Manager #1

AddComponent와 UI_Popup.cs에 대한 질문

Written on

·

481

0

안녕하세요 강의 너무 잘 듣고 있습니다.

강의를 들으면 들을수록 기초 개념이 부족하다는 생각이 듭니다.

1.

이미 되게 자연스럽게 쓰고있던 AddComponent 함수에 대한 질문입니다.

를 실행하면 

ShowPopupUI에 들어가 GetOrAddComponent<UI_Button>(go) 함수를 호출한 셈이 될테고, 만약 go에 UI_Button 컴포넌트가 없다면 Add를 하게 될텐데 Add될 컴포넌트는 UI_Button.cs인가요? 더 궁금한건 실제 Prefabs/UI/Popup 안에도 UI_Button이란 prefab이 존재하는데 Unity가 이 둘을 잘 알아서 구분하나요? (물론 prefab이 컴포넌트로 붙을 수는 없다고 생각하지만 예를 들어 같은 이름의 스크립트 파일이 다른 파일에도 여러개 존재할 수 도 있을텐데 이럴땐 어떻게 구별하나요?)

2. UI_Popup의 init함수에 들어가는 내용이 Start에서 실행되지 않기에 UI_Button.cs의 Start()->Init()->base.Init()를 통해 간접 실행하게 되는데 

UI_Popup에 있는 gameObject가 UI_Button으로 뜨는 이유가 아리송합니다. gameObject가 Component라는 조상클래스의 맴버 변수이며 UI_Button이 UI_Popup을 상속받았기에 가능한 일인가요?

3. ClosePopupUI함수를 virtual 키워드로 작성하신 이유를 알 수 있을까요? UI_Base에서 재정의하여 사용하는 경우가 있나요?

unityC#

Answer 8

1

rookiss님의 프로필 이미지
rookiss
Instructor

Component(gameObject 변수 소유)<----- ... <-----UI_Base <-----UI_Popup<-----UI_Button

아하, 강의를 만든지 너무 오래돼서 기억이 가물가물했는데
UI_Button이 UI_Popup 상속이었군요 -_- 답변을 정정 드립니다.

결국 UI_Button에서 사용하는 gameObject나 UI_Popup에서 사용하는 gameObject나 UI_Base에서 사용하는 gameObject나 모두 동일한 gameObject아닌가요? 

-> 네 동일합니다. 

gameObject가 Component라는 조상클래스의 맴버 변수이며 UI_Button이 UI_Popup을 상속받았기에 가능한 일인가요?

-> 그러고보니 이 질문도 제가 잘못 이해했네요. UI_Button이 UI_Popup을 상속받은 것 '자체'와 gameObject는 상관없다고 말씀드렸는데, 그렇다고 상속이랑 아예 무관한건 또 아닙니다. 정확히 말하면 UI_Button, UI_Popup이 상속 관계이면서 UI_Popup도 타고 타고 가면 Component를 상속 받아서 그런 것이 맞습니다. GameObject는 프리팹을 Instantiate하는 순간 별도로 지정하지 않으면 프리팹이름(Clone)으로 이름이 세팅됩니다. UI_Button 프리팹을 이용해 만든 GameObject이기 때문에 이름이 그렇게 지정된 것이고, 그 상태에서 UI_Button 스크립트 Component를 붙인 상태입니다. gameObject로 접근하는 것은 원래 Component 쪽에 있는 기능인데, Component를 상속받은 애들은 당연히 그 기능을 똑같이 사용할 수 있습니다.

UI_Popup은 어느 GameObject의 Component로 붙여주지도 않았는데 SetCanvas를 호출하는게 어색하구요

-> 스크립트끼리 상속 관계가 있을 때는 각각을 별도로 생각하면 안 됩니다. UI_Button은 실질적으로 UI_Popup이기도 하고, MonoBehavior이기도 하고, Component이기도 한 것이죠. 따라서 부모가 물려준 유산은 동일하게 다 사용할 수 있습니다. gameObject는 Component가 물려준 것이니 UI_Popup에서도 사용할 수 있습니다.

그리고 UI_Button은 붙였고 UI_Popup은 붙인 적이 없다고 생각하시는데, UI_Button을 붙인 것이 곧 UI_Popup을 붙인 것도 됩니다. 애당초 상속 관계이기 때문에 둘을 분리해서 생각할 수 없습니다.

0

흑흑 ㅠㅠ감사합니다 선생님 가려운 부분이 시원하게 긁혔습니다

0

답변 감사합니다.

정성스럽게 써주신 답변 너무 감사합니다.. 다만 아직도 이해가 되지 않습니다.

첫 번째로 프리팹에 UI_Popup 스크립트를 실수로 붙이진 않았음을 확인했습니다.

제가 말 주변이 없어서 이번을 마지막으로 제가 궁금한 부분을 질문드리고 그래도 이해가 되지 않는다면 넘어가겠습니다.

UI_Button 클래스는 는 UI_Popup 클래스를 상속받고

UI_Popup클래스는 UI_Base를 상속받는데 

Component(gameObject 변수 소유)<----- ... <-----UI_Base <-----UI_Popup<-----UI_Button

결국 UI_Button에서 사용하는 gameObject나 UI_Popup에서 사용하는 gameObject나 UI_Base에서 사용하는 gameObject나 모두 동일한 gameObject아닌가요? 

그렇다고 어느정도 확신을 하는것이  선생님의 말씀대로 UI_Button의 gameObject와 UI_Popup의 gameObject가 상속과 관련없이 별개의 변수라면 UI_Button클래스의 Start를 시작으로 UI_Popup에 대한 SetCanvas함수 호출만 있을 뿐 UI_Button에 대한 SetCanvas함수 호출은 코드 어디에서도 찾을 수 없었습니다.. 뿐만 아니라 UI_Popup은 어느 GameObject의 Component로 붙여주지도 않았는데 SetCanvas를 호출하는게 어색하구요

ㅠㅠ너무 여러번 질문드려서 죄송합니다.. 마지막으로 가 궁금한 부분을 강사님이 캐치해주셨으면 좋겠네요

매번 감사합니다.

0

rookiss님의 프로필 이미지
rookiss
Instructor

1. UI_Button에 붙은 컴포넌트는 UI_Popup.cs가 아닌 UI_Button.cs인데 어떠한 이유로 UI_Popup.cs내에서  UI_Button이라는 gameObject(base)를 갖을 수 있는지 궁금합니다. 
-> 이건 저도 알 수 없습니다.
UI_Button 프리팹에 UI_Popup 스크립트를 잘못 붙인게 아닌지 확인 바랍니다.

2. 
UI_Popup.cs의 Init에서 Managers.UI.SetCanvas(gameObject, true); 해당 코드의 gameObject는 누군가요?

-> Monobehavior를 상속받은 cs파일 또한 Component입니다.
따라서 gameObject는 당연히 UI_Popup.cs를 붙인 GameObject를 말하는겁니다.
Component는 독단적으로 존재할 수 없고, 반드시 GameObject에 기생해서 살아갑니다.
강의 코드에서는 UI를 띄울 때 어디선가 AddComponent 혹은 GetOrAddComponent 를 해서
Component를 연결 해줍니다.

UI_Button GameObject에 UI_Popup.cs이 붙은 것은 프리팹을 잘못 만든것으로 의심됩니다.

0

오랜 시간 고민을 해도 이해가 잘 안돼서 질문 드립니다.

1.

상속 관계랑은 아무런 상관이 없고
모든 Component는 자신을 포함하고 있는 GameObject를 gameObject 로 통해 접근 가능합니다.
UI_Popup에서 gameObject 사용 가능한건 UI_Popup이 MonoBehavior를 상속 받아서 그런겁니다.
(MonoBehavior도 결국 Component를 상속 받는 구조)
gameObject에 F12를 눌러보면 아마도 Component 쪽으로 이동할꺼에요.

-> UI_Popup이 MonoBehavior를 상속받아서 gameObject를 사용할 수 있는건 이해가 가지만

UI_Button에 붙은 컴포넌트는 UI_Popup.cs가 아닌 UI_Button.cs인데 어떠한 이유로 UI_Popup.cs내에서  UI_Button이라는 gameObject(base)를 갖을 수 있는지 궁금합니다. 

답변 해 주신 "모든 Component는 자신을 포함하고 있는 GameObject를 gameObject 로 통해 접근 가능합니다." 이 말씀은 이해가 되지만 코드 어느 부분에서도 UI_Popup 클래스를 컴포넌트로 붙여주지 않았기에 더욱 의문이 생깁니다. 혹시나 이런게 가능한 이유가 상속으로 인해 가능했던건지 궁금해서 첫 질문에 올렸던겁니다.

2. 2번질문은 1번 질문과 어느정도 연관성이 있는 질문 같은데 아마 1번이 해결되면 2번도 자동으로 해결 될 것 같은 느낌이 납니다.

UI_Popup.cs의 Init에서 Managers.UI.SetCanvas(gameObject, true); 해당 코드의 gameObject는 누군가요? UI_Popup 클래스는 어느 오브젝트의 컴포넌트로 들어가지도 않았는데 SetCanvas를 한다는게 이해가 안됩니다. 오히려 해당 코드를 UI_Button.cs에서 호출하는게 맞지 않을까요?  

0

rookiss님의 프로필 이미지
rookiss
Instructor

아 죄송합니다.
답변에 오타가 있었네요.

프리팹은 자기를 소유하고 있는 GameObject를 손쉽게 접근할 수 있고,
반대로 GameObject는 자신에 소유하고 있는 Component에 손쉽게 접근할 수 있는데
-> 이게 아니고

Component
은 자기를 소유하고 있는 GameObject를 손쉽게 접근할 수 있고,

반대로 GameObject는 자신이 소유하고 있는 Component에 손쉽게 접근할 수 있는데
->으로 정정합니다.

상속 관계랑은 아무런 상관이 없고
모든 Component는 자신을 포함하고 있는 GameObject를 gameObject 로 통해 접근 가능합니다.
UI_Popup에서 gameObject 사용 가능한건 UI_Popup이 MonoBehavior를 상속 받아서 그런겁니다.
(MonoBehavior도 결국 Component를 상속 받는 구조)
gameObject에 F12를 눌러보면 아마도 Component 쪽으로 이동할꺼에요.

0

답변 감사합니다.

몇 가지 질문들 더 드리면 

2.
프리팹은 자기를 소유하고 있는 GameObject를 손쉽게 접근할 수 있고,
반대로 GameObject는 자신에 소유하고 있는 Component에 손쉽게 접근할 수 있는데
전자의 경우 gameObject를 통해 소유자에 접근이 가능합니다.
UI_Button을 Instantiate해서 만든 GameObject에
해당 cs파일 Component를 붙였으니 저렇게 뜨고 있는 겁니다.

-> UI_Button에 붙인 Component는 UI_Popup.cs가 아닌 UI_Button.cs인데 아래와 같이 UI_Popup에서 gameObject를 사용 가능한건 UI_Popup과 UI_Button이 상속관계에 있어서 그런건가요?

0

rookiss님의 프로필 이미지
rookiss
Instructor

1.
프리팹은 cs 파일이 아니라서 아무런 상관이 없습니다.
동일한 class가 다수의 파일에 두 번 정의되어 있으면
컴파일 에러가 나서 애당초 통과 되지 않습니다.
따라서 구별에 대한 고민도 할 필요가 없습니다.

2.
프리팹은 자기를 소유하고 있는 GameObject를 손쉽게 접근할 수 있고,
반대로 GameObject는 자신에 소유하고 있는 Component에 손쉽게 접근할 수 있는데
전자의 경우 gameObject를 통해 소유자에 접근이 가능합니다.
UI_Button을 Instantiate해서 만든 GameObject에
해당 cs파일 Component를 붙였으니 저렇게 뜨고 있는 겁니다.

3.
세부적인 코드 하나 하나에 의미를 두지 마시기 바랍니다.
UI_Popup을 상속받는 다른 클래스에서
팝업이 닫힐 때의 행동을 재정의 하고 싶을 수도 있고 아닐 수도 있으니
그런 컨텐츠단 문제는 본인의 판단대로 작성하면 됩니다.

No author

This post's author information has been deleted.

Ask a question