LifePlay-Revival/Docs/Migration/etat/CAM/CAM-COMMUN9-DIAG.md
edujiro5972 8084622450 LifePlay UE 5.8 : état de développement au 2026-10-19
Tickets : REP1-T4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:57:42 +02:00

18 KiB
Raw Blame History

CAM-COMMUN9-DIAG : le couple sort de la pièce et passe sous le plancher pendant la scène (lecture seule, 2026-10-14)

Origine : essai COMMUN-9 (relais de Big Boss). L'utilisateur : « le couple ne doit pas quitter la pièce pendant la scène et se retrouver à l'extérieur ». Sa capture montre le couple sous le plancher, avec le ciel visible. Journal lu sans le modifier : D:\Game\LifePlay_Build_5.8_COMMUN-9_Development\Windows\LifePlay\Saved\Logs\LifePlay.log (10:03 à 10:07 UTC). Sources : témoin « Sexe : touches » (B2p-C et B2p-D), relevés « LPDebug persons » (STG, toutes les 5 s). Aucune écriture, aucun UE.

1. Repères

  • Room en (-3131543, -14967213, -115), échelle (8, 8, 0,2). Dessus du sol (Room_C_0.Box) : Z = -102,2 (relevé LPDebug). Si Box occupe toute la pièce, X va de -3131943 à -3131143 et Y de -14967613 à -14966813 (estimé : 8 m × 8 m centrés sur Room ; à confirmer par les bornes du composant).
  • Lit (NODE_AddStaticMeshComponent-0_38) : dessus à Z = -49,1.
  • Écart racine du maillage / acteur : meshZ = -88. Sur une surface, la racine du maillage est à peu près au niveau de la surface (COMMUN-6 : root=-46, under=…fnt_bed02:-49.1).

2. Chronologie (établi)

Heure Fait Lecture
10:03:41 Couple sur le lit : acteur Z = 42, maillage −46, dessus du lit −49 normal
10:03:43 couple pris (deplacement) … hauteur sur la surface 91 cm (B2p-D) 42 − (−49) = 91 : le tracé vertical a bien touché le lit
10:03:51 Pendant le glisser, acteur Z = −11 (maillage −99) au-dessus du sol normal : −102 + 91
10:03:53 et 54 Pendant le glisser, acteur Z = −99 (maillage −188) anormal : la surface trouvée est à −190, 88 cm sous le dessus du sol. Le tracé vertical a traversé le sol.
10:03:54 couple pose a (-3131448, -14967003, -99) le couple est posé sous le plancher, mais encore dans la pièce en XY
10:03:56 à 10:04:17 La position XY change à chaque seconde où fleches n'est pas nul (+1/+0, +0/+1, +1/+1, +0/-1) ; prise=0 les flèches (P2 de B2p-R : couple sans Maj, voie d'origine de Room, nœud 139) déplacent le couple, sans aucune borne : de X −3131448 à −3132724, soit environ 12 m
10:04:21 X = −3132676 à 7 m hors du bord ouest de la pièce
10:05:35, 10:05:50, 10:06:54 Z : −100, puis −132, −145, −177 ; les deux personnes bougent ensemble ; ni flèches, ni Maj, ni prise dans les relevés d'une seconde ; bouton droit tenu (D=1, MoveCamera=1), donc orbite source non vue (voir § 3c)

Le clic droit tenu sans prise (D=1 prise=0) est l'orbite de la caméra. Ce n'est pas une rotation du couple : le clic n'était pas sur le couple.

3. Causes

a) Sortie de la pièce en XY : les flèches n'ont aucune borne (établi). P2 envoie les flèches sur la voie d'origine de Room (14 et 17 vers 27 et 23, puis ForEach SexPersons → SetActorLocation). Cette voie n'a jamais eu de borne : dans le jeu d'origine, Maj + flèches pouvait aussi sortir le couple de la pièce. P2 la rend plus facile à atteindre, puisque les flèches suffisent.

  • B2p-D (glisser-déposer) est borné au sol de Room.Box, moins 30 cm : la pose de 10:03:54 était dans la pièce.

