게임클라이언트 프로그래밍/Guns N Rachel's

UIShop 디자인 패턴 적용. Factory Pattern(팩토리패턴)

Game Client Lee Hwanguk 2023. 4. 21. 03:37

* 어제 만든 UIShop 에 수정해야하는 부분이 생겼다. 기존 방식은 모든 Cell을 생성해놓고 활성/ 비활성으로 동작하는 방식이었는데 기획해 놓은 시스템을 적용하려니 문제 투성이었다. 

셀을 생성할때 셀의 요소들을 유연하게 제어하기 위하여 팩토리 패턴을 사용하여 생성하는 방식으로 변경해보았다

팩토리 패턴 중 추상 팩토리 패턴을 사용하였다.

*추상 팩토리 패턴에 대한 예시 이미지. 마우스(LG,Samsung)=>creatMouse/ 키보드(LG, Samsung)=>키보드 형식으로 작은 부품부터 조립해서 상단으로 올라오는 구조이다.

 구조를 먼저 짜보았다. AbsEquipmentFactory 클래스를 abstract 추상클래스로 만든 후 메서드들을정의한다

(image의 color변경 메서드, stat 변경 메서드) 

AbsEquipmentFactory 를 상속받은 ShopSwordFactory 메서드를 만들었다(Sword,Axe,Arrow,Wand 가 있다. 모두 같은 방식으로 만들었다.) 상속받은 AbsEquipmentFactory 의 메서드를 구체화하였다.

ShopFactory 를 만들었다 ShopSwordFactory에서 조립된 부품들을 직접적으로 생산하는 클래스이다(Instantiate)

using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
using UnityEngine.UI;

