ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2021/10/27 상점구현
    개발일지/팀GC Defence 2021. 10. 27. 19:51

    새로 개발하는 디펜스 게임의 상점을 구현

     

    조건

    • 스테이지 깰때마다 상점에 파는 아이템이 달라짐
    • 무기 종류 5개, 등급 5개
    • 등급에 따라 다른 확률 적용
    • 중복 상관없음
    • 상점 아이템 출력 개수 6개

     

     

    1. 무기 등급에 따른 확률 테이블 제작 및 파싱 클래스 제작

    json파일

    shop_weapon_grade_percentage.json

    [{"raw":100,"grade":0,"grade_name":"흔한","percentage":40},
        {"raw":101,"grade":1,"grade_name":"안흔함","percentage":30},
        {"raw":102,"grade":2,"grade_name":"희귀","percentage":20},
        {"raw":103,"grade":3,"grade_name":"고유","percentage":8},
        {"raw":104,"grade":4,"grade_name":"전설","percentage":2}]

    item_weapon.json

    [{"raw":1000,"item_name":"지팡이1","item_description":"흔한 지팡이","kind_of_money":0,"price":100,"item_type":0,"attack_power":10,"critical_attack_power":10,"critical_chance":10,"speed_of_attack":10,"item_grade":0,"weapon_type":0},
      {"raw":1001,"item_name":"지팡이2","item_description":"안흔한 지팡이","kind_of_money":0,"price":200,"item_type":0,"attack_power":11,"critical_attack_power":11,"critical_chance":11,"speed_of_attack":11,"item_grade":1,"weapon_type":0},
      {"raw":1002,"item_name":"지팡이3","item_description":"희귀 지팡이","kind_of_money":0,"price":300,"item_type":0,"attack_power":12,"critical_attack_power":12,"critical_chance":12,"speed_of_attack":12,"item_grade":2,"weapon_type":0},
      {"raw":1003,"item_name":"지팡이4","item_description":"고유 지팡이","kind_of_money":0,"price":400,"item_type":0,"attack_power":13,"critical_attack_power":13,"critical_chance":13,"speed_of_attack":13,"item_grade":3,"weapon_type":0},
      {"raw":1004,"item_name":"지팡이5","item_description":"전설 지팡이","kind_of_money":0,"price":500,"item_type":0,"attack_power":14,"critical_attack_power":14,"critical_chance":14,"speed_of_attack":14,"item_grade":4,"weapon_type":0},
      {"raw":1005,"item_name":"활1","item_description":"흔한 활","kind_of_money":0,"price":100,"item_type":0,"attack_power":10,"critical_attack_power":10,"critical_chance":10,"speed_of_attack":10,"item_grade":0,"weapon_type":1},
      {"raw":1006,"item_name":"활2","item_description":"안흔한 활","kind_of_money":0,"price":200,"item_type":0,"attack_power":11,"critical_attack_power":11,"critical_chance":11,"speed_of_attack":11,"item_grade":1,"weapon_type":1},
      {"raw":1007,"item_name":"활3","item_description":"희귀 활","kind_of_money":0,"price":300,"item_type":0,"attack_power":12,"critical_attack_power":12,"critical_chance":12,"speed_of_attack":12,"item_grade":2,"weapon_type":1},
      {"raw":1008,"item_name":"활4","item_description":"고유 활","kind_of_money":0,"price":400,"item_type":0,"attack_power":13,"critical_attack_power":13,"critical_chance":13,"speed_of_attack":13,"item_grade":3,"weapon_type":1},
      {"raw":1009,"item_name":"활5","item_description":"전설 활","kind_of_money":0,"price":500,"item_type":0,"attack_power":14,"critical_attack_power":14,"critical_chance":14,"speed_of_attack":14,"item_grade":4,"weapon_type":1},
      {"raw":1010,"item_name":"창1","item_description":"흔한 창","kind_of_money":0,"price":100,"item_type":0,"attack_power":10,"critical_attack_power":10,"critical_chance":10,"speed_of_attack":10,"item_grade":0,"weapon_type":2},
      {"raw":1011,"item_name":"창2","item_description":"안흔한 창","kind_of_money":0,"price":200,"item_type":0,"attack_power":11,"critical_attack_power":11,"critical_chance":11,"speed_of_attack":11,"item_grade":1,"weapon_type":2},
      {"raw":1012,"item_name":"창3","item_description":"희귀 창","kind_of_money":0,"price":300,"item_type":0,"attack_power":12,"critical_attack_power":12,"critical_chance":12,"speed_of_attack":12,"item_grade":2,"weapon_type":2},
      {"raw":1013,"item_name":"창4","item_description":"고유 창","kind_of_money":0,"price":400,"item_type":0,"attack_power":13,"critical_attack_power":13,"critical_chance":13,"speed_of_attack":13,"item_grade":3,"weapon_type":2},
      {"raw":1014,"item_name":"창5","item_description":"전설 창","kind_of_money":0,"price":500,"item_type":0,"attack_power":14,"critical_attack_power":14,"critical_chance":14,"speed_of_attack":14,"item_grade":4,"weapon_type":2},
      {"raw":1015,"item_name":"성수1","item_description":"흔한 성수","kind_of_money":0,"price":100,"item_type":0,"attack_power":10,"critical_attack_power":10,"critical_chance":10,"speed_of_attack":10,"item_grade":0,"weapon_type":3},
      {"raw":1016,"item_name":"성수2","item_description":"안흔한 성수","kind_of_money":0,"price":200,"item_type":0,"attack_power":11,"critical_attack_power":11,"critical_chance":11,"speed_of_attack":11,"item_grade":1,"weapon_type":3},
      {"raw":1017,"item_name":"성수3","item_description":"희귀 성수","kind_of_money":0,"price":300,"item_type":0,"attack_power":12,"critical_attack_power":12,"critical_chance":12,"speed_of_attack":12,"item_grade":2,"weapon_type":3},
      {"raw":1018,"item_name":"성수4","item_description":"고유 성수","kind_of_money":0,"price":400,"item_type":0,"attack_power":13,"critical_attack_power":13,"critical_chance":13,"speed_of_attack":13,"item_grade":3,"weapon_type":3},
      {"raw":1019,"item_name":"성수5","item_description":"전설 성수","kind_of_money":0,"price":500,"item_type":0,"attack_power":14,"critical_attack_power":14,"critical_chance":14,"speed_of_attack":14,"item_grade":4,"weapon_type":3},
      {"raw":1020,"item_name":"검1","item_description":"흔한 검","kind_of_money":0,"price":100,"item_type":0,"attack_power":10,"critical_attack_power":10,"critical_chance":10,"speed_of_attack":10,"item_grade":0,"weapon_type":4},
      {"raw":1021,"item_name":"검2","item_description":"안흔한 검","kind_of_money":0,"price":200,"item_type":0,"attack_power":11,"critical_attack_power":11,"critical_chance":11,"speed_of_attack":11,"item_grade":1,"weapon_type":4},
      {"raw":1022,"item_name":"검3","item_description":"희귀 검","kind_of_money":0,"price":300,"item_type":0,"attack_power":12,"critical_attack_power":12,"critical_chance":12,"speed_of_attack":12,"item_grade":2,"weapon_type":4},
      {"raw":1023,"item_name":"검4","item_description":"고유 검","kind_of_money":0,"price":400,"item_type":0,"attack_power":13,"critical_attack_power":13,"critical_chance":13,"speed_of_attack":13,"item_grade":3,"weapon_type":4},
      {"raw":1024,"item_name":"검5","item_description":"전설 검","kind_of_money":0,"price":500,"item_type":0,"attack_power":14,"critical_attack_power":14,"critical_chance":14,"speed_of_attack":14,"item_grade":4,"weapon_type":4}]

     

    파싱클래스

    RawData.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class RawData
    {
        public string raw;
    }

     

    JsonItem.cs

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class JsonItem : RawData
    {
        public string item_name;
        public string item_description;
        public int kind_of_money;
        public int price;
        public int item_type;
    }
    
    public class JsonWeapon : JsonItem
    {
        public float attack_power;
        public float critical_attack_power;
        public float critical_chance;
        public float speed_of_attack;
        public int item_grade;
        public int weapon_type;
    }
    
    
    public class JsonShopWeaponGradePercentage : RawData
    {
        public int grade;
        public string grade_name;
        public float percentage;
    }

     

    2. json파일을 읽고 메모리상에 가지고 있을 데이터 매니저 제작

    DataManager.cs

    using Newtonsoft.Json;
    using System.Collections.Generic;
    using System.Linq;
    using UnityEngine;
    
    public class DataManager
    {
        public static readonly DataManager Instance = new DataManager();
        private List<RawData> list = new List<RawData>();
    
        public void LoadData<T>(string path) where T : RawData
        {
            var json = this.ReadFile(path).text;
            var arr = JsonConvert.DeserializeObject<T[]>(json);
            if (arr != null)
            {
                this.list.AddRange(arr);
            }
        }
        private TextAsset ReadFile(string path)
        {
            var json = Resources.Load<TextAsset>(path);
            return json;
        }
    
    
        public IEnumerable<T> GetDatas<T>()
        {
            return this.list.OfType<T>();
        }
    
        public T GetData<T>(string id) where T : RawData
        {
            var data = this.list.FindAll(x => x != null && x.GetType().Equals(typeof(T)));
    
            foreach (RawData rawData in data)
            {
                if (rawData.raw == id)
                {
                    return (T)rawData;
                }
            }
            return null;
        }
    }

     

    3. 게임 시작 시 DataManager의 list에 json데이터를 추가

    App.cs

        public void LoadJsonData()
        {
            DataManager.Instance.LoadData<JsonWeapon>("JsonData/item_weapon");        
            DataManager.Instance.LoadData<JsonShopWeaponGradePercentage>("JsonData/shop_weapon_grade_percentage");
        }

     

    4. 로비에서 상점목록 로드

    Lobby.cs

    public void ShopLoading()
        {
            var prefab = Resources.Load<GameObject>("Prefabs/shopItem");
    
            var percentages = DataManager.Instance.GetDatas<JsonShopWeaponGradePercentage>();
            List<float> listPercentages = new List<float>();
            foreach(var per in percentages)
            {
                listPercentages.Add(per.percentage);
            }
    
            //6개 아이템만 표시
            for (int i = 0; i < 6; i++)
            {
                var go = Instantiate(prefab);
                var shopItem = go.GetComponent<ShopItem>();
                //데이터 매니저에서JsonWeapon타입만 취득
                var listWeaponItems = DataManager.Instance.GetDatas<JsonWeapon>();
                //shop_weapon_grade_percentage.json파일의 확률을 적용
                var grade = Choose(listPercentages.ToArray());
                //무기 종류가 5개이므로 동일한 확률로 랜덤 적용
                var weaponType = Random.Range(0, 5);
    
    
                foreach(var item in listWeaponItems)
                {
                    if(item.item_grade == grade && item.weapon_type == weaponType)
                    {
                        shopItem.Init(item);
                        shopItem.transform.SetParent(shopWeapon.transform);
                        break;
                    }
                }
                
            }
    
           
        }
    
        public float Choose(float[] probs)
        {
    
            float total = 0;
    
            foreach (float elem in probs)
            {
                total += elem;
            }
    
            float randomPoint = Random.value * total;
    
            for (int i = 0; i < probs.Length; i++)
            {
                if (randomPoint < probs[i])
                {
                    return i;
                }
                else
                {
                    randomPoint -= probs[i];
                }
            }
            return probs.Length - 1;
        }

     

     

     

    확률이 다른 항목 선택 참고

    https://docs.unity3d.com/kr/2019.4/Manual/RandomNumbers.html

     

    랜덤 게임플레이 요소 추가 - Unity 매뉴얼

    여러 게임에서 임의로 선택되는 항목 및 값은 중요합니다. 이 섹션에서는 Unity에 내장된 랜덤 함수를 사용하여 일반적인 게임 역학을 구현하는 방법에 대해 알아봅니다.

    docs.unity3d.com

     

    '개발일지 > 팀GC Defence' 카테고리의 다른 글

    2021/10/29 상점구현2  (0) 2021.10.29
Designed by Tistory.