368 lines
30 KiB
Markdown
368 lines
30 KiB
Markdown
|
|
# CAM-COMMUN6-DIAG : caméra immobile en mode Scene pendant le sexe (lecture seule, sans UE, 2026-10-14)
|
|||
|
|
|
|||
|
|
Origine : essai COMMUN-6 (relais de Big Boss). L'utilisateur : « J'ai perdu à nouveau le droit de déplacer la caméra
|
|||
|
|
dans la scène de sexe ». Journal lu sans le modifier :
|
|||
|
|
`D:\Game\LifePlay_Build_5.8_COMMUN-6_Development\Windows\LifePlay\Saved\Logs\LifePlay.log` (05:11 à 05:18 UTC).
|
|||
|
|
Sources : dumps de la VAL B2kmn (Room `CAM-B2kmn-VAL_LPDumpFunction_20261014-011706.txt`, PC
|
|||
|
|
`…-011816.txt`), état actuel (Room `3A451FDD`, PC `F45BE57A`). Aucune écriture, aucun appel MCP.
|
|||
|
|
|
|||
|
|
## 0. Ordre de traitement (priorité de l'utilisateur : « injouable à cause de C1 »)
|
|||
|
|
| Rang | Défaut | Section | Cause | Correctif | Fiche | Avant ORG4 ? |
|
|||
|
|
|---|---|---|---|---|---|---|
|
|||
|
|
| 1 | Après CharGen : C bloqué, souris C1 sans effet | § 10 | établie pour `SpaceOn` (GI `ShowRender` → 233 ; `CloseCharGen` en cours de partie ne le remet pas) ; souris : H-M (`MainMenuOn` resté vrai), à prouver | B2r : C++ CAM, remet `SpaceOn` (et `MainMenuOn` si le menu est fermé) à la sortie de CharGen ; témoins étendus | `CAM-B2r-FICHE.md` | **oui** : environ 45 min, plus 10 min de compilation, sans éditeur |
|
|||
|
|
| 2 | C1 à côté de la tête après un lever ; à-coup à la sortie de CharGen | § 9, § 10.3 | orientation de C1 figée à l'entrée (la minuterie B2k tourne et ne recale que la position) ; pose prise une image avant le retour de la vue | B2s : P5 (orientation à chaque passage) + P6 (pose avant `434`) | `CAM-B2s-FICHE.md` | **oui** : environ 35 min d'éditeur, plus 15 min de VAL |
|
|||
|
|
| 3 | Vue C1 au plafond au retour d'une scène | § 7 | même cause que 2 (pose prise sur la tête couchée de fin de scène) | B2s, P5 | `CAM-B2s-FICHE.md` | avec 2 |
|
|||
|
|
| 4 | Maj + souris pendant une scène lancée depuis C1 | § 6 | pas de défaut de code trouvé ; POV hors voie Room par conception ; `MoveCamera` requis | B2p, P2 (flèches sans Maj) + témoin | `CAM-B2p-SPEC.md` | non |
|
|||
|
|
| 5 | Personnages assis éliminés par le rendu ; caméra immobile en Scene ; ZQSD et flèches | § 8, § 2-3, SPEC | bornes de pose de référence ; Q8 + B2i | B2q (lot à attribuer) ; B2p (P1, P2, P3) | `CAM-B2p-SPEC.md` | non |
|
|||
|
|
|
|||
|
|
B2r et B2s se suivent dans un seul jeton UE : compilation C++ (B2r), puis éditeur MCP (B2s), puis VAL. Les fichiers
|
|||
|
|
touchés sont distincts : `LPCameraModeSubsystem.*` et `Room.uasset`.
|
|||
|
|
|
|||
|
|
## 1. Ce que dit le journal
|
|||
|
|
| Heure | Ligne | Lecture |
|
|||
|
|
|---|---|---|
|
|||
|
|
| 05:12:30 | C : C2 → C3, vue `CameraScene` | `CameraScene` = `ChargenCameras[0]` = `Room.SceneCamera` (C3 « old ») |
|
|||
|
|
| 05:12:33 | C : C3 → C1, `CamC1On=1`, `C1Hidden=1` | vue `PlayerCharacter` à l'image suivante |
|
|||
|
|
| 05:12:39 | « Camera: Scene » | entrée en sexe **depuis C1** ; aucun `SetViewTarget` à l'entrée (`CAM-COMMUN4-DIAG.md` § 2) : la vue reste `PlayerCharacter` |
|
|||
|
|
| 05:12:43 | C → POV, vue `PlayerCharacter` | POV de `SexPersons[0]` (le MC) |
|
|||
|
|
| 05:12:53 | C → POV, vue `Person_C_2147481881` | POV du partenaire |
|
|||
|
|
| 05:13:04 | C → Scene, vue **`CameraActor_2147480656`**, `C1Hidden` 1 → 0 | `CameraActor_…` = **`CamRoom`**, la caméra C2 (même acteur qu'à 05:12:08 en C2 ; cf. `CAM-COMMUN5-DIAG.md` § 0) |
|
|||
|
|
| 05:13:18 à 05:15:11 | même cycle | à chaque retour en Scene : `CamRoom` |
|
|||
|
|
| 05:18:57 | « Camera: C1 First person » | après la scène, C1 revient (fin de sexe, crochet B1-11 de GI : `2699` → `ApplyRoomCamera`, `SexOn` faux) |
|
|||
|
|
|
|||
|
|
En mode Scene, la vue n'est donc **jamais** `SceneCamera` : d'abord `PlayerCharacter` (vue C1 conservée à
|
|||
|
|
l'entrée), puis `CamRoom` après chaque passage POV → Scene.
|
|||
|
|
|
|||
|
|
## 2. Cause (prouvée par les dumps)
|
|||
|
|
Deux choses s'additionnent.
|
|||
|
|
|
|||
|
|
**a) La vue pendant le sexe est la caméra C2 (décision Q8, B1-2 et B1-8).**
|
|||
|
|
- PC, retour en Scene : `VariableSet_12` (`SexCameraIndex` = 0) → `1800` → `353`
|
|||
|
|
`SetViewTargetWithBlend(ChargenCameras[0])` → **`140` `Room.ApplyRoomCamera`** (B1-8).
|
|||
|
|
- Room, `ApplyRoomCamera` (`CustomEvent_43`) → `77` (`CamC1On`) vrai → `78` (`SexOn`) vrai → `VariableSet_63`
|
|||
|
|
(`C2Scripted` = faux) → `465` `PlaceC2` → `466` `SetViewTargetWithBlend(CamRoom)` → `94` `RestoreC1` (d'où
|
|||
|
|
`C1Hidden` = 0) → `329` minuterie. Si `CamC1On` est faux et `CamC3On` faux (mode C2), `79.else` mène au même
|
|||
|
|
`VariableSet_63`. **Seul le mode C3** prend `79.then` → `394` `SetViewTargetWithBlend(ChargenCameras[0])`.
|
|||
|
|
- Minuterie `UpdateRoomCam` : `91` (vue = `CamRoom`) vrai → `92` (`CamC3On` faux) → `93` (`C2Scripted` faux) →
|
|||
|
|
`467` : `CamRoom` suit la tête du joueur, **sans garde `SexOn`**.
|
|||
|
|
|
|||
|
|
**b) La souris sans Maj fait tourner `SceneCamera`, qui n'est pas en vue (B2i).**
|
|||
|
|
- PC, souris X pendant le sexe : `InputAxisEvent_0` → `244` → `VariableSet_27` (`leftright`) → `73`
|
|||
|
|
(`MoveCamera`) → `37` → `101` (`SexOn`) vrai → `75` (`SexCameraIndex` = 0) vrai → `71` (`Room.bHidden`) faux →
|
|||
|
|
`499` `Birdview.CircleCamera(leftright)`.
|
|||
|
|
- Room, `CircleCamera` (`CustomEvent_1`) → `96` : condition `AND_61` = (`OR_60` (vue = `CamRoom` OU `CamC1On`))
|
|||
|
|
ET **`NOT SexOn` (`453`, B2i)**. Pendant le sexe, 96 est toujours faux → `26` → `19` (`MoveObject`, Maj) faux →
|
|||
|
|
`149` `SetActorRotation(SceneCamera)` → B2n (orbite de `SceneCamera`). La même garde ferme 97 (`AND_61`) et
|
|||
|
|
98, 99, 100 (`AND_62`).
|
|||
|
|
- Avant B2i, avec la vue sur `CamRoom`, 96 était vrai et la souris faisait tourner `CamRoom` (C2) : la caméra
|
|||
|
|
bougeait, mais Maj ne déplaçait plus les personnages (défaut corrigé par B2i). **B2i a fermé la voie C2 pendant
|
|||
|
|
le sexe, alors que Q8 garde la vue sur la caméra C2.** Rien de visible ne répond plus à la souris en mode Scene.
|
|||
|
|
|
|||
|
|
**Pourquoi COMMUN-5 n'a rien montré** : le cas H1 portait sur Maj + souris (personnages), qui marche. La scène
|
|||
|
|
lancée depuis C2 a exactement le même défaut (vue `CamRoom`, souris vers `SceneCamera`). Le départ depuis C1 n'est
|
|||
|
|
pas la cause : il change seulement la vue de la première phase (`PlayerCharacter` au lieu de `CamRoom`).
|
|||
|
|
|
|||
|
|
**Hors de cause** :
|
|||
|
|
- STG : `LPDirectControlSubsystem` s'arrête pendant le sexe (`ScenePlaying`, `.cpp:759` et `:889`) ;
|
|||
|
|
- B2m : le POV passe par `75.else` → `136` → `204`, sans lien avec le mode Scene ;
|
|||
|
|
- B2k : sa branche est derrière `81` (`SexOn` faux) ;
|
|||
|
|
- B2n : il est correct, mais il fait tourner une caméra qui n'est pas en vue.
|
|||
|
|
|
|||
|
|
## 3. Correctif proposé (Room seul, fiche lp-mcp-bp « B2p ») : option A recommandée
|
|||
|
|
**Option A : pendant le sexe, la vue Scene est `SceneCamera`, comme dans le jeu d'origine.** Cela revient sur Q8
|
|||
|
|
(décision de l'utilisateur : « étape hors POV = caméra de pièce, C2 si le mode est C1 »). C'est donc à l'utilisateur
|
|||
|
|
de décider. L'option A rend B2n utile (orbite autour du couple) et règle aussi la limite B2o (vue de la première
|
|||
|
|
phase).
|
|||
|
|
- E1 : `ApplyRoomCamera` : Branche S1 (`VariableGet_258.SexOn`) entre `CustomEvent_43.then` et `77`. S1.then → `394`
|
|||
|
|
(`SetViewTargetWithBlend(ChargenCameras[0])` → `303` `RestoreC1`, nœuds existants), S1.else → `77`. Le nœud 78
|
|||
|
|
devient inatteignable quand `SexOn` est vrai (laissé en place).
|
|||
|
|
- E2 : `UpdateRoomCam` : Branche S2 (`258.SexOn`) entre `CustomEvent_45.then` et `91`. S2.then → `394`,
|
|||
|
|
S2.else → `91`. À l'entrée du sexe, la minuterie (qui tourne en C1 et en C2) pose `SceneCamera` dans les 16 ms.
|
|||
|
|
- E3 : `303.then` → `441` (`K2_ClearAndInvalidateTimerHandle(RoomCamTimer)`, existant) : la minuterie s'arrête après
|
|||
|
|
la pose. Sans cela, elle reprendrait la vue à chaque passage en POV. Hors sexe, en C3, elle s'arrêtait déjà au
|
|||
|
|
passage suivant (`82.else` → `440` → `441`) : le résultat est le même.
|
|||
|
|
- Fin du sexe : inchangée. Le crochet de fin de sexe (B1-11, GI `2699` → `ApplyRoomCamera`) rappelle `ApplyRoomCamera`, qui rend C1
|
|||
|
|
ou C2 et relance la minuterie (vu à 05:18:57).
|
|||
|
|
- Volume : 2 nœuds (Branche), 9 liens, environ 30 appels MCP. Barème : a0 b1 c1 d0 e1 f1 = 4 → N1, ajusté à N3 ;
|
|||
|
|
S = C3 1 + f 1 = 2 (moins de 3) : une fiche. Case C9a.
|
|||
|
|
- Garde `Accessed None` : `ChargenCameras[0]` est déjà lu sans garde par 394 et par le PC 353. `SexOn` est lu
|
|||
|
|
sur `258`, comme 78 et 81.
|
|||
|
|
- Risque : le cadrage de `SceneCamera` en début de scène est celui que le jeu d'origine pose (`pickPreset`,
|
|||
|
|
`moveToBedIfPossible`). Non revu depuis la migration : à vérifier en V7.
|
|||
|
|
|
|||
|
|
**Option B : garder Q8 (vue `CamRoom`) et rendre la souris à C2 hors Maj.** Le `NOT` de 453 lirait
|
|||
|
|
`SexOn ET MoveObject` au lieu de `SexOn` (1 nœud AND, 3 liens). La caméra tournerait alors autour de la tête du
|
|||
|
|
joueur, à 1 m (cadrage C2), et non autour du couple. B2n resterait sans effet (sauf départ en C3). La première phase
|
|||
|
|
depuis C1 tournerait le regard C1. C'est moins proche du jeu d'origine : **non recommandée**.
|
|||
|
|
|
|||
|
|
## 4. Cas de test (à ajouter, V7)
|
|||
|
|
| N° | Action | Attendu |
|
|||
|
|
|---|---|---|
|
|||
|
|
| CAM-41 | Lancer une scène depuis C1, puis depuis C2, puis depuis C3. Souris sans Maj dès le début. | Vue de scène (`SceneCamera`) dès l'entrée ; la caméra tourne autour du couple. |
|
|||
|
|
| CAM-42 | C : POV, POV, Scene. Souris sans Maj. | Même orbite ; aucune reprise de la vue par C2. |
|
|||
|
|
| CAM-43 | Maj + souris, flèches. | Les personnages tournent et se déplacent (B2i). |
|
|||
|
|
| CAM-44 | Fin de la scène. | Retour au mode d'avant (C1, C2 ou C3), minuterie relancée en C1 et C2. |
|
|||
|
|
|
|||
|
|
## 5. Estimation et ordre
|
|||
|
|
- Rédaction de la fiche et instantané : 15 min. Passage UE (lp-mcp-bp, puis VAL V5 et V6 par lp-validator) :
|
|||
|
|
environ 45 min d'éditeur, plus 1 min de compilation stricte et 1 à 2 min par commandlet.
|
|||
|
|
- Room seul. Aucun recouvrement avec STE (ORG4) tant que STE ne touche pas Room. **Pas besoin de passer avant
|
|||
|
|
ORG4** : le défaut ne bloque pas l'essai en cours (POV et Maj marchent), et il entre au prochain passage UE.
|
|||
|
|
- Décision attendue de l'utilisateur : **option A (revenir sur Q8 pendant le sexe)** ou option B.
|
|||
|
|
|
|||
|
|
## 6. Complément : KO « souris + déplacement » = Maj + souris pour déplacer le couple (précision de l'utilisateur)
|
|||
|
|
Question de Big Boss : B2n (après 149) ou B2k (voie C1 de la minuterie) prennent-ils ou coupent-ils la voie Maj
|
|||
|
|
quand `CamC1On` est vrai pendant le sexe ? **Non, ni l'un ni l'autre (établi par les dumps).**
|
|||
|
|
- B2n est sur `19.else` (sans Maj), après 149. La voie Maj est `19.then` → `29` (`SexOn`) → `ForEach SexPersons`
|
|||
|
|
→ `SetActorRotation` : B2n ne la touche pas.
|
|||
|
|
- B2k est sur `83.then`, derrière `81` (`SexOn` faux). Pendant le sexe, la minuterie s'arrête à `81.then`, qui est
|
|||
|
|
vide.
|
|||
|
|
- `CamC1On` n'entre dans la voie de la souris que par `OR_60`, qui est masqué par `NOT SexOn` (B2i) dans `AND_61`.
|
|||
|
|
Pendant le sexe, 96 et 97 sont faux quel que soit `CamC1On`. Les flèches (97 → 9 → 14 → 27 → 139) suivent la même
|
|||
|
|
garde.
|
|||
|
|
- STG est coupé pendant le sexe (`LPDirectControlSubsystem.cpp:759`). Aucun C++ ne consomme Maj, la souris ou les
|
|||
|
|
flèches (pas d'`InputComponent`, seulement des lectures d'état).
|
|||
|
|
- **Preuve au journal que la voie couple marche** : les relevés « LPDebug persons » montrent le couple déplacé
|
|||
|
|
ensemble entre 05:13:17 et 05:13:27 (MC et partenaire : (-3131513, -14967009) → (-3131471, -14967049) →
|
|||
|
|
(-3131558, -14967097)). Cela se passe en mode Scene, dans une scène lancée depuis C1. Ensuite, la position ne
|
|||
|
|
change plus jusqu'à la fin (05:18:57). Le journal ne dit pas si l'utilisateur a essayé.
|
|||
|
|
|
|||
|
|
Pistes qui expliqueraient le ressenti sans défaut de code (à confirmer avec l'utilisateur) :
|
|||
|
|
1. **En POV, Maj + souris n'a jamais tourné le couple**, même dans le jeu d'origine : la souris va à `75.else` →
|
|||
|
|
`136` → `204` (regard), et Room n'est pas appelée. La scène a passé environ 52 s en POV (05:12:43-05:13:04,
|
|||
|
|
05:13:18-19, 05:14:19-05:15:11). Le cas CAM-38 (« en POV : Maj + souris ») attendait à tort une rotation.
|
|||
|
|
2. **La rotation demande aussi `MoveCamera`** (PC `73`, `InputAction_50` : estimé bouton du milieu ou Alt). Sans
|
|||
|
|
ce bouton, la souris va vers `247`/`246` (vitesse d'animation avec `Manual`).
|
|||
|
|
3. Le déplacement par flèches demande Maj (`14`/`17`).
|
|||
|
|
|
|||
|
|
Proposition : pas de correctif propre à ce KO. `CAM-B2p-SPEC.md` le couvre :
|
|||
|
|
- P2 : les flèches déplacent le couple sans Maj pendant le sexe ;
|
|||
|
|
- P3 : un témoin « Sexe : touches … » journalise Maj, `MoveObject`, `MoveCamera` et la vue si le cas revient.
|
|||
|
|
|
|||
|
|
## 7. Complément : après la scène, la vue C1 regarde le plafond (cinéma, assis, `fnt_new047`, dès 05:23)
|
|||
|
|
Journal : C1 rétabli à 05:18:57 (fin de scène). Aucune ligne caméra jusqu'à 05:26:00 : C passe de C1 à C2, puis
|
|||
|
|
`RestoreC1` remet `C1Hidden` à 0. L'utilisateur dit qu'un passage en C2 rétablit la vue.
|
|||
|
|
|
|||
|
|
**Cause (établie par le dump de Room ; seul le moment de la pose est estimé).** En C1, l'orientation de la vue est
|
|||
|
|
celle du composant caméra `FirstPersonSM` (classe `FirstPerson_C`, une `UCameraComponent`). Elle est **figée une fois
|
|||
|
|
pour toutes à l'entrée en C1, sur la pose de la tête à cet instant** :
|
|||
|
|
- voie C1 d'`ApplyRoomCamera`, seulement si `C1Hidden` est faux (`80.else`) :
|
|||
|
|
- `430` : `AttachToComponent(Mesh, head, KeepRelative)` ;
|
|||
|
|
- `431` : `SetRelativeTransform` à la rotation (90, 90, 0) **par rapport à l'os `head`** ;
|
|||
|
|
- `446` : `SetWorldLocation` au milieu des yeux ;
|
|||
|
|
- `433` : `AttachToComponent(Mesh, KeepWorld)`. À partir de là, la caméra suit le corps (lacet de l'acteur), mais
|
|||
|
|
son tangage reste celui que la tête avait à l'instant de la pose ;
|
|||
|
|
- si `C1Hidden` est déjà vrai (`80.then`), on passe directement à `434` `SetViewTarget`, sans aucune remise ;
|
|||
|
|
- minuterie C1 : B2k (`512`) recale la **position** à chaque passage, jamais l'**orientation** ;
|
|||
|
|
- en C1, hors sexe, aucune voie ne règle le tangage de `FirstPersonSM` : la souris Y va vers `RotateCamera` → 99,
|
|||
|
|
qui est faux hors `CamRoom` ; 316 n'est que dans la voie sexe.
|
|||
|
|
|
|||
|
|
Enchaînement probable (estimé) :
|
|||
|
|
- pendant la scène, chaque retour en Scene passe par `RestoreC1`, qui met `C1Hidden` à 0 (05:13:04, 05:15:11) ;
|
|||
|
|
- à la fin de la scène, `ApplyRoomCamera` (crochet B1-11 de GI) prend `80.else` et pose `FirstPersonSM` sur la
|
|||
|
|
tête **alors que le corps est encore dans la pose de fin de scène** (`SF_ft04_0`, couché au relevé de 05:18:47).
|
|||
|
|
La tête regarde vers le haut, et la vue est figée vers le plafond ;
|
|||
|
|
- `C1Hidden` passe à vrai : les `ApplyRoomCamera` suivants (cinéma) prennent `80.then`, sans nouvelle pose ;
|
|||
|
|
- le passage en C2 (05:26:00) refait `RestoreC1`. Au retour en C1, la pose est refaite sur une tête droite : la vue
|
|||
|
|
revient.
|
|||
|
|
- Ce n'est pas B2m : `204` et `316` tournent le `FirstPersonSM` de `SexPersons[i]`, et `431` remplace ensuite toute
|
|||
|
|
la rotation relative. B2m n'agit que si `80.then` est pris sans remise.
|
|||
|
|
- Le même mécanisme explique toute vue C1 penchée quand on entre en C1 dans une pose où la tête est inclinée (assis,
|
|||
|
|
allongé, animation de meuble).
|
|||
|
|
|
|||
|
|
**Correctif (B2p, partie P5, Room, même passage que P1 et P2).** Dans la minuterie C1, après `512` (B2k) :
|
|||
|
|
`K2_SetWorldRotation(FirstPersonSM 265, MakeRotator(Pitch 0, Yaw ← 514.Yaw, Roll 0))`, avec 514 =
|
|||
|
|
`BreakRotator(GetControlRotation)`, qui existe déjà. La vue C1 est remise à l'horizontale, dans la direction de
|
|||
|
|
contrôle, à chaque passage (0,016 s), quelle que soit la pose de la tête. Effet de bord voulu : assis, la souris fait
|
|||
|
|
aussi tourner la vue (le lacet de contrôle est réglé par B2h). 2 nœuds, 4 liens. Le tangage à la souris en C1 n'est
|
|||
|
|
pas traité (ce serait une demande à part).
|
|||
|
|
|
|||
|
|
**Déplacement impossible** au même moment : piste STG, hors CAM. Le relevé de 05:19:02 montre que le joueur occupe
|
|||
|
|
de nouveau `NODE_AddStaticMeshComponent-0_37` après la scène (`OnSeat` : la marche ne tourne pas le corps).
|
|||
|
|
|
|||
|
|
## 8. PRIORITAIRE (C5-2 bis) : personnages assis éliminés par le rendu (bar, C2, 05:28-05:29 et 05:31-05:32)
|
|||
|
|
Cas 1 (05:28-05:29) : la PNJ assise en face disparaît selon l'angle. Cas 2 (05:31-05:32) : le joueur (Bridget,
|
|||
|
|
assise à la place `_93`, `hidden=0`, `fnt_new048-f-0-sit`, meshZ -80,4) disparaît quand la caméra bouge ; la chaise
|
|||
|
|
est vide au premier plan, les deux PNJ restent visibles.
|
|||
|
|
|
|||
|
|
**Preuve que ce n'est pas un meuble entre la caméra et la tête (établi)** : la vue est C2 sans interruption de
|
|||
|
|
05:26:00 à 05:32:57 (lignes « Touche C »). T-occ trace de `CamRoom` vers la tête toutes les 0,5 s (canal Visibility,
|
|||
|
|
collision complexe, Room compris). Il n'a écrit qu'une ligne, à 05:26:03 (`fnt_new163`), puis **rien** jusqu'à
|
|||
|
|
05:32:57. Le rayon caméra → tête était donc libre pendant les deux disparitions. C'est le rendu qui élimine le
|
|||
|
|
maillage : frustum ou requête d'occlusion, sur des bornes fausses. Cela touche **tous les personnages assis** (et sans
|
|||
|
|
doute aussi couchés ou en animation de meuble).
|
|||
|
|
|
|||
|
|
**Ce qui est établi (lecture des assets, sans éditeur)** :
|
|||
|
|
- `bridget_gp.uasset` et `michael.uasset` n'importent **aucun asset physique** (imports : matériaux, squelette,
|
|||
|
|
`/Script/Engine.SkeletalMesh` ; aucun `PhysicsAsset` en import). Sans asset physique, UE calcule les bornes d'un
|
|||
|
|
`SkeletalMeshComponent` à partir des **bornes importées de la pose de référence** (debout), décalées de la seule
|
|||
|
|
translation de l'os racine. Elles ne suivent pas la pose (moteur, `USkinnedMeshComponent::CalcMeshBound`) ;
|
|||
|
|
- `Person.uasset` contient `BoundsScale` (3 fois) et `bUseAttachParentBound` (2 fois) dans sa table des noms : un ou
|
|||
|
|
plusieurs composants de Person les modifient. Lesquels et avec quelles valeurs : c'est à lire par MCP ;
|
|||
|
|
- aucun C++ du projet ne règle les bornes ni le culling. `r.AllowOcclusionQueries=True` (`DefaultEngine.ini:30`).
|
|||
|
|
|
|||
|
|
**Hypothèse (forte, pas encore prouvée)** : la pose assise des meubles (`fnt_*`) déplace le corps par rapport à la
|
|||
|
|
racine (meshZ -80,4 au lieu de -90 et décalage du siège). Les bornes debout, centrées sur la racine, peuvent alors se
|
|||
|
|
retrouver derrière la table ou le dossier, alors que le corps est visible. La requête d'occlusion matérielle juge ces
|
|||
|
|
bornes cachées et élimine tout le maillage. C'est la « chaise vide » sous un angle voisin. Si le maillage du corps
|
|||
|
|
utilise en plus `bUseAttachParentBound`, ses bornes sont celles de la capsule, et l'écart est encore plus grand.
|
|||
|
|
|
|||
|
|
**Preuve proposée, rapide et sans écriture** : le build COMMUN-6 est en Development, donc la console est disponible.
|
|||
|
|
Au même endroit, avec le même angle :
|
|||
|
|
- `r.AllowOcclusionQueries 0` : si la PNJ ne disparaît plus, c'est l'occlusion qui est en cause (la commande ne se
|
|||
|
|
sauvegarde pas) ;
|
|||
|
|
- `show Bounds` : affiche les bornes, on voit si elles sont décalées du corps.
|
|||
|
|
|
|||
|
|
**Correctif proposé (CAM-B2q, C++, environ 40 lignes)** : balayage léger toutes les 2 s des `ACharacter` de
|
|||
|
|
classe `Person_C`. Pour chacun, on ne retouche que si les valeurs diffèrent, ce qui couvre aussi le changement de
|
|||
|
|
maillage. Sur le `SkeletalMeshComponent` du corps et ses enfants maillés (vêtements, cheveux) :
|
|||
|
|
- `bUseAttachParentBound = false` pour le corps (les enfants gardent leur réglage) ;
|
|||
|
|
- `BoundsScale = 3,0`. `BoundsScale` agrandit la boîte autour de son centre, sans la déplacer : un facteur 2
|
|||
|
|
(environ ±50 × ±25 × ±90 cm → ±100 × ±50 × ±180) peut ne pas couvrir un corps assis décalé de plus d'un mètre de
|
|||
|
|
la racine ; 3 laisse de la marge. À ajuster à l'essai avec `show Bounds` ;
|
|||
|
|
- `UpdateBounds()` et `MarkRenderStateDirty()`.
|
|||
|
|
|
|||
|
|
**Coût** :
|
|||
|
|
- Écriture : 30 min, compilation 10 min (sous jeton UE), VAL statique 15 min, essai au build suivant.
|
|||
|
|
- En jeu : seuls les personnages de la pièce courante sont concernés (les autres sont cachés). Avec des bornes 3 fois
|
|||
|
|
plus grandes, un personnage juste hors écran ou juste caché est encore dessiné (ombres comprises). Pour une dizaine
|
|||
|
|
de maillages Daz, le surcoût GPU est faible ; à mesurer par `stat unit` au bar avant et après. Le jeu ne fait aucun
|
|||
|
|
travail CPU de plus par image.
|
|||
|
|
- Risque : aucun sur la collision et les tracés (les bornes de rendu ne servent pas aux collisions).
|
|||
|
|
|
|||
|
|
**Alternatives** :
|
|||
|
|
- Un asset physique pour `bridget_gp` et `michael` donnerait des bornes qui suivent les os. C'est plus juste, mais il
|
|||
|
|
faut modifier deux gros assets dans l'éditeur, et ses corps entreraient en jeu dans les tracés Visibility (sondes C2
|
|||
|
|
de B2f, T-occ). Hors alpha.
|
|||
|
|
- `r.AllowOcclusionQueries 0` dans `DefaultEngine.ini` supprimerait le cas d'occlusion pour tout le jeu, avec un coût
|
|||
|
|
de rendu global, et ne règle pas le cas frustum. Non recommandé.
|
|||
|
|
|
|||
|
|
**Attention au périmètre** : il ne s'agit pas d'éditer `Person.uasset`, mais de régler en jeu les composants des
|
|||
|
|
instances. Le domaine Person relève de STG/STE : **Big Boss attribue le lot**. Le même correctif couvrirait les
|
|||
|
|
disparitions du joueur assis dues aux bornes. Celles dues à un vrai meuble entre la caméra et le joueur (T-occ,
|
|||
|
|
05:26:03, `fnt_new163`) relèvent de B2l, après l'alpha.
|
|||
|
|
|
|||
|
|
**Témoin proposé avec B2q (T-cull)** : toutes les 0,5 s, pour chaque Person à moins de 15 m dont le bassin est dans
|
|||
|
|
l'écran mais qui n'a pas été rendue depuis 0,2 s (`WasRecentlyRendered(0.2)` faux), écrire :
|
|||
|
|
`Temoin culling : <Person> non rendue, bassin a %.0f cm du centre des bornes, bornes %.0f x %.0f x %.0f,
|
|||
|
|
BoundsScale %.1f, parent=%d`. Le témoin peut entrer **avant** le correctif, dans le même build, pour chiffrer le
|
|||
|
|
décalage. Il touche le même fichier et prend 15 min de plus.
|
|||
|
|
|
|||
|
|
## 9. Complément (J5) : C1 décalée après le lever au bar (épaule et bras visibles, 05:33-05:34)
|
|||
|
|
Journal :
|
|||
|
|
- 05:33:02 : passage en C1, assis à `_93` (`C1Hidden=1`, indicateur « C1 First person ») ;
|
|||
|
|
- 05:33:04 : « Marche : le joueur quitte …_93 (unOccupyFnt) », puis la marche ;
|
|||
|
|
- aucune ligne d'indicateur avant le C de 05:34:22 : la vue est restée `PlayerCharacter` en C1 ;
|
|||
|
|
- après le cycle C2 → C3 → C1 (05:34:22-05:34:28), la vue est correcte.
|
|||
|
|
|
|||
|
|
**La minuterie de B2k tourne (établi par le dump)** :
|
|||
|
|
- elle part sur la voie C1 d'`ApplyRoomCamera` (`434` → `329` `SetTimerDelegate(UpdateRoomCam, 0,016, en boucle)`) ;
|
|||
|
|
- elle ne s'arrête que par `441`, après `440` `RestoreC1`, quand `CamC1On` est faux (`82.else`) ou que la vue n'est
|
|||
|
|
plus le joueur (`83.else`), ou par un passage en C2 ou C3 ;
|
|||
|
|
- ni le lever (`unOccupyFnt`, KO3c) ni la marche de STG n'y touchent : le C++ ne lit et n'écrit aucune variable de
|
|||
|
|
Room liée à la caméra. La vue n'a pas quitté le joueur (aucune ligne d'indicateur) ;
|
|||
|
|
- l'utilisateur voit la vue « à peu près à hauteur d'yeux » : le recalage de **position** fonctionne.
|
|||
|
|
|
|||
|
|
**Cause : l'orientation, la même que § 7 (établi pour le mécanisme, estimé pour la pose)** :
|
|||
|
|
- l'orientation de `FirstPersonSM` est posée une fois, à l'entrée en C1 (`431`, par rapport à l'os `head`). Ici,
|
|||
|
|
c'était en position assise, la tête tournée ou penchée selon `fnt_new048` ;
|
|||
|
|
- ensuite, la caméra est accrochée au corps (`433`, KeepWorld) : elle suit le lacet de l'acteur, mais garde l'écart
|
|||
|
|
d'orientation de la tête assise ;
|
|||
|
|
- une fois debout, la marche de STG aligne le corps sur le lacet de contrôle (`LPDirectControlSubsystem.cpp:1034`),
|
|||
|
|
et la caméra garde l'écart. On voit son épaule et son bras gauches ;
|
|||
|
|
- le cycle C refait la pose sur une tête droite, ce qui corrige.
|
|||
|
|
- B2k ne recale que la position (`512` `SetWorldLocation`), jamais l'orientation.
|
|||
|
|
|
|||
|
|
**Correctif : P5 de `CAM-B2p-SPEC.md`** (`SetWorldRotation(0, lacet de contrôle, 0)` après 512, à chaque passage).
|
|||
|
|
Il règle § 7 et § 9 d'un coup : 2 nœuds, 4 liens dans Room.
|
|||
|
|
|
|||
|
|
Remarque pour STG : `currentAnimation` reste `fnt_new048-f-0-sit` après le lever (relevés LPDebug). Si `RestoreAnim`
|
|||
|
|
rend l'Anim BP `Daily_F_C`, qui relit cette chaîne, le corps pourrait reprendre la pose assise à l'arrêt. Ce n'est pas
|
|||
|
|
de mon ressort ; à signaler à STG.
|
|||
|
|
|
|||
|
|
## 10. Complément : après un changement de personnage (CharGen) en C1, C bloqué et souris sans effet (05:35-05:37)
|
|||
|
|
Journal :
|
|||
|
|
- 05:34:28 : C1 (`SpaceOn=1`) ;
|
|||
|
|
- 05:35:55-57 : menu principal, puis CharGen (`LOAD ROOM chargenroom`) ;
|
|||
|
|
- 05:36:09 : `LOAD ROOM pub___vin01`, puis `GI FOLLOWUP` ;
|
|||
|
|
- 05:37:28 : témoin « Touche C » : `BuilderOn=0 SpaceOn=0 SexOn=0 CamC1On=1 C1Hidden=1 ; entree PC=1 regard ignore=0
|
|||
|
|
viewport ignore=0 ; vue PlayerCharacter`. **H1 est établie** (C bloqué par la garde `SpaceOn` du PC, B1-7, `131`) ;
|
|||
|
|
**H4 est écartée** (entrées du PC intactes).
|
|||
|
|
|
|||
|
|
### 10.1 Qui met `SpaceOn` à faux, et pourquoi rien ne le remet (établi, dump GI EventGraph de B1-VAL)
|
|||
|
|
Dump du 2026-10-13. Depuis, GI n'a été modifié que par STE-H3d (`CallFunctionReturnBool`), pas sur ces chaînes ; à
|
|||
|
|
redumper à la fiche.
|
|||
|
|
- Écritures de `SpaceOn` dans GI : 5 nœuds.
|
|||
|
|
- Vrai : `240` (`OpenSpace`), `296` (`CreateCharGenWidget`), `297` (`CreateInventoryWidget`).
|
|||
|
|
- Faux : `241` (`CloseSpace`), **`233` (`ShowRender`)**.
|
|||
|
|
- Sortie de CharGen (`CloseCharGen`, `CustomEvent_101`) : … `RevertStripAll` → `4263` `MovePlayerBack` → `346`
|
|||
|
|
`ShowUI` → **`347` `ShowRender`** → `6009` `ClearCharGenWidget` → `1337` `CharGenOn` = faux → `1563`
|
|||
|
|
(`GameStart`) :
|
|||
|
|
- vrai (nouvelle partie) : `InventoryInput` → `CreateInventoryWidget` → `SpaceOn` = vrai (297) ;
|
|||
|
|
- **faux (changement de personnage en cours de partie) : `167` `DelayThenFollowUp`, et rien ne remet `SpaceOn`.**
|
|||
|
|
- `ShowRender` (`CustomEvent_519`) : `3014` → `213`, et **les deux branches de 213** mènent à `2920` → `2977`
|
|||
|
|
`SetViewTargetWithBlend(PC, Birdview)` → **`233` `SpaceOn` = faux** → `694` `updateAllPersonButtons`.
|
|||
|
|
`ShowRender` remet le jeu en mode carte de la ville. Or, ici, le joueur revient dans une pièce (`MovePlayerBack`,
|
|||
|
|
puis `LOAD ROOM pub`).
|
|||
|
|
- Le seul appel d'`OpenSpace` dans GI est `671`, sur la chaîne de fin de scène (`SceneOn`, `PregnancyBlocked`,
|
|||
|
|
`ConsolidateBeautyStandards`). `SpaceOn` reste donc faux jusqu'à la prochaine fin de scène ou la prochaine
|
|||
|
|
ouverture de l'inventaire.
|
|||
|
|
- C'est un **défaut latent du jeu d'origine**. Il est devenu visible avec nos gardes `SpaceOn` : B1-7 (touche C) et
|
|||
|
|
B1-6 (`LoadRoom` n'appelle `ApplyRoomCamera` que si `SpaceOn` est vrai). Après CharGen, un changement de pièce ne
|
|||
|
|
réapplique donc plus le mode de caméra.
|
|||
|
|
|
|||
|
|
### 10.2 Souris sans effet en C1 : `SpaceOn` n'en est pas la cause ; hypothèse H-M (à prouver)
|
|||
|
|
- Le regard C1 passe par `CircleCamera` → `96.then` (`OR_60` contient `CamC1On`) → `516` `SetControlRotation`.
|
|||
|
|
Cette voie ne lit pas `SpaceOn`.
|
|||
|
|
- Côté PC, la souris n'appelle `CircleCamera` que si `MoveCamera` est vrai (`73`). `MoveCamera` passe à vrai par
|
|||
|
|
`StartMoveCamera`, sur appui d'un bouton de souris (`InputKey_10` et `_14` → `108` / `106`). **Sauf si
|
|||
|
|
`JournalOn` OU `ContactsOn` OU `MainMenuOn` est vrai** (`OR_33`, `OR_37` : la branche « vrai » est vide).
|
|||
|
|
- **H-M** : CharGen a été ouvert **depuis le menu principal** (`menus=[MainMenu_C]` à 05:35:57). `MainMenuOn` ne
|
|||
|
|
passe à faux que par `CloseMainMenu` (GI `CustomEvent_904`). Il est appelé par le PC (`273`) et par le widget
|
|||
|
|
`MainMenu` (le nom est dans `MainMenu.uasset`, mais ce widget n'a pas été dumpé). Si le bouton « changer de
|
|||
|
|
personnage » ne ferme pas le menu par `CloseMainMenu`, `MainMenuOn` reste vrai : les boutons de souris ne lancent
|
|||
|
|
plus `MoveCamera`, et aucune caméra ne répond plus à la souris, dans aucun mode.
|
|||
|
|
- Test sans écriture : après CharGen, ouvrir puis fermer le menu principal (Échap, Échap). Si la souris revient,
|
|||
|
|
H-M est établie. Le témoin « Touche C » pourrait aussi écrire `MainMenuOn`, `JournalOn`, `ContactsOn` et
|
|||
|
|
`MoveCamera` (environ 10 lignes, fichier CAM).
|
|||
|
|
|
|||
|
|
### 10.3 À-coup de la caméra à la sortie de CharGen (estimé)
|
|||
|
|
Ordre probable :
|
|||
|
|
1. `MovePlayerBack` recharge la pièce (`LOAD ROOM pub` à 05:36:09.212, avant `FOLLOWUP` à .226). `SpaceOn` est
|
|||
|
|
encore vrai (posé par `CreateCharGenWidget`), donc B1-6 appelle `ApplyRoomCamera`. La voie C1 pose
|
|||
|
|
`FirstPersonSM` sur la tête (430 à 433), puis attend une image (`449` `DelayUntilNextFrame`).
|
|||
|
|
2. Pendant cette image, `ShowRender` met la vue sur `Birdview` et `SpaceOn` à faux.
|
|||
|
|
3. À l'image suivante, `434` remet la vue sur le joueur et relance la minuterie. B2k recale la position 16 ms plus
|
|||
|
|
tard.
|
|||
|
|
|
|||
|
|
On voit donc une image de `Birdview`, puis une vue C1 posée sur une tête qui n'est pas encore à sa place (joueur
|
|||
|
|
déplacé, pose de CharGen), recalée au passage suivant : c'est l'à-coup.
|
|||
|
|
- Avec P5 (B2p), le recalage de l'orientation se fait aussi au premier passage.
|
|||
|
|
- Option P6 (Room, environ 3 nœuds), pour supprimer l'à-coup : recaler position et orientation entre `449` et `434`,
|
|||
|
|
avant que la vue revienne.
|
|||
|
|
|
|||
|
|
### 10.4 Correctif proposé (CAM-B2r)
|
|||
|
|
**F-S (`SpaceOn`)**. Trois options :
|
|||
|
|
- (a) **GI**, dans `CloseCharGen`, branche `GameStart` faux : remettre `SpaceOn` à vrai, ou appeler `HideRender` et
|
|||
|
|
`OpenSpace`. C'est la réparation la plus juste, mais **GI n'est pas un fichier CAM** : propriétaire à désigner par
|
|||
|
|
Big Boss.
|
|||
|
|
- (b) **C++ CAM** (`LPCameraModeSubsystem`, environ 30 lignes) : sur le passage de `GI.CharGenOn` de vrai à faux,
|
|||
|
|
dès que la vue est de nouveau une caméra de pièce (le joueur avec `CamC1On`, `CamRoom`, ou `SceneCamera` avec
|
|||
|
|
`CamC3On`), si `SpaceOn` est faux : mise à vrai par réflexion, avec une ligne au journal (`SpaceOn remis a vrai
|
|||
|
|
apres CharGen`). Il agit seulement après CharGen, une fois. 30 min + compilation. Il écrit une variable de GI en
|
|||
|
|
jeu, ce qui relève du domaine GI : **à valider par Big Boss**.
|
|||
|
|
- (c) Retirer `SpaceOn` des gardes B1-6 et B1-7 (PC et Room). Non recommandé : ces gardes empêchent C et
|
|||
|
|
`ApplyRoomCamera` de jouer sur la carte de la ville.
|
|||
|
|
|
|||
|
|
**Recommandation : (b) pour l'alpha, (a) ensuite.**
|
|||
|
|
|
|||
|
|
**H-M** : correctif seulement si le test le prouve. Ce serait un appel `CloseMainMenu` sur la voie du bouton
|
|||
|
|
CharGen du widget `MainMenu` (fichier UI, propriétaire à désigner), ou la même méthode que (b) : `MainMenuOn` remis
|
|||
|
|
à faux à la sortie de CharGen si le widget `MainMenu` n'est plus à l'écran.
|
|||
|
|
|
|||
|
|
**À-coup** : P6, facultatif, avec B2p-R.
|
|||
|
|
|
|||
|
|
**Estimation de B2r** :
|
|||
|
|
- (b) et le témoin étendu : environ 45 min, plus la compilation, sous jeton UE ;
|
|||
|
|
- (a) et la correction de H-M : 30 à 45 min de MCP chacune, chez leur propriétaire.
|