Skip to content

Commit c88c141

Browse files
committed
-bump
0 parents  commit c88c141

46 files changed

Lines changed: 4709 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.DS_Store

6 KB
Binary file not shown.

.idea/.idea.RemoteConfigGenerator.dir/.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.RemoteConfigGenerator.dir/.idea/copilot.data.migration.ask2agent.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.RemoteConfigGenerator.dir/.idea/encodings.xml

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.idea.RemoteConfigGenerator.dir/.idea/indexLayout.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Docs/QUICK_START_VI.md

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
# Hướng Dẫn Sử Dụng Nhanh - Remote Config Generator
2+
3+
## Bước 1: Cài Đặt Source Generator
4+
5+
### Thêm vào project (.csproj)
6+
7+
```xml
8+
<ItemGroup>
9+
<ProjectReference Include="..\SourceGenerator\RemoteConfigGenerator.csproj"
10+
OutputItemType="Analyzer"
11+
ReferenceOutputAssembly="false" />
12+
</ItemGroup>
13+
```
14+
15+
## Bước 2: Tạo Remote Config Class
16+
17+
```csharp
18+
using RemoteConfigGenerator;
19+
20+
[RemoteConfigData(PrefsPrefix = "rc_")]
21+
public static partial class RemoteData
22+
{
23+
public static int GoldReward = 100;
24+
public static string WelcomeMessage = "Welcome!";
25+
public static float SpawnRate = 2.5f;
26+
public static bool EnableFeatureX = true;
27+
public static long UserId = 123456789;
28+
}
29+
```
30+
31+
**Lưu ý:**
32+
- Class phải là `static partial`
33+
- Thêm attribute `[RemoteConfigData]`
34+
- Tất cả fields sẽ tự động được quét (không cần `[RemoteConfigField]`)
35+
36+
## Bước 3: Implement Storage
37+
38+
### Option A: Sử dụng PlayerPrefs (đơn giản)
39+
40+
Tạo file `PlayerPrefsStorage.cs`:
41+
42+
```csharp
43+
using UnityEngine;
44+
using RemoteConfigGenerator;
45+
46+
public class PlayerPrefsStorage : IRemoteConfigStorage
47+
{
48+
public void SetInt(string key, int value) => PlayerPrefs.SetInt(key, value);
49+
public int GetInt(string key, int defaultValue) => PlayerPrefs.GetInt(key, defaultValue);
50+
51+
public void SetFloat(string key, float value) => PlayerPrefs.SetFloat(key, value);
52+
public float GetFloat(string key, float defaultValue) => PlayerPrefs.GetFloat(key, defaultValue);
53+
54+
public void SetString(string key, string value) => PlayerPrefs.SetString(key, value);
55+
public string GetString(string key, string defaultValue) => PlayerPrefs.GetString(key, defaultValue);
56+
57+
public void SetBool(string key, bool value) => PlayerPrefs.SetInt(key, value ? 1 : 0);
58+
public bool GetBool(string key, bool defaultValue) => PlayerPrefs.GetInt(key, defaultValue ? 1 : 0) != 0;
59+
60+
public void SetLong(string key, long value) => PlayerPrefs.SetString(key, value.ToString());
61+
public long GetLong(string key, long defaultValue) =>
62+
long.TryParse(PlayerPrefs.GetString(key, defaultValue.ToString()), out var v) ? v : defaultValue;
63+
64+
public void Save() => PlayerPrefs.Save();
65+
}
66+
```
67+
68+
### Option B: Sử dụng GameData (nâng cao)
69+
70+
Nếu bạn có [game-data-unity](https://github.com/VirtueSky/game-data-unity):
71+
72+
```csharp
73+
using VirtueSky.DataStorage;
74+
using RemoteConfigGenerator;
75+
76+
public class GameDataStorage : IRemoteConfigStorage
77+
{
78+
public void SetInt(string key, int value) => GameData.Set(key, value);
79+
public int GetInt(string key, int defaultValue) => GameData.Get(key, defaultValue);
80+
81+
public void SetFloat(string key, float value) => GameData.Set(key, value);
82+
public float GetFloat(string key, float defaultValue) => GameData.Get(key, defaultValue);
83+
84+
public void SetString(string key, string value) => GameData.Set(key, value);
85+
public string GetString(string key, string defaultValue) => GameData.Get(key, defaultValue);
86+
87+
public void SetBool(string key, bool value) => GameData.Set(key, value);
88+
public bool GetBool(string key, bool defaultValue) => GameData.Get(key, defaultValue);
89+
90+
public void SetLong(string key, long value) => GameData.Set(key, value);
91+
public long GetLong(string key, long defaultValue) => GameData.Get(key, defaultValue);
92+
93+
public void Save() => GameData.Save();
94+
}
95+
```
96+
97+
## Bước 4: Khởi Tạo Storage
98+
99+
Tạo script khởi tạo khi game start:
100+
101+
```csharp
102+
using UnityEngine;
103+
104+
public class GameBootstrap : MonoBehaviour
105+
{
106+
void Awake()
107+
{
108+
// Assign storage implementation
109+
RemoteDataExtensions.Storage = new PlayerPrefsStorage();
110+
// hoặc: RemoteDataExtensions.Storage = new GameDataStorage();
111+
112+
// Load saved data
113+
RemoteDataExtensions.LoadFromPrefs_Generated();
114+
115+
Debug.Log($"Gold Reward: {RemoteData.GoldReward}");
116+
}
117+
}
118+
```
119+
120+
## Bước 5: Sử Dụng Trong Game
121+
122+
### Đọc giá trị
123+
124+
```csharp
125+
int gold = RemoteData.GoldReward;
126+
string message = RemoteData.WelcomeMessage;
127+
bool featureEnabled = RemoteData.EnableFeatureX;
128+
```
129+
130+
### Lưu giá trị mới
131+
132+
```csharp
133+
RemoteData.GoldReward = 200;
134+
RemoteData.WelcomeMessage = "Hello World!";
135+
136+
// Lưu vào storage
137+
RemoteDataExtensions.SaveToPrefs_Generated();
138+
```
139+
140+
### Sync từ Firebase Remote Config
141+
142+
```csharp
143+
using Firebase.RemoteConfig;
144+
using System.Threading.Tasks;
145+
146+
public async Task SyncFromFirebase()
147+
{
148+
await FirebaseRemoteConfig.DefaultInstance.FetchAndActivateAsync();
149+
150+
// Sync tất cả fields từ Firebase
151+
RemoteConfig.SyncToStaticClass(RemoteData.SetFieldValue);
152+
153+
// Lưu vào local storage
154+
RemoteDataExtensions.SaveToPrefs_Generated();
155+
156+
Debug.Log("Synced from Firebase!");
157+
}
158+
```
159+
160+
## Ví Dụ Hoàn Chỉnh
161+
162+
```csharp
163+
using UnityEngine;
164+
using Firebase.RemoteConfig;
165+
using System.Threading.Tasks;
166+
167+
public class RemoteConfigManager : MonoBehaviour
168+
{
169+
void Awake()
170+
{
171+
// 1. Setup storage
172+
RemoteDataExtensions.Storage = new PlayerPrefsStorage();
173+
174+
// 2. Load từ local
175+
RemoteDataExtensions.LoadFromPrefs_Generated();
176+
}
177+
178+
void Start()
179+
{
180+
// 3. Sync từ Firebase (async)
181+
SyncFromFirebase();
182+
}
183+
184+
async Task SyncFromFirebase()
185+
{
186+
try
187+
{
188+
// Fetch từ Firebase
189+
await FirebaseRemoteConfig.DefaultInstance.FetchAndActivateAsync();
190+
191+
// Sync vào static class
192+
RemoteConfig.SyncToStaticClass(RemoteData.SetFieldValue);
193+
194+
// Lưu vào storage
195+
RemoteDataExtensions.SaveToPrefs_Generated();
196+
197+
Debug.Log("✅ Remote Config synced!");
198+
Debug.Log($"Gold Reward: {RemoteData.GoldReward}");
199+
}
200+
catch (System.Exception ex)
201+
{
202+
Debug.LogError($"❌ Sync failed: {ex.Message}");
203+
}
204+
}
205+
206+
void OnDestroy()
207+
{
208+
// Lưu trước khi thoát game
209+
RemoteDataExtensions.SaveToPrefs_Generated();
210+
}
211+
}
212+
```
213+
214+
## Debug và Kiểm Tra
215+
216+
### Xem giá trị hiện tại
217+
218+
```csharp
219+
string debugInfo = RemoteDataExtensions.ExportToString_Generated();
220+
Debug.Log(debugInfo);
221+
```
222+
223+
Output:
224+
```
225+
GoldReward: 100
226+
WelcomeMessage: Welcome!
227+
SpawnRate: 2.5
228+
EnableFeatureX: True
229+
UserId: 123456789
230+
```
231+
232+
### Kiểm tra generated code
233+
234+
Sau khi build, tìm file generated trong:
235+
- Visual Studio: `obj/Debug/generated/`
236+
- Rider: `.generated/`
237+
238+
File: `RemoteData_Generated.g.cs`
239+
240+
## Các Tính Năng Nâng Cao
241+
242+
### 1. Custom Key Names
243+
244+
```csharp
245+
[RemoteConfigData]
246+
public static partial class RemoteData
247+
{
248+
[RemoteConfigField(Key = "reward_gold")]
249+
public static int GoldReward = 100;
250+
}
251+
```
252+
253+
### 2. Disable Save/Sync cho field cụ thể
254+
255+
```csharp
256+
[RemoteConfigData]
257+
public static partial class RemoteData
258+
{
259+
[RemoteConfigField(PersistToPrefs = false)]
260+
public static int TempValue = 0; // Không lưu vào storage
261+
262+
[RemoteConfigField(SyncFromRemote = false)]
263+
public static int LocalOnly = 0; // Không sync từ Firebase
264+
}
265+
```
266+
267+
### 3. Custom Prefix
268+
269+
```csharp
270+
[RemoteConfigData(PrefsPrefix = "game_config_")]
271+
public static partial class RemoteData
272+
{
273+
// Keys sẽ là: game_config_GoldReward, game_config_WelcomeMessage, ...
274+
}
275+
```
276+
277+
### 4. Multiple Config Classes
278+
279+
```csharp
280+
[RemoteConfigData(PrefsPrefix = "game_")]
281+
public static partial class GameConfig
282+
{
283+
public static int MaxLevel = 100;
284+
}
285+
286+
[RemoteConfigData(PrefsPrefix = "shop_")]
287+
public static partial class ShopConfig
288+
{
289+
public static int DiamondPrice = 99;
290+
}
291+
292+
// Setup
293+
GameConfigExtensions.Storage = new PlayerPrefsStorage();
294+
ShopConfigExtensions.Storage = new PlayerPrefsStorage();
295+
```
296+
297+
## Troubleshooting
298+
299+
### ❌ Lỗi: "Storage is not set"
300+
301+
**Giải pháp:** Assign storage trước khi gọi Save/Load:
302+
```csharp
303+
RemoteDataExtensions.Storage = new PlayerPrefsStorage();
304+
```
305+
306+
### ❌ Không thấy generated code
307+
308+
**Kiểm tra:**
309+
1. Class có `static partial` chưa?
310+
2. Có attribute `[RemoteConfigData]` chưa?
311+
3. Rebuild project
312+
4. Restart IDE (Visual Studio/Rider)
313+
314+
### ❌ Compile error ở generated code
315+
316+
**Nguyên nhân:** Kiểu dữ liệu không được hỗ trợ
317+
318+
**Supported types:**
319+
- `int`, `float`, `string`, `bool`, `long`
320+
- `int[]`, `float[]`
321+
322+
### ❌ Data không save/load
323+
324+
**Kiểm tra:**
325+
1. Storage đã được assign chưa?
326+
2. Gọi `Save()` sau khi set value
327+
3. Gọi `Load()` trước khi đọc value
328+
329+
## Best Practices
330+
331+
**DO:**
332+
- Assign storage trong `Awake()` hoặc game bootstrap
333+
- Gọi `LoadFromPrefs_Generated()` khi game start
334+
- Gọi `SaveToPrefs_Generated()` trước khi quit game
335+
- Sử dụng async/await cho Firebase sync
336+
337+
**DON'T:**
338+
- Gọi Save() trong Update() (performance issue)
339+
- Quên assign Storage
340+
- Truy cập RemoteData trước khi Load()
341+
342+
## Tài Liệu Tham Khảo
343+
344+
- [STORAGE_WRAPPER_VI.md](STORAGE_WRAPPER_VI.md) - Chi tiết về Storage Wrapper Pattern
345+
- [README_VI.md](README_VI.md) - Hướng dẫn đầy đủ
346+
- [TECHNICAL_DETAILS_VI.md](TECHNICAL_DETAILS_VI.md) - Kỹ thuật nâng cao
347+
348+
## Liên Hệ & Hỗ Trợ
349+
350+
Có vấn đề? Tạo issue trên GitHub hoặc liên hệ maintainer.

0 commit comments

Comments
 (0)