아래 사진처럼 직접 드래그 앤 드롭으로 오브젝트를 연결하는 것이 아닌
코드로 오브젝트를 연결하려 한다.
리플렉션을 이용하여 enum을 넘겨준다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UI_Button : MonoBehaviour
{
[SerializeField]
Text _text;
enum Buttons
{
PointButton
}
enum Texts
{
PointText,
ScoreText
}
private void Start()
{
Bind(typeof(Buttons));
Bind(typeof(Texts));
}
void Bind(Type type)
{
}
}
UI_Button 오브젝트에 위 스크립트가 붙어 있기때문에
해당 오브젝트를 기준으로 자식 오브젝트를 찾아가는 방법을 사용할 것이다.
이때 오브젝트를 찾는 함수는 따로 빼두어 Util.cs라는 이름의 스크립트로 정리한다.
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
public class Util
{
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;
}
}
이제 다시 UI_Button 스크립트로 돌아가 아래와 같이 작성하여 마무리한다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UI_Button : MonoBehaviour
{
Dictionary<Type, UnityEngine.Object[]> _objects = new Dictionary<Type, UnityEngine.Object[]>();
enum Buttons
{
PointButton
}
enum Texts
{
PointText,
ScoreText
}
private void Start()
{
Bind<Button>(typeof(Buttons));
Bind<Text>(typeof(Texts));
}
void Bind<T>(Type type) where T : UnityEngine.Object
{
string[] names = Enum.GetNames(type);
UnityEngine.Object[] objects = new UnityEngine.Object[names.Length];
_objects.Add(typeof(T), objects);
for (int i = 0; i < names.Length; i++)
{
objects[i] = Util.FindChild<T>(gameObject, names[i], true);
}
}
}
값 설정은 아래와 같이 진행한다.
private void Start()
{
Bind<Button>(typeof(Buttons));
Bind<Text>(typeof(Texts));
Get<Text>((int)Texts.ScoreText).text = "Bind Test";
}
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;
}
컴포넌트 형식이 아닌 오브젝트는 어떻게 매핑할까?
UI 버튼 프리펍 아래에 빈 오브젝트인 TestObject를 추가한다.
GameObject 형식 전용의 FindChild를 만들어준다.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UI_Button : MonoBehaviour
{
Dictionary<Type, UnityEngine.Object[]> _objects = new Dictionary<Type, UnityEngine.Object[]>();
enum Buttons
{
PointButton
}
enum Texts
{
PointText,
ScoreText
}
enum GameObject
{
TestObject,
}
private void Start()
{
Bind<Button>(typeof(Buttons));
Bind<Text>(typeof(Texts));
Get<Text>((int)Texts.ScoreText).text = "Bind Test";
}
void Bind<T>(Type type) where T : UnityEngine.Object
{
string[] names = Enum.GetNames(type);
UnityEngine.Object[] objects = new UnityEngine.Object[names.Length];
_objects.Add(typeof(T), objects);
for (int i = 0; i < names.Length; i++)
{
if(typeof(T) == typeof(GameObject))
objects[i] = Util.FindChild(gameObject, names[i], true);
else
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;
}
Util.cs 도 추가해준다.
public static GameObject FindChild(GameObject go, string name = null, bool recursive = false)
{
Transform transform = FindChild<Transform>(go, name, recursive);
if (transform == null)
return null;
return transform.gameObject;
}
소중한 정보 감사드립니다!