ํฌ์ŠคํŠธ

๐Ÿซ WitchMendokusai DevLog 01

๐ŸŽฒ _


์ปค๋ฐ‹
๋„ˆ๋ฌด ๋งŽ์€ ์ผ์ด ์ž‡์—‡์–ด

์ €๋ฒˆ ์ผ์ง€์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ,
์ด๋ฒˆ ์ผ์ง€์—์„œ๋„ ๋งˆ์„ ์˜๋ขฐ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๊ตฌํ˜„ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ๊ธฐ๋กํ•ด๋ณธ๋‹ค.

๐ŸŽฒ ๋ฐ์ดํ„ฐ ์ €์žฅ


์ €๋ฒˆ ์ผ์ง€์—์„œ ํ€˜์ŠคํŠธ์™€ ์ผ์ด ๊ธฐ๋Šฅ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ๋งŒ๋“ค์—ˆ๋‹ค.
์ด์ œ ํ€˜์ŠคํŠธ์™€ ์ผ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฑธ ๊ตฌํ˜„ํ•ด๋ณธ๋‹ค.

์ •๋ง ๋งŽ์€ ์ผ์ด ์žˆ์—ˆ๋‹ค.

๐Ÿ‘พ 1. ์ผ๋‹จ ์ €์žฅํ•ด๋ด !

1
2
3
4
5
6
7
8
9
10
11
12
[Serializable]
public struct QuestData
{
	public int QuestID;
	public QuestState State;

	public QuestData(int questID, QuestState state)
	{
		QuestID = questID;
		State = state;
	}
}
1
2
3
4
5
6
7
[Serializable]
public class GameData
{
	public Dictionary<int, List<Work>> works = new();
	public List<QuestData> questDatas = new();
	// ...
}

๋‹จ์ˆœํžˆ QuestData๋ฅผ ์ƒˆ๋กœ ์ •์˜ํ•˜๊ณ  GameData์— ์ถ”๊ฐ€ํ–ˆ๋‹ค.
๊ฐ„๋‹จํ•˜๊ฒŒ ํ€˜์ŠคํŠธ ์ •๋ณด์™€ ์ผ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค.

๐Ÿ‘พ 2. ์กฐ๊ฑด ์ •๋ณด ์ €์žฅ (Criteria, RuntimeCriteria)

ํ•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.

ํ€˜์ŠคํŠธ๋ฅผ ์™„๋ฃŒํ•˜๊ธฐ ์œ„ํ•œ ์„œ๋ธŒ ํ€˜์ŠคํŠธ๋ฅผ Criteria, ์กฐ๊ฑด์œผ๋กœ ์นญํ•˜๊ฒ ๋‹ค.
ํ€˜์ŠคํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ๋กœ ์กด์žฌํ•œ๋‹ค.

๋Ÿฐํƒ€์ž„์—์„œ ๊ณ„์† ์ง„ํ–‰์ƒํ™ฉ์„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด๋“ค๋„ ์žˆ์ง€๋งŒ,
๋”ฑ ํ•œ ๋ฒˆ๋งŒ ๋‹ฌ์„ฑํ•ด๋„ ๋˜๊ฑฐ๋‚˜, ๋žœ๋คํ•œ ์š”์†Œ๋ฅผ ๊ฐ€์ง€๋Š” ๋“ฑ์˜ ํŠน์ง•์„ ๊ฐ€์ง„ ์กฐ๊ฑด๋“ค๋„ ์žˆ๋‹ค.

์ด๋Ÿฐ ์กฐ๊ฑด๋“ค์€ ๊ฒŒ์ž„์ด ๊ป๋‹ค์ผฐ์„ ๋•Œ ์ •๋ณด๋ฅผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
๋•Œ๋ฌธ์— ์ด๋Ÿฐ ์กฐ๊ฑด๋“ค์˜ ์ •๋ณด๋‚˜ ์ง„ํ–‰ ์ƒํ™ฉ์„ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค.

์ฒ˜์Œ์—” QuestData์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ CriteriaData๋ฅผ ๋งŒ๋“ค์–ด CriteriaID, IsCompleted, Value ๋“ฑ์„ ์ €์žฅํ•ด๋ณด๋ ค ํ–ˆ๋‹ค.

