232 lines
18 KiB
Markdown
232 lines
18 KiB
Markdown
Fiche CAM-B2d — Niveau N3 — Modèle prévu opus | utilisé claude-opus-5-5 (Opus 5.5) — Agent lp-mcp-bp — Skills sk-protocol, sk-change-safety, lp-mcp, lp-lot
|
||
# CAM-B2d-IMPL : C2 sur la rotation de contrôle (B2d-1 à B2d-4) (2026-10-13)
|
||
|
||
Consignes : `CAM-B2d-FICHE.md` § « Consignes de l'agent » ; rubriques communes de `CAM-B2b-FICHES.md` (l. 23-63).
|
||
SPEC : `CAM-SPEC.md` § « CAM-B2d » (l. 384-393). UE-GO de Big Boss pour le passage Room B2d + B2e (2026-10-13, cité
|
||
par l'orchestrateur). Éditeur headless PID 22060, port 8000, connexion `unreal-mcp` partagée (MCPA-T1) ; Room chargé
|
||
par la session (état B2b F1-F7 enregistré). Consigne de l'orchestrateur, **différente de la fiche** : pas de
|
||
`save_assets` en B2d, B2e enregistre Room dans le même éditeur.
|
||
Un seul `call_tool` par message. **53 appels MCP** : 4 `find_node_types`, 13 `create_node` (dont 1 en erreur voulue,
|
||
§ 2 E1), 6 `delete_node`, 21 `connect_pins`, 1 `break_pins`, 5 `get_node_infos` (dont 1 en erreur), 2 `find_nodes`,
|
||
1 `compile_blueprint`. Aucun `set_pin_value`, `save_assets`, `write_graph_dsl` ni `ProgrammaticToolset`. Aucune
|
||
écriture par HyperAIStudio.
|
||
|
||
## 1. Fichiers modifiés
|
||
|
||
- `Content/BPs/Room.uasset` : modifié **en mémoire de l'éditeur seulement**, non enregistré (consigne : B2e
|
||
enregistre). Le MD5 du disque est celui de l'instantané (§ 3).
|
||
- Graphe `/Game/BPs/Room.Room:EventGraph` : `ComputeC2Target` (zone de 454, x 34450 y 1850), `CircleCamera` (96,
|
||
x 5650 y 4450), `LeftRight` (97, x 5250 y 2950), `PlaceC2` (CE48, x 34000 y 3000).
|
||
|
||
### 1.1 Identifiants trouvés (`find_node_types`)
|
||
- `ControlRotation`, contexte = sortie 0 de `VariableGet_262` : `Pion|SetControlRotation`, `Pion|GetControlRotation`.
|
||
- `Rotator` : `Math|Rotateur|BreakRotator`, `Math|Rotateur|MakeRotator`.
|
||
- `GetForwardVector` : `Transformation|GetForwardVector`, `Math|Vecteur|GetForwardVector` (version rotateur, relue :
|
||
entrée `InRot` Rotator).
|
||
- `GetActorRotation` : `Transformation|GetActorRotation`.
|
||
|
||
### 1.2 Lecture avant câblage (`get_node_infos` groupé, 11 créés + 15 existants), conforme à la fiche
|
||
- 453 `Transformation|GetActorForwardVector` : self ← 261.0 ; out 0 → 454.A 0. 454 `Normalize2D(Vector)` : A 0,
|
||
Tolerance 1 ; out 0 → PO17.A.
|
||
- 262 `|GetPC` (out 0 `PC Référence d'objet`, self ← `VariableGet_257` GI) → 394.1, 434.1, 439.0, 466.1.
|
||
- 261 `|GetPlayerCharacter` (out 0 `Person Référence d'objet`) → 264, 265, 266, 434.2, PO0.1, 451, 452, 453, MakeArray_5.
|
||
- 96 : execute ← CE1.1 ; Condition ← PO8 ; then 0 → 67.0 ; else 1 → IfThenElse_26. PO28 `float+float` : A ← 292,
|
||
B ← CE1.2 (DeltaSeconds) ; out → 67.1. 67 `|SetC2Yaw` : then libre.
|
||
- 97 : execute ← CE4.1 ; Condition ← PO8 ; then 0 → 68.0 ; else 1 → IfThenElse_9. PO30 : A ← 293, B ← PO29 ;
|
||
out → 68.1. 68 : then libre.
|
||
- CE48 `AddEvent|Custom|PlaceC2` : then (out 1) → 461.execute 0. 461 `|EnsureCamRoom` : then → `CallFunction_462`.
|
||
- `K2Node_CallFunction_521` : **nœud existant**, `MakeRotator` (8240, 5872 ; sortie → `CallFunction_90`.2, Pitch ←
|
||
`CommutativeAssociativeBinaryOperator_12`, Yaw ← `CallFunction_84`.2). Lu comme sonde (mon 3e `MakeRotator` a reçu
|
||
le n° 522) ; non touché.
|
||
|
||
### 1.3 Nœuds créés (préfixe `refPath` : `/Game/BPs/Room.Room:EventGraph.`)
|
||
|
||
| Rôle | `refPath` (suffixe) | `type_id` | Broches relues (index) | Position |
|
||
|---|---|---|---|---|
|
||
| CR = `GetControlRotation` (Controller) | `K2Node_CallFunction_524` | `Pion\|GetControlRotation` + `declaring_class` (§ 2 E1) | self in 0 (`Controller Référence d'objet`) ; ReturnValue out 0 (Rotator) | 33700, 2200 |
|
||
| `GetForwardVector(CR)` | `K2Node_CallFunction_513` | `Math\|Vecteur\|GetForwardVector` | InRot in 0 ; ReturnValue out 0 (Vector) | 34000, 2050 |
|
||
| BR = `BreakRotator(CR)` (partagé) | `K2Node_CallFunction_514` | `Math\|Rotateur\|BreakRotator` | InRot in 0 ; Roll out 0, Pitch out 1, Yaw out 2 (simple précision) | 34000, 1900 |
|
||
| `MakeRotator` (CircleCamera) | `K2Node_CallFunction_515` | `Math\|Rotateur\|MakeRotator` | Roll in 0, Pitch in 1, Yaw in 2 (simple précision) ; out 0 | 6050, 4250 |
|
||
| `SetControlRotation` (CircleCamera) | `K2Node_CallFunction_516` | `Pion\|SetControlRotation` | execute in 0, self in 1 (`Controller`), NewRotation in 2 (Rotator par référence) ; then out 0 | 6300, 4400 |
|
||
| `MakeRotator` (LeftRight) | `K2Node_CallFunction_517` | `Math\|Rotateur\|MakeRotator` | idem 515 | 5900, 2700 |
|
||
| `SetControlRotation` (LeftRight) | `K2Node_CallFunction_518` | `Pion\|SetControlRotation` | idem 516 | 6150, 2900 |
|
||
| `GetActorRotation(MC)` (PlaceC2) | `K2Node_CallFunction_519` | `Transformation\|GetActorRotation` | self in 0 (`Acteur`) ; ReturnValue out 0 (Rotator) | 37000, 3000 |
|
||
| `BreakRotator` (PlaceC2) | `K2Node_CallFunction_520` | `Math\|Rotateur\|BreakRotator` | idem 514 | 37250, 3000 |
|
||
| `MakeRotator` (PlaceC2) | `K2Node_CallFunction_522` | `Math\|Rotateur\|MakeRotator` | idem 515 | 37500, 3000 |
|
||
| `SetControlRotation` (PlaceC2) | `K2Node_CallFunction_523` | `Pion\|SetControlRotation` | idem 516 | 37750, 3100 |
|
||
|
||
Roll et Pitch des trois `MakeRotator` : défaut `0.0`, non liés (SPEC : `MakeRotator(0, 0, Yaw)`).
|
||
|
||
### 1.4 Nœuds supprimés (`delete_node`, 6, tous `{"returnValue":null}`)
|
||
|
||
| Nœud | Rôle | Ligne SPEC |
|
||
|---|---|---|
|
||
| `K2Node_CallFunction_512` | mon premier `GetControlRotation`, version **Pawn** (self `Pion`), jamais relié | § 2 E1 |
|
||
| `K2Node_CallFunction_453` | `GetActorForwardVector(MC)` | B2d-1 |
|
||
| `K2Node_VariableSet_67` puis `K2Node_VariableGet_292` | `Définir C2Yaw` / `Obtenir C2Yaw` (CircleCamera) | B2d-2 |
|
||
| `K2Node_VariableSet_68` puis `K2Node_VariableGet_293` | idem (LeftRight) | B2d-3 |
|
||
|
||
### 1.5 Liens coupés
|
||
- Par `break_pins` (1) : C1 `CustomEvent_48.then 1` → `CallFunction_461.execute 0` (B2d-4).
|
||
- Par `delete_node` (§ 2 E2) : 453.0 → 454.A 0 et 261.0 → 453.self ; 292.0 → PO28.A 0 ; 96.then 0 → 67.execute 0 et
|
||
PO28.0 → 67.C2Yaw 1 ; 293.0 → PO30.A 0 ; 97.then 0 → 68.execute 0 et PO30.0 → 68.C2Yaw 1.
|
||
|
||
### 1.6 Liens faits (`connect_pins`, 21, tous `{"returnValue":null}`)
|
||
|
||
| # | Sortie | Entrée | Ligne SPEC |
|
||
|---|---|---|---|
|
||
| L1 | VariableGet_262.0 (PC) | CallFunction_524.self 0 | B2d-1 |
|
||
| L2 | CallFunction_524.0 | CallFunction_513.InRot 0 | B2d-1 |
|
||
| L3 | CallFunction_513.0 | CallFunction_454.A 0 | B2d-1 |
|
||
| L4 | CallFunction_524.0 | CallFunction_514.InRot 0 | BR |
|
||
| L5 | CallFunction_514.Yaw 2 | PromotableOperator_28.A 0 | B2d-2 |
|
||
| L6 | PromotableOperator_28.0 | CallFunction_515.Yaw 2 | B2d-2 |
|
||
| L7 | CallFunction_515.0 | CallFunction_516.NewRotation 2 | B2d-2 |
|
||
| L8 | VariableGet_262.0 | CallFunction_516.self 1 | B2d-2 |
|
||
| L9 | IfThenElse_96.then 0 | CallFunction_516.execute 0 | B2d-2 |
|
||
| L10 | CallFunction_514.Yaw 2 | PromotableOperator_30.A 0 | B2d-3 |
|
||
| L11 | PromotableOperator_30.0 | CallFunction_517.Yaw 2 | B2d-3 |
|
||
| L12 | CallFunction_517.0 | CallFunction_518.NewRotation 2 | B2d-3 |
|
||
| L13 | VariableGet_262.0 | CallFunction_518.self 1 | B2d-3 |
|
||
| L14 | IfThenElse_97.then 0 | CallFunction_518.execute 0 | B2d-3 |
|
||
| L15 | VariableGet_261.0 (MC) | CallFunction_519.self 0 | B2d-4 |
|
||
| L16 | CallFunction_519.0 | CallFunction_520.InRot 0 | B2d-4 |
|
||
| L17 | CallFunction_520.Yaw 2 | CallFunction_522.Yaw 2 | B2d-4 |
|
||
| L18 | CallFunction_522.0 | CallFunction_523.NewRotation 2 | B2d-4 |
|
||
| L19 | VariableGet_262.0 | CallFunction_523.self 1 | B2d-4 |
|
||
| L20 | CustomEvent_48.then 1 | CallFunction_523.execute 0 | B2d-4 |
|
||
| L21 | CallFunction_523.then 0 | CallFunction_461.execute 0 | B2d-4 |
|
||
|
||
`516.then` et `518.then` laissés libres (fin de l'événement côté C2, comme 67 et 68 avant).
|
||
|
||
### 1.7 Relecture (`get_node_infos` groupé final, 20 nœuds : 11 créés + 454, PO28, PO30, 96, 97, CE48, 461, 262, 261)
|
||
Les 21 liens apparaissent des deux côtés. 454.A ← 513 seul ; PO28 : A ← 514.Yaw, B ← CE1.DeltaSeconds, out → 515
|
||
seul (`float+float`, double précision conservée) ; PO30 : A ← 514.Yaw, B ← PO29, out → 517 seul ; 96 : then → 516
|
||
seul, else → IfThenElse_26 (inchangé), Condition ← PO8 ; 97 : then → 518 seul, else → IfThenElse_9 (inchangé),
|
||
Condition ← PO8 ; CE48.then → 523 seul ; 461 : execute ← 523, then → 462 (inchangé) ; 262 → 394, 434, 439, 466
|
||
(inchangés) + 524, 516, 518, 523 ; 261 → liens d'origine sans 453, + 519. Aucune divergence.
|
||
Absence : `find_nodes {title:"Forward"}` → `[K2Node_CallFunction_513]` seul (témoin positif : la recherche par
|
||
sous-chaîne marche ; 453 n'est plus dans le graphe). `get_node_infos` sur 512 → `Parameter error: …K2Node_CallFunction_512
|
||
is not valid EdGraphNode`. Voir § 2 E5 pour 453 et § 5 pour 67, 68, 292, 293.
|
||
|
||
Chaîne obtenue :
|
||
- `ComputeC2Target` : direction arrière = `Normalize2D(GetForwardVector(PC.GetControlRotation()))` (au lieu de
|
||
`GetActorForwardVector(MC)`), puis PO17 (× −1) → 497 (`C2Yaw`, désormais toujours 0) → PO3, inchangés.
|
||
- `CircleCamera` en C2 : `PC.SetControlRotation(0, 0, ControlYaw + DeltaSeconds)`, fin. Hors C2 : `IfThenElse_26`.
|
||
- `LeftRight` en C2 : `PC.SetControlRotation(0, 0, ControlYaw + AxisValue × 2)`, fin. Hors C2 : `IfThenElse_9`.
|
||
- `PlaceC2` : `PC.SetControlRotation(0, 0, MC.GetActorRotation().Yaw)` → `EnsureCamRoom` (461) → suite inchangée.
|
||
|
||
### 1.8 Compilation
|
||
`compile_blueprint {blueprint:{refPath:"/Game/BPs/Room.Room"}, warnings_as_errors:true}` → `{"returnValue":null}`,
|
||
aucune exception. `hyper_blueprint_debug_inspect` non appelé : il était absent du serveur le 2026-10-10 (mémoire
|
||
`unreal-mcp-reconnect`), non revérifié. Journal de l'éditeur non lu : chemin `-abslog` non fourni. Pas de `save_assets`
|
||
(consigne de l'orchestrateur).
|
||
|
||
## 2. Écarts à la SPEC
|
||
|
||
- **E1 (identifiant, résolu ; méthode hors fiche)** : `create_node` avec `Pion|GetControlRotation` a créé la version
|
||
**Pawn** (512, self `Pion Référence d'objet`), qui n'accepte pas 262 (`PC Référence d'objet`). Le `find_node_types`
|
||
avec contexte ne donnait qu'un seul `type_id` ; `create_node` ne prend pas ce contexte. Un appel `create_node`
|
||
volontairement mal formé (`pos:"schema"`) a renvoyé `Function input params Json - {…,"declaring_class":null}`. Ce
|
||
retour révèle un paramètre caché. `create_node {…, declaring_class:"/Script/Engine.Controller"}` a créé 524, relu
|
||
`Controller Référence d'objet`. 512, jamais relié, a été supprimé. La cible est conforme à la SPEC : la marche lit
|
||
`PC->GetControlRotation()` (`Source/LifePlay/LPDirectControlSubsystem.cpp:887`). `Pion|SetControlRotation` a donné
|
||
d'emblée la version Controller (516, 518, 523 : self `Controller`).
|
||
- **E2 (procédure, même résultat)** : les 5 coupures nommées par la fiche (453 → 454.A, 292 → PO28.A, 96.then → 67,
|
||
293 → PO30.A, 97.then → 68) n'ont pas été faites par `break_pins`. Elles résultent du `delete_node` du nœud à retirer,
|
||
fait **avant** de relier le remplaçant : un nœud supprimé perd tous ses liens. Motif : le budget de tours (60), qui
|
||
n'aurait pas couvert 5 appels de plus. Le résultat est vérifié au § 1.7 : chaque entrée n'a qu'un lien, celui du
|
||
remplaçant. Seule coupure explicite : CE48.then → 461, puisque 461 reste en place.
|
||
- **E3 (types)** : `BreakRotator.Yaw` (simple précision) → PO28.A / PO30.A (double) et PO28 / PO30 (double) →
|
||
`MakeRotator.Yaw` (simple) : conversions implicites. PO28 et PO30 restent `float+float` en double. La compilation
|
||
stricte les accepte.
|
||
- **E4 (contrôle partagé)** : un seul `GetControlRotation` (524) et un seul `BreakRotator` (514), purs, servent B2d-1 à
|
||
B2d-3, comme le permet la SPEC (l. 392). Ils sont reliés de loin : `ComputeC2Target` est en x ≈ 34000,
|
||
CircleCamera et LeftRight en x ≈ 5000-6000. Effet cosmétique seulement.
|
||
- **E5 (fait inattendu, sans effet sur le graphe)** : après sa suppression, `get_node_infos` sur 453 rend encore un
|
||
objet (broches vides), alors que 512 est refusé (`not valid EdGraphNode`). `find_nodes` établit que 453 n'est plus
|
||
dans `EventGraph`. Hypothèse estimée : l'objet reste en mémoire, tenu par le tampon d'annulation, jusqu'au
|
||
ramasse-miettes ou à l'enregistrement. À trancher par le dump après enregistrement (§ 5.1).
|
||
- Positions (cosmétique, non prescrites) : les nœuds de B2d-4 sont en x 37000-37750, y 3000-3100. Ils sont donc loin de
|
||
CE48 (34000, 3000) et de 461 (34300, 3000), qui n'étaient pas connus à la création.
|
||
- Garde `Accessed None` : aucune `IsValid` ajoutée. « Vide » n'est pas un état normal de `GI.PC` (262) ni de
|
||
`GI.PlayerCharacter` (261) en C2, et ni la SPEC ni la fiche n'en demandent. Les lectures nouvelles sont au § 5.3.
|
||
- Comportement : hors C2, `CircleCamera` et `LeftRight` sont inchangés (`else` relus). En C2, le changement est voulu
|
||
par la SPEC : la rotation de contrôle remplace `C2Yaw`. `PlaceC2` pose désormais la rotation de contrôle avant
|
||
`EnsureCamRoom`.
|
||
|
||
## 3. Instantané
|
||
|
||
Fait par l'orchestrateur (non refait, consigne) : `D:\Game\LifePlay_Backup_5.5\CAM-B2d\`. Relevé :
|
||
```
|
||
date -Iseconds; md5sum "/d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset"; grep -i "Room.uasset" "/d/Game/LifePlay_Backup_5.5/CAM-B2d/manifest.csv"; git -C "/d/Game/LifePlay-master 5.8" status --short -- Content/BPs/Room.uasset; git -C "/d/Game/LifePlay-master 5.8" rev-parse --short HEAD
|
||
2026-10-13T17:19:04+02:00
|
||
e0517c63541f249bd9dbda5c39815ba5 */d/Game/LifePlay-master 5.8/Content/BPs/Room.uasset
|
||
"Content\BPs\Room.uasset","True","6318319","E0517C63541F249BD9DBDA5C39815BA5","2026-10-13T17:11:26"
|
||
M Content/BPs/Room.uasset
|
||
0745917
|
||
```
|
||
Le MD5 du disque après B2d est celui de l'instantané : rien n'a été enregistré (attendu). Le `M` vient de B2b, déjà
|
||
enregistré et non commité. Retour arrière avant l'enregistrement de B2e : fermer l'éditeur sans enregistrer, ce qui perd
|
||
B2d. Après : `Tools\Restore.ps1 -Lot CAM-B2d -Only Content\BPs\Room.uasset`, éditeur fermé, sur décision de
|
||
l'orchestrateur (jamais lancé ici).
|
||
|
||
## 4. Ce qui n'a pas été fait
|
||
|
||
- `save_assets` : non fait, sur consigne de l'orchestrateur (B2e enregistre Room une fois). B2d vit en mémoire de
|
||
l'éditeur PID 22060 : une fermeture ou un plantage avant l'enregistrement de B2e le perd ; l'instantané reste intact.
|
||
- Mesures de la fiche « MD5 de Room après l'enregistrement (≠ E0517C63) » : sans objet ici, à prendre après B2e.
|
||
- Absence de 67, 68, 292 et 293 dans le graphe : non prouvée par `find_nodes`, faute de tours. Elle est établie
|
||
seulement par `delete_node` → `null` et par l'absence de leurs liens sur PO28, PO30, 96 et 97 (§ 1.7).
|
||
- `hyper_blueprint_debug_inspect` et journal de l'éditeur : non consultés (§ 1.8).
|
||
- Comportement à l'exécution : non mesuré (pas de PIE ni de build), seulement déduit du câblage. La preuve en jeu
|
||
(build empaqueté + `LogStats`) n'est pas de mon rôle.
|
||
|
||
## 5. Points à confirmer en VAL
|
||
|
||
1. V5 (`CAM-SPEC.md:393`), après l'enregistrement de B2e, par dump : `GetControlRotation` ≥ 1 (524, de classe
|
||
`Controller`) ; `SetControlRotation` = 3 (516, 518, 523) ; aucun `GetActorForwardVector` dans `ComputeC2Target`
|
||
(453 absent du fichier, cf. E5) ; `C2Yaw` écrite 0 fois (aucun `SetC2Yaw` : 67 et 68 absents) ; plus de
|
||
`VariableGet_292` ni `_293` ; critères de B2b inchangés.
|
||
2. Hors C2 : `CircleCamera` → `IfThenElse_26` et `LeftRight` → `IfThenElse_9` sont inchangés (relu). À confirmer en jeu.
|
||
3. `LogStats` : aucun `Accessed None` nouveau sur `VariableGet_262`, `_261`, `CallFunction_519`, `_523`, `_524`.
|
||
Lectures nouvelles : `GI.PC` (262) dans `ComputeC2Target` (524 ; avant, cette fonction lisait 261 par 453) et dans
|
||
`PlaceC2` **avant** `EnsureCamRoom` (523 ; 262 était déjà lu plus loin, par 466) ; `GI.PlayerCharacter` (261) dans
|
||
`PlaceC2` (519). Dans CircleCamera et LeftRight, 262 est déjà lu par la condition (PO8 → 439) avant 516 / 518 :
|
||
aucun risque nouveau là.
|
||
4. Essai B2d de la fiche (l. 49-53) : Z s'éloigne de la caméra ; souris et flèches tournent la caméra ; la caméra est
|
||
derrière le personnage en entrant en C2. Estimé, non lu : si `Person` utilise la rotation de contrôle en lacet
|
||
(`bUseControllerRotationYaw`), `SetControlRotation` fera aussi tourner le personnage. À observer.
|
||
5. `SetControlRotation(0, 0, Yaw)` remet à 0 le tangage et le roulis de contrôle à chaque `CircleCamera`, `LeftRight` et
|
||
`PlaceC2`. C'est voulu (SPEC : `MakeRotator(0, 0, …)`) ; la hauteur de C2 reste réglée par `C2Height`.
|
||
6. Le lacet de contrôle n'est pas borné (somme libre). `SetControlRotation` ne normalise pas (estimé, non lu). Sans
|
||
effet sur `GetForwardVector`.
|
||
7. Compilation stricte jugée sur l'absence d'exception seulement : à recontrôler après B2e et par
|
||
`CompileAllBlueprints` (V6).
|
||
8. E5 : vérifier que l'enregistrement de B2e n'écrit pas 453 (dump : aucun `GetActorForwardVector` dans Room, sauf
|
||
d'autres nœuds éventuels hors `ComputeC2Target`, à lister).
|
||
|
||
## 6. Fichiers à commiter
|
||
|
||
- `A Docs/Migration/etat/CAM/CAM-B2d-IMPL.md` (dépôt du jeu, branche `ue5.8`).
|
||
- `Content/BPs/Room.uasset` : rien pour B2d seul (non enregistré). Il sera enregistré par B2e, puis commité après
|
||
l'essai commun (fiche, § « Après »).
|
||
|
||
Tours : 59 / 60
|
||
|
||
## Constats
|
||
|
||
- À verser : `lp-mcp` § 3. `create_node` accepte un paramètre caché `declaring_class` (ex. `"/Script/Engine.Controller"`)
|
||
qui choisit la classe quand deux fonctions ont le même `type_id`. Sans lui, `Pion|GetControlRotation` donne la version
|
||
Pawn. On le voit en provoquant une erreur de conversion (`pos` en chaîne) : la liste des paramètres est rendue.
|
||
- À verser : `lp-mcp` § 3. Index de broches relus :
|
||
- `GetControlRotation` (Controller) : self in 0, out 0 ;
|
||
- `SetControlRotation` : execute in 0, self in 1, NewRotation in 2, then out 0 ;
|
||
- `BreakRotator` : InRot in 0, Roll out 0, Pitch out 1, Yaw out 2 (simple précision) ;
|
||
- `MakeRotator` : Roll in 0, Pitch in 1, Yaw in 2, out 0 ;
|
||
- `Math|Vecteur|GetForwardVector` : InRot in 0, out 0 ;
|
||
- `Transformation|GetActorRotation` : self in 0, out 0.
|
||
- À verser : `lp-mcp` § 3. Un nœud supprimé peut encore se lire par son `refPath` (broches vides). Son absence se prouve
|
||
par `find_nodes {title}`, qui cherche par sous-chaîne, avec un témoin positif.
|
||
- Les numéros de nœud ne sont pas consécutifs : `CallFunction_521` existait déjà, et le `MakeRotator` suivant est 522.
|
||
Toujours relire le `refPath` rendu par `create_node`.
|