// Lot STC - voir LPUserSettings.h #include "LPUserSettings.h" #include "LifePlay.h" #include "UObject/UnrealType.h" namespace LPUserSettingsGi { constexpr float DefaultCameraSpeed = 3.f; // GI.CameraSpeed est une variable Blueprint : reel double en 5.x (FDoubleProperty), float accepte aussi. // Propriete absente ou d'un autre type : avertissement, GI n'est pas touche. FProperty* FindCameraSpeed(UObject* GameInstance, const TCHAR* Caller) { static const FName CameraSpeedName(TEXT("CameraSpeed")); if (!GameInstance) { UE_LOG(LogLifePlay, Warning, TEXT("Camera : %s sans GameInstance, GI.CameraSpeed non touche"), Caller); return nullptr; } FProperty* Prop = GameInstance->GetClass()->FindPropertyByName(CameraSpeedName); if (!CastField(Prop) && !CastField(Prop)) { UE_LOG(LogLifePlay, Warning, TEXT("Camera : %s, pas de propriete reelle CameraSpeed dans %s, GI non touche"), Caller, *GameInstance->GetClass()->GetName()); return nullptr; } return Prop; } float ReadValue(const FProperty* Prop, const UObject* GameInstance) { if (const FDoubleProperty* AsDouble = CastField(Prop)) { return static_cast(AsDouble->GetPropertyValue_InContainer(GameInstance)); } if (const FFloatProperty* AsFloat = CastField(Prop)) { return AsFloat->GetPropertyValue_InContainer(GameInstance); } return DefaultCameraSpeed; } void WriteValue(const FProperty* Prop, UObject* GameInstance, float Value) { if (const FDoubleProperty* AsDouble = CastField(Prop)) { AsDouble->SetPropertyValue_InContainer(GameInstance, static_cast(Value)); } else if (const FFloatProperty* AsFloat = CastField(Prop)) { AsFloat->SetPropertyValue_InContainer(GameInstance, Value); } } } float ULPUserSettingsLibrary::ClampCameraSpeed(float V) { return FMath::Clamp(FMath::RoundToFloat(V), 1.f, 7.f); } void ULPUserSettingsLibrary::ApplyCameraSpeedAtStartup(UObject* GameInstance) { ULPUserSettings* Settings = GetMutableDefault(); FProperty* Prop = LPUserSettingsGi::FindCameraSpeed(GameInstance, TEXT("ApplyCameraSpeedAtStartup")); if (!Prop) { // Avertissement deja ecrit. Ini inchange : au premier lancement, la reprise depuis GI sera retentee. return; } if (Settings->bCameraSpeedSet) { const float Value = ClampCameraSpeed(Settings->CameraSpeed); const float Before = LPUserSettingsGi::ReadValue(Prop, GameInstance); LPUserSettingsGi::WriteValue(Prop, GameInstance, Value); UE_LOG(LogLifePlay, Display, TEXT("Camera : vitesse %.0f lue dans GameUserSettings.ini (ini %.2f), recopiee dans GI (avant %.2f)"), Value, Settings->CameraSpeed, Before); return; } // Premier lancement : entree jamais ecrite. GI.CameraSpeed vient de GameSettings.sav (GI.LoadSettings). const float FromGi = LPUserSettingsGi::ReadValue(Prop, GameInstance); const float Value = ClampCameraSpeed(FromGi); LPUserSettingsGi::WriteValue(Prop, GameInstance, Value); Settings->CameraSpeed = Value; Settings->bCameraSpeedSet = true; Settings->SaveConfig(); UE_LOG(LogLifePlay, Display, TEXT("Camera : vitesse %.0f reprise de GI (GameSettings.sav : %.2f), ecrite dans GameUserSettings.ini (premier lancement)"), Value, FromGi); } void ULPUserSettingsLibrary::SetCameraSpeed(UObject* GameInstance, float V) { const float Value = ClampCameraSpeed(V); if (FProperty* Prop = LPUserSettingsGi::FindCameraSpeed(GameInstance, TEXT("SetCameraSpeed"))) { LPUserSettingsGi::WriteValue(Prop, GameInstance, Value); } // L'ini fait foi : ecrit seulement si la valeur change, ou si l'entree n'a jamais ete ecrite. ULPUserSettings* Settings = GetMutableDefault(); if (Settings->bCameraSpeedSet && Settings->CameraSpeed == Value) { return; } Settings->CameraSpeed = Value; Settings->bCameraSpeedSet = true; Settings->SaveConfig(); UE_LOG(LogLifePlay, Display, TEXT("Camera : vitesse %.0f enregistree dans GameUserSettings.ini"), Value); } float ULPUserSettingsLibrary::GetCameraSpeed() { const ULPUserSettings* Settings = GetDefault(); return Settings->bCameraSpeedSet ? ClampCameraSpeed(Settings->CameraSpeed) : LPUserSettingsGi::DefaultCameraSpeed; }