Quest ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ์— ๊ธฐ์กด State์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ [NonSerialized]์ธ List<bool> IsCompleted์™€ List<SomeValue> CriteriaValue๋ฅผ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ,
CriteriaData๋ฅผ ์ฝ์–ด๋ณผ ๋•Œ ๊ฐ ์กฐ๊ฑด์˜ ID์— ๋งž์ถฐ ์™„๋ฃŒ ์—ฌ๋ถ€๋‚˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

..๋Œ€์ถฉ๋ด๋„ ์•„๋ฆ„๋‹ต์ง€๋Š” ์•Š์€ ๋ฐฉ์‹์ด๋‹ค. ์‹ค์ œ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฌธ์ œ๋“ค์ด ์žˆ๋‹ค.

  • ์ˆœ์„œ๊ฐ€ ์กด์žฌํ•˜๊ธด ํ•˜์ง€๋งŒ, ID๊ฐ€ ๋˜‘๊ฐ™์€ ์กฐ๊ฑด์ด ์žˆ๋‹ค๋ฉด ๋ชจํ˜ธํ•ด์ง„๋‹ค.
  • CriteriaValue๋ฅผ ์–ด๋–ค ํƒ€์ž…์œผ๋กœ ๋งŒ๋“ค์–ด ์ €์žฅํ• ์ง€๊ฐ€ ๊ณ ๋ฏผ์Šค๋Ÿฝ๋‹ค. ์กฐ๊ฑด๋งˆ๋‹ค ํ•„์š”ํ•œ ๋ถ€๊ฐ€ ์ •๋ณด๊ฐ€ ๋‹ค๋ฅผ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ์กฐ๊ฑด๊ณผ ๊ด€๋ จ๋œ ๋ณ€์ˆ˜๊ฐ€ Criterias, IsCompleted, Value๋‚˜ ์ƒ๊ธด๋‹ค. ํ•˜๋‚˜๋กœ ํ•ฉ์น˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.
  • ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ์— ๋„ˆ๋ฌด ๋งŽ์€ ์ •๋ณด๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค. ํŠนํžˆ [NonSerialized] ํ•œ ์ •๋ณด๋“ค์ด ๋งŽ์•„์ง„๋‹ค. ๋ถ„๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์ฒ˜๋Ÿผ ๊ตฌ์กฐ๋ฅผ ๋ฐ”๊พธ๊ณ  ๊ตฌํ˜„ํ–ˆ๋‹ค.

  • Criteria
    • ๊ธฐ์กด Criteria๋Š” CriteriaSO๋กœ ๋ณ€๊ฒฝ
    • ์ƒˆ๋กœ Criteria ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ, ๋™์ ์œผ๋กœ๋„ Criteria๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€๊ฒฝ
    • ์ƒˆ๋กœ RuntimeCriteria ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ, Criteria, IsCompleted ๋“ฑ์„ ์ €์žฅ
  • Quest ๋ถ„๋ฆฌ
    • ๊ธฐ์กด Quest๋Š” ์—๋””ํ„ฐ ํƒ€์ž„์—์„œ ์ •์ ์ธ ๋ฐ์ดํ„ฐ๋งŒ์„ ์ €์žฅํ•˜๋„๋ก QuestData๋กœ ๋ณ€๊ฒฝ
    • ๊ธฐ์กด QuestData๋Š” QuestDataSave๋กœ ๋ณ€๊ฒฝ
    • ์ƒˆ๋กœ Quest ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด์„œ, QuestData์™€ RuntimeCriteria๋ฅผ ์ €์žฅ
    • GameData์— List<Quest>๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ๋ฐ”๋กœ ์ง๋ ฌํ™”

์ด๋ ‡๊ฒŒ ์žˆ์„ ๋ฒ•ํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ–ˆ๋‹ค.
CriteriaValue์˜ ํƒ€์ž… ๊ฒฐ์ • ๋ฌธ์ œ๋Š”, JSON ๋ฐ์ดํ„ฐ ์ €์žฅ ์‹œ TypeNameHandling = TypeNameHandling.Auto ์˜ต์…˜์„ ์ผœ์„œ, Criteria ํƒ€์ž…์œผ๋กœ ์ €์žฅํ•˜๋”๋ผ๋„ ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ํ•„๋“œ ์—ญ์‹œ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด์ง„ ํด๋ž˜์Šค๋“ค์€ ์•„๋ž˜ ๊ฐ™์€ ๋ชจ์–‘์„ ๊ฐ€์ง€๊ฒŒ ๋๋‹ค.

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
29
30
31
32
33
public class RuntimeCriteria : ICriteria
{
	public Criteria Criteria { get; private set; }
	// ํ•œ ๋ฒˆ๋งŒ ๋‹ฌ์„ฑํ•˜๋ฉด ๋˜๋Š”์ง€
	public bool JustOnce { get; private set; }
	public bool IsCompleted { get; private set; }

