Unity Engine

[Unity] ScriptableObject + Reflection

Aostols 2023. 3. 28. 09:24
반응형

프로젝트를 진행하다보면 많은 양의 ScriptableObject를 사용할 경우가 있습니다.

종류가 많아지게 되면 로드단에서 관리가 필요하게 되는데 이떄 Attribute과 Reflection을 활용해서 로드단에서 ScriptableObject를 분류하여 정리하는 방식을 알아보겠습니다.

 

우선 ScriptableObject에 사용할 Attribute를 만들어 줍니다.

하나하나가 의미있는것이 아니고 그냥 넣은값이 잘 보이는지 확인하는 용도이기 떄문에 개별 변수는 의미가 없습니다.

using System;

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class SOAttribute : Attribute
{
    private eSOType soType;
    private string prefabName;

    public SOAttribute(eSOType soType, string prefabName)
    {
        this.soType = soType;
        this.prefabName = prefabName;
    }

    public eSOType SOType => soType;
    public string PrefabName => prefabName;
}

 

이제 이것을 활용하는 ScriptableObject를 만들어 줍니다.

using UnityEngine;

public class BaseScriptableObject : ScriptableObject
{
    public int type;
}

[CreateAssetMenu(fileName = "TestSOData1", menuName = "Scriptable Object/TestSOData1", order = int.MaxValue)]
[SO(soType:eSOType.Test1, prefabName:"aaaa")]
public class TestScriptableObject1 : BaseScriptableObject
{
    public float x;
    public float y;
}

[CreateAssetMenu(fileName = "TestSOData2", menuName = "Scriptable Object/TestSOData2", order = int.MaxValue)]
[SO(soType:eSOType.Test2, prefabName:"bbbb")]
public class TestScriptableObject2 : BaseScriptableObject
{
    public float width;
    public float height;
    
}

단순한 상속구조고 상속을 안해도 상관없습니다.

여기서 포인트는 Attribute를 넣는것 입니다.

Attribute를 잘 넣었고 이것으로 잘 분류가 되는지 확인할 수 있습니다.

 

 

이제 빈 객체 하나 만들어서 이것을 확인하는 스크립트를 추가 해 줍니다.

void Start()
{
    var result = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsDefined(typeof(SOAttribute)));

    foreach (var t in result)
    {
        List<SOAttribute> soAttributes = t.GetCustomAttributes<SOAttribute>().ToList();
        foreach (var soAttribute in soAttributes)
        {
            eSOType type = soAttribute.SOType;
            string prefabName = soAttribute.PrefabName;

            Debug.Log($"SOAttribute : {type} {prefabName}");
        }
    }

}

result는 어셈블리에서 SOAttribute로 정의된 모든것을 가져오게 됩니다.

디버깅을 해보게 되면 아까 우리가 만들어 두었던 2개의 클래스가 보입니다.

이제 리스트로 내용을 뽑아 Attribute출력합니다.

 

CustomAttribute를 받아서 확인해 보게 되면 Attribute속의 내용을 확인 할 수 있습니다.

이것 역시 스크립트에서 바로 활용 할 수 있습니다.

 

위 내용은 ScriptableObject종류가 아주 다양하고 카테고리 분류를 잘 해야 할 경우 유용한 방법이라고 생각됩니다.

활용법은 위와 같은 방식으로 Attribute기준으로 분류하여 Dictionary를 구성 후 해당 Dictionary에 ScriptableObject값을 넣는 방식으로 활용하고 있습니다.

여기서 ScriptableObject를 정의만 했지 만들지 않았는데 이는 어셈블리 차원에서 확인하는 것이라 분류만 해당 하는 내용입니다.

ScriptableObject의 생성및 로드는 다루지 않았습니다.

 

반응형

'Unity Engine' 카테고리의 다른 글

[Unity]ECS  (1) 2023.12.05
[Unity] Animation Controller  (0) 2023.04.23
[Unity]Job System + String  (0) 2023.03.03
Cinemachine - Impulse + SecondaryNoise  (0) 2023.02.09
Cinemachine - Impulse  (0) 2023.01.02