94 lines
6.2 KiB
Markdown
94 lines
6.2 KiB
Markdown
|
|
# CAM-B2n : orbite de la caméra de scène autour du couple (Room, fiche lp-mcp-bp, 2026-10-14)
|
|||
|
|
|
|||
|
|
Origine : `CAM-COMMUN5-DIAG.md` § 3. Défaut d'origine : en mode Scene, la souris fait tourner la caméra sur place au
|
|||
|
|
lieu de tourner autour du couple. Gel des scènes levé pour l'alpha. Room seul.
|
|||
|
|
|
|||
|
|
## Barème
|
|||
|
|
a0 b1 c1 d0 e1 f1 = 4 → N1, ajusté à N3 (MCP) ; S = C3 1 + f 1 (choix du pivot) = 2 < 3 : une fiche, sans SPEC
|
|||
|
|
séparée. 7 nœuds, environ 14 liens, environ 35 appels. Case C9a.
|
|||
|
|
|
|||
|
|
## État (dump Room `CAM-B2i-VAL_LPDumpFunction_20261013-225125.txt`, Room `18565365…` ou celui laissé par B2k)
|
|||
|
|
Chemin de la souris sans Maj :
|
|||
|
|
- `CircleCamera` (`CustomEvent_1`, sortie `DeltaSeconds` = lacet souris) → 96 (après B2i : faux pendant le sexe) →
|
|||
|
|
`IfThenElse_26` (`BuilderOn` OU `SexOn` OU `SpaceOn`) → `IfThenElse_19` (`MoveObject`) **faux** →
|
|||
|
|
`K2Node_CallFunction_149` = `SceneCamera.K2_SetActorRotation(148)` ;
|
|||
|
|
- 148 = `MakeRotator(Pitch ← 147.Pitch, Yaw ← CommutativeAssociativeBinaryOperator_26 = 147.Yaw + DeltaSeconds)` ;
|
|||
|
|
- 147 = `BreakRotator(146 = SceneCamera.GetActorRotation)` ;
|
|||
|
|
- **`149.then` vide**.
|
|||
|
|
Getters existants :
|
|||
|
|
- `VariableGet_102.SceneCamera` (self Room ; sorties 146, 149, 229, 228) ;
|
|||
|
|
- `VariableGet_86.SexOn` (self ← 103.GI ; après B2i : 19.B, 29, 28 et NOT 453) ;
|
|||
|
|
- `VariableGet_106.SexPersons` (self ← 105.GI ; sortie → `MacroInstance_13.Array`).
|
|||
|
|
|
|||
|
|
## Règle
|
|||
|
|
Pendant le sexe seulement (`SexOn` vrai), après la rotation de 149 :
|
|||
|
|
- Pivot P = `GetActorArrayAverageLocation(GI.SexPersons)`, la moyenne des personnes du sexe ;
|
|||
|
|
- `SceneCamera.SetActorLocation(P + RotateAngleAxis(SceneCamera.GetActorLocation − P, DeltaSeconds, (0, 0, 1)))`.
|
|||
|
|
La position tourne autour de P du même angle que le lacet : la caméra garde son cadrage sur le couple. Hors sexe
|
|||
|
|
(constructeur, ancienne vue C3), le comportement est inchangé.
|
|||
|
|
|
|||
|
|
## Écritures (préfixe `/Game/BPs/Room.Room:EventGraph.`)
|
|||
|
|
1. `load_asset` `/Game/BPs/Room`. `get_node_infos` sur 149, 148, 147, 146, 26, 19, 102, 86, 106 et `CustomEvent_1`.
|
|||
|
|
Tout écart avec la section « État » : arrêt. Relever les PinID.
|
|||
|
|
2. Types (`find_node_types`, puis confirmation par `get_node_infos` après création) :
|
|||
|
|
- Branche : `Utilitaires|ContrôleDeFlux|Branche` ;
|
|||
|
|
- `GameplayStatics::GetActorArrayAverageLocation` ;
|
|||
|
|
- `Actor::K2_GetActorLocation` ;
|
|||
|
|
- `KismetMathLibrary::Subtract_VectorVector` ;
|
|||
|
|
- `KismetMathLibrary::RotateAngleAxis` (déjà utilisé : 497) ;
|
|||
|
|
- `KismetMathLibrary::Add_VectorVector` ;
|
|||
|
|
- `Actor::K2_SetActorLocation`.
|
|||
|
|
3. `create_node` des 7 nœuds, près de 149.
|
|||
|
|
4. Liens :
|
|||
|
|
- L1 : `149.then` → Branche.execute ;
|
|||
|
|
- L2 : `86.SexOn` → Branche.Condition ;
|
|||
|
|
- L3 : `106.SexPersons` → `GetActorArrayAverageLocation.Actors`. Si le type est refusé (tableau de `Person`
|
|||
|
|
contre tableau d'`Actor`) : arrêt et compte rendu. Repli à décider : `SexPersons[0]`, avec un `IsValidIndex`.
|
|||
|
|
- L4 : `102.SceneCamera` → `GetActorLocation.self` ;
|
|||
|
|
- L5 : `GetActorLocation.ReturnValue` → `Subtract.A` ; L6 : `Average.ReturnValue` → `Subtract.B` ;
|
|||
|
|
- L7 : `Subtract.ReturnValue` → `RotateAngleAxis.InVect` ; L8 : `CustomEvent_1.DeltaSeconds` →
|
|||
|
|
`RotateAngleAxis.AngleDeg` ; `set_pin_value` `RotateAngleAxis.Axis` = `0,0,1` ;
|
|||
|
|
- L9 : `Average.ReturnValue` → `Add.A` ; L10 : `RotateAngleAxis.ReturnValue` → `Add.B` ;
|
|||
|
|
- L11 : `Branche.then` → `SetActorLocation.execute` ; L12 : `102.SceneCamera` → `SetActorLocation.self` ;
|
|||
|
|
L13 : `Add.ReturnValue` → `SetActorLocation.NewLocation` ;
|
|||
|
|
- `SetActorLocation` : `bSweep` et `bTeleport` faux ; Branche.else vide.
|
|||
|
|
5. Relecture :
|
|||
|
|
- 149 then → Branche ;
|
|||
|
|
- 102 : sorties 146, 149, 229, 228, `GetActorLocation` et `SetActorLocation` ;
|
|||
|
|
- 86 : + Branche ; 106 : + Average ;
|
|||
|
|
- `CustomEvent_1.DeltaSeconds` : + `RotateAngleAxis` ;
|
|||
|
|
- aucun autre lien modifié (19, 26, 29, 96 et la boucle `SexPersons` 13 et 153 inchangés).
|
|||
|
|
6. `is_dirty` = vrai ; compilation stricte ; `save_assets` de Room seul ; MD5.
|
|||
|
|
|
|||
|
|
## Garde `Accessed None`
|
|||
|
|
- `SceneCamera` est déjà lu sans garde par 146 et 149 sur ce même chemin : comportement inchangé.
|
|||
|
|
- `SexPersons` vide pendant `SexOn` : `GetActorArrayAverageLocation` rend (0, 0, 0), sans `Accessed None`. La caméra
|
|||
|
|
tournerait alors autour de l'origine. Cas non observé, à surveiller à l'essai.
|
|||
|
|
|
|||
|
|
## Limite connue (non traitée ici, à décider)
|
|||
|
|
Si la scène part de C2, la vue reste sur `CamRoom` jusqu'au premier C (`CAM-COMMUN4-DIAG.md` § 2). L'orbite ne se
|
|||
|
|
voit qu'après un premier passage Scene → POV → Scene, quand la vue est `SceneCamera`. Pour l'avoir dès le début, il
|
|||
|
|
faudrait poser `SceneCamera` en vue à l'entrée du sexe : branche `SexOn` dans la voie C2 de `UpdateRoomCam`, avec
|
|||
|
|
environ 4 nœuds. Ce serait une fiche B2o, à décider par l'utilisateur.
|
|||
|
|
|
|||
|
|
## VAL
|
|||
|
|
- V5 : dump Room ; seules différences : 7 nœuds et les liens ci-dessus ; EventGraph = nœuds avant + 7.
|
|||
|
|
- V6 : `CompileAllBlueprints` = référence.
|
|||
|
|
- V7 : voir `CAM-COMMUN-6-TESTS.md`.
|
|||
|
|
|
|||
|
|
## Retour arrière
|
|||
|
|
`.\Tools\Restore.ps1 -Lot CAM-B2n -Only Content\BPs\Room.uasset` (ou l'instantané commun du passage), éditeur fermé.
|
|||
|
|
|
|||
|
|
## Amendement B2n-a (2026-10-14, arrêt de `lp-mcp-bp` à l'étape 3, décision de l'orchestrateur)
|
|||
|
|
- **E1** : `GameplayStatics::GetActorArrayAverageLocation` est `BlueprintCallable`, pas pur (`GameplayStatics.h:76`).
|
|||
|
|
Il a execute et then. **Option A retenue** : le mettre dans le fil, après la Branche.
|
|||
|
|
- **L11a** : `Branche.then` → `GetActorArrayAverageLocation.execute` (`K2Node_CallFunction_535`, déjà créé) ;
|
|||
|
|
- **L11b** : `535.then` → `SetActorLocation.execute`.
|
|||
|
|
Le reste ne change pas : `SexPersons` n'est lu que si `SexOn` est vrai.
|
|||
|
|
- **E2** : la soustraction et l'addition de vecteurs se font par les opérateurs génériques `Utilitaires|Opérateurs|
|
|||
|
|
Soustraire` et `Ajouter`, typés vecteur au branchement. C'est la même fonction (`Subtract_VectorVector`,
|
|||
|
|
`Add_VectorVector`), dans une autre classe de nœud.
|
|||
|
|
- Nœuds déjà créés et gardés : Branche `K2Node_IfThenElse_101`, moyenne `K2Node_CallFunction_535`.
|
|||
|
|
- L3 (`SexPersons` vers `Actors`) reste la condition d'arrêt prévue : si le type est refusé, arrêt sans repli.
|
|||
|
|
- V5 : EventGraph = nœuds avant B2n + 7, avec un lien d'exécution de plus (L11a et L11b au lieu de L11).
|