23 KiB
Fiche STC-T3 — Niveau N3 — Modèle prévu lp-impl | utilisé claude-opus-5-5 — Agent lp-impl — Skills lp-ue-compat, ue-cpp-build, lp-build, sk-protocol
STC-T3-IMPL : C++ ULPUserSettings (GameUserSettings.ini) et style des sliders de Settings (2026-10-10)
Copie D:\Game\LifePlay-master 5.8, branche ue5.8, HEAD 20620f6. SPEC : STC-SPEC.md § 0-2, 7 (lue en entier).
Non compilé (fiche : BUILD par lp-builder, éditeur ouvert). Aucun asset, config, Build.cs ni git touché.
1. Fichiers modifiés (chemins, lignes)
| Fichier | État | Lignes (wc -l) |
Fins de ligne (git ls-files --eol / -o --eol) |
MD5 |
|---|---|---|---|---|
D:\Game\LifePlay-master 5.8\Source\LifePlay\LPUserSettings.h |
neuf | 59 | w/lf (comme le modèle LPModSettingsLibrary.h/.cpp, i/lf w/lf) |
7d67c3f755930bcf1c0fd4c65aced897 |
D:\Game\LifePlay-master 5.8\Source\LifePlay\LPUserSettings.cpp |
neuf | 115 | w/lf |
ba74f9e3e6dbaa4a02579be89ea2e037 |
D:\Game\LifePlay-master 5.8\Source\LifePlay\LPSettingsSubsystem.cpp |
modifié, +52 / -0 (git diff --stat) |
835 → 887 | i/crlf w/crlf (inchangé, CRLF gardé par Edit) |
2fe96f77… → ede28e6d9aeff9a27f1adb988c03ae36 |
LPSettingsSubsystem.hnon modifié (MD50f98c055…= instantané).LifePlay.Build.csnon modifié :Slate,SlateCore,UMGdéjà en privé (LifePlay.Build.cs:38),CoreUObject/Engineen public (:17) ; aucune dépendance manquante (estimé : toutes les API utilisées sont dans ces modules).- Dossier
Source/LifePlay: 18 fichiers CRLF, 35 LF (git ls-files --eol -- Source/LifePlay) ; les neufs suivent leur modèle (LF). - Aucun caractère hors ASCII dans les deux fichiers neufs (Grep
[^\x00-\x7F]: 0 résultat). - Emplacements dans
LPSettingsSubsystem.cpp(après modification) : includeComponents/Slider.hl. 19 ;CollectSlidersl. 281-303 ; couleurs l. 346-351 ; collecte l. 355 et 360 ; boucle de style l. 403-420 (SetWidgetStylel. 415,SetSliderBarColorl. 417,SetSliderHandleColorl. 418, Grep relu).
2. Écarts à la SPEC (obligatoire)
- E1 (style, § 2.3) : les couleurs sont portées par la teinte des pinceaux du style (
NormalBarImage0.06/0.06/0.06/0.95,HoveredBarImage0.12/0.12/0.12/0.98,NormalThumbImage0.2/0.45/0.9/1,HoveredThumbImage0.3/0.55/1/1) etSetSliderBarColor/SetSliderHandleColorreçoivent blanc (multiplicateur neutre). Motif :SSlider::OnPaintdessine teinte du pinceau × couleur (SSlider.cpp:125, 137) ; mettre les couleurs dans les pinceaux garde un état survolé distinct (GetBarImage/GetThumbImage,SSlider.cpp:483-513). Les teintes de survol (0.12 et 0.3/0.55/1) ne sont pas dans la SPEC (reprises deSpinBgHoveretCheckedHover). Base = style propre du slider (GetWidgetStyle), pasFCoreStylecomme les SpinBox : pinceaux,BarThickness(2 px par défaut) et taille de poignée (8×14) gardés. Seuls appels d'écriture : les trois permis par la SPEC ; aucunSetValue, niSetIsEnabled/SetRenderOpacity. - E2 (portée du style, § 2.3) : appliqué, comme écrit, à tous les
USliderdeSettingsScrollBox: donc aussi aux 5 lignesLPColor*(LPColorGradeSubsystem.cpp:298-302), aux slidersLPVideo*(LPVideoQualitySubsystem.cpp:392) et à tout slider Blueprint de la liste. Effet visible au-delà du slider caméra : à confirmer par l'orchestrateur (une restriction au nomSliderCameraSpeedserait un changement d'une ligne). - E3 (propriété GI absente) : interprétation de « avertissement, rien d'autre ».
ApplyCameraSpeedAtStartup: avertissement puis retour, ini non écrit dans les deux branches (la reprise du premier lancement sera retentée).SetCameraSpeed: avertissement pour GI, ini quand même mis à jour (l'ini fait foi, D4). GameInstance nul = même traitement. - E4 :
SetCameraSpeedécrit une ligneDisplayà chaque écriture de l'ini (Camera : vitesse N enregistree dans GameUserSettings.ini) ; non demandé, utile à V5 ; au plus une ligne par cran réellement changé. - E5 : formule de la SPEC gardée telle quelle, sans garde NaN :
FMath::Clamp=Max(Min(X, Max), Min)(UnrealMathUtility.h:592-595), donc NaN → 7 (estimé par lecture du code, non essayé). - E6 : broche
Vgardée (nom de la SPEC) pourClampCameraSpeedetSetCameraSpeed. - Aucun autre écart : signatures, catégorie
LifePlay|Settings,UCLASS(config = GameUserSettings), valeurs par défaut (3, faux),SaveConfig()seulement si valeur changée oubCameraSpeedSetfaux, lecture/écriture GI par réflexionFDoublePropertypuisFFloatProperty.
3. Instantané (lot, manifeste)
- Lot
STC, manifesteD:\Game\LifePlay_Backup_5.5\STC\manifest.csv(fait par l'orchestrateur, 2026-10-10T09:11:26) :LPUserSettings.het.cppExisted=False;LPSettingsSubsystem.cppMD52FE96F776A0F3DFDA803F6E0EB1BC73Bet.h0F98C05568AE789C5C0B78F6EC580503, identiques aux fichiers avant modification (md5sum, relu avant la première écriture). - Retour arrière (proposé, non fait) :
Tools\Restore.ps1 -Lot STC(déplace les deux neufs, restaure le.cpp).
4. Ce qui n'a pas été fait
- Compilation (BUILD par lp-builder, éditeur fermé) ; aucun build 5.5 de contrôle (le lot vit dans la copie 5.8).
- Blueprints
MainMenu(§ 3) etGI(§ 4), CHG, ini,GameSettings.sav: hors fiche. - Aucun commit, aucun
git add, aucune écriture dansDocs/de la copie 5.8, aucun script.
5. Points à confirmer en VAL
- BUILD 5.8 : code 0 ;
LPUserSettings.gen.cppproduit par UHT ;LPUserSettings.cppetLPSettingsSubsystem.cppcompilés ; 0 avertissement nouveau (règles V7 : ombrage, code inatteignable). - Unity build : espace de noms
LPUserSettingsGi(nommé, unique : GrepLPUserSettingssur Source, Plugins et addon 5.8 avant écriture = 0) sans C2374. - Palette Blueprint : 4 nœuds sous
LifePlay|Settingsavec les broches de la table « Signatures » (Constats). - V8 : journal
LogLifePlayDisplay« Camera : vitesse N reprise de GI (GameSettings.sav : X), ecrite dans GameUserSettings.ini (premier lancement) » et section[/Script/LifePlay.LPUserSettings]avecCameraSpeed=…etbCameraSpeedSet=True. - V8 (risque) : valeur de
CameraSpeeddansGameSettings.savavant migration ; si elle vaut 0.2 (cause (c)), la reprise donne 1, pas 3 (Round(0.2)=0puis borne 1) ; attendu SPEC V8 = 3. - V6 : au relancement, ligne « Camera : vitesse 5 lue dans GameUserSettings.ini (ini 5.00), recopiee dans GI (avant X) » et
GI.CameraSpeed = 5. - V5 : une ligne « enregistree dans GameUserSettings.ini » par cran changé, aucune quand la valeur ne change pas ; fichier écrit sur disque (
SaveConfig→Flush,Obj.cpp:3942-3944). - V9 : seule la section
LPUserSettingsajoutée dansGameUserSettings.ini. - Style (E1, E2) : slider caméra lisible sur fond clair (barre 2 px, poignée 8×14 inchangées) ; aspect des sliders
LPColor*/LPVideo*/ Blueprint acceptable ; aucune valeur de slider modifiée à l'ouverture du menu. - Cases et SpinBox : rendu inchangé (aucune ligne de leur traitement modifiée, diff relu).
6. Fichiers à commiter
Dépôt jeu D:\Game\LifePlay-master 5.8, branche ue5.8 :
A Source/LifePlay/LPUserSettings.h
A Source/LifePlay/LPUserSettings.cpp
M Source/LifePlay/LPSettingsSubsystem.cpp
Tours : 56 / 60
Constats
Signatures telles qu'un Blueprint les verra (estimé : affichage par FName::NameToDisplayString, à confirmer en VAL)
Cible : LPUser Settings Library (classe ULPUserSettingsLibrary, statiques, aucune broche Target). Catégorie LifePlay|Settings.
| Nœud (titre) | C++ | Type | Broches d'entrée (nom interne → affiché) | Broches de sortie |
|---|---|---|---|---|
| Clamp Camera Speed | static float ClampCameraSpeed(float V) |
BlueprintPure |
V → « V » (Float simple précision) |
ReturnValue → « Return Value » (Float) |
| Apply Camera Speed At Startup | static void ApplyCameraSpeedAtStartup(UObject* GameInstance) |
BlueprintCallable |
execute ; GameInstance → « Game Instance » (Object Reference) |
then |
| Set Camera Speed | static void SetCameraSpeed(UObject* GameInstance, float V) |
BlueprintCallable |
execute ; GameInstance → « Game Instance » ; V → « V » (Float) |
then |
| Get Camera Speed | static float GetCameraSpeed() |
BlueprintPure |
— | ReturnValue → « Return Value » (Float) |
Pas de DefaultToSelf : la broche GameInstance doit être reliée (self dans GI, Get Game Instance dans MainMenu). |
||||
Classe de configuration : ULPUserSettings (UCLASS(config = GameUserSettings), UPROPERTY(config) float CameraSpeed = 3.f, |
||||
UPROPERTY(config) bool bCameraSpeedSet = false), non visible des Blueprints (pas de spécificateur Blueprint, conforme SPEC 2.1). |
Choix faits
- Accès à l'ini :
GetMutableDefault<ULPUserSettings>()(objet par défaut chargé de l'ini à sa création), écritureSaveConfig()sans argument : fichier = nom de config de la classe (Obj.cpp:3697,GetConfigFilenameObj.cpp:2332-2338,UClass::GetConfigNameClass.cpp:7144-7149:GameUserSettingsest un nom de config connu), puisFlushsur disque (Obj.cpp:3942-3944). - Réflexion GI :
FindPropertyByName("CameraSpeed"),CastField<FDoubleProperty>puisCastField<FFloatProperty>(UnrealType.h:2507, 2547;CastFieldconstField.h:1133) ;Get/SetPropertyValue_InContainerconst (UnrealType.h:1663, 1673). Tout autre type ou absence :Warning« pas de propriete reelle CameraSpeed dans , GI non touche ». ApplyCameraSpeedAtStartup: une ligneDisplaypar appel réussi (source ini avec valeur ini et valeur GI d'avant, ou reprise depuis GI avec valeur du sav) ;SaveConfigseulement dans la branche premier lancement.SetCameraSpeed: GI toujours écrit (valeur bornée) ; ini etSaveConfigseulement si!bCameraSpeedSet || CameraSpeed != V(comparaison exacte : entiers 1-7 exacts en float).GetCameraSpeed:bCameraSpeedSet ? ClampCameraSpeed(CameraSpeed) : 3.- Helpers dans l'espace de noms nommé
LPUserSettingsGi(piège unity C2374,lp-build§ 8) ;FNameenstaticlocal (commeLPModSettingsLibrary.cpp:13). - Compatibilité 5.5 (estimé, non compilé) : API du slider présentes en 5.5 (
UE_5.5/.../Components/Slider.h:147, 150, 184, 191) ; aucune garde de version nécessaire ; aucun correctif UE4 (LPStringCompat,LPMeshCompat,LPNavigationHelpers…) touché.
API moteur 5.8 lues (établi)
UE_5.8/Engine/Source/Runtime/UMG/Public/Components/Slider.h:151GetWidgetStyle,:154SetWidgetStyle,:188SetSliderBarColor(FLinearColor),:195SetSliderHandleColor(FLinearColor); accès direct aux membres déprécié 5.1 (:51, 61, 66).UMG/Private/Components/Slider.cpp:210-217, 284-305: ces setters ne touchent pasValue;:30style d'exécution par défaut =FDefaultStyleCache::GetRuntime().GetSliderStyle()(SlateCore/Private/Styling/DefaultStyleCache.cpp:60→UMGCoreStyle.cpp:723-731: barreFSlateColorBrushblanche, poignéeCommon/Button8×14, épaisseur 2).SlateCore/Public/Styling/SlateTypes.h:1339-1386:FSliderStyle(NormalBarImage,HoveredBarImage,DisabledBarImage,NormalThumbImage,HoveredThumbImage,DisabledThumbImage,BarThickness).Slate/Private/Widgets/Input/SSlider.cpp:119-138(peinture : teinte × couleur × teinte du widget),:483-513(pinceau survolé).CoreUObject/Public/UObject/Object.h:1283SaveConfig(uint64 RequiredPropertyFlags = CPF_Config, const TCHAR* Filename = nullptr, …).Core/Public/GenericPlatform/GenericPlatformMath.h:332RoundToFloat(float);Core/Public/Math/UnrealMathUtility.h:592Clamp. Aucune API supposée par la SPEC absente en 5.8 (arrêt rubrique 7 non déclenché).
Diff complet
Source/LifePlay/LPSettingsSubsystem.cpp (git diff, CR retirés à l'affichage) :
@@ -16,6 +16,7 @@
#include "Components/OverlaySlot.h"
#include "Components/ScrollBox.h"
#include "Components/SizeBox.h"
+#include "Components/Slider.h"
#include "Components/SpinBox.h"
#include "Components/TextBlock.h"
#include "Components/PanelWidget.h"
@@ -277,6 +278,30 @@ namespace LPSettingsUi
}
}
+ void CollectSliders(UWidget* Widget, TArray<USlider*>& Out)
+ {
+ if (!Widget)
+ {
+ return;
+ }
+ if (USlider* Slider = Cast<USlider>(Widget))
+ {
+ Out.Add(Slider);
+ return;
+ }
+ if (UUserWidget* User = Cast<UUserWidget>(Widget))
+ {
+ CollectSliders(User->GetRootWidget(), Out);
+ }
+ if (UPanelWidget* Panel = Cast<UPanelWidget>(Widget))
+ {
+ for (int32 Index = 0; Index < Panel->GetChildrenCount(); ++Index)
+ {
+ CollectSliders(Panel->GetChildAt(Index), Out);
+ }
+ }
+ }
+
void TintBrush(FSlateBrush& Brush, const FLinearColor& Tint)
{
Brush.TintColor = FSlateColor(Tint);
@@ -318,12 +343,21 @@ namespace LPSettingsUi
TintBrush(SpinStyle.ActiveFillBrush, FLinearColor(0.2f, 0.45f, 0.9f, 0.85f));
SpinStyle.ForegroundColor = FSlateColor(FLinearColor(1.f, 1.f, 1.f, 1.f));
+ // Lot STC : sliders (vitesse de camera, lignes LPColor* et LPVideo*). Barre sombre comme le fond des spinboxes,
+ // poignee bleue comme leur remplissage. Style et couleurs seulement : aucune valeur ecrite (pas de SetValue).
+ const FLinearColor SliderBar(0.06f, 0.06f, 0.06f, 0.95f);
+ const FLinearColor SliderBarHover(0.12f, 0.12f, 0.12f, 0.98f);
+ const FLinearColor SliderHandle(0.2f, 0.45f, 0.9f, 1.f);
+ const FLinearColor SliderHandleHover(0.3f, 0.55f, 1.f, 1.f);
+
TArray<UCheckBox*> Boxes;
TArray<USpinBox*> Spins;
+ TArray<USlider*> Sliders;
for (int32 Index = 0; Index < Scroll->GetChildrenCount(); ++Index)
{
CollectCheckBoxes(Scroll->GetChildAt(Index), Boxes);
CollectSpinBoxes(Scroll->GetChildAt(Index), Spins);
+ CollectSliders(Scroll->GetChildAt(Index), Sliders);
}
for (UCheckBox* Box : Boxes)
@@ -366,6 +400,24 @@ namespace LPSettingsUi
Spin->SetFont(Font);
}
+ for (USlider* Slider : Sliders)
+ {
+ if (!Slider)
+ {
+ continue;
+ }
+ // Style propre du slider (pinceaux et epaisseur gardes), seules les teintes changent.
+ FSliderStyle SliderStyle = Slider->GetWidgetStyle();
+ TintBrush(SliderStyle.NormalBarImage, SliderBar);
+ TintBrush(SliderStyle.HoveredBarImage, SliderBarHover);
+ TintBrush(SliderStyle.NormalThumbImage, SliderHandle);
+ TintBrush(SliderStyle.HoveredThumbImage, SliderHandleHover);
+ Slider->SetWidgetStyle(SliderStyle);
+ // SSlider::OnPaint multiplie la teinte du pinceau par ces couleurs : blanc = teintes ci-dessus telles quelles.
+ Slider->SetSliderBarColor(FLinearColor::White);
+ Slider->SetSliderHandleColor(FLinearColor::White);
+ }
+
if (UWidget* ShowFPS = [&]() -> UWidget*
{
for (int32 Index = 0; Index < Scroll->GetChildrenCount(); ++Index)
Source/LifePlay/LPUserSettings.h (fichier neuf, 59 lignes, contenu intégral) :
// Lot STC - vitesse de camera adossee a GameUserSettings.ini (STC-SPEC, partie 2).
//
// La valeur de reference de la vitesse de camera est la section [/Script/LifePlay.LPUserSettings] de
// GameUserSettings.ini (PIE : Saved/Config/WindowsEditor/, jeu : Saved/Config/Windows/). GI.CameraSpeed n'en est
// qu'une recopie : ApplyCameraSpeedAtStartup la remplit au demarrage (apres GI.LoadSettings), SetCameraSpeed la met a
// jour quand le joueur bouge le slider du menu Settings. L'ini n'est ecrit que si la valeur change, ou une fois au
// premier lancement (bCameraSpeedSet faux) : la valeur de GI, issue de GameSettings.sav, est alors reprise et bornee.
// GameSettings.sav garde son champ CameraSpeed, recopie de GI par GI.SaveSettings.
// Valeurs permises : entiers de 1 a 7 (slider a pas de 1), 3 par defaut.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/Object.h"
#include "LPUserSettings.generated.h"
/** Reglages du joueur propres a LifePlay, enregistres dans GameUserSettings.ini (objet par defaut seulement). */
UCLASS(config = GameUserSettings)
class LIFEPLAY_API ULPUserSettings : public UObject
{
GENERATED_BODY()
public:
/** Vitesse de camera choisie dans le menu Settings (1 a 7). */
UPROPERTY(config)
float CameraSpeed = 3.f;
/** Faux tant que l'entree n'a jamais ete ecrite (premier lancement : reprise de GI.CameraSpeed). */
UPROPERTY(config)
bool bCameraSpeedSet = false;
};
UCLASS()
class LIFEPLAY_API ULPUserSettingsLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/** Arrondit a l'entier le plus proche et borne entre 1 et 7. */
UFUNCTION(BlueprintPure, Category = "LifePlay|Settings")
static float ClampCameraSpeed(float V);
/**
* A appeler au demarrage, apres GI.LoadSettings : recopie dans GI.CameraSpeed la valeur de GameUserSettings.ini.
* Premier lancement (entree jamais ecrite) : reprend GI.CameraSpeed (lu dans GameSettings.sav), la borne, l'ecrit
* dans GI et dans l'ini.
*/
UFUNCTION(BlueprintCallable, Category = "LifePlay|Settings")
static void ApplyCameraSpeedAtStartup(UObject* GameInstance);
/** Slider du menu Settings : borne V, l'ecrit dans GI.CameraSpeed et, si elle change, dans GameUserSettings.ini. */
UFUNCTION(BlueprintCallable, Category = "LifePlay|Settings")
static void SetCameraSpeed(UObject* GameInstance, float V);
/** Vitesse de camera enregistree dans GameUserSettings.ini, bornee (3 si jamais ecrite). */
UFUNCTION(BlueprintPure, Category = "LifePlay|Settings")
static float GetCameraSpeed();
};
Source/LifePlay/LPUserSettings.cpp (fichier neuf, 115 lignes, contenu intégral) :
// 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<FDoubleProperty>(Prop) && !CastField<FFloatProperty>(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<FDoubleProperty>(Prop))
{
return static_cast<float>(AsDouble->GetPropertyValue_InContainer(GameInstance));
}
if (const FFloatProperty* AsFloat = CastField<FFloatProperty>(Prop))
{
return AsFloat->GetPropertyValue_InContainer(GameInstance);
}
return DefaultCameraSpeed;
}
void WriteValue(const FProperty* Prop, UObject* GameInstance, float Value)
{
if (const FDoubleProperty* AsDouble = CastField<FDoubleProperty>(Prop))
{
AsDouble->SetPropertyValue_InContainer(GameInstance, static_cast<double>(Value));
}
else if (const FFloatProperty* AsFloat = CastField<FFloatProperty>(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<ULPUserSettings>();
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<ULPUserSettings>();
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<ULPUserSettings>();
return Settings->bCameraSpeedSet ? ClampCameraSpeed(Settings->CameraSpeed) : LPUserSettingsGi::DefaultCameraSpeed;
}
Commandes de contrôle rejouables
git -C "D:/Game/LifePlay-master 5.8" status --short→M Source/LifePlay/LPSettingsSubsystem.cpp,?? Source/LifePlay/LPUserSettings.cpp,?? Source/LifePlay/LPUserSettings.h(+?? Docs/Migration/32_Organisation_Agents.md, préexistant, non touché).git -C "D:/Game/LifePlay-master 5.8" ls-files --eol -- Source/LifePlay/LPSettingsSubsystem.cpp→i/crlf w/crlf;git … ls-files -o --eol -- Source/LifePlay/→w/lfpour les deux neufs.
Addendum orchestrateur (2026-10-10, après remise du livrable)
Écart E2 tranché : le style ne s'applique qu'au slider SliderCameraSpeed (les sliders LPColor* / LPVideo* gardent
leur aspect). Code actuel de la boucle : if (!Slider || Slider->GetFName() != TEXT("SliderCameraSpeed")) { continue; } et
commentaire « slider de vitesse de camera seulement ». MD5 actuel de LPSettingsSubsystem.cpp : b72671af… (le MD5
ede28e6d… cité plus haut est celui de la version remise par lp-impl). Le diff de ce livrable décrit la version
antérieure ; la version qui fait foi est celle relue en STC-VAL (contrôle a).