
여기에 초록NPC와 파란NPC가 있다.
초록NPC는 상호작용시 강화UI를 열어준다.
파란NPC는 상호작용시 옵션추출UI를 열어준다.
UI 여는 함수 :
Managers.UI.Show<UIReputation>();
위처럼 제네릭 형식으로 되어있어서 UI 타입을 제네릭에 넣어주어 UI를 연다.
방법1. 스크립트를 따로따로 만들어서 각각 Interact함수에 UI를 열게끔 한다.
public void Interact()
{
Managers.UI.Show<UIEnhancement>();
}
그러면 모든 NPC마다 새롭게 스크립트를 작성해줘야하나?
사실 npc마다 다르게 행동하거나 보여주는게 워낙 다양하니까 그렇게 해도 상관없지만 이번에 나는 단 하나의 스크립트에서 처리하게 하고싶었다.
방법2. 클래스 이름을 인스펙터창에서 미리 설정해서 할 수 있다면?
위와 같은 궁금증으로 찾아본 결과 리플렉션이라는 것을 사용하라고 했다.
using System;
using UnityEngine;
using System.Reflection;
public class NPC : MonoBehaviour, IInteractable
{
public NPCData data;
[Tooltip ("열고자하는 UI클래스와 정확히 일치하는 이름")]
public string uiClassName;
#region 리플렉션
private Assembly assembly;
private Type ui;
private MethodInfo showMethod;
private MethodInfo genericShowMethod;
#endregion
/// <summary>
/// 리플렉션을 이용해 uiClassName과 일치하는 Show<T>함수 호출
/// </summary>
public void Interact()
{
assembly = Assembly.GetExecutingAssembly();
ui = assembly.GetType(uiClassName);
showMethod = typeof(UIManager).GetMethod("Show");
genericShowMethod = showMethod.MakeGenericMethod(ui);
genericShowMethod.Invoke(Managers.UI, new object[] {new object[0] });
}
}
먼저 Assembly.GetExecutingAssembly를 통해 현재 실행중인 어셈블리를 캐싱한다.
assembly.GetType()함수를 사용해 내가 지정해둔 클래스 이름(string)과 일치하는 클래스의 타입을 가져온다.
Show라는 함수 그 자체를 가져온다. 이제 이 함수에 제네릭에 ui를 넣고
그 함수를 Invoke, 즉 실행한다.
리플렉션은 흑마법이다. 진짜 어디에서든 필드나 함수에 손쉽게 접근할 수 있으니 말이다.
그리고 당연히 이제 공부하고있는 입장에서 이런거에 의존하지말고 최대한 방법을 생각해보는게 좋긴 하지만
이정도는 사용해도 되겠지?
'Unity' 카테고리의 다른 글
| 가비지 콜렉터 (0) | 2024.12.11 |
|---|---|
| 유니티 정리 (0) | 2024.12.05 |
| UI를 잡아서 마음대로 움직여보자. (0) | 2024.12.03 |
| 인벤토리 MVP로 도전만 해보기 (2) | 2024.12.02 |
| UIManager를 만들어 UI를 관리해보자 (1) | 2024.11.26 |