개발일지/팀GC Defence
2021/10/27 상점구현
박준희
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