public abstract class AbsEquipmentFactory
{
    public abstract Color32 MakeGradeBGColor(string grade);
    public abstract Sprite MakeEquipmentImage(string grade);      
    public abstract int MakeEquipmentStat(string grade);      
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShopSwordFactory : AbsShopFactory
{
    public override Color MakeFrameColor(string grade)
    {
        Color gradeColor = new Color();
        switch (grade)
        {
            case "Wood":
                gradeColor = new Color32(176, 82, 0, 255);
                break;
            case "Iron":
                gradeColor = new Color32(192, 178, 166, 255);
                break;
            case "Gold":
                gradeColor = new Color32(255, 255, 0, 255);
                break;
            case "Diamond":
                gradeColor = new Color32(0, 255, 188, 255);
                break;
        }
        return gradeColor;
    }

    public override Sprite MakeShopIconImage(string grade)
    {
        var atlas = AtlasManager.instance.GetAtlasByName("UIShopIcon");
        Sprite SwordImage = null;
        switch (grade)
        {
            case "Wood":
                SwordImage = atlas.GetSprite("Wood_Sword");
                break;
            case "Iron":
                SwordImage = atlas.GetSprite("Iron_Sword");
                break;
            case "Gold":
                SwordImage = atlas.GetSprite("Gold_Sword");
                break;
            case "Diamond":
                SwordImage = atlas.GetSprite("Diamond_Sword");
                break;

        }
        return SwordImage;
    }
    public override string MakeShopName(string grade)
    {
        string name = null;
        switch (grade)
        {
            case "Wood":
                name = "나무검";
                break;
            case "Iron":
                name = "강철검";
                break;
            case "Gold":
                name = "황금검";
                break;
            case "Diamond":
                name = "다이아몬드검";
                break;
        }
        return name;
    }
    public override int MakeShopPowerStat(string grade)
    {
        int powerStat = 0;
        switch (grade)
        {
            case "Wood":
                powerStat = 10;
                break;
            case "Iron":
                powerStat = 20;
                break;
            case "Gold":
                powerStat = 30;
                break;
            case "Diamond":
                powerStat = 40;
                break;
        }
        return powerStat;
    }
    public override int MakeShopCriticalHitAmount(string grade)
    {
        int criticalHitAmount = 0;
        switch (grade)
        {
            case "Wood":
                criticalHitAmount = 0;
                break;
            case "Iron":
                criticalHitAmount = 0;
                break;
            case "Gold":
                criticalHitAmount = 0;
                break;
            case "Diamond":
                criticalHitAmount = 0;
                break;
        }
        return criticalHitAmount;
    }
    public override int MakeShopCriticalHitChance(string grade)
    {
        int criticalHitChance = 0;
        switch (grade)
        {
            case "Wood":
                criticalHitChance = 0;
                break;
            case "Iron":
                criticalHitChance = 0;
                break;
            case "Gold":
                criticalHitChance = 0;
                break;
            case "Diamond":
                criticalHitChance = 0;
                break;
        }
        return criticalHitChance;
    }
    public override int MakeShopFireRateStat(string grade)
    {
        int fireRateStat = 0;
        switch (grade)
        {
            case "Wood":
                fireRateStat = 0;
                break;
            case "Iron":
                fireRateStat = 0;
                break;
            case "Gold":
                fireRateStat = 0;
                break;
            case "Diamond":
                fireRateStat = 0;
                break;
        }
        return fireRateStat;
    }
    public override int MakeShopRecoveryAmount(string grade)
    {
        int recoveryAmount = 0;
        switch (grade)
        {
            case "Wood":
                recoveryAmount = 0;
                break;
            case "Iron":
                recoveryAmount = 0;
                break;
            case "Gold":
                recoveryAmount = 0;
                break;
            case "Diamond":
                recoveryAmount = 0;
                break;
        }
        return recoveryAmount;
    }
}
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ShopFactory : MonoBehaviour
{
    [SerializeField]
    private GameObject swordPrefab;
    [SerializeField]
    private GameObject axePrefab;
    [SerializeField]
    private GameObject wandPrefab;
    [SerializeField]
    private GameObject arrowPrefab;
    [SerializeField]
    private GameObject foodPrefab;

    public GameObject CreatShopCell(string cellName)
    {
        var grade=this.ExtractGrade(cellName);
        GameObject shopCell=null;
        //if (cellName.Contains("Sword")) this.CreatShopSword(grade);
        //else if (cellName.Contains("Axe")) this.CreatShopAxe(grade);
        //else if(cellName.Contains("Arrow")) this.CreatShopArrow(grade);
        //else if (cellName.Contains("Wand")) this.CreatShopWand(grade);
        //else if (cellName.Contains("Food")) this.CreatShopFood(grade);

        return shopCell;
    }
    private string ExtractGrade(string EquipmentName)
    {
        var index = EquipmentName.IndexOf('_');
        var grade = EquipmentName.Substring(0, index);
        return grade;
    }
    public void CreatShopSword(string grade,Transform content)
    {
        AbsShopFactory swordFactory = new ShopSwordFactory();
        var swordGo=Instantiate(this.swordPrefab, content).GetComponent<EquipmentCell>();
        swordGo.name= swordFactory.MakeShopName(grade);
        swordGo.powerStat= swordFactory.MakeShopPowerStat(grade);
        swordGo.criticalHitAmount= swordFactory.MakeShopCriticalHitAmount(grade);
        swordGo.criticalHitChance= swordFactory.MakeShopCriticalHitChance(grade); 
        swordGo.fireRateStat= swordFactory.MakeShopFireRateStat(grade);
        swordGo.recoveryAmount= swordFactory.MakeShopRecoveryAmount(grade);

        swordGo.transform.GetChild(1).GetComponent<Image>().sprite= swordFactory.MakeShopIconImage(grade);
        swordGo.transform.GetChild(0).GetComponent<Image>().color= swordFactory.MakeFrameColor(grade);
    }
    //private void CreatShopAxe(string grade)
    //{
    //    AbsShopFactory axeFactory= new ShopAxeFactory();
    //    var axeGo=Instantiate(this.axePrefab);
    //    axeFactory.MakeFrameColor(grade);
    //    axeFactory.MakeShopIconImage(grade);
    //    axeFactory.MakeShopName(grade);
    //    axeFactory.MakeShopPowerStat(grade);
    //    axeFactory.MakeShopCriticalHitAmount(grade);
    //    axeFactory.MakeShopCriticalHitChance(grade);
    //    axeFactory.MakeShopFireRateStat(grade);
    //    axeFactory.MakeShopRecoveryAmount(grade);
    //}
    //private void CreatShopArrow(string grade)
    //{
    //    AbsShopFactory arrowFactory= new ShopArrowFactory();
    //    var arrowGo=Instantiate(this.arrowPrefab);
    //    arrowFactory.MakeFrameColor(grade);
    //    arrowFactory.MakeShopIconImage(grade);
    //    arrowFactory.MakeShopName(grade);
    //    arrowFactory.MakeShopPowerStat(grade);
    //    arrowFactory.MakeShopCriticalHitAmount(grade);
    //    arrowFactory.MakeShopCriticalHitChance(grade);
    //    arrowFactory.MakeShopFireRateStat(grade);
    //    arrowFactory.MakeShopRecoveryAmount(grade);
    //}
    //private void CreatShopWand(string grade)
    //{
    //    AbsShopFactory wandFactory = new ShopWandFactory();
    //    var WandGo=Instantiate(this.wandPrefab);
    //    wandFactory.MakeFrameColor(grade);
    //    wandFactory.MakeShopIconImage(grade);
    //    wandFactory.MakeShopName(grade);
    //    wandFactory.MakeShopPowerStat(grade);
    //    wandFactory.MakeShopCriticalHitAmount(grade);
    //    wandFactory.MakeShopCriticalHitChance(grade);
    //    wandFactory.MakeShopFireRateStat(grade);
    //    wandFactory.MakeShopRecoveryAmount(grade);
    //}
    //private void CreatShopFood(string grade) 
    //{
    //    AbsShopFactory foodFactory = new ShopFoodFactory();
    //    Instantiate(this.foodPrefab);
    //    foodFactory.MakeFrameColor(grade);
    //    foodFactory.MakeShopIconImage(grade);
    //    foodFactory.MakeShopName(grade);
    //    foodFactory.MakeShopPowerStat(grade);
    //    foodFactory.MakeShopCriticalHitAmount(grade);
    //    foodFactory.MakeShopCriticalHitChance(grade);
    //    foodFactory.MakeShopFireRateStat(grade);
    //    foodFactory.MakeShopRecoveryAmount(grade);
    //}
}

아직 만들어놓은 시스템으로 옴기기에는 공부가 조금 더 필요할 것 같아서 테스트 용으로 셀 하나만 생성해보았다

public void CreatNormaCell()
    {
        //Test
        //Shuffle(this.ranGrad);
        //List<string> list = new List<string>(); 
        //list.Capacity = (int)eShopType.Dungeon;

        
        //this.ranGrad.Clear();
        this.shopFactory.CreatShopSword("Gold", this.content);
        //this.shopFactory.CreatShopSword("Wood", this.content);
        //this.shopFactory.CreatShopSword("Diamond", this.content);
        //this.shopFactory.CreatShopSword("Wood", this.content);
    }

매개변수인 "Gold"를 grade로 받아 생성되었다. 이제 기획해놓은 시스템으로 옴겨야겠다.