	public bool Evaluate()
	{
		if (JustOnce && IsCompleted)
			return true;

		return IsCompleted = Criteria.Evaluate();
	}

	public float GetProgress()
	{
		return Criteria.GetProgress();
	}

	[JsonConstructor]
	public RuntimeCriteria(Criteria criteria, bool justOnce = false)
	{
		Criteria = criteria;
		JustOnce = justOnce;
	}

	public RuntimeCriteria(CriteriaInfo criteriaInfo)
	{
		Criteria = criteriaInfo.CriteriaSO.Data;
		JustOnce = criteriaInfo.JustOnce;
	}
}
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
29
30
31
32
33
34
public class Quest
{
	public Guid? Guid { get; private set; }
	public int DataID { get; private set; }
	public QuestState State { get; private set; }
	public List<RuntimeCriteria> Criterias { get; private set; }

	public QuestData GetData()
	{
		return DataManager.Instance.QuestDic[DataID];
	}

	[JsonConstructor]
	public Quest(Guid? guid, int dataID, QuestState state, List<RuntimeCriteria> criterias)
	{
		Guid = guid;
		DataID = dataID;
		State = state;
		Criterias = criterias;

		StartQuest();
	}

	public Quest(QuestData questData)
	{
		Guid = System.Guid.NewGuid();
		DataID = questData.ID;
		Criterias = Data.Criterias.ConvertAll(criteriaData => new RuntimeCriteria(criteriaData));

		StartQuest();
	}

	// ...
}


๐Ÿ‘พ 3. ํ†ต๊ณ„์™€ ์Šคํƒฏ ์ €์žฅ

์กฐ๊ฑด์˜ ์„ธ๋ถ€ ์ •๋ณด๋Š” Criteria๊ฐ€ ์ง์ ‘ ๋“ค๊ณ  ์žˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, โ€˜๋ชน์„ 10๋งˆ๋ฆฌ ์žก์œผ์‹œ์˜คโ€™ ๊ฐ™์€ ์กฐ๊ฑด์ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค๋ฉด,
MonsterKill ๊ฐ’์„ ์ง€์ผœ๋ณด๋ฉด์„œ, ๊ฐ’์ด 10 ์ด์ƒ์ผ ๋•Œ Criteria.Evaluate() ํ•จ์ˆ˜์—์„œ true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๊ธฐ์กด์—๋Š” MonsterKill ๊ฐ™์€ ํ†ต๊ณ„ ๊ฐ’์ด๋‚˜ ์Šคํƒฏ๋“ค์„ ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ๋กœ ๋งŒ๋“ค์–ด ๊ด€๋ฆฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—,
Criteria์—์„œ๋„ ์ด๋Ÿฐ ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ํ•„๋“œ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์œ„์—์„œ ๋ฐ์ดํ„ฐ ์ €์žฅ ๊ตฌ์กฐ๋ฅผ ๋ฐ”๊พธ๋ฉด์„œ ์ด๋Ÿฐ ๋ฐฉ์‹์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋‹ค.

Criteria๋„ ์ด์ œ RuntimeCriteria์˜ ํ•„๋“œ๋กœ์„œ ๋ฐ์ดํ„ฐ๋กœ ์ €์žฅ์ด ๋˜๋Š”๋ฐ, ์ด๋Ÿฌ๋ฉด Criteria๋ฅผ ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™” ํ•  ๋•Œ ๊ฐ’์€ ์ €์žฅ๋ผ๋„ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์‚ฌ๋ผ์ ธ์„œ ๋ฒˆ๊ฑฐ๋กญ๊ฒŒ ์ง์ ‘ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ์ž‘์—…์ด ํ•„์š”ํ•˜๊ฒŒ ๋œ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ†ต๊ณ„ ๊ฐ’์„ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์„ ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ์—์„œ Enum์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ ,
๋ณ„๋„๋กœ Statistics SO๋ฅผ ๋งŒ๋“ค์–ด์„œ Dictionaty<StatisticsType, int>๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

