224 lines
18 KiB
Markdown
224 lines
18 KiB
Markdown
|
|
# 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.
|