26 KiB
CAM-COMMUN3-DIAG : D8 KO, caméra collée à la nuque (2026-10-13)
Demande de Big Boss : quel Wall, pourquoi la tête est dans sa collision, quel correctif parmi (a), (b), (c). Lecture
seule, sans UE ni MCP. Aucune écriture avant GO.
Sources :
- journal partiel
D:\Game\LifePlay_Backup_5.5\COMMUN-3\essais\LifePlay_commun3_partiel_2030_BOSS.log(MD5d42c53f9…, heures UTC = locale − 2 h) ; - dump Room
CAM-B2f-VAL_LPDumpFunction_20261013-195332.txt; - composants Person
CAM-T4_LPDumpComponents_20261011-004910.txt; - carte
ST/STE/STE-D_LPDumpComponents_20261010-113200.txt; - StreetMap_Static
ST/STA/dumps/StreetMap_Static__EventGraph.txt; CAM-B1-IMPL.md(B1-12).
1. Relevé du témoin (23 lignes Temoin C2, 18:25 à 18:29 UTC)
| Objet touché par les deux sondes (Camera et Visibility, toujours identiques) | Lignes | Pièces (largeur de boîte X × Y) |
|---|---|---|
StaticMeshComponent0 de Wall (caché), départ déjà dedans |
16 | 665 × 640 (15), 847 × 815 (1) |
StaticMeshComponent0 de Wall (caché), à 61-131 cm de la tête |
4 | 257 × 1515 (rue, 2), 1028 × 990, 665 × 640 |
| rien | 3 | rue 257 × 1515 (2), 847 × 815, marge de boîte 19 à 37 cm |
Aucune ligne ne touche un personnage (Person_C : 0). |
2. DIAG
Quel Wall (prouvé). Ce n'est pas un mur de Room (Wall1-4, ignorés avec Room par bIgnoreSelf). C'est l'acteur
StaticMeshActor PersistentLevel.Wall de CentralLondon :
- il fait partie des
ShowOnlyActorsdes SceneCapture (STE-D_LPDumpComponents, l. 11) ; GI.Wallle référence ;- c'est le panneau de fond qui montre l'image du lieu :
StreetMap_Static.UpdateWall(Amenity)lui donne la textureAmenityBackgrounds(WallDM, paramètrePNG). Il est caché dès qu'une pièce est affichée : Room B1-12,GI.Wallcaché = NON(Room.bHidden), nœud 88 ; etWallcaché en C1, nœud 438. Le témoin le donne toujourscache=1.
Pourquoi la tête est dedans (prouvé pour le fond, estimé pour la position).
Wallest fixe dans le niveau. La pièce, elle, est toujours posée au même point (Room loc = (-3131543, -14967213, -115)dans tous les relevés du journal COMMUN-2) mais change d'échelle selon le lieu (3,5 × 18, 8 × 8, 12 × 12, 45 × 45). Le panneau traverse donc l'intérieur de certaines pièces : 4 pièces différentes ici.- Le joueur le traverse sans être arrêté : la capsule de
Personignore WorldStatic (profilCustom, écarts Visibility / WorldStatic / Pawn Ignore, dump T4).Wallest unStaticMeshActor, donc WorldStatic (type par défaut, estimé). - Sa collision, invisible mais active, bloque Camera et Visibility. Les sondes partent de la douille
headdéjà dans le panneau : impact à 0 cm,bStartPenetrating. La caméra se place alors à 20 cm de la tête, à hauteur 0 (à 18:28-18:29, joueur immobile, 13 lignes de suite).
Correction du DIAG de COMMUN-2. La cause « PNJ cachés en collision » était fausse. Le témoin ne voit aucun
personnage, et le passage au canal Visibility (B2f) n'a rien changé, puisque Wall bloque aussi ce canal. La vraie
cause de « caméra trop près autour des meubles » est très probablement Wall : le joueur debout près d'un meuble se
trouve dans la bande du panneau. Le passage à Visibility reste neutre et peut rester en place.
Les 3 lignes « rien » (marge de boîte de 19 à 37 cm, rue étroite surtout) relèvent de la boîte B2e. C'est l'effet voulu, « toujours dans la pièce ».
3. Les 3 pistes
| Piste | Effet sur les 23 lignes | Coût | Risque | Avis |
|---|---|---|---|---|
(a) GI.Wall dans les acteurs ignorés des sondes |
les 20 lignes Wall (16 dedans + 4 à distance) |
Room : add_node_pin sur MakeArray_5 + connect_pins VariableGet_260.Wall (getter GI.Wall déjà présent) → nouvelle entrée [2] ; 2 écritures, aucun nœud créé |
nul hors caméra : seule la liste ActorsToIgnore des 3 sondes (459, 499, 505) change ; GI.Wall nul → entrée ignorée |
retenue |
| (b) ignorer un impact « départ déjà dedans » | 16 lignes sur 20 : les 4 Wall à distance restent |
≈ 4-6 nœuds par sonde (BreakHitResult, NOT, AND) × 3 | masque aussi les vrais cas « dedans » ; ne traite pas la cause | non |
| (c) collision des murs cachés en Ignore (Camera, Visibility) | les 20 lignes | 3 voies de masquage de Wall (PC, Room, GI) ou un sous-système C++ ; touche un acteur du niveau |
change le jeu hors caméra (clics, scènes) ; hors périmètre CAM | non pour CAM ; voir § 5 |
4. Correctif proposé : B2g (Room par lp-mcp-bp, plus le témoin C++)
- Instantané
.\Tools\Snapshot.ps1 -Lot CAM-B2g(RoomF2B082D2911D9F7C7BE60C2CF30EE6D5attendu). - Room :
get_node_infossurK2Node_MakeArray_5(entrées [0] PlayerCharacter et [1] CamRoom ; sortie vers 459, 499 et 505) et surK2Node_VariableGet_260(Wall, self ←VariableGet_257.GI) ;add_node_pinsurMakeArray_5, puisconnect_pins260.Wall→ nouvelle entrée [2] ;- relecture,
is_dirty= vrai, compilation stricte,save_assetsde Room seul, MD5 différent.
- Témoin C++ (
LPCameraModeSubsystem.cpp,WitnessC2) : ajouterGI.Wallaux acteurs ignorés, pour qu'il reste le miroir de la sonde de Room (2 lignes : lecture deWallsur GI,AddIgnoredActor).
- VAL :
- V5 :
MakeArray_5a 3 entrées, [2] ←260.Wall, aucune autre différence ; - V6 = référence ;
- V7 au prochain build commun.
- V5 :
- Essai : rejouer D8 dans la même chambre (665 × 640), près du meuble, debout immobile. La caméra reste derrière, à sa
distance. Les lignes
Temoin C2ne doivent plus citerWall. - Barème :
- Room : a0 b1 c0 d0 e1 f0 = 2 → N1, ajusté à N3 (MCP par
lp-mcp-bp) ; S = C3 1 + f 0 = 1 : une fiche ; - C++ : a0 b0 c0 d0 e1 f0 = 1 → N1 ; S = 0.
- Room : a0 b1 c0 d0 e1 f0 = 2 → N1, ajusté à N3 (MCP par
5. Hors CAM, à signaler (avis seulement)
Wall caché garde une collision qui bloque Visibility au milieu de certaines pièces. Les clics à la souris
(GetHitResultUnderCursor, canal Visibility par défaut) pourraient donc buter sur ce panneau invisible, dans la même
bande. C'est un défaut probable du jeu d'origine, non mesuré ici. S'il est confirmé, la piste (c), par exemple
Wall en Ignore pour Visibility et Camera pendant qu'il est caché, relève du lot qui tient les clics ou le décor, pas
de CAM.
6. Second cas (18:30:11, 18:30:17, 18:30:23 UTC ; lignes relayées par Big Boss, après la copie partielle)
Signature : « caméra à 23 cm de la tête (hauteur +22) ; sonde Camera : rien ; sonde Visibility : rien ; boîte C2 :
marge 149 cm (largeur X 847, Y 815) ». À 18:30:05, c'était encore le cas « Wall, départ déjà dedans ».
Hypothèses de Big Boss écartées (dump de Room après B2f) :
- distance restée au minimum après le repli : non.
C2Targetn'a pas de mémoire.UpdateRoomCamappelleComputeC2Target(467) à chaque passage de la minuterie, et la cible est recalculée depuis la tête (61, 62, puis 66 en repli). Seule la poursuiteVInterpTo(468, vitesse 8) lisse le trajet : environ 0,3 s pour combler 90 %, pas 12 s. - molette : non.
C2Distest borné entre −75 et +125 autour de 200 cm, donc au moins 125 cm, jamais 23. - boîte B2e : non. La marge est de 149 cm.
Cause estimée : le même Wall, cette fois juste derrière la tête et non autour d'elle.
- La sonde principale 459 va de la tête vers la cible, derrière la rotation de contrôle. Elle touche
Wallà quelques centimètres. La cible devient l'impact + normale × 20 (61), donc à moins de 80 cm. - Le repli s'enclenche (95, seuil 80). La sonde 505 va de la tête vers « tête + 100 en Z + 60 cm vers l'arrière » (24, 23, 25). Elle traverse encore le panneau, juste derrière. La cible devient l'impact + normale × 20 (27, 66) : un point à environ 20 cm de la tête et un peu au-dessus. C'est exactement la signature : 23 cm, hauteur +22.
- Le témoin ne voit rien parce qu'il sonde vers la caméra, à plat. La caméra est presque à la verticale de la tête, légèrement ramenée vers l'avant par la normale × 20. La sonde part donc à l'opposé du panneau. Le témoin n'est pas faux, mais il est aveugle à ce cas : il ne refait pas le trajet de la sonde 459.
- Statut : estimé. Il est cohérent avec la position du joueur juste après le cas « dedans » de 18:30:05 : il en sort de quelques centimètres et le panneau reste derrière lui. Il est à confirmer sur le journal définitif, ou par le témoin corrigé ci-dessous.
Effet du correctif (a) : les 3 sondes (459, 499, 505) partagent MakeArray_5. Ignorer GI.Wall couvre donc aussi
ce second cas.
Complément au témoin C++ (B2g) pour que le cas devienne prouvable :
- sonder aussi dans l'axe de la sonde 459 : à plat, vers l'arrière de la rotation de contrôle du PC, sur 250 cm ;
- journaliser la distance tête →
Room.C2Target. Une cible proche avec une sonde vers l'arrière qui touche désigne l'obstacle. Une cible lointaine avec une caméra proche désignerait la poursuite. Barème inchangé : N1, S = 0.
7. KO C1 : « la souris ne fait plus tourner la vue » (vers 18:37:50 UTC)
DIAG (prouvé par le dump de Room après B2f et par l'historique git).
- Ce n'est pas une régression de B2d, et l'orientation vers la marche n'est pas de B2d.
bOrientRotationToMovement = trueetbUseControllerRotationYaw = falsesont posés dansLPDirectControlSubsystem::Walkdepuis le commit d'origine5e901be(Proximité).git log -S bOrientRotationToMovementne donne que ce commit. Le diff non commité de STG (3a, 3b) n'y touche pas.- En C1, la souris n'a jamais tourné la vue. C'est la décision Q11 de la SPEC (« C1 masque cheveux, soleil, mur ; pas de regard à la souris »).
- Dans Room,
CircleCamera(souris) etLeftRight(flèches) ne tournent la rotation de contrôle qu'en C2 (IfThenElse_96/_97, condition PO_8 : vue =CamRoom). Hors C2, sans constructeur, sexe ni espace (IfThenElse_26, OR 19), la brancheelseest vide. Elle l'était déjà avant B2d.
- Ce que voit le joueur en C1 :
- la vue est attachée au maillage, au niveau de la tête (B1-3) : elle tourne seulement avec le corps ;
- le corps se tourne vers la marche (
bOrientRotationToMovement) ; - la marche suit le lacet de la rotation de contrôle (
Walk, l. 908), qui ne change qu'en C2 (souris, flèches,PlaceC2). En C1, on ne choisit donc la direction du regard qu'en marchant. Après Q ou D, le corps regarde de côté, mais Z ramène vers l'axe de contrôle.
- La piste « rétablir
bUseControllerRotationYaw = true» ne marcherait pas (estimé fort). Le joueur n'est pas possédé par le PC : la marche tourne en « physique sans contrôleur »,bRunPhysicsWithNoController(Walk, l. 875-879 ; la marche ne fonctionne que grâce à ce réglage).bUseControllerRotationYawn'agit que parFaceRotation, appelée par le contrôleur du pion possédé. Sans contrôleur, le corps ne suivrait pas la souris. - Autre point :
WalkremetbOrientRotationToMovementà vrai à chaque passage où il est faux (l. 888-892). Le couper ailleurs, dans Room par exemple, serait annulé à l'image suivante.
Correctif proposé : regard horizontal à la souris en C1, comme un jeu à la première personne. Il se fait en deux parties qui vont ensemble.
- Room (CAM,
lp-mcp-bp) : la souris et les flèches gauche/droite tournent la rotation de contrôle en C1 aussi.- (N)
BooleanOR: A ←PromotableOperator_8(vue =CamRoom), B ←VariableGet_269.CamC1On; - sortie →
IfThenElse_96.ConditionetIfThenElse_97.Condition(remplace PO_8 sur ces deux seules entrées) ; - PO_8 reste relié à 91, 98, 99 et 100 : molette et flèches haut/bas inchangées hors C2. 1 nœud, 4 liens. Barème : a0 b1 c0 d0 e1 f1 = 3 → N1, ajusté à N3 (MCP) ; S = C3 1 + f 1 = 2 < 3. Peut passer dans la même ouverture d'éditeur que B2g.
- (N)
LPDirectControlSubsystem::Walk(fichier STG, correctif exact) : en C1, le corps suit le lacet de contrôle et n'est plus orienté par la marche. En sortant de C1, on revient à l'orientation vers la marche.
// dans Walk, a la place du bloc « if (!Move->bOrientRotationToMovement) { ... } » (l. 888-892)
const bool bFirstPerson = FirstPersonView(GI, Pawn, PC); // C1 : Room.CamC1On et vue = le joueur
if (Move->bOrientRotationToMovement == bFirstPerson)
{
Move->bOrientRotationToMovement = !bFirstPerson;
Character->bUseControllerRotationYaw = false; // sans effet sans controleur ; garde l'etat d'origine
}
if (bFirstPerson)
{
// C1 : le corps (et la vue attachee a la tete) suit le lacet de la souris, a chaque image.
Character->SetActorRotation(FRotator(0.f, PC->GetControlRotation().Yaw, 0.f));
}
// espace anonyme, a cote de ScenePlaying
bool FirstPersonView(const UObject* GI, const APawn* Pawn, const APlayerController* PC)
{
const FObjectPropertyBase* RoomProp = GI ? CastField<FObjectPropertyBase>(GI->GetClass()->FindPropertyByName(TEXT("Room"))) : nullptr;
const UObject* Room = RoomProp ? RoomProp->GetObjectPropertyValue_InContainer(GI) : nullptr;
const FBoolProperty* C1 = IsValid(Room) ? CastField<FBoolProperty>(Room->GetClass()->FindPropertyByName(TEXT("CamC1On"))) : nullptr;
return C1 && C1->GetPropertyValue_InContainer(Room) && PC && PC->GetViewTarget() == Pawn;
}
- En entrant en C1 par C, le corps prend le lacet de contrôle, donc la direction où regardait C2. La vue reste ainsi dans l'axe de la caméra précédente. Aucun alignement n'est nécessaire.
- Pas de regard vertical (tangage) dans ce correctif : il faudrait tourner
FirstPersonSM. C'est à décider à part. - Barème STG : a0 b1 c0 d1 e1 f1 = 4 → N1 ; S = 0 (code exact) + 1 = 1.
- Essai :
- en C1, la souris et les flèches gauche/droite tournent la vue sur place ;
- Z avance là où l'on regarde, Q et D font un pas de côté sans tourner la vue ;
- en C2, rien ne change ;
- en revenant en C1, la vue regarde dans l'axe de la caméra C2.
- Dépendance : sans la partie 1, la partie 2 fige le corps sur un lacet que rien ne change en C1. Les deux parties doivent entrer dans le même build.
8. Troisième cas (session 2, joueur assis, 18:54:08-20) et géométrie de Wall (prouvée)
Géométrie de Wall (prouvée, deux sources concordantes) :
- relevé de la carte
portage55/L6f/L6f_LPDumpComponents_20260930-112932.txt(-Filter=Wall) :StaticMesh = /Engine/BasicShapes/Cube,BodyInstance = (ObjectType=ECC_WorldStatic, CollisionProfileName="BlockAll"),RelativeLocation = (-3131490, -14967219, 26),RelativeScale3D = (0.1, 12.5625, 5.75); - boîte journalisée en jeu par ShowCouple (« coque Wall ignorée », journal COMMUN-2) :
Min = (-3131495, -14967847.1, -261.5),Max = (-3131485, -14966590.9, 313.5).
C'est une plaque verticale de 10 cm d'épaisseur (X), longue de 12,56 m (Y) et haute de 5,75 m. Elle est fixe et
se trouve à 53 cm du centre de la pièce (Room toujours en X = -3131543), parallèle à Y. Elle traverse donc
toutes les pièces, pas seulement certaines (correction du § 2). Elle est cachée, mais BlockAll bloque Camera,
Visibility et tout le reste. Le joueur la traverse, car sa capsule ignore WorldStatic. ShowCouple l'ignorait déjà
comme « coque ».
Recoupement avec le témoin (session 1, MD5 27e654cc…) :
- la longue série « départ déjà dedans » de 18:28:08 à 18:29:21 a lieu joueur immobile en X = -3131499,6 : dans la plaque, à 5 cm de la face X = -3131495 ;
- à 18:30:11-23 (« rien », 23 cm, +22) puis 18:30:29 (« dedans », même caméra), le joueur est immobile en X = -3131522,9 : à 28 cm de la face, la tête oscille au bord de la plaque ;
- les autres lignes ont une position relevée jusqu'à 5 s plus tôt (vidage périodique), le joueur étant en marche : elles ne se comparent pas.
Le troisième cas est le même mécanisme que le § 6 : la plaque juste derrière la tête.
- La sonde 459 touche la plaque à quelques centimètres derrière, et la cible passe sous 80 cm.
- Le repli 505 (haut 100, arrière 60) touche encore la plaque. Si la face est à environ 35 cm derrière la tête, la sphère de 20 cm la touche à environ 15 cm en arrière et 25 cm en haut. Avec la normale × 20 vers le joueur, on obtient environ 25 cm de la tête, hauteur +25 : la signature « 26 cm, +26 » est retrouvée.
- Assis, la tête est plus basse, mais le calcul part de la douille
headdu maillage (455, et pareil pour le témoin). Les pistes « point de tête lu sur la capsule », « position assise décalée » et « tangage de C2 » sont donc écartées. Le tangage n'existe pas :MakeRotator(0, 0, lacet). - Le témoin dit « rien » parce qu'il sonde à plat vers la caméra. Ici, elle est presque à la verticale de la tête et un peu en avant, à cause de la normale × 20 : la sonde part à l'opposé de la plaque.
- Contrôle à faire au journal définitif de la session 2 : X du joueur à 18:54 entre environ -3131560 et -3131420 (plaque à ±70 cm, selon la direction du regard). Si X sort nettement de cette bande, l'hypothèse tombe et le cas reste ouvert.
Le correctif (a) couvre les trois cas. Les 3 sondes (459, 499, 505) partagent MakeArray_5. Avec GI.Wall
ignoré, ni la sonde principale ni le repli ne voient plus la plaque. Rien d'autre que la plaque ne bloque Visibility
dans la pièce : les personnages l'ignorent, et Room est ignoré par bIgnoreSelf.
- Variante plus robuste, au choix de Big Boss : ignorer tout acteur caché dans les sondes. Il faudrait un filtre
sur
HitActor.bHiddenet un nouveau balayage, ce qui fait bien plus de nœuds. Non retenue :Wallest le seul cas relevé.
Conséquence hors CAM (renforce le § 5) : une paroi invisible et BlockAll coupe chaque pièce en deux, à 53 cm
du centre. Pour la marche, le joueur ne la sent pas (WorldStatic ignoré). En revanche, tout tracé Visibility, comme
les clics, ou WorldStatic, comme la sonde de ShowCouple qui l'ignore déjà, peut buter dessus. Il faudrait la passer
en NoCollision, puisqu'elle ne sert que de fond aux SceneCapture, mais c'est une décision hors CAM : acteur du
niveau, lot de décor ou STG.
9. Finalisation sur les journaux définitifs (bilan etat\BOSS\COMMUN-3-BILAN.md)
Journaux lus :
- session 1 :
LifePlay_commun3_session1_definitif_BOSS.log(27e654cc…, 275 relevésRoom loc) ; - session 2 :
LifePlay_commun3_session2_ferme_BOSS.log(61e37cf3…, 164 relevésRoom loc). Dans les deux sessions, Room est toujours en (-3131543, -14967213, -115).
D8 cas 1 et 2 : prouvés, cause GI.Wall
Voir le § 8. La plaque est fixe : aucun Blueprint relevé ne la déplace. GI, PC, Room et StreetMap ne font que la cacher, changer sa visibilité ou son matériau (dumps lus). Les cas « dedans » relevés loin de la plaque ont une position vieille de 1 à 4 s, joueur en marche ou changement de pièce (18:56:54-59 en session 2) : ils ne s'y opposent pas.
D8 cas 3 (session 2, 18:53:20 à 18:54:38 UTC, assis) : mécanisme prouvé par élimination, objet probable
- Le joueur (Bridget) est immobile pendant 80 s, en X = -3131579,5, Y = -14967396 (
fnt_chair06-f-0-sit,_48). La caméra reste stable, à 26-27 cm de la tête et hauteur +26 (14 lignes). - Une sonde a forcément touché. Sans impact, la cible est à au moins 125 cm (
C2Distborné) et la caméra la rejoint en environ 0,3 s.C2Scriptedn'est jamais mis à vrai (B4 non fait, seule écriture = faux). La boîte a une marge de 135 cm. Le repli sans impact place la cible à environ 117 cm. Seul un impact suivi du repli donne « 26 cm, +26 ». - Ce qui peut bloquer Visibility à moins de 80 cm :
- Room : ignoré par
bIgnoreSelf; - le joueur et
CamRoom: ignorés ; - les personnages : capsule et maillage ignorent Visibility, et le plus proche, Laura, visible, est à 187 cm ; les PNJ cachés sont à 212 cm et plus ;
- il ne reste que la plaque
Wall, à 84 cm du centre de la capsule, dans l'axe X.
- Room : ignoré par
- Point non mesuré : la tête du personnage assis est-elle décalée d'environ 50 cm vers la plaque par rapport à la capsule ? C'est la condition géométrique pour obtenir 26 cm, +26. Le journal ne donne pas la position de la tête.
- Le témoin dit « rien », car il sonde vers la caméra, presque à la verticale, et pas dans l'axe de la sonde 459.
- Statut : probable. Le correctif (a) le couvre si l'objet est bien
Wall. Le témoin complété (§ 10, C) le tranchera à COMMUN-4 : position de la tête, décalage par rapport à la capsule, distance de la cible et sonde dans l'axe de 459.
C1, souris : voir le § 7 (prouvé). Correctif en deux parties, Room (CAM) et Walk (STG).
10. Correctifs exacts pour COMMUN-4 (aucune écriture avant GO)
| Id | Fichier | MD5 attendu avant écriture | Écrit par | Jeton |
|---|---|---|---|---|
| A. B2g (D8) | Content/BPs/Room.uasset |
F2B082D2911D9F7C7BE60C2CF30EE6D5 |
lp-mcp-bp |
UE |
| B. B2h (C1, partie Room) | Content/BPs/Room.uasset (même ouverture que A) |
idem, puis MD5 après A et B | lp-mcp-bp |
UE |
| C. témoin C2 complété | Source/LifePlay/LPCameraModeSubsystem.cpp |
1DE73AA932AF2A056E1B8528CED4DCAB (.h 84F9BA30… inchangé) |
session CAM | aucun (compilé au build) |
D. C1, partie Walk |
Source/LifePlay/LPDirectControlSubsystem.cpp (STG) |
827F19C0B7A78BDF578ACF4AE6C2289D (relevé du 2026-10-13, état STG non commité) |
STG | aucun (compilé au build) |
GI (E64B5B37…) et Person (8668A47C…) ne sont pas touchés. |
A. B2g : GI.Wall ignoré par les 3 sondes de C2. Instantané .\Tools\Snapshot.ps1 -Lot CAM-B2g -Path Content\BPs\Room.uasset. Préfixe /Game/BPs/Room.Room:EventGraph., un appel MCP par message :
get_node_infosK2Node_MakeArray_5: entrées [0] ←VariableGet_261.PlayerCharacter, [1] ←VariableGet_268.CamRoom; sortieArray→ 459, 499, 505.ActorsToIgnore. EtK2Node_VariableGet_260:Wall, self ←VariableGet_257.GI, sortie → 88 et 438.self.add_node_pinK2Node_MakeArray_5→ nouvelle entrée [2] (relever son PinID).connect_pins260.Wall(sortie) →MakeArray_5.[2].- Relecture des 3 entrées et des 3 sorties de
MakeArray_5, puis de 88 et 438 (liens de 260 conservés). B ne crée ni ne supprime de nœud. Si elle vient seule, faire la séquencecreate_node/delete_noded'une Branche isolée avant l'enregistrement (amendement B2f-a), siis_dirtyest faux.
B. B2h : en C1, la souris et les flèches gauche/droite tournent la rotation de contrôle (§ 7, partie 1).
5. create_node du OU booléen. Même type que K2Node_CommutativeAssociativeBinaryOperator_19 (BooleanOR) :
prendre le type_id par find_node_types (filtre « OR »). 2 entrées A et B.
6. connect_pins PromotableOperator_8.ReturnValue → OR.A ; VariableGet_269.CamC1On → OR.B.
7. connect_pins OR.ReturnValue → IfThenElse_96.Condition, puis → IfThenElse_97.Condition.
connect_pins remplace le lien d'entrée existant (PO_8) sur ces deux seules conditions.
8. Relecture :
- PO_8 reste relié à 91, 98, 99, 100 et OR.A, et ne l'est plus à 96 ni 97 (amendement E1 : 100 =
DownUp, hauteur de C2, omis dans la première liste ; écritures inchangées) ; - 269 garde ses liens (77, 82, 84) et ajoute OR.B ;
- 96.then → 516 et 97.then → 518 sont inchangés.
- Pour A et B :
is_dirty= vrai, compilation stricte,save_assetsde Room seul, MD5 différent deF2B082D2. VAL : V5, avec seulement ces différences (MakeArray_5[2], 1 nœud OR, conditions de 96 et 97), Room = 1261 nœuds ; V6 = référence. Barème A + B : a0 b1 c0 d0 e1 f1 = 3 → N1, ajusté à N3 (MCP) ; S = C3 1 + f 1 = 2 < 3 : une fiche.
C. Témoin C2 complété (LPCameraModeSubsystem.cpp, code exact) :
// LPCameraModeLocal
const FName GIWall(TEXT("Wall"));
const FName RoomC2Target(TEXT("C2Target"));
// WitnessC2, apres Query.AddIgnoredActor(Cam) : meme liste que MakeArray_5 apres B2g
if (AActor* Wall = Cast<AActor>(LPCameraModeLocal::ReadObject(GI, LPCameraModeLocal::GIWall)))
{
Query.AddIgnoredActor(Wall);
}
// Probe prend la direction en parametre : auto Probe = [&](ECollisionChannel Channel, const FVector& Direction) -> FString
const FString CameraText = Probe(ECC_Camera, Dir);
const FString VisibilityText = Probe(ECC_Visibility, Dir);
// Axe de la sonde 459 : a plat, derriere la rotation de controle du PC.
const APlayerController* PC = World->GetFirstPlayerController();
const FVector Back = PC ? -FRotationMatrix(FRotator(0.f, PC->GetControlRotation().Yaw, 0.f)).GetUnitAxis(EAxis::X) : -Player->GetActorForwardVector();
const FString BackText = Probe(ECC_Visibility, Back);
FVector Target;
const FString TargetText = LPCameraModeLocal::ReadVector(Room, LPCameraModeLocal::RoomC2Target, Target) ? FString::Printf(TEXT("%.0f cm"), FVector::Dist(Head, Target)) : FString(TEXT("illisible"));
const FVector Offset = Head - Player->GetActorLocation();
UE_LOG(LogLifePlay, Log, TEXT("Temoin C2 : camera a %.0f cm de la tete (hauteur %+.0f) ; cible C2 a %s ; tete (%.0f, %.0f), decalage capsule %.0f cm ; vers la camera, Camera : %s, Visibility : %s ; vers l'arriere, Visibility : %s ; boite C2 : %s"),
Distance, CamLoc.Z - Head.Z, *TargetText, Head.X, Head.Y, Offset.Size2D(), *CameraText, *VisibilityText, *BackText, *BoxText);
Sauvegarde Backup_5.5\CAM-B2g\Source\LifePlay\ avant modification. Barème : N1 ; S = 0.
D. Walk, partie STG : le code exact est au § 7. Le bloc à remplacer est maintenant aux l. 935-939 de la
version 827F19C0 : if (!Move->bOrientRotationToMovement) { … }. La lecture de GI et PC se trouve en tête de
Walk (l. 908 et suivantes). D n'a de sens qu'avec B : il faut les mettre dans le même build.
Cas de test pour COMMUN-4 :
- D8 : rejouer la chambre et le joueur assis. Aucune ligne
Temoin C2sous 100 cm hors des rues étroites. Si une ligne reste, elle donne la cible, la tête et la sonde vers l'arrière. - C1 : la souris et les flèches gauche/droite tournent la vue ; Z avance là où l'on regarde ; C2 est inchangé.