์ด๋Ÿฌ๋ฉด Enum ์ •์ˆ˜๊ฐ’์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋˜๊ณ , Evaluate() ๋“ฑ์—์„œ ํ†ต๊ณ„ ๊ฐ’์„ ์•Œ๊ณ ์ž ํ•  ๋•Œ๋Š” Statistics์—์„œ ๊ฐ€์ ธ์˜ค๋ฉด ๋œ๋‹ค.

์ „์ฒด์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ชจ์–‘์ด ๋œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class Criteria : ICriteria
{
	public abstract int GetCurValue();
	public abstract int GetTargetValue();
	public abstract bool Evaluate();

	// NewtonSoft๋กœ Json ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”๋ฅผ ์‹œํ‚ค๊ณ  ์žˆ๋Š”๋ฐ,
	// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ง๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ ๊ฐ™์•„์„œ ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜ ๋ชจ์–‘์œผ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.
	// ์ข€ ๋” ์•Œ์•„๋ด์•ผ ํ•  ๋“ฏ
	public virtual float GetProgress()
	{
		return (float)GetCurValue() / GetTargetValue();
	}
}
1
2
3
4
5
6
7
public abstract class NumCriteria : Criteria
{
	public ComparisonOperator ComparisonOperator { get; private set; }
	public int TargetValue { get; private set; }

	// ...
}
1
2
3
4
5
6
7
8
9
10
11
public class StatisticsCriteria : NumCriteria
{
	public StatisticsType Type { get; private set; }

	public override int GetCurValue()
	{
		return SOManager.Instance.Statistics[Type];
	}

	// ...
}
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
public class Statistics : ScriptableObject, ISerializationCallbackReceiver
{
	[SerializeField] private List<StatisticsInfo> initStatistics = new();

	[NonSerialized] private Dictionary<StatisticsType, int> statistics = new();

	public int this[StatisticsType type]
	{
		get
		{
			if (!statistics.ContainsKey(type))
				statistics[type] = 0;
				
			return statistics[type];
		}
		set
		{
			if (!statistics.ContainsKey(type))
				statistics[type] = 0;

			statistics[type] = value;
		}
	}

	// ...
}

์œ„ ์˜์ƒ์„ ์ฐธ๊ณ ํ–ˆ๋‹ค.

์˜์ƒ์—์„œ ์†Œ๊ฐœํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์Šคํƒฏ๋„ ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ์—์„œ Enum์œผ๋กœ ๋ฐ”๊พธ๊ณ ,
๋ณ„๋„๋กœ Dictionaty<StatType, int>๋ฅผ ๊ฐ€์ง€๋Š” Stat ํด๋ž˜์Šค๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

์ด๋Ÿฐ ๋ฐฉ์‹์ด ์“ธ ๋•Œ๋‚˜ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•  ๋•Œ๋‚˜ ํŽธํ•˜๊ธดํ•œ๋ฐ,
ํ•œ ๊ฐ€์ง€ ๋ฌธ์ œ์ ์ด๋ผ ํ•œ๋‹ค๋ฉด Enum ๊ฐ’์˜ ์ˆœ์„œ๋ฅผ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ํ•œ๋‹ค๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ๊ผฌ์ธ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ทธ๋ž˜์„œ ์ตœ๋Œ€ํ•œ ๋ณ€๊ฒฝ์„ ํ”ผํ•˜๋„๋ก ์•„๋ž˜์™€ ๊ฐ™์ด ์‘์ง‘์„ฑ์ด ์žˆ๋Š” ๊ฒƒ๋“ค์„ 100 ๋‹จ์œ„๋กœ ๋ถ„๋ฅ˜ํ–ˆ๋‹ค.

