WitchMendokusai DevLog 02
๐ _
์ด๋ฒ ์ผ์ง์์๋ ์์ ๋ค์ ๊ด๋ฆฌํ๊ธฐ ์ํ ํด ๊ธฐ๋ฐ์ ๋ง๋ค์ด๋ณธ๋ค.
๐ UI Toolkit, ๊ธฐ๋ณธ์ ์ธ ๋ ์ด์์
์ ์ ํด์ ๋ง๋ค์ด๋ณด๋ ค๊ณ UI ToolKit์ ์ ๊น ๊ณต๋ถํด๋ณธ ์ ์ด ์๋ค.
์ด์ด์ UI ToolKit์ผ๋ก ๋ง๋ค์ด๋ณธ๋ค.
๊ธฐ๋ณธ์ ์ธ ๋ ์ด์์์ ์ ์์์ ์ฐธ๊ณ ํ๋ค.
์์ ์ค๋ช
๋์ ์ ํ ๋งํฌ์์ ์์ธํ ํํ ๋ฆฌ์ผ์ ์ ๊ณตํ๋ค.
ํด๋น ํํ ๋ฆฌ์ผ์์๋ ๋ฐํ์์์ ์ฌ์ฉํ๊ธฐ ์ํ ์ธ๋ฒคํ ๋ฆฌ UI๋ฅผ ๋ชฉํ๋ก ํ๋๋ฐ, UI ToolKit์ ๋ฐํ์๊ณผ ์๋ํฐ UI ๋ชจ๋์ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ ํฌ๊ฒ ๋ฌธ์ ๋ ์๋ค.
ํํ ๋ฆฌ์ผ์ ๋ณด๊ณ ๋ฐ๋ผ ๋ง๋ UI์, ๋ช ๊ฐ์ง ๊ธฐ๋ฅ์ ์ถ๊ฐํ ๋ชจ์ต์ด๋ค.
๋ฏธ๋ฆฌ InitAllList()
ํจ์์์ QuestData
ํ์
์ ์คํฌ๋ฆฝํฐ๋ธ ์ค๋ธ์ ํธ ๋ฆฌ์คํธ๋ฅผ ์ ์ฅํ๊ณ ,
CreateGUI()
ํจ์์์ ๊ฐ QuestData
๋ฅผ MArtifactVisual
๋ก ๋ง๋ค์ด ์ถ๊ฐํ๋ค.
์๋๊ฐ ๊ทธ ์ฝ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MArtifactVisual : Button
{
public Artifact Artifact { get; private set;}
public MArtifactVisual(Artifact artifact)
{
this.Artifact = artifact;
name = $"{artifact.Name}";
Add(new Label(){ text = artifact.Name });
Add(new Label(){ text = artifact.ID.ToString() });
if (artifact.Sprite != null)
style.backgroundImage = artifact.Sprite.texture;
AddToClassList("slot-icons");
}
}
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
private void InitAllList()
{
const string QUEST_DIRECTORY_PATH = "Assets/_Mascari4615/ScriptableObjects/Quest/";
questDatas = new();
InitList(ref questDatas, QUEST_DIRECTORY_PATH);
static void InitList<T>(ref List<T> list, string dirPath, bool searchSubDir = true) where T : ScriptableObject
{
const string extension = ".asset";
DirectoryInfo dir = new(dirPath);
foreach (FileInfo file in dir.GetFiles())
{
if (string.Compare(file.Extension, extension, StringComparison.Ordinal) != 0)
continue;
// QuestData ์คํฌ๋ฆฝํฐ๋ธ ๊ฐ์ฒด๊ฐ ์๋๋ฉด Continue
if (AssetDatabase.GetMainAssetTypeAtPath($"{dirPath}/{file.Name}") != typeof(T))
continue;
list.Add(AssetDatabase.LoadAssetAtPath<T>($"{dirPath}/{file.Name}"));
}
if (searchSubDir)
{
// dir ์๋ ๋ชจ๋ ํด๋ ์์ ์๋ ํ์ผ์ ํ์
foreach (DirectoryInfo subDir in dir.GetDirectories())
InitList(ref list, $"{dirPath}/{subDir.Name}/");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
public void CreateGUI()
{
// ...
VisualElement grid = rootVisualElement.Q<VisualElement>(name: "Grid");
foreach (QuestData questData in questDatas)
{
MAritifactVisual mAritifactVisual = new(questData);
mAritifactVisual.RegisterCallback<ClickEvent>(ShowArtifact);
grid.Add(mAritifactVisual);
}
}
๐ ์์ ์ ๋ ฌ
์ ์คํฌ๋ฆฐ์ท์ ๋ค์ ์ดํด๋ณด๋ฉด, ์์ ์์๊ฐ ์๋ง์ธ๊ฑธ ์ ์ ์๋ค.
๊ฐ ์์
์ฌ๋กฏ์์ ์ด๋ฆ ํ
์คํธ ์์ ์๋ ๊ฒ์ ๋ด๊ฐ ์์๋ก ์ค์ ํ ID
๋ค.
๋ณด๋ฉด ID
1 ์์
๋ค์ ID
2 ์์
์ด ์๋๋ผ ID
100 ์์
์ด ์ค๊ณ ์๊ณ ,
๋ ID
3 ์์
์ ๋งจ ๋ค์ ์์นํ๋ค.
์ด๋ ๊ฒ ์์๊ฐ ์๋ง์ธ ์ด์ ๋,
ํ์ผ์ ๋ถ๋ฌ์ฌ ๋ ํ์ผ ์ด๋ฆ ๋ฌธ์์ด ์์๋ก ๋ถ๋ฌ์ค๊ณ , (ํจ์ ๋ฌธ์์ ๊ทธ๋ฐ ์ธ๊ธ์ ์์ง๋ง)
๋จผ์ ํ์ฌ ๋๋ ํ ๋ฆฌ์ ์๋ ํ์ผ๋ค์ ๋ฆฌ์คํธ์ ์ถ๊ฐํ ๋ค ํ์ ๋๋ ํ ๋ฆฌ๋ฅผ ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ด์จ๊ฑฐ๋, ์์ ์ ์ ๋ ฌํด์ค์ผ ํ๋ค.
๐ฟ ๋์ ๋๋ฆฌ?
๊ตณ์ด ์ ๋ ฌํ์ง ์๊ณ Dictionary<int, Artifact>
๋ชจ์์ผ๋ก ๋์
๋๋ฆฌ๋ฅผ ์จ๋ ๋ ๊ฒ ๊ฐ๊ธดํ๋ค.
ID
๋ฅผ Artifact
์ ๊ณ ์ ํ ๊ฐ์ผ๋ก ์ค์ ํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ ID
๋ฅผ ๊ฐ์ง Artifact
๋ ์๋ค.
๋ง์ฝ ์กด์ฌํ๋ค๋ฉด ์๋ชป๋ ID
์ด๊ธฐ ๋๋ฌธ์ ID
๋ฅผ ์์ ํด์ผ ํ๋ค.
์ ๋ ฌ ์๊ณ ๋ฆฌ๋ฌ์ ์ด๋ค๋ฉด, ์ด๋ฏธ ์กด์ฌํ๋ ID
์ธ์ง ํ์ธํ๊ธฐ ์ํด ๋ณ๋์ ์ปจํ
์ด๋๋ฅผ ์จ์ผ ํ๋๋ฐ,
๊ทธ๋ฅ ๋์
๋๋ฆฌ๋ฅผ ์ด๋ค๋ฉด, ๋จ์ํ ID
๋ก Contains
๋ TryGetValue
๋ฅผ ์จ๋ณด๋ฉด ์ ์ ์๋ค.
์ฌ๋กฏ UI ์ถ๊ฐ๋,
ID
๊ฐ ์ปค๋ดค์ 10๋ง๋ณด๋ค๋ ์์ ๊ฑฐ๋ผ์, for
๋ฌธ์ผ๋ก 0 ~ MAX_ID
๊น์ง ๋๋ฆฌ๋ฉด์ TryGetValue
๊ฐ true
์ธ ๊ฒ์ ๋ํด ์ฌ๋กฏ์ ์ถ๊ฐํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void CreateGUI()
{
// ...
System.Diagnostics.Stopwatch sw = new();
sw.Start();
VisualElement grid = rootVisualElement.Q<VisualElement>(name: "Grid");
for (int i = 0; i < ID_MAX; i++)
{
if (questDataDic.TryGetValue(i, out QuestData questData))
{
MArtifactVisual mAritifactVisual = new(questData);
mAritifactVisual.RegisterCallback<ClickEvent>(ShowArtifact);
grid.Add(mAritifactVisual);
}
}
sw.Stop();
Debug.Log($"TryGetValue x {ID_MAX} = {sw.ElapsedMilliseconds}ms");
}
์, ๋น์ฅ ์๋๋ ๊ฑฑ์ ์๋ค!
ํ์ด์ง ๋ง๋๋ ๊ฒ๋ ๋จ์ํ ์ด ๋ชจ์์์ ํ ํ์ด์ง์ ํ์ํ ์์ ์ ๋งํผ TryGetValue
๊ฐ true
๋ฉด ์ถ๊ฐํ๋ฉด ๋ ๊ฒ์ด๋ค.
๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ๋ค.
๐ ์์ ๊ด๋ฆฌ
์์ ์ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ ๋ง๋ค์ด๋ณด์.
์์
์ ๋ง๋๋ ๊ธฐ๋ฅ์ ๋ณ๋์ UI๊ฐ ํ์ํ ๊ฒ ๊ฐ์์,
๋น์ฅ ๋ฒํผ ํ๋๋ง ์์ผ๋ฉด ๋๋ ์์
๋ณต์ ์ ์ญ์ ๊ธฐ๋ฅ๋ถํฐ ๊ตฌํํด๋ณธ๋ค.
๐ฟ ์์ ๋ณต์
์์ ๋ณต์ ๊ธฐ๋ฅ์ด๋ค.
๋ ์ด์์ ์ฐ์ธก์ ์์นํ ํดํ์ ๊ธฐ๋ฅ์ ๋ด๋นํ๋ MArtifactDetail
ํด๋์ค๋ฅผ ์๋ก ๋ง๋ค๊ณ ,
MArtifactDetail
์์ ๋ฒํผ์ ํด๋ฆญ ํ์ ๋, ํ์ฌ ์ ํ๋ Artifact
์ ๋ํด MArtifact
์ DuplicateArtifact
๋ฅผ ํธ์ถํ๋๋ก ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MArtifactDetail
{
// ...
public MArtifactDetail()
{
// ...
duplicateButton = root.Q<Button>(name: "BTN_Dup");
duplicateButton.clicked += DuplicateCurArtifact;
}
public void DuplicateCurArtifact()
{
MArtifact.Instance.DuplicateArtifact(CurArtifact);
}
// ...
}
์ดํ MArttifact
์์ ์ค์ DuplicateArtifact
ํจ์๋ฅผ ๊ตฌํํ๋ค.
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
public class MArtifact : EditorWindow
{
public void DuplicateArtifact(Artifact artifact)
{
string nName = artifact.Name + " Copy";
// ์ค๋ณต๋์ง ์๋ ID๋ฅผ ์ฐพ๋๋ค.
int nID = artifact.ID + 1;
while (questDataDic.ContainsKey(nID))
nID++;
string assetName = $"Q_{nID}_{nName}";
string path = AssetDatabase.GenerateUniqueAssetPath($"{QUEST_DIRECTORY_PATH}{assetName}.asset");
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(artifact), path);
QuestData newQuestData = AssetDatabase.LoadAssetAtPath<QuestData>(path);
newQuestData.ID = nID;
newQuestData.Name = nName;
questDataDic.Add(nID, newQuestData);
VisualElement grid = rootVisualElement.Q<VisualElement>(name: "Grid");
grid.Add(new MArtifactVisual(newQuestData));
Repaint();
}
}
์ฝ๋๋ฅผ ๋ณด๋ฉด while (questDataDic.ContainsKey(nID))
์ questDataDic.Add(nID, newQuestData);
์์ questDataDic
์ ์ฌ์ฉํ๊ณ , ๋ ์์
์ ๋ค์ ๋ก๋ํ ๋ QuestData
ํ์
์ผ๋ก ๋ถ๋ฌ์ค๊ณ ์๋ค.
ํ์ง๋ง ์ด ํจ์๋ ๋ชจ๋ Artifact
์คํฌ๋ฆฝํฐ๋ธ ์ค๋ธ์ ํธ์ ๋ํด์ ์ฌ์ฉํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ์ผ๋ฐํ ํด์ผํ๋ค.
์ด๋ป๊ฒ ์ผ๋ฐํ ์ํค๋ฉด ์ข์๊น?
์ผ๋จ ํ์คํธ๋ฅผ ์ ์ฅํด๋๊ธฐ ์ํ questDataDic
์ด ์๋ ๊ฒ ์ฒ๋ผ, ๋ค๋ฅธ Artifact
๋ค๋ ๊ฐ์ ์ปจํ
์ด๋๊ฐ ์์ ๊ฒ์ด๋ค.
์ ๋ฌ๋ฐ์ Artifact artifact
๋ฅผ ์ค์ ํ์
์ ๋ง๋ ์ปจํ
์ด๋์ ์ถ๊ฐํด ๋ฐ์ดํฐ๋ฅผ ๊ฐฑ์ ํด์ค์ผ ํ๋ค.
Dictionary<Type, Dictionary>
๋ฅผ ๋ง๋ค์ด์ Dictionary
๋ค๋ ํ๋์ Dictionary
๋ก ๊ด๋ฆฌํด๋ณผ๊น?
Dictionary
์ Value
ํ์
์ ๊ณ ์ ํด์ผ ํ๊ธฐ์ Dictionary<Type, Dictionary<int, Artifact>>
ํ์
์ผ๋ก ๋ง๋ค๊ณ , ์ธ ๋๋ ๋ค์ด์บ์คํ
์ด ํด์ ์ฐ๋ฉด ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋ ๊ฒ ๊ฐ์ง ์๋ค.
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
public void DuplicateArtifact(Artifact artifact)
{
Type type = artifact.GetType();
Dictionary<int, Artifact> dic = dataDics[type];
string nName = artifact.Name + " Copy";
// ์ฌ์ฉ๋์ง ์์ ID๋ฅผ ์ฐพ๋๋ค.
int nID = artifact.ID + 1;
while (dic.ContainsKey(nID))
nID++;
string assetName = $"Q_{nID}_{nName}";
string path = AssetDatabase.GenerateUniqueAssetPath($"{QUEST_DIRECTORY_PATH}{assetName}.asset");
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(artifact), path);
Artifact newArtifact = AssetDatabase.LoadAssetAtPath<Artifact>(path);
newArtifact.ID = nID;
newArtifact.Name = nName;
dic.Add(nID, newArtifact);
VisualElement grid = rootVisualElement.Q<VisualElement>(name: "Grid");
grid.Add(new MArtifactVisual(newArtifact));
Repaint();
}
์์ ๋ ์ฝ๋๋ค.
์ด๋ ๊ฒ ๋ณต์ ๊ธฐ๋ฅ์ ๋ง๋ค์ด๋ดค๋ค.
๐ฟ ์์ ์ญ์
์์ ์ญ์ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณธ๋ค.
๋ณต์ ๊ธฐ๋ฅ์ฒ๋ผ ์ฃผ์ด์ง Artifact์ ๋ง๋ ์ปจํ
์ด๋๋ฅผ ์ฐพ์ ์ญ์ ํด์ผ ํ๋ค.
.. ๋ ํ๋ ์ฝ๋ฉ์ ํด์ผ ํ๋ ๊ฒ์ธ๊ฐ? ๊ณ ๋ฏผ์ค๋ฌ์ด ๋ฌธ์ ๋ค.
.. ๊ทธ๋ฅ Dictionary<Type, Dictionary<int, Artifact>>
๋ฅผ ์ธ๊น?
์๊ฐํด๋ณด๋ฉด ๋ค์ด์บ์คํ
์ ํ์ํ๋ค๊ณ ํด์ ์ฑ๋ฅ์ด๋ ๊ตฌํ์ ํฌ๊ฒ ๋ฌธ์ ๊ฐ ๋ ๊ฒ ๊ฐ์ง ์๋ค.
๊ทธ๋ ๊ฒ ์์ ํ๊ณ ๊ตฌํํด๋ณด์.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private readonly Dictionary<Type, Dictionary<int, Artifact>> dataDics = new();
public void DeleteArtifact(Artifact artifact)
{
Type type = artifact.GetType();
Dictionary<int, Artifact> dic = dataDics[type];
string assetName = $"Q_{artifact.ID}_{artifact.Name}";
string path = AssetDatabase.GenerateUniqueAssetPath($"{QUEST_DIRECTORY_PATH}{assetName}.asset");
dic.Remove(artifact.ID);
AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(artifact));
UpdateGrid();
}
// ...
๐ฟ ์์ ์ถ๊ฐ
์ด์ ์์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณธ๋ค.
๊ทผ๋ฐ.. ์๊ฐํด๋ณด๋ฉด ์์ ์ถ๊ฐ๋ฅผ ์ํ ๋ณ๋์ UI๊ฐ ์์ด๋ ๋ ๊ฒ ๊ฐ๋ค.
๊ธฐ๋ณธ ์์
์ ์ถ๊ฐํ๋ ๋ฒํผ ํ๋๋ง ๊ฐ๋จํ ๋ง๋ค๊ณ ,
์์
์ ๋ณด๋ฅผ ๋ํ๋ด๋ ํ๋ฉด์์ ๋๋กญ๋ฐ์ค ๋ฑ์ผ๋ก ๊ณง๋ฐ๋ก ์์ ๊ฐ๋ฅํ๋๋ก ํ๋ฉด ๋์ง ์์๊น?
๊ทธ๋ฌ๊ธฐ ์ํด์๋ ์์
์ ์ ๋ณด๋ฅผ ์์ ๊ฐ๋ฅํ๋๋ก UI๋ฅผ ์ถ๊ฐํด์ผํ๋ค.
.. ์ด์ฐจํผ UI๋ ๋ง๋ค์ด์ผํ๋ค.
(๋ช ์๊ฐ ๋คโฆ)
.. PropertyField
์ ์กด์ฌ๋ฅผ ๋ชจ๋ฅด๊ณ ์ง์ ํ๋กํผํฐ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์์ ๋ง๋ค๊ณ ์์๋ค.
์ด์ฌํ ๋ง๋ค์๋๋ฐ ๊ทธ๋ฅ ์ง์ฐ๊ธฐ ์์ฌ์์ ๋จ๊ฒจ๋ณธ๋ค.
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public PropertyBlock(Artifact artifact, PropertyInfo propertyInfo)
{
this.artifact = artifact;
this.propertyInfo = propertyInfo;
PropertyName = new Label(propertyInfo.Name);
PropertyName.AddToClassList("property-name");
Add(PropertyName);
SetPropertyValue();
AddToClassList("property-block");
}
private void SetPropertyValueWithType<T, U>() where U : BaseField<T>, new()
{
T value = (T)propertyInfo.GetValue(artifact);
PropertyValue = new U();
(PropertyValue as U).value = value;
}
private void SetPropertyValue()
{
Type propertyType = propertyInfo.PropertyType;
switch (propertyType)
{
case Type intType when intType == typeof(int):
SetPropertyValueWithType<int, IntegerField>();
break;
case Type stringType when stringType == typeof(string):
SetPropertyValueWithType<string, TextField>();
bool isDescription = propertyInfo.Name == nameof(Artifact.Description);
if (isDescription)
{
(PropertyValue as TextField).multiline = true;
(PropertyValue as TextField).style.minHeight = 100;
}
PropertyValue.RegisterCallback<ChangeEvent<string>>(evt =>
{
propertyInfo.SetValue(artifact, evt.newValue);
});
break;
// ...
}
}
// ...
PropertyField
๋ฅผ ์ด์ฉํ ์ฝ๋๋ ์๋์ ๊ฐ๋ค.
์ด๋, PropertyField
๋ฅผ ์ด๊ธฐํํ๋ ๋ถ๋ถ์์ ๋ง์ด ์ ๋ฅผ ๋จน์๋ค.
๋๋ ์คํฌ๋ฆฝํฐ๋ธ ์ค๋ธ์ ํธ์ ๋ชจ๋ ํ๋๋ฅผ [field: SerializeField] public int ID { get; set; }
๊ฐ์ด ์๋๊ตฌํ ํ๋กํผํฐ๋ก ๋ง๋ค์๋๋ฐ,
CurArtifact.GetType().GetFields()
๋ก๋ ํ๋๊ฐ ๊ฒ์๋์ง ์์๊ณ ,
serializedObject.FindProperty()
์์๋ PropertyInfo.Name
์ผ๋ก๋ ํ๋๋ฅผ ์ฐพ์ ์ ์์๋ค.
ํ๋ ์ด๋ฆ์ด ๋๋์ฒด ๋ญ๊น ํ๊ณ sharplab.io์์ IL ์ฝ๋๋ฅผ ํ์ธํด๋ณด๊ณ ๋์์ผ, ํ๋กํผํฐ์ ํ๋ ์ด๋ฆ์ด <ํ๋กํผํฐ์ด๋ฆ>k__BackingField
๊ฐ์ ๋ชจ์์ผ๋ก ์๊ธด๋ค๋ ๊ฒ์ ์์๋ค.
์ด๋ ๊ฒ ๊ตฌํํด๋ ๋๋ ๊ฑด์ง๋ ์ ๋ชจ๋ฅด๊ฒ ์ง๋ง, ์ด์จ๋ ์ ๋์ํ๊ธฐ์ ๊ทธ๋๋ก ์จ๋ณด๊ธฐ๋ก ํ๋ค.
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
public void UpdateUI()
{
SerializedObject serializedObject = new(CurArtifact);
// CurArtifact์ ๋ชจ๋ ํ๋กํผํฐ๋ฅผ ๋ฆฌํ๋ ์
์ผ๋ก ๊ฐ์ ธ์ค๊ธฐ
List<PropertyInfo> propertyInfos = CurArtifact.GetType()
.GetProperties()
.OrderBy(
p =>
{
var attribute = p.GetCustomAttribute(typeof(PropertyOrderAttribute));
if (attribute == null)
return int.MaxValue;
else
return ((PropertyOrderAttribute)attribute).Order;
}).ToList();
// CurArtifact์ ๋ชจ๋ ํ๋กํผํฐ๋ฅผ PropertyBlock์ผ๋ก ๋ง๋ค์ด์ artifactContent์ ์ถ๊ฐ
artifactContent.Clear();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
if (propertyInfo.Name == "name" || propertyInfo.Name == "hideFlags")
continue;
// HACK : ์๋์ผ๋ก ์์ฑ๋๋ ํ๋กํผํฐ์ ํ๋์ ์ด๋ฆ = <ํ๋กํผํฐ์ด๋ฆ>k__BackingField
PropertyField propertyField = new (serializedObject.FindProperty($"<{propertyInfo.Name}>k__BackingField"));
propertyField.Bind(serializedObject);
artifactContent.Add(propertyField);
}
}
์ ๋์ํ๋ค.
๊ทผ๋ฐ ์ด๋ด๊ฑฐ๋ฉด ๊ทธ๋ฅ ์ธ์คํํฐ๋ฅผ ํ์ฅ์ํค๋ฉด ๋๋๊ฑฐ ์๋์๋?
.. ์ผ๋จ ๊ทธ๋ฅ ์ฐ์
์ด์ด์ ๊ฐ๋จํ ์์ ์ถ๊ฐ ๋ฒํผ๋ ๋ง๋ค์ด๋ณธ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void UpdateGrid()
{
// ...
Button addButton = new()
{
text = "+",
};
addButton.AddToClassList("slot-icons");
addButton.RegisterCallback<ClickEvent>(ev =>
{
AddArtifact(MArtifactDetail.CurArtifact.GetType());
});
grid.Add(addButton);
Repaint();
}
๋จ์ํ ๋ง์ง๋ง ๋ฒํผ์ผ๋ก ์ถ๊ฐํ๋ค.
๐ ์ฌ๋ฌ ์์
์ง๊ธ์ QuestData
์คํฌ๋ฆฝํฐ๋ธ ์ค๋ธ์ ํธ๋ง ๋ถ๋ฌ์ค๊ณ ์๋ค.
UI๋ฅผ ๊ฐ๋จํ ์์ ํ ํ, ๋ค๋ฅธ ํ์
์ ์คํฌ๋ฆฝํฐ๋ธ ์ค๋ธ์ ํธ๋ ๋ถ๋ฌ์ค์.
ํ์ฌ UI๋ก ํ์ํ ํ์
์ CurType
์ผ๋ก ์ ์ํ๊ณ ,
๊ทธ CurType
์ ์ํ๋ ํ์
์ผ๋ก ์ค์ ํ๋ ๋ฒํผ๋ค์ด ๋ชจ์ธ ๋ฉ๋ด๋ฅผ ๋ง๋ค์๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private Type CurType { get; set; } = typeof(QuestData);
public void CreateGUI()
{
// ...
VisualElement menu = rootVisualElement.Q<VisualElement>(name: "Menu");
foreach (Type type in dataDics.Keys)
{
Button button = new()
{
text = type.Name,
};
button.clicked += () =>
{
CurType = type;
UpdateGrid();
MArtifactDetail.UpdateCurArtifact(dataDics[CurType].Values.First());
};
menu.Add(button);
}
// ...
}