일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- Unreal Engine
- Replication
- 유스케이스
- 메카님
- 언리얼 엔진
- 언리얼엔진
- ability task
- 운영체제
- photon fusion2
- Rr
- unity
- MAC
- animation
- stride
- CTF
- 유니티
- 게임개발
- boss monster
- 게임 개발
- gas
- Security
- ret2libc
- Multiplay
- dirty cow
- Delegate
- Race condition
- gameplay ability system
- MLFQ
- DSP
- DP
Archives
- Today
- Total
다양한 기록
[Fortess Craft] 스프레드 시트와 연결 본문
이런식으로 필요한 데이터들이 스프레드 시트로 관리됨
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections.ObjectModel;
namespace Agit.FortressCraft {
public static class GoogleSheetManager
{
public static List<CommanderData> commanderDatas = new List<CommanderData>();
public static List<UnitData> unitDatas = new List<UnitData>();
//link change : edit ~ -> export?format=tsv
private static readonly List<string> _urls = new List<string>
{
"커맨더 시트 링크",
"유닛 시트 링크"
};
public static readonly ReadOnlyCollection<string> Urls = new ReadOnlyCollection<string>(_urls);
public static IEnumerator Loader()
{
List<string> data = new List<string>();
foreach (var url in Urls)
{
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
data.Add(www.downloadHandler.text);
}
if (data[0] != null)
ParseCommanderData(data[0]);
if (data[1] != null)
ParseUnitData(data[1]);
foreach(string d in data)
{
Debug.Log(d);
}
}
private static void ParseCommanderData(string data)
{
string[] lines = data.Split('\n');
for (int i = 1; i < lines.Length; i++)
{
string[] fields = lines[i].Split('\t');
if (fields.Length < 5)
{
Debug.LogError($"Line {i} has insufficient fields: {fields.Length} fields found.");
continue;
}
try
{
CommanderData commanderData = new CommanderData()
{
CommanderType = fields[0],
Level = ParseInt(fields[1]),
NeedExp = ParseInt(fields[2]),
HP = ParseFloat(fields[3]),
MP = ParseFloat(fields[4]),
Attack = ParseFloat(fields[5]),
AttackSpeed = ParseFloat(fields[6]),
AttackDelay = ParseFloat(fields[7]),
Defense = ParseFloat(fields[8]),
MoveSpeed = ParseFloat(fields[9]),
HealPerSecond = ParseFloat(fields[10]),
};
commanderDatas.Add(commanderData);
}
catch (FormatException e)
{
Debug.LogError($"FormatException on line {i}: {e.Message}");
}
catch (OverflowException e)
{
Debug.LogError($"OverflowException on line {i}: {e.Message}");
}
}
}
private static void ParseUnitData(string data)
{
string[] lines = data.Split('\n');
for (int i = 1; i < lines.Length; i++)
{
string[] fields = lines[i].Split('\t');
if (fields.Length < 11) // enough field?
{
Debug.LogError($"Line {i} has insufficient fields: {fields.Length} fields found.");
continue;
}
try
{
UnitData unitData = new UnitData()
{
Level = ParseInt(fields[0]),
UpgradeCost = ParseInt(fields[1]),
HP = ParseFloat(fields[2]),
MP = ParseFloat(fields[3]),
Attack = ParseFloat(fields[4]),
AttackDelay = ParseFloat(fields[5]),
Defense = ParseFloat(fields[6]),
MoveSpeed = ParseFloat(fields[7]),
SpawnDelay = ParseFloat(fields[8]),
CostReward = ParseInt(fields[9]),
ExpReward = ParseInt(fields[10]),
};
unitDatas.Add(unitData);
}
catch (FormatException e)
{
Debug.LogError($"FormatException on line {i}: {e.Message}");
}
catch (OverflowException e)
{
Debug.LogError($"OverflowException on line {i}: {e.Message}");
}
}
}
private static int ParseInt(string input)
{
if (int.TryParse(input, out int result))
{
return result;
}
throw new FormatException($"Unable to parse '{input}' as integer.");
}
private static float ParseFloat(string input)
{
if (float.TryParse(input, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float result))
{
return result;
}
throw new FormatException($"Unable to parse '{input}' as float.");
}
public static CommanderData GetCommanderData(int level, JobType jobType)
{
if (level > 15) level = 15;
int offset = 0;
switch (jobType)
{
case JobType.Warrior:
offset = -1;
break;
case JobType.Magician:
offset = 14;
break;
case JobType.Archer:
offset = 29;
break;
}
return GoogleSheetManager.commanderDatas[level + offset];
}
public static UnitData GetUnitData(int level)
{
return GoogleSheetManager.unitDatas[level - 1];
}
}
[System.Serializable]
public class CommanderData
{
public string CommanderType;
public int Level;
public int NeedExp;
public float HP;
public float MP;
public float Attack;
public float AttackSpeed;
public float AttackDelay;
public float Defense;
public float MoveSpeed;
public float HealPerSecond;
}
[System.Serializable]
public class UnitData
{
public int Level;
public int UpgradeCost;
public float HP;
public float MP;
public float Attack;
public float AttackDelay;
public float Defense;
public float MoveSpeed;
public float SpawnDelay;
public int CostReward;
public int ExpReward;
}
}
싱글톤으로 매니저 만들고, 데이터 로드하고 파싱
public static CommanderData GetCommanderData(int level, JobType jobType)
{
if (level > 15) level = 15;
int offset = 0;
switch (jobType)
{
case JobType.Warrior:
offset = -1;
break;
case JobType.Magician:
offset = 14;
break;
case JobType.Archer:
offset = 29;
break;
}
return GoogleSheetManager.commanderDatas[level + offset];
}
public static UnitData GetUnitData(int level)
{
return GoogleSheetManager.unitDatas[level - 1];
}
시트 오프셋에 따라 위 두 함수가 구현되고,
외부에서는 커맨더나 유닛의 레벨만 넣으면 데이터를 얻을 수 있음
public void SetMaxHPByLevel(int level, JobType jobType)
{
MAX_HEALTH = GoogleSheetManager.GetCommanderData(level, jobType).HP;
Debug.Log("Max HP: " + MAX_HEALTH);
}
public void SetAttack(int level, JobType jobType)
{
AttackDamage = GoogleSheetManager.GetCommanderData(level, jobType).Attack;
}
public void SetDefenseHPByLevel(int level, JobType jobType)
{
Defense = GoogleSheetManager.GetCommanderData(level, jobType).Defense;
}
public float GetNeedExpByLevel(int level, JobType jobType)
{
return GoogleSheetManager.GetCommanderData(level, jobType).NeedExp;
}
Player 코드의 일부
매니저에서 데이터 빼내서 Set하거나 Get하여 사용
'유니티 엔진 > Fortress Craft' 카테고리의 다른 글
[Fortress Craft] Commander_Archer - 기본 공격, 스킬1, 스킬2 (0) | 2025.02.05 |
---|---|
[Fortress Craft] Commander_Archer - 외형, 화살 나가는 방향 UI (0) | 2025.02.05 |
[Fortress Craft] 골드, 경험치 (0) | 2025.02.05 |
[Fortress Craft] Castle 생성 UI, 가격 설정 (0) | 2025.02.05 |
[Fortress Craft] ** Network Object Pooling (Photon Fusion2, Shared Mode) ** (0) | 2025.02.05 |