์–ด๋–ค ์Šคํƒฏ์„ ์–ด๋–ค ๋ถ„๋ฅ˜์— ๋ฐฐ์น˜ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋“ฑ์˜ ๊ฒฝ๊ณ„์˜ ๋ฌธ์ œ๋„ ์žˆ์„ ๊ฒƒ์ด๊ณ , ์–ธ์  ๊ฐ€ ๋ถˆ๊ฐ€ํ”ผํ•˜๊ฒŒ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋‚ ์ด ์žˆ์„ํ…Œ์ง€๋งŒ.. ์ผ๋‹จ ๊ณ„์† ๊ตฌํ˜„ํ•ด๋ณด๋„๋ก ํ•œ๋‹ค.

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
29
public enum StatType
{
	// ์ฒด๋ ฅ
	HP_CUR = 0,
	HP_MAX = 1,

	// ๊ฒฝํ—˜์น˜, ๋ ˆ๋ฒจ
	EXP_CUR = 100,
	EXP_MAX = 101,
	LEVEL_CUR = 102,

	// ๋งˆ๋‚˜
	MANA_CUR = 200,
	MANA_MAX = 201,

	// ์ด๋™
	MOVEMENT_SPEED = 300,
	MOVEMENT_SPEED_BONUS = 301,

	// ์Šคํ‚ฌ
	COOLTIME_BONUS = 400,

	// ๋ฐ๋ฏธ์ง€
	DAMAGE_BONUS = 500,

	// ํ‚ค์›Œ๋“œ
	PLAYER_EXP_COLLIDER_SCALE = 10000,
	SATELLITE_COUNT = 100001,
}


๐Ÿ‘พ 4. Reward

์กฐ๊ฑด๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ณด์ƒ๋„ ์ €์žฅํ•ด์•ผํ•œ๋‹ค. (๋ณด์ƒ๋„ ๋žœ๋ค์ผ ์ˆ˜ ์žˆ๊ณ , ํฌ๊ฒŒ๋Š” ํ€˜์ŠคํŠธ๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด)
์ด๋ฅผ ์œ„ํ•œ ๊ตฌ์กฐ์ฒด, ํด๋ž˜์Šค๋“ค์„ ์ •์˜ํ–ˆ๋‹ค.

1
2
3
4
5
6
public enum RewardType
{
	Item,
	Gold,
	Exp,
}
1
2
3
4
5
6
7
[Serializable]
public struct RewardInfo
{
	public RewardType Type;
	public Artifact Artifact;
	public int Amount;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Serializable]
public struct RewardData
{
	public RewardType Type;
	public int ArtifactID;
	public int Amount;

