Overview
LCK automatically persists user settings between sessions:- Camera mode (Selfie, First Person, Third Person)
- Quality profile (SD, HD, 2K, 4K)
- Camera settings (FOV, smoothness, distance)
- Audio configuration
Platform-Specific Paths
- Windows
- Android
Windows Save Path
Copy
Ask AI
FString SavePath = FPaths::ProjectSavedDir() / TEXT("LCK") / TEXT("settings.json");
// Example: C:/Users/Player/AppData/Local/MyGame/Saved/LCK/settings.json
Android Save Path
Copy
Ask AI
FString SavePath = FPaths::GamePersistentDownloadDir() / TEXT("LCK") / TEXT("settings.json");
// Example: /storage/emulated/0/Android/data/com.company.mygame/files/LCK/settings.json
Platform Detection
Copy
Ask AI
FString GetLCKSettingsPath()
{
#if PLATFORM_ANDROID
return FPaths::GamePersistentDownloadDir() / TEXT("LCK") / TEXT("settings.json");
#else
return FPaths::ProjectSavedDir() / TEXT("LCK") / TEXT("settings.json");
#endif
}
Settings Structure
FLCKSavedSettings
Copy
Ask AI
USTRUCT(BlueprintType)
struct FLCKSavedSettings
{
GENERATED_BODY()
// Camera mode
UPROPERTY()
ELCKCameraMode CameraMode = ELCKCameraMode::Selfie;
// Quality profile
UPROPERTY()
ELCKVideoQuality Quality = ELCKVideoQuality::HD;
// Orientation
UPROPERTY()
ELCKScreenOrientation Orientation = ELCKScreenOrientation::Landscape;
// Selfie mode settings
UPROPERTY()
float SelfieFOV = 80.0f;
UPROPERTY()
float SelfieSmoothness = 50.0f;
UPROPERTY()
bool bSelfieFollowEnabled = false;
// First person settings
UPROPERTY()
float FirstPersonFOV = 90.0f;
UPROPERTY()
float FirstPersonSmoothness = 75.0f;
// Third person settings
UPROPERTY()
float ThirdPersonFOV = 90.0f;
UPROPERTY()
float ThirdPersonSmoothness = 100.0f;
UPROPERTY()
float ThirdPersonDistance = 2.0f;
// Audio
UPROPERTY()
bool bMicrophoneEnabled = true;
UPROPERTY()
bool bGameAudioEnabled = true;
};
Saving Settings
Using FJsonObjectConverter
Copy
Ask AI
void ULCKTabletDataModel::SaveSettings()
{
// Create settings struct
FLCKSavedSettings Settings;
Settings.CameraMode = CurrentCameraMode;
Settings.Quality = CurrentQuality;
Settings.SelfieFOV = SelfieModeSettings.FOV;
// ... populate other fields
// Convert to JSON
FString JsonString;
if (!FJsonObjectConverter::UStructToJsonObjectString(Settings, JsonString))
{
UE_LOG(LogLCK, Error, TEXT("Failed to serialize settings to JSON"));
return;
}
// Ensure directory exists
FString SavePath = GetLCKSettingsPath();
FString Directory = FPaths::GetPath(SavePath);
IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
if (!PlatformFile.DirectoryExists(*Directory))
{
PlatformFile.CreateDirectoryTree(*Directory);
}
// Write to file
if (!FFileHelper::SaveStringToFile(JsonString, *SavePath))
{
UE_LOG(LogLCK, Error, TEXT("Failed to save settings to: %s"), *SavePath);
}
}
Save Triggers
Settings are saved automatically when:- Camera mode changes
- Quality profile changes
- Camera settings (FOV, smoothness) change
- Audio configuration changes
Copy
Ask AI
void ULCKTabletDataModel::SetCameraMode(ELCKCameraMode NewMode)
{
if (CurrentCameraMode != NewMode)
{
CurrentCameraMode = NewMode;
OnCameraModeChanged.Broadcast(NewMode);
// Auto-save
SaveSettings();
}
}
Loading Settings
On Tablet Spawn
Copy
Ask AI
void ALCKTablet::BeginPlay()
{
Super::BeginPlay();
// Try to load saved settings
LoadSettings();
}
void ALCKTablet::LoadSettings()
{
FString SavePath = GetLCKSettingsPath();
// Check if file exists
if (!FPaths::FileExists(SavePath))
{
UE_LOG(LogLCK, Log, TEXT("No saved settings found, using defaults"));
return;
}
// Read file
FString JsonString;
if (!FFileHelper::LoadFileToString(JsonString, *SavePath))
{
UE_LOG(LogLCK, Warning, TEXT("Failed to read settings file"));
return;
}
// Parse JSON
FLCKSavedSettings Settings;
if (!FJsonObjectConverter::JsonObjectStringToUStruct(JsonString, &Settings))
{
UE_LOG(LogLCK, Warning, TEXT("Failed to parse settings JSON"));
return;
}
// Apply settings
ApplySettings(Settings);
}
void ALCKTablet::ApplySettings(const FLCKSavedSettings& Settings)
{
DataModel->SetCameraMode(Settings.CameraMode);
DataModel->SetQuality(Settings.Quality);
DataModel->SetOrientation(Settings.Orientation);
// Apply camera-specific settings
DataModel->SetSelfieFOV(Settings.SelfieFOV);
DataModel->SetSelfieSmoothness(Settings.SelfieSmoothness);
// ... etc
}
Error Handling
Robust Loading Pattern
Copy
Ask AI
bool ULCKSettingsManager::TryLoadSettings(FLCKSavedSettings& OutSettings)
{
FString SavePath = GetLCKSettingsPath();
// File existence check
if (!FPaths::FileExists(SavePath))
{
return false;
}
// Read with error handling
FString JsonString;
if (!FFileHelper::LoadFileToString(JsonString, *SavePath))
{
UE_LOG(LogLCK, Warning, TEXT("Could not read settings file"));
return false;
}
// Validate JSON is not empty
if (JsonString.IsEmpty())
{
UE_LOG(LogLCK, Warning, TEXT("Settings file is empty"));
DeleteCorruptedSettings();
return false;
}
// Parse with validation
if (!FJsonObjectConverter::JsonObjectStringToUStruct(JsonString, &OutSettings))
{
UE_LOG(LogLCK, Warning, TEXT("Settings JSON is invalid, resetting"));
DeleteCorruptedSettings();
return false;
}
// Validate loaded values
if (!ValidateSettings(OutSettings))
{
UE_LOG(LogLCK, Warning, TEXT("Settings values out of range, resetting"));
OutSettings = FLCKSavedSettings(); // Reset to defaults
SaveSettings();
}
return true;
}
bool ULCKSettingsManager::ValidateSettings(const FLCKSavedSettings& Settings)
{
// Validate FOV ranges
if (Settings.SelfieFOV < 20.0f || Settings.SelfieFOV > 120.0f)
return false;
// Validate smoothness
if (Settings.SelfieSmoothness < 0.0f || Settings.SelfieSmoothness > 100.0f)
return false;
// Validate distance
if (Settings.ThirdPersonDistance < 0.5f || Settings.ThirdPersonDistance > 10.0f)
return false;
return true;
}
Async Operations
For better performance, especially on Android:Copy
Ask AI
void ULCKSettingsManager::SaveSettingsAsync()
{
// Capture settings copy
FLCKSavedSettings SettingsCopy = CurrentSettings;
Async(EAsyncExecution::ThreadPool, [SettingsCopy]()
{
FString JsonString;
FJsonObjectConverter::UStructToJsonObjectString(SettingsCopy, JsonString);
FString SavePath = GetLCKSettingsPath();
FFileHelper::SaveStringToFile(JsonString, *SavePath);
});
}
void ULCKSettingsManager::LoadSettingsAsync(TFunction<void(FLCKSavedSettings)> Callback)
{
Async(EAsyncExecution::ThreadPool, [Callback]()
{
FLCKSavedSettings Settings;
bool bLoaded = TryLoadSettings(Settings);
// Return to game thread
AsyncTask(ENamedThreads::GameThread, [Callback, Settings, bLoaded]()
{
if (bLoaded)
{
Callback(Settings);
}
else
{
Callback(FLCKSavedSettings()); // Defaults
}
});
});
}
Recording Paths
Video recordings are saved to platform-specific locations:- Windows
- Android
Copy
Ask AI
// Videos saved to user's Videos folder
FString VideoPath = FPaths::VideosDir() / TEXT("LCK") / FileName;
// Example: C:/Users/Player/Videos/LCK/Recording_2024-01-15_14-30-00.mp4
Copy
Ask AI
// Videos saved to Movies folder (accessible in gallery)
FString VideoPath = FPaths::GamePersistentDownloadDir() /
TEXT("Movies") / AlbumName / FileName;
// Example: /storage/emulated/0/Movies/MyGame/Recording_2024-01-15.mp4
On Android 10+, videos are registered with MediaStore for gallery visibility.