[유니티] 문자열을 이용하여 클래스 인스턴스 생성하기 :상속 관계에서의 동적 클래스 생성

2024. 3. 24. 10:47유니티 unity

A라는 클래스를 상속한 나머지 클래스를 문자열로 생성할 때 여러 가지 방법이 있는데 스위치로 생성하거나 딕셔너리를 이용해서 생성하는 방법이 있습니다. 예시를 보자면

 

public class BaseEffect
{
    public virtual void Action()
    {
    }
}
public class Attack : BaseEffect
{
    public override void Action()
    {
        Debug.Log("Attack Action");
    }
}
public class Defense : BaseEffect
{
    public override void Action()
    {
        Debug.Log("Defense Action");
    }
}

 

BaseEffect 를 상속한 Attack 과 Defense를 불러올 때 방법은 스위치문을 이용한 방법과 딕셔너리를 이용한 방법이 있습니다

 

스위치를 이용한 방법은

 

    private void Start()
    {
        var attack = CreateEffect("Attack");
        attack.Action();

        var defense = CreateEffect("Defense");
        defense.Action();

        var poison = CreateEffect("poison");
        poison.Action();
    }

    public BaseEffect CreateEffect(string type) => type switch
    {
        "Attack" => new Attack(),
        "Defense" => new Defense(),
        _ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown class name: <b><color=red>{type}</color></b>"),
    };

 

 

스위치 패턴일치 식을 이용해서 해당 클래스를 생성시키는 방법입니다.

 

 

 

 

딕셔너리를 이용한 방법은

 

public static class ClassFactory
{
    private static Dictionary<string, Func<BaseEffect>> classConstructors = new Dictionary<string, Func<BaseEffect>>
    {
        { "Attack", () => new Attack() },
        { "Defense", () => new Defense() },
    };
    public static BaseEffect CreateInstance(string type)
    {
        if (classConstructors.ContainsKey(type))
            return classConstructors[type]();
        else
            throw new ArgumentOutOfRangeException(nameof(type), $"Unknown class name: <b><color=red>{type}</color></b>");

    }
}
public class TestWolstar : MonoBehaviour
{
    private void Start()
    {
        var attack = ClassFactory.CreateInstance("Attack");
        attack.Action();

        var defense = ClassFactory.CreateInstance("Defense");
        defense.Action();

        var poison = ClassFactory.CreateInstance("poison");
        poison.Action();
    }
}

 

 

 

이런식으로 동적 클래스 인스턴스 생성 할 수 있습니다.

 

저는 문자열로 하는방법보다는 enum으로 빼는 방법이 더 좋더라구요

 

 

 

전체코드

더보기
using System;
using System.Collections.Generic;
using UnityEngine;


public class BaseEffect
{
    public virtual void Action()
    {
    }
}
public class Attack : BaseEffect
{
    public override void Action()
    {
        Debug.Log("Attack Action");
    }
}
public class Defense : BaseEffect
{
    public override void Action()
    {
        Debug.Log("Defense Action");
    }
}

public static class ClassFactory
{
    private static Dictionary<EffectType, Func<BaseEffect>> classConstructors = new Dictionary<EffectType, Func<BaseEffect>>
    {
        { EffectType.Attack, () => new Attack() },
        { EffectType.Defense, () => new Defense() },
    };
    public static BaseEffect CreateInstance(EffectType type)
    {
        if (classConstructors.ContainsKey(type))
            return classConstructors[type]();
        else
            throw new ArgumentOutOfRangeException(nameof(type), $"Unknown class name: <b><color=red>{type}</color></b>");

    }
}

public enum EffectType
{
    Attack,
    Defense
}
public class TestWolstar : MonoBehaviour
{
    private void Start()
    {
        var attack = ClassFactory.CreateInstance(EffectType.Attack);
        attack.Action();

        var defense = ClassFactory.CreateInstance(EffectType.Defense);
        defense.Action();
    }

    public BaseEffect CreateEffect(EffectType type) => type switch
    {
        EffectType.Attack => new Attack(),
        EffectType.Defense => new Defense(),
        _ => throw new ArgumentOutOfRangeException(nameof(type), $"Unknown class name: <b><color=red>{type}</color></b>"),
    };
}