	public RewardData(RewardInfo rewardInfo)
	{
		Type = rewardInfo.Type;
		ArtifactID = rewardInfo.Artifact ? rewardInfo.Artifact.ID : Artifact.NONE_ID;
		Amount = rewardInfo.Amount;
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Reward
{
	public static void GetReward(RewardData reward)
	{
		switch (reward.Type)
		{
			case RewardType.Item:
				ItemData itemData = DataManager.Instance.ItemDic[reward.ArtifactID];
				SOManager.Instance.ItemInventory.Add(itemData, reward.Amount);
				break;
			case RewardType.Gold:
				SOManager.Instance.Nyang.RuntimeValue += reward.Amount;
				break;
			case RewardType.Exp:
				SOManager.Instance.VQExp.RuntimeValue += reward.Amount;
				break;
		}
	}
}

์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•œ ๊ตฌ์กฐ์ฒด, ํด๋ž˜์Šค๋“ค์„ QuestData์™€ Quest์—์„œ ์ €์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.


๐ŸŽฒ ๊ทธ ์™ธ


  • ํ€˜์ŠคํŠธ UI๋ฅผ ๊ฐœ์„ ํ•˜๋ฉด์„œ, ํ€˜์ŠคํŠธ์˜ ํˆดํŒ์— ์กฐ๊ฑด๊ณผ ๋ณด์ƒ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.

  • ์ธํ˜•๊ณผ ์นด๋ฉ”๋ผ ์‚ฌ์ด์— ์žˆ๋Š” ์˜ค๋ธŒ์ ํŠธ๋“ค์„ ํˆฌ๋ช…ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.
    • ์‚ฌ์‹ค ๊ธฐ๋Šฅ์€ ๊ธฐ์กด์—๋„ ์žˆ์—ˆ๋Š”๋ฐ, ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋˜ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด์„œ ๋ฆฌํŒฉํ† ๋ง์„ ์ง„ํ–‰ํ–ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ์ปฌ JSON ํŒŒ์ผ๋กœ ์ €์žฅํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค.
    • ๊ธฐ์กด์—๋Š” PlayFab์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ–ˆ๋Š”๋ฐ, ๋‹น์žฅ ์ €์žฅ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๊ฐ€ ๊ณ„์† ๋ฐ”๋€Œ๋Š” ์ƒํ™ฉ์—์„œ PlayFab ํŽ˜์ด์ง€๊นŒ์ง€ ๋“ค์–ด๊ฐ€ ์ˆ˜์ •ํ•˜๊ณ  ์ง€์šฐ๋Š” ๊ณผ์ •์ด ๋ฒˆ๊ฑฐ๋กœ์› ๊ธฐ์—..

๐Ÿ‘พ ISavable

1
2
3
4
5
public interface ISavable<T>
{
	void Load(T saveData);
	T Save();
}

๊ฐ„๋‹จํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

๐ŸŽฒ ํ˜„์žฌ๊นŒ์ง€์˜ ์ง„ํ–‰ ์ƒํ™ฉ



๐ŸŽฒ ๋‹ค์Œ ๋ชฉํ‘œ


์–ผ์ถ” ๋งˆ์„ ์˜๋ขฐ๊ฐ€ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

๋งˆ์„ ์˜๋ขฐ๋ฅผ ๋งŒ๋“ค๋ฉด์„œ ์—ฌ๋Ÿฌ ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ๋“ค์„ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋๋Š”๋ฐ,
๋งค๋ฒˆ ๋Š๊ผˆ๋˜ ๊ฒƒ์ด ๋ฒˆ๊ฑฐ๋กœ์›€์ด์—ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์Šคํฌ๋ฆฝํ„ฐ๋ธ” ์˜ค๋ธŒ์ ํŠธ๋Š”, ๋‚ด๊ฐ€ ๋งŒ๋“  ํด๋ž˜์Šค์ธ Artifact๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค.
Artifact์—๋Š” ๊ณ ์œ ํ•œ ์ˆซ์ž์ธ ID๊ฐ€ ์†์„ฑ์œผ๋กœ ์žˆ๊ณ , ์ด ID๋ฅผ ํ†ตํ•ด Artifact๋ฅผ ๊ตฌ๋ณ„ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฑด ์˜จ์ „ํžˆ ๋‚ด ๋ชซ์ด๊ธฐ ๋•Œ๋ฌธ์—,
์ด๊ฒƒ์ €๊ฒƒ ๊ด€๋ฆฌํ•˜๋ฉด์„œ Artifact๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋•Œ ๋งค๋ฒˆ ์ ์ ˆํ•œ ID๋ฅผ ์ฐพ์•„ ์„ค์ •ํ•ด์ค˜์•ผํ•œ๋‹ค.
์—ฌ๊ฐ„ ๋ฒˆ๊ฑฐ๋กœ์šด ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.

๋˜, ์ด๋Ÿฐ Artifact๋“ค์„ ๋ถ„๋ฅ˜์— ๋งž๊ฒŒ ์ €์žฅํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ๋‹ค.
๋‹จ์ˆœํžˆ ํŠน์ • ๋ถ„๋ฅ˜์˜ ๋ชจ๋“  Artifact๋ฅผ ๋ชจ๋‘ ๋ชจ์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๊ณ , (๋ฐ์ดํ„ฐ ์ ‘๊ทผ์„ ์œ„ํ•œ ๋”•์…”๋„ˆ๋ฆฌ๋“ค)
๋ชฉ์ ์— ๋งž๊ฒŒ ๋ชจ์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค. (ํŠน์ • ๋ฑ์— ๋“ค์–ด๊ฐˆ ์นด๋“œ๋“ค)

์ด๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ๋“œ๋ž˜๊ทธ/๋“œ๋กญํ•˜๋Š”๊ฒƒ๋„ ์ฐธ ๊ท€์ฐฎ์€ ์ž‘์—…์ด๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, UI ToolKit์„ ์ด์šฉํ•œ ์—์…‹ ๊ด€๋ฆฌ ํˆด์„ ๋งŒ๋“ค์–ด๋ณผ ๊ฒƒ์ด๋‹ค.

To Be Continued..

์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.