14 KiB
Fiche CAM-B2c-IMPL — Niveau N3 — Modèle prévu opus | utilisé claude-opus-5-5 — Agent lp-impl — Skills sk-protocol, sk-change-safety, ue-cpp-build, lp-ue-compat (préchargés : sk-protocol, ue-cpp-build, lp-build, lp-ue-compat ; sk-change-safety absent du contexte, règle de la fiche appliquée : fichiers neufs)
CAM-B2c-IMPL : indicateur du mode de caméra, ULPCameraModeSubsystem (2026-10-13)
SPEC : Docs/Migration/etat/CAM/CAM-B2c-SPEC.md (lue en entier). Copie D:\Game\LifePlay-master 5.8, branche ue5.8.
Aucune compilation, aucun éditeur, aucun MCP, aucune écriture git (fiche, rubriques 2 et 5).
1. Fichiers modifiés (chemins, lignes)
Deux fichiers neufs, aucun fichier existant modifié par cette fiche.
| Fichier | Taille | MD5 | Lignes | Fins de ligne | Codage |
|---|---|---|---|---|---|
Source/LifePlay/LPCameraModeSubsystem.h |
1790 o | bf3412c1857a06ba1626a477eea5ef62 |
48 | LF (CR = 0) | ASCII pur (0 octet non ASCII), sans BOM |
Source/LifePlay/LPCameraModeSubsystem.cpp |
8879 o | 8253ff12534e2933d16ccb997f967982 |
273 | LF (CR = 0) | ASCII pur, sans BOM |
Mesure (commande rejouée après écriture) :
for f in …LPCameraModeSubsystem.h …cpp; do wc -c ; tr -cd '\r' | wc -c ; tr -cd '\n' | wc -c ; head -c 3 | od -An -tx1 ; LC_ALL=C tr -d '\000-\177' | wc -c ; done ; md5sum …
Source/LifePlay/LPCameraModeSubsystem.h taille=1790 CR=0 LF=48 debut= 2f 2f 20 non-ASCII=0
Source/LifePlay/LPCameraModeSubsystem.cpp taille=8879 CR=0 LF=273 debut= 2f 2f 20 non-ASCII=0
bf3412c1857a06ba1626a477eea5ef62 *Source/LifePlay/LPCameraModeSubsystem.h
8253ff12534e2933d16ccb997f967982 *Source/LifePlay/LPCameraModeSubsystem.cpp
Référence des fins de ligne : git ls-files --eol Source/LifePlay/LPOutdoorRoomSubsystem.cpp → i/lf w/lf attr/-text
(modèle désigné par la fiche) ; dossier Source/LifePlay : 40 fichiers i/lf, 18 i/crlf ; .gitattributes = * -text.
Voisins sans BOM (2f 2f 20 en tête de LPOutdoorRoomSubsystem.*, LPDirectControlSubsystem.cpp, LPKeyboardSubsystem.h).
Contenu :
.h:ULPCameraModeSubsystem : UGameInstanceSubsystem(enregistrement automatique) ;Initialize,Deinitialize; privésTick,ComputeLabel,EnsureWidget,RemoveWidget,SetShown; membresTickHandle,Root(TSharedPtr<SWidget>),Text(TSharedPtr<STextBlock>),Viewport(TWeakObjectPtr<UGameViewportClient>),ShownLabel,bShown. En-tête de fichier en français (lot, rôle, aucun asset modifié), style de LPOutdoorRoomSubsystem.h..cpp: espace de noms nomméLPCameraModeLocal(lectures par réflexionReadObject,ReadBool,ArrayContains; copie deMenuClassesetMenuOnScreen) ; tickerFTSTickertoutes les 0,1 s ; classement ; texte Slate.
Classement (ComputeLabel, ordre du § 2 de la SPEC, premier vrai gagne) :
| # | Condition (C++) | Libellé |
|---|---|---|
| 0 | pas de PC, ou cible de vue nulle | rien |
| 1 | vue == GI.Birdview (non nul) ou nom de classe de la vue contient Birdview |
Camera: Overview |
| 2 | GI.SexOn et GI.POVOn |
Camera: POV |
| 3 | GI.SexOn |
Camera: Scene |
| 4 | vue == GI.PlayerCharacter (non nul) et Room.CamC1On |
Camera: C1 First person |
| 5 | vue == Room.CamRoom (non nul) et Room.CamC3On |
Camera: C3 Ceiling |
| 6 | vue == Room.CamRoom (non nul) |
Camera: C2 Follow |
| 7 | Room.CamC3On |
Camera: C3 Room (old) |
| 8 | vue ∈ GI.ChargenCameras (tableau d'objets, parcouru par FScriptArrayHelper) |
Camera: Studio |
| 9 | vue == Room.SceneCamera (non nul) |
Camera: Builder |
| — | sinon | rien |
PC : GetGameInstance()->GetWorld()->GetFirstPlayerController(), à défaut GI.PC ; vue : PC->GetViewTarget(). Room : |
||
GI.Room si IsValid, sinon nul (les lectures sur un conteneur nul rendent nul / faux). Propriété absente, d'un autre |
||
type, ou référence nulle : la ligne ne s'applique pas ; aucune lecture Blueprint, donc pas d'Accessed None. |
Affichage : SOverlay racine, slot HAlign_Left / VAlign_Bottom, marge FMargin(16.f) ; STextBlock police
FCoreStyle::GetDefaultFontStyle("Regular", 12), couleur FLinearColor(1, 1, 1, 0.7), ombre décalée (1, 1) noire à
70 %. Racine EVisibility::HitTestInvisible quand visible, Collapsed sinon (changement seulement quand l'état
change). Ajout unique par AddViewportWidgetContent(Root, 50) sur le viewport du GameInstance, refait seulement si ce
viewport a changé. SetText seulement quand le libellé change (+ une ligne LogLifePlay: Indicateur de camera : <libellé>).
Masqué si libellé vide ou menu ouvert (copie de MenuOnScreen : ULPKeyboardSubsystem::IsMenuOpen, classes
MenuClasses, champ focalisé Editable) ; le test de menu n'est fait que si un libellé est à afficher.
Deinitialize : RemoveTicker(TickHandle), puis RemoveViewportWidgetContent(Root) si le viewport porteur est encore
valide (pointeur faible), puis remise à zéro des pointeurs.
Noms de propriétés relus (établi) : GI Birdview (ST/STE/dumps/GI__EventGraph_V5.txt:625), ChargenCameras (:4442),
PlayerCharacter (:918), PC (:569), Room (:20904), SexOn (:6896), POVOn (:20528) ; Room CamC1On
(CAM/CAM-B2b-VAL_LPDumpFunction_20261013-161237.txt:9699), CamC3On (:9712), CamRoom (:9970), SceneCamera (:2312).
Types : Birdview = acteur Birdview_C (CAM-AUDIT.md:15), CamRoom = CameraActor (CAM-B0-IMPL.md:25),
CamC1On / CamC3On = bool (CAM-B1-IMPL.md:20), ChargenCameras = tableau de CameraActor (CAM-AUDIT.md:16-18).
API moteur lues dans D:/Game/Launcher/Engine/UE_5.8/Engine/Source (5.8.3, Engine/Build/Build.version) :
UGameViewportClient::AddViewportWidgetContentRuntime/Engine/Classes/Engine/GameViewportClient.h:258,RemoveViewportWidgetContent:265 (corpsPrivate/GameViewportClient.cpp:3376, :3387 :RemoveSlotsi l'overlay existe) ;RemoveAllViewportWidgetsn'est appelé qu'enBeginDestroy/DetachViewportClient(GameViewportClient.cpp:472, :480).UGameInstance::GetWorldRuntime/Engine/Classes/Engine/GameInstance.h:211,GetGameViewportClient:295 ;UGameInstanceSubsystem::GetGameInstanceRuntime/Engine/Public/Subsystems/GameInstanceSubsystem.h:25.UWorld::GetFirstPlayerControllerRuntime/Engine/Classes/Engine/World.h:2781;APlayerController::GetViewTargetRuntime/Engine/Classes/GameFramework/PlayerController.h:1911.FTSTicker::AddTicker(const FTickerDelegate&, float InDelay)Runtime/Core/Public/Containers/Ticker.h:45(InDelay :43),RemoveTicker:66.EVisibility::HitTestInvisibleRuntime/SlateCore/Public/Layout/Visibility.h:23;SWidget::SetVisibilityRuntime/SlateCore/Public/Widgets/SWidget.h:1068;STextBlockFont/ColorAndOpacity/ShadowOffset/ShadowColorAndOpacityRuntime/Slate/Public/Widgets/Text/STextBlock.h:89, 95, 98, 101,SetText:200 ;FCoreStyle::GetDefaultFontStyleRuntime/SlateCore/Public/Styling/CoreStyle.h:51.UWidget::IsInViewportRuntime/UMG/Public/Components/Widget.h:549,GetVisibility:586,GetGameInstance:871 ;FSlateApplication::GetKeyboardFocusedWidgetRuntime/Slate/Public/Framework/Application/SlateApplication.h:1653;TObjectIteratorRuntime/CoreUObject/Public/UObject/UObjectIterator.h:251.Runtime/CoreUObject/Public/UObject/UnrealType.h:FBoolProperty:2589,GetPropertyValue_InContainer:2688 ;FObjectPropertyBase:2773,GetObjectPropertyValue:2894,GetObjectPropertyValue_InContainer:2896 ;FArrayProperty:3776,Inner:3782 ;FScriptArrayHelper:4262, constructeur(const FArrayProperty*, const void*):4285,Num:4303,GetRawPtr:4324 ;ContainerPtrToValuePtr(conteneurconst UObject*) :811.- Précédents compilés dans le module : même lecture de tableau (
LPModDailies.cpp:114-137), espace de noms nommé (LPModDailiesImpl,LPUserSettingsGi),TWeakObjectPtrd'un type déclaré en avant (LPOutdoorRoomSubsystem.h).
2. Écarts à la SPEC
- E1 (interprétation) Ligne 1 : « vue =
GI.Birdview(classe contenantBirdview) » est codée en ou : égalité avecGI.Birdview, ou nom de classe de la vue contenantBirdview(Birdview_C,CAM-AUDIT.md:15). Conséquence : la carte est reconnue même siGI.Birdviewest nul. Pour l'égalité seule : retirer le second terme (LPCameraModeSubsystem.cpp, ligneif ((Birdview && View == Birdview) || …)). - E2 PC : premier PlayerController du monde du GameInstance (fiche),
GI.PCseulement en repli. Pas de PC ou pas de cible de vue : rien n'est affiché, y compris pour les lignes 2-3 (SexOn,POVOn) qui ne dépendent pas de la vue. - E3 Viewport :
GetGameInstance()->GetGameViewportClient()au lieu deGEngine->GameViewport(modèle LPDirectControlSubsystem) : viewport propre à ce GameInstance (PIE à plusieurs instances) ; ajout refait si le viewport change (pointeur faible), sinon une seule fois. - E4 Ajout : une ligne
LogLifePlay(niveau Log) à chaque changement du libellé affiché, preuve de chargement pour la VAL et l'essai (lp-build§ 9 (8)). Non demandée par la SPEC. - E5 Valeurs choisies (SPEC : « petite taille », « ombre ») : police Regular 12, ombre (1, 1) noire à 70 %, ordre Z 50 (celui du modèle, sans recouvrement : les invites de LPDirectControl sont centrées en bas).
- E6 Menu : partage « par copie » (option du § 3 de la SPEC), LPDirectControlSubsystem non modifié ; le test n'est fait
que lorsqu'un libellé est à afficher (coût du
TObjectIterator<UUserWidget>évité sinon). - E7 Espace de noms nommé
LPCameraModeLocalau lieu d'un espace anonyme :MenuClassesetMenuOnScreenexistent déjà dans l'espace anonyme de LPDirectControlSubsystem.cpp ; en unity build ce serait une redéfinition (lp-build§ 8). - Constat sur la SPEC, non corrigé (aucune correction d'initiative) : la ligne 9 (
Camera: Builder) est inatteignable, carRoom.SceneCamera=GI.ChargenCameras[0](CAM-AUDIT.md:16,CAM-T2-CART.md:95) et la ligne 8 (Camera: Studio) est évaluée avant. Le constructeur affichera doncCamera: Studio(estimé). Correctif possible, à décider : tester un indicateur du constructeur (BuilderOn,CAM-T2-CART.md:66, 182) avant la ligne 8, ou placer la ligne 9 avant la ligne 8. - Constat lié (estimé) : la ligne 7 ne dépend que de
CamC3On; siCamC3Onreste vrai quand la vue passe à une caméra du CharGen, des contacts ou du constructeur, le libellé seraCamera: C3 Room (old)(les menus CharGen_C et ContactMenu_C masquent déjà le texte dans deux de ces cas).
3. Instantané (lot, manifeste)
sans objet : fichiers neufs, rien à sauvegarder (fiche, rubrique 2b) ; Existed=False pour
Source/LifePlay/LPCameraModeSubsystem.h et Source/LifePlay/LPCameraModeSubsystem.cpp (absents avant écriture :
Grep "LPCameraMode|CameraMode" sur Source → No files found, puis création par Write).
4. Ce qui n'a pas été fait
- Aucune compilation (confiée à lp-builder), aucun essai en jeu, aucune vérification en 5.5 (développement 5.5 arrêté).
- Pas de libellés français (SPEC : anglais proposés ; français « si l'utilisateur le préfère »).
- Pas de fonction partagée avec LPDirectControlSubsystem (copie, fiche rubrique 4 et 5).
- Pas d'entrée CHG ni de ticket (orchestrateur, gardien).
- Ligne 9 de la SPEC non réordonnée (§ 2 ci-dessus).
5. Points à confirmer en VAL
- V1 Build LifePlayEditor 5.8 (
Tools/Build.ps1) : code 0,LPCameraModeSubsystem.cppet.gen.cppcompilés,UnrealEditor-LifePlay.dlllié. - V2 Aucun avertissement nouveau, en particulier C4456/C4458/C4459 (masquage de noms) et C4996.
- V3 Unity build complet (pas seulement adaptive) : pas de C2374/C2084/C2995 entre LPCameraModeSubsystem.cpp, LPDirectControlSubsystem.cpp et LPOutdoorRoomSubsystem.cpp.
- V4 Fichiers : LF, sans BOM, ASCII ; MD5 du § 1 inchangés avant commit.
- V5
git status --short -- Source: les 2 fichiers en??; aucun fichier existant modifié par cette fiche (voir Constats : LPOutdoorRoomSubsystem.* modifiés par STG). - V6 En jeu, journal : lignes
LogLifePlay: Indicateur de camera : Camera: …aux changements de mode. - V7 En jeu : texte en bas à gauche, marge 16 px, blanc translucide avec ombre, non cliquable (clics de la souris de pièce inchangés).
- V8 En jeu : texte masqué avec MainMenu, Journal, CityMenu, StatMenu, ContactMenu, Inventory, CharGen, ModManager, BodyShapeMenu, menu Clavier, champ de saisie focalisé.
- V9 En jeu : C (C1 → C2 → C3) donne
C1 First person,C2 Follow,C3 Room (old); sortie de pièceOverview; sexeScene, POVPOV. - V10 En jeu : constructeur affiche
Camera: Studio(ligne 9 inatteignable, § 2) : décision de l'orchestrateur. - V11 Fermeture du jeu et arrêt / relance de PIE : pas de crash, pas d'
Accessed None, texte présent une seule fois après relance.
6. Fichiers à commiter
Dépôt du jeu D:\Game\LifePlay-master 5.8, branche ue5.8 :
- A
Source/LifePlay/LPCameraModeSubsystem.h - A
Source/LifePlay/LPCameraModeSubsystem.cpp - A
Docs/Migration/etat/CAM/CAM-B2c-IMPL.md
Tours : 22 / 40
Constats
- Écriture concurrente pendant la fiche (établi) :
git status --short -- Sourcemontrait au débutM LPDebugSubsystem.cpp,M LPDebugSubsystem.hseulement ; après mes écritures il montre aussiM Source/LifePlay/LPOutdoorRoomSubsystem.cppet.h. Horodatages : LPOutdoorRoomSubsystem.cpp 17:12:31,.h17:12:38 ; mes fichiers 17:13:42 (.h) et 17:14:14 (.cpp) ; le diff (+92 / -2) porte l'en-tête « Lot STG (S-F4, B-SOL / B-DEPL) » (plancherRoom.Box). Ce n'est pas cette fiche (lecture seule de ces fichiers). Le critère 6 de la fiche (« exactement ces 2 fichiers en ?? en plus de l'existant ») se lit donc avec 4M(STG) + 2??(CAM-B2c). Les nouveaux noms de l'espace anonyme de LPOutdoorRoomSubsystem.cpp (FloorPropertyName,IndoorScaleZ) ne rencontrent aucun nom de LPCameraModeSubsystem.cpp (relu, lignes 12-28). - Recherche de noms globaux qui masqueraient mes variables locales en unity build (C4459) :
Grepdes déclarations de niveau 0-1 tabulation surSource/LifePlay/*.cpp: seules des variables locales de fonctions membres, aucune globale homonyme (estimé sans compilation).