A C# Source Generator for Unity that creates optimized, reflection-free Remote Config access code. Firebase integration is optional and guarded by define symbols so projects can compile before Firebase packages are installed.
- Zero reflection overhead: generated dictionary/switch based setters and getters.
- Type-safe fields: compile-time field access for config values.
- Auto-scan mode: if no field has
[RemoteConfigField], all public static fields/properties are included. - Manual mode: if at least one field has
[RemoteConfigField], only attributed fields/properties are included. - Firebase-safe generation: Firebase-specific generated code is wrapped in
VIRTUESKY_FIREBASE_REMOTECONFIG. - No storage layer: Firebase Remote Config persists activated values between sessions, so the generator no longer creates
Storage,SaveToPrefs_Generated(), orLoadFromPrefs_Generated().
Dependencies: Install NuGet For Unity, then install Microsoft.CodeAnalysis.CSharp
Use the SourceGenerator.dll from release, or build it yourself.
- Copy
SourceGenerator.dllintoAssets/Plugins/. - Select the DLL in Unity Inspector.
- Disable Any Platform.
- Enable Editor only.
- Add the asset label
RoslynAnalyzer. - Apply changes.
The runtime example and generated code use these symbols:
| Symbol | Required when | Purpose |
|---|---|---|
VIRTUESKY_FIREBASE |
Firebase App is installed | Enables FirebaseApp.CheckAndFixDependenciesAsync(). |
VIRTUESKY_FIREBASE_REMOTECONFIG |
Firebase Remote Config is installed | Enables Firebase.RemoteConfig, Firebase.Extensions, and generated SetFieldValue_Generated(string, ConfigValue). |
When Firebase is not installed, do not define these symbols. The project should still compile because Firebase-specific code is excluded.
using RemoteConfigGenerator;
[RemoteConfigData]
public static partial class RemoteData
{
[RemoteConfigField(Key = "inter_time_gap")]
public static int InterTimeGap = 30;
[RemoteConfigField(Key = "start_level_show_inter")]
public static int StartLevelShowInter = 15;
}Important:
- The class must be
static partial. - Add
[RemoteConfigData]. - Use
[RemoteConfigField(Key = "...")]when the Firebase key differs from the C# member name. PrefsPrefixandPersistToPrefsare kept only for backwards compatibility. They no longer affect generated storage code.
int gap = RemoteData.InterTimeGap;
int startLevel = RemoteData.StartLevelShowInter;string debugInfo = RemoteDataExtensions.ExportToString_Generated();
Debug.Log(debugInfo);Use the provided Example/RemoteConfig.cs as the runtime loader. It:
- Checks Firebase dependencies when
VIRTUESKY_FIREBASEis defined. - Activates cached Remote Config values from previous sessions.
- Fetches remote values.
- Activates fetched values.
- Applies keys through generated lookup methods.
The generator creates two sync paths:
RemoteDataExtensions.FieldSetterLookup.TryGetValue(key, out Action<string> setter);
RemoteDataExtensions.SetFieldValue_Generated(key, configValue);SetFieldValue_Generated is generated only when VIRTUESKY_FIREBASE_REMOTECONFIG is defined because it uses Firebase's ConfigValue type.
Example/RemoteConfig.cs supports Firebase keys ending with Settings. The runtime removes Settings from the key and prefixes each JSON child key with the remaining name.
Firebase key:
AdSettings
Firebase JSON value:
{
"InterTimeGap": 30,
"StartLevelShowInter": 15
}Generated lookup keys:
AdInterTimeGap
AdStartLevelShowInter
Remote data declaration:
[RemoteConfigData]
public static partial class RemoteData
{
[RemoteConfigField(Key = "AdInterTimeGap")]
public static int InterTimeGap = 30;
[RemoteConfigField(Key = "AdStartLevelShowInter")]
public static int StartLevelShowInter = 15;
}If no member uses [RemoteConfigField], the generator includes all public static members:
[RemoteConfigData]
public static partial class RemoteData
{
public static int GoldReward = 100;
public static bool EnableFeature = false;
}If at least one member uses [RemoteConfigField], only attributed members are included:
[RemoteConfigData]
public static partial class RemoteData
{
[RemoteConfigField(Key = "gold_reward")]
public static int GoldReward = 100;
public static int LocalOnlyValue = 1; // Not generated
}[RemoteConfigField(SyncFromRemote = false)]
public static int LocalOnlyValue = 0;intfloatstringboollongint[]float[]
Arrays are parsed from comma-separated strings by generated helper methods.
cd SourceGenerator
dotnet build -c ReleaseOutput:
SourceGenerator/bin/Release/netstandard2.0/RemoteConfigGenerator.dll
For a class named RemoteData, the generator creates RemoteDataExtensions with:
public static readonly Dictionary<string, Action<string>> FieldSetterLookup;
public static readonly Dictionary<string, Func<object>> FieldGetterLookup;
public static object GetFieldValue_Generated(string fieldName);
public static string ExportToString_Generated();When VIRTUESKY_FIREBASE_REMOTECONFIG is defined, it also creates:
public static bool SetFieldValue_Generated(string fieldName, ConfigValue configValue);The generator no longer creates:
RemoteDataExtensions.Storage
RemoteDataExtensions.SaveToPrefs_Generated()
RemoteDataExtensions.LoadFromPrefs_Generated()
IRemoteConfigStorageCheck your scripting define symbols:
- Firebase App installed: add
VIRTUESKY_FIREBASE. - Firebase Remote Config installed: add
VIRTUESKY_FIREBASE_REMOTECONFIG. - Firebase not installed: remove both symbols.
Check:
- Class is
static partial. - Class has
[RemoteConfigData]. - Project was rebuilt.
- IDE/Unity was refreshed.
Check:
- The Firebase key matches
[RemoteConfigField(Key = "...")]or the member name. - If using
AdSettingsstyle JSON, the generated key isAd+ JSON child key. - The field type is supported.
- The field is not marked
SyncFromRemote = false.
- Create an issue on GitHub.
- Check the
Examplefolder for current runtime integration.