b) Couple sous le plancher : le tracé vertical de B2p-D traverse le sol (établi pour l'effet, estimé pour la cause).

  • La hauteur prise sur le lit (91 cm) est juste.
  • Au-dessus du sol, le tracé vertical (canal Visibility) a d'abord rendu −102 (Z = −11 à 10:03:51), puis −190 (Z = −99 à 10:03:53). Le composant Box (sol) ne bloque probablement pas le canal Visibility, ou pas sur toute sa surface. Le tracé descend alors jusqu'à un autre objet, 88 cm plus bas.
  • On le vérifiera à l'essai avec la ligne de prise et le témoin (§ 5).

c) Descentes en Z après la pose, sans flèches ni prise (incertain). Trois pas de −32, −13 et −32 cm, sur les deux personnes à la fois. Ils n'arrivent pas au changement d'animation (10:04:56).

  • Candidat 1 : la molette. Si Room.bHidden est vrai, la molette (PC 159 → 69 → ForEach SexPersons → SetActorLocation, nœud 810) déplace le couple sans Maj. Sinon, avec Maj (Room 12 → 24), entre deux relevés. Les pas inégaux font penser à des crans de molette.
  • Candidat 2 : un recalage du jeu (moveToBedIfPossible, voie STG/STE « Show couple »). Les relevés n'en montrent aucune trace à ces heures.
  • La borne dure (§ 4) couvre ces cas, quelle que soit la source. Le témoin (§ 5) la désignera.

4. Correctif proposé : CAM-B2p-E (C++, LPCameraModeSubsystem, aucun asset)

E1, borne dure à chaque image, pendant le sexe, quelle que soit la source. À la fin de TickSexCamera, y compris quand un menu est ouvert, tant que SexOn est vrai, Room.Box valide et Room.bHidden faux (pièce d'intérieur) :

  • pivot du couple borné aux limites XY de Room.Box moins 30 cm ;
  • plancher : pour chaque personne, la racine du maillage (Z du composant Mesh) ne descend jamais sous le dessus de Box − 5 cm. Si elle descend, tout le couple remonte de l'écart, sans jamais descendre ;
  • correction par un seul vecteur appliqué à toutes les SexPersons, ce qui garde le couple entier. Une ligne au journal à chaque correction, au plus une par seconde : Sexe : couple ramene dans la piece de (dx, dy, dz), source probable ….
  • Coût : quelques lectures et un SetActorLocation seulement si une borne est franchie. Il n'y a rien de plus par image quand le couple est dans la pièce.

E2, correction de la source b. Dans B2p-D, la surface trouvée sous le couple est relevée au dessus de Box quand le tracé passe sous le sol : surface = max(impact, dessus du sol) dans les limites XY de la pièce. Le couple posé au sol garde ainsi ses 91 cm.

E3, source a (flèches). Rien à changer dans Room : E1 retient le couple au bord de la pièce. C'est le même comportement que le glisser-déposer.

E4, témoin pour la source c. Le témoin « Sexe : touches » écrit aussi Room.bHidden, la valeur de la molette et Maj. Une ligne Sexe : couple deplace hors prise de (dx, dy, dz) est écrite quand le pivot bouge de plus de 5 cm en une image sans prise, au plus une par seconde, avec l'état des touches.

Hors champ :

  • les cloisons intérieures (seuls les bords du sol comptent) ;
  • les pièces cachées (Room.bHidden vrai, scènes d'extérieur) : la borne ne joue pas, faute de sol de référence. Le témoin écrit une ligne une fois par scène.

5. Estimation et ordre

  • E1 à E4 : environ 80 lignes de C++ dans le fichier CAM, 45 min d'écriture et 20 min de VAL statique par un agent distinct. Pas de jeton UE pour écrire ; compilation au prochain build.
  • Aucun asset touché : ni Room, ni PC, ni GI, ni Person.
  • Risques :
    • une pose légitime dont la racine du maillage passe sous la surface (agenouillé, allongé au sol) serait remontée de quelques centimètres. Marge de 5 cm, à régler à l'essai ;
    • si Box ne couvre pas tout le sol de certaines pièces, la borne XY serait trop serrée. La ligne de journal le montrera.
  • Essais :
    • CAM-64 : flèches jusqu'au mur, le couple s'arrête au bord ;
    • CAM-65 : glisser du lit au sol, le couple reste sur le sol, pas dessous ;
    • CAM-66 : molette et Maj + molette vers le bas, le couple ne passe pas sous le sol ;
    • CAM-67 : changer d'animation pendant la scène, aucun saut sous le sol ;
    • CAM-68 : sortie de scène, plus aucune borne (marche normale).

Décision attendue : GO pour B2p-E (C++ seul), à écrire tout de suite pour le prochain build.

6. COMMUN-10 : B2p-E insuffisant, le couple sort encore par les murs (lecture seule)

Journal : …COMMUN-10_Development\…\LifePlay.log, 10:31 à 10:36 UTC. L'utilisateur : « plus difficile de passer au travers, mais j'y suis quand même arrivé ».

6.1 Ce qui est établi

  • E1 tourne. Le journal a 5 lignes couple ramene dans la piece (10:32:01 à 10:32:24), toutes en Z (+7, +50, +22), pendant des prises (prise=1), avec sol -102, plafond estime 248. La borne du plancher marche, et la condition « pièce cachée » ne l'a pas coupée (Room cachee=0 sur toutes les lignes E4, aucune ligne pas de borne). E1 tourne dans TickSwitchKey, à chaque image, en POV comme en Scene.
  • Aucune correction en XY, alors que le couple a été posé à (-3131066, -14966983) à 10:33:48, soit +477 cm en X du centre de Room. La borne XY vaut Box.Max.X − 30. Si elle n'a pas joué, c'est que Box.Max.X ≥ -3131036, donc le demi-côté de Room.Box dépasse 507 cm : le sol (Box) est plus large que la pièce entre ses murs. L'hypothèse « bornes plus larges que les murs » est donc établie par l'absence de correction ; l'écart exact reste à mesurer.
  • Lecture du dump de Room (getAllComponents, resizeRoom) :
    • la pièce se règle par l'échelle du composant racine (StaticMeshComponent, SetRelativeScale3D) ;
    • AllComponents = la racine, puis ses enfants maillés, dans l'ordre ;
    • resizeRoom ne compense l'échelle qu'à partir de l'indice 6, pour garder les meubles à leur taille. Les indices 0 à 5 sont donc la structure de la pièce (racine, sol, murs, sans doute plafond), qui suit la taille de la pièce. Leurs rôles exacts ne sont pas nommés dans le dump : ils sont à identifier par leurs bornes.
  • E4 donne un faux positif à chaque pose : couple deplace hors prise de (+1, -126, -141) à 10:33:30, au moment même de couple pose. La prise se termine dans la même image que le dernier déplacement du glisser, et le témoin le compte comme « hors prise ».
  • Un vrai déplacement hors prise reste inexpliqué : +211, -14 à 10:32:48, sans touche ni molette. La source c du § 3 (jeu, ou recalage) reste ouverte. La borne la couvrira dès qu'elle portera sur les murs.

6.2 Correctif proposé : CAM-B2p-F (C++, LPCameraModeSubsystem, aucun asset)

  • F1, intérieur réel de la pièce, calculé par une seule fonction utilisée par E1 et par le glisser de B2p-D :
    • la base est la boîte XY du sol (Room.Box), avec le dessus du sol en Z ;
    • on parcourt Room.AllComponents[0..5] (structure de la pièce) et on prend leurs bornes :
      • un mur est haut (plus de 100 cm en Z) et mince (son petit côté horizontal fait moins du quart du grand). Selon son côté par rapport au centre du sol, il resserre la borne : un mur à l'est ramène MaxX à son Min.X, un mur à l'ouest relève MinX à son Max.X, et de même en Y ;
      • un plafond est mince en Z (moins de 50 cm) et à plus de 150 cm au-dessus du sol : la borne haute devient son Min.Z (au lieu des 350 cm estimés) ;
    • repli : sans murs trouvés, la boîte du sol (comme aujourd'hui) ; sans plafond, sol + 350 cm.
    • Pour l'alpha, au cas où les murs ne seraient pas reconnus, la boîte XY est aussi bornée au demi-côté d'échelle de la racine : ±(échelle X ou Y de la racine × 50 cm), c'est-à-dire ±400 cm pour l'échelle 8. C'est la taille de la pièce si le maillage racine est un carré de 100 cm (estimé, à confirmer par la ligne de journal ci-dessous).
  • F2, ligne de journal à la première image du sexe (une fois par scène), avec les bornes retenues : Sexe : bornes du couple X [a, b] Y [c, d] sol z plafond z ; murs trouves n/6, plafond trouve 0|1 ; sol Box X [..] Y [..] ; echelle racine (sx, sy). Elle tranche entre les murs, le sol et l'échelle, au premier essai.
  • F3, même borne pour le glisser (B2p-D) que pour E1 : une seule fonction, aucun écart possible entre les deux.
  • F4, témoin E4 sans faux positif : on ne compte pas l'image où une prise vient de finir (le dernier déplacement du glisser).
  • F5 : E1 tourne déjà à chaque image en POV et en Scene (établi). Rien à changer ; F2 le montre à chaque scène.

6.3 Estimation et risques

  • Environ 70 lignes de C++ : 45 min d'écriture, 20 min de VAL statique (avec le contrôle d'ombrage de tout le fichier). Pas de jeton pour écrire ; compilation au prochain build.
  • Risques :
    • si AllComponents[0..5] ne contient pas les murs dans certaines pièces, on se replie sur le demi-côté d'échelle, qui peut être un peu plus large ou plus étroit que les murs réels. La ligne F2 le dira ;
    • une pièce non rectangulaire (en L) serait bornée par sa boîte englobante ;
    • les meubles et les cloisons intérieures ne sont pas des bornes.
  • Essais :
    • CAM-69 : glisser vers chacun des 4 murs, le couple s'arrête à 30 cm du mur intérieur ;
    • CAM-70 : flèches vers chacun des 4 murs, même chose ;
    • CAM-71 : ligne F2 présente à chaque scène, bornes cohérentes avec la pièce ;
    • CAM-72 : Maj + molette vers le haut, arrêt sous le plafond.

6.4 Couple bloqué dans un meuble ou un mur, et garde de collision de STE (lecture de LPShowCoupleSubsystem.cpp)

  • ULPShowCoupleSubsystem::AfterActors tourne après le tick des acteurs. KeepTogether (l. 750-805) prend le déplacement du meneur depuis sa dernière position sûre (LastSafe) et le passe au résolveur partagé LPCoupleSim::ResolveCoupleMove : balayage de la boîte du couple, 3 passes, dépénétration ; lits franchissables ; la coque Wall (le panneau de GI) est ignorée.
  • Les murs de la pièce sont des composants de Room nommés Wall… : le journal donne bloque par Room_C_0/Wall2. Cela précise F1 : on prend les murs par leur nom (Wall* parmi les composants de Room), avant le repli par indices ou par échelle.
  • Ordre dans une image :
    • B2p-D et E1 (ticker du cœur, avant le monde) téléportent le couple ;
    • le résolveur de STE (après les acteurs) balaie de LastSafe à la nouvelle place, puis bloque ou dépénètre.
  • Comment le couple sort (estimé) :
    • la borne XY de B2p-D (trop large, § 6.1) pose la boîte du couple, qui mesure environ 78 × 46 cm d'après Show couple : boite … etendue, à cheval sur un mur ;
    • le résolveur la dépénètre le long de la normale du mur (normal X=1, profondeur 3), donc vers l'extérieur si le centre est déjà au-delà du plan du mur ;
    • entre deux meubles, le résolveur reste en recouvrement (profondeur 3 à chaque image) et refuse les mouvements : le couple est coincé.
  • Conséquences pour B2p-F :
    • G1, pose libre : avant chaque déplacement de B2p-D, on teste le recouvrement de la boîte du couple à la place visée (OverlapAnyTestByChannel, canal Pawn, Room compris, couple ignoré, lits admis comme STE). Si la place recouvre un meuble ou un mur, le couple ne va pas là ; il reste à la dernière place libre de la prise ;
    • G2, marge des murs = demi-boîte du couple (environ 80 cm, au lieu de 30) pour la borne XY de F1. La boîte ne touche alors jamais le mur, et la dépénétration ne peut plus pousser dehors ;
    • G3, dégagement : une prise qui commence en recouvrement (couple coincé) peut aller vers n'importe quelle place libre (G1 ne teste que la place visée). Mais le résolveur de STE balaie depuis LastSafe, qui est peut-être dans le meuble. Sans aide de STE, il peut refuser ce dégagement. Il faut un petit ajout côté STE (fichier STE) : par exemple une fonction publique NotifyCoupleTeleported() qui reprend LastSafe à la position actuelle, appelée par B2p-D après une pose libre validée par G1. À attribuer à STE par Big Boss.
  • Le refus est déjà en place chez STE pour les déplacements lents : un glisser lent vers un meuble est arrêté par le balayage. G1 ajoute le refus pour les déplacements rapides (téléportation).

6.5 Clavier pris par le champ de filtre du menu des positions

  • De 10:32:22 à 10:33:48, M1e : marche coupee par le menu focus SEditableText toutes les quelques secondes (STG) : le champ « Type keyword to filter » du menu des positions garde le focus clavier.
  • Côté CAM, MenuOnScreen traite déjà un SEditableText qui a le focus comme un menu ouvert. TickSexCamera sort alors tôt : ZQSD, le glisser et le clic droit ne marchent plus, et les touches partent dans le champ, que Slate prend avant le PlayerInput.
  • H1 : pendant le sexe, si un bouton de souris est vu par le PlayerInput (clic dans la vue 3D, pas sur l'interface) et qu'un SEditableText a le focus, on rend le focus au viewport (FSlateApplication::SetAllUserFocusToGameViewport). Ce test passe avant la garde de menu. Une ligne au journal : Sexe : focus clavier rendu a la vue (champ …).
  • Le champ reste utilisable : un clic dedans lui redonne le focus, et la frappe y va jusqu'au prochain clic dans la vue.
  • H2 : à l'entrée en mode Scene (première image), si le champ a le focus et qu'il est vide, on rend le focus au viewport une fois.
  • H1 et H2 n'agissent que pendant le sexe. Hors sexe, la garde M1e de STG (marche coupée quand un champ de texte a le focus) est inchangée.

6.6 Estimation revue de B2p-F (F1 à F5, G1 à G3, H1 et H2)

  • CAM (C++ LPCameraModeSubsystem) : F1 (murs Wall*, avec replis), F2, F3, F4, G1, G2, H1, H2. Environ 160 lignes : 1 h 30 d'écriture, 25 min de VAL statique (avec le contrôle d'ombrage). Pas de jeton pour écrire.
  • STE (fichier STE) : G3, NotifyCoupleTeleported(), environ 10 lignes, chez son propriétaire. Sans G3, le dégagement d'un couple déjà coincé peut rester refusé. Le reste marche sans G3.
  • Essais en plus : CAM-73 (glisser vers un meuble, refus à la place libre la plus proche du curseur), CAM-74 (couple coincé, glisser vers le milieu de la pièce : dégagé, avec G3), CAM-75 (focus dans le champ de filtre, clic dans la vue : ZQSD remarche ; clic dans le champ : la frappe y va).

Décision attendue : GO pour B2p-F (CAM), et attribution de G3 à STE.