‹
Pomocné skripty

Připnutí postavy

Nechá CharacterVirtual sledovat úplný trojrozměrný transform rigid body pro sedadla, vozidla, výtahy a pohyblivé stroje.

JoltCharacter.attachment_attach() přepne existující managed postavu z nezávislého pohybu CharacterVirtual do režimu následování transformu. Zadaná position a rotation se uloží v local-space cílového tělesa. Každý fixed step z něj odvodí world position, orientaci, up vector a point velocity postavy, dokud ji neodpojíte nebo cílové těleso nezanikne.

Syntaxe#

Syntax
character.attachment_attach(body, options=undefined)
character.attachment_detach()
character.attachment_is_active()
character.attachment_get_body()

Argumenty#

ArgumentTypPopis
bodyJoltBodyPlatné managed rigid body ve stejném worldu jako postava. Cílem může být Static, Kinematic i Dynamic rigid body.
optionsStruct nebo undefinedVolitelná body-local position a orientation. Vynechané hodnoty použijí počátek tělesa a identity rotation.

Options#

FieldVýchozí hodnotaPopis
position{x:0,y:0,z:0}Konečná body-local pozice připnutí. Nejde o world-space cíl; transformuje se pozicí a rotací cílového tělesa.
rotation_euler{x:0,y:0,z:0}Konečná body-local XYZ rotation ve stupních. Používá Euler convention qZ * qY * qX tohoto rozšíření.
rotationundefinedPokročilý body-local quaternion {x,y,z,w}. Má přednost před rotation_euler, musí být konečný a nenulový a interně se normalizuje.

Model transformu#

GML
world_position = body_transform * local_position
world_rotation = body_rotation * local_rotation
world_up       = world_rotation * {x:0, y:0, z:1}
  • Lokální position se otáčí s tělesem. Offset sedadla {x:1,y:0,z:0} proto sleduje lokální osu X tělesa a nezůstává jednu world unit směrem na východ.
  • Lokální rotation se skládá za rotation tělesa, takže roll, pitch, yaw i poloha vzhůru nohama zůstávají platné po celý attached stav.
  • Pro běžné zadávání použijte rotation_euler. rotation použijte jen tehdy, když už projekt pracuje s normalizovaným nebo normalizovatelným quaternionem.
  • Další attach okamžitě nahradí starý cíl a lokální transform; při přesednutí není nutné nejprve volat detach.

Typická interakce se sedadlem#

GML
// player je platný JoltCharacter; seat_body je platný JoltBody.
if (keyboard_check_pressed(ord("E"))) {
    if (!player.attachment_is_active()) {
        if (!player.attachment_attach(seat_body, {
            position: {x:0, y:-0.7, z:1.2},
            rotation_euler: {x:0, y:0, z:180}
        })) {
            show_debug_message(jolt_get_error().message);
        }
    } else {
        player.attachment_detach();
    }
}

// Pozici může převzít character.sync(); orientaci nastavte samostatně.
player.sync();
if (player.attachment_is_active()) {
    var facing = player.get_rotation_euler();
    character_object.rotation_x = facing.x;
    character_object.rotation_y = facing.y;
    character_object.rotation_z = facing.z;
}

Co se během připnutí změní#

SystémChování v attached stavu
Position a rotationAutoritou je rigid body. Attachment se čte před i po každém fixed physics stepu, takže render nemá zpoždění o jeden step.
Chůze a gravitaceBěžný pohyb CharacterVirtual, gravitace, stairs, slope solving a ground movement jsou pozastavené.
Skok a crouchJump requests, jump buffering, coyote time ani crouch transitions attached postavu neřídí.
Kolize a pushingNezávislé CharacterVirtual collision solving, character contacts a pushing se pozastaví, aby vlastní sedadlo nebo chassis pasažéra nevytlačovalo.
VelocityPostava hlásí rychlost cílového tělesa přesně v bodě připnutí včetně příspěvku angular motion.
Reference framePři úspěšném plném připnutí se předchozí character reference frame zruší.

Související metody#

MetodaNávratová hodnota a účel
attachment_detach()Vrací Boolean. Zachová world position, převezme point velocity cíle a obnoví běžný globální Z-up pohyb.
attachment_is_active()Vrací native Boolean stav. Zaznamená také automatické odpojení po zničení cíle.
attachment_get_body()Vrátí aktuální platný managed JoltBody, nebo undefined.
attachment_get_position()Vrátí uloženou body-local position {x,y,z}.
attachment_get_rotation()Vrátí uložený body-local quaternion {x,y,z,w}.
get_rotation()Vrátí aktuální world quaternion postavy.
get_rotation_euler()Vrátí aktuální world orientation jako GameMaker Euler stupně pro rendering.
get_up()Vrátí aktuální world-space up vector včetně rollu a pitche připojeného tělesa.

Rendering a fyzikální smyčka#

  • Postavu a rigid body vytvořte až po jolt_start() a v běžném Step toku volejte jolt_update(delta_time / 1000000).
  • Native attachment se po simulaci rigid bodies znovu načte, takže get_position(), get_rotation() a get_up() po jolt_update() zpřístupňují aktuální pose tělesa.
  • JoltCharacter.sync() kopíruje position a character state do propojené GameMaker instance, ale nenastavuje rotation modelu. Vizuální orientation nastavte samostatně pomocí get_rotation() nebo get_rotation_euler().
  • V attached stavu se nesnažte jako konkurenční autoritu používat set_position(), set_velocity(), chůzi, jump ani crouch.

Bezpečné odpojení#

  • attachment_detach() lze bezpečně volat i na odpojené postavě a vrátí true.
  • Aktuální world position zůstane zachovaná. Postava převezme point velocity tělesa v místě attachmentu, takže opuštění pohybujícího nebo rotujícího vozidla zachová fyzikálně odpovídající momentum.
  • Běžný controller používá globální Z-up. Při odpojení implementace v možné míře zachová heading a současně narovná nakloněného nebo obráceného pasažéra zpět k Z-up.
  • Jump a forced-jump state se vyčistí. Pro další physics stepy se obnoví běžná registrace character collisions.

Vlastnictví a automatické odpojení#

  • Postava cílové body nevlastní. Odpojení ani zničení postavy těleso nezničí.
  • Zničení cílového tělesa automaticky odpojí všechny připnuté postavy ještě před zastaráním jeho generačního handlu.
  • Automatické odpojení zachová poslední position postavy; při běžném zničení cíle se podle dostupnosti převede také jeho aktuální point velocity.
  • Stale body wrapper, těleso z jiného worldu nebo neplatná postava se odmítnou. Opětovné použití slotu handlu nemůže postavu tiše připnout k jinému pozdějšímu body.
  • jolt_stop() oba resources uklidí běžným managed teardownem; jejich metody potom nevolejte.

Volba lokálního pose#

  • Offset sedadla zadávejte relativně k veřejnému transform origin tělesa. U bodies s center-of-mass offsetem jde stále o vystavený body transform, nikoli o libovolný world point.
  • Začněte s identity rotation a upravujte vždy jednu Euler osu. Snadněji tak odhalíte rozdíl ve směru modelu.
  • Pokud je postava na správném místě jen do chvíle, než vozidlo zatočí, byla pravděpodobně zadána world-space souřadnice místo body-local position.
  • Pro logiku vstupu do nejbližšího sedadla převádějte nebo předem definujte každé sedadlo v local-space; nepřepisujte attachment pose každým framem z world coordinates.

Validace a chyby#

  • Postava i cíl musí být platné managed resources ve stejném worldu.
  • options.position musí obsahovat konečné hodnoty x, y a z.
  • Pokud chybí rotation, options.rotation_euler musí obsahovat konečné stupně x, y a z.
  • options.rotation musí obsahovat konečné x, y, z a w a nesmí mít téměř nulovou délku.
  • attachment_attach(), attachment_detach() a stav měnící metody při chybě vrací false. jolt_get_error() přečtěte ihned, než diagnostiku nahradí další Jolt volání.

Časté chyby#

ProjevPravděpodobná příčina a oprava
attachment_attach je undefinedMetoda byla zavolána globálně. Použijte player.attachment_attach(body, options) na JoltCharacter.
Pasažér obíhá kolem špatného boduposition obsahuje world coordinates. Zadejte offset v local-space tělesa.
Position se mění, ale model zůstává vzpřímenýsync() nezapisuje visual rotation. Aplikujte get_rotation() nebo get_rotation_euler() na renderovanou instanci či model.
Hráč nemůže chodit ani skákatBěhem full attachmentu jde o záměr. Nejprve jej odpojte, nebo pro pochozí pohyblivou geometrii použijte reference frame.
Hráč po výstupu prudce odletíPřevzatá point velocity je u rychle rotujícího attachmentu fyzikálně skutečná. Omezte angular speed vozidla nebo po odpojení použijte vlastní gameplay pravidlo.

Konfigurace přes settery#

GML
var seat = jolt_character_attachment(seat_body);
seat.set_position(0, -0.7, 1.2);
seat.set_rotation_euler(0, 0, 180);
player.attachment_attach(seat);

Změna settings nemění již aktivní attachment; zavolej attachment_attach znovu. Settings settery vracejí self; attachment_attach vrací Boolean. Staré názvy attach_to_body, detach_from_body a is_attached nejsou aktuální metody.

Ověřené kontrakty operací#

Následující kontrakty rozlišují jednotky, návratové hodnoty, chyby a životnost podle aktuální implementace. Nevynechávej kontrolu výsledku: false, 0 a undefined mohou mít u různých metod odlišný význam.

Symbol / vlastníkSignaturaKontrakt operace
jolt_character_attachmentjolt_character_attachment(body=undefined)Vytvoří pouze nastavení, body volitelné (undefined); nevyžaduje svět, nevytváří fyziku. Vrací JoltCharacterAttachmentSettings, použij character.attachment_attach(settings).
JoltCharacter.attachment_attachJoltCharacter.attachment_attach(body, options = undefined)Živý JoltBody stejného světa + options, nebo JoltCharacterAttachmentSettings. Boolean. Místní position default {0, 0, 0} m; rotation XYZW má přednost před rotation_euler XYZ° (default identity). Přepne na následování hosta, zruší reference frame a čekající skok; není samostatný chodící solver.
JoltCharacter.attachment_detachJoltCharacter.attachment_detach()Boolean; odpojí Character se zachováním rychlosti hosta podle native detach, hosta nezničí.
JoltCharacter.attachment_get_bodyJoltCharacter.attachment_get_body()Živý managed host nebo undefined.
JoltCharacter.attachment_get_positionJoltCharacter.attachment_get_position()Místní offset {x, y, z} v m vůči hostu, nikoliv světová pozice ruky/postavy; undefined při chybě čtení. Stav attachmentu kontroluj samostatně.
JoltCharacter.attachment_get_rotationJoltCharacter.attachment_get_rotation()Místní quaternion {x, y, z, w} vůči hostu, nikoliv světová orientace; undefined při chybě čtení.
JoltCharacter.attachment_is_activeJoltCharacter.attachment_is_active()Boolean aktuálního attachmentu; false i při chybě.
JoltCharacter.get_rotationJoltCharacter.get_rotation()Světová orientace Characteru: quaternion {x, y, z, w}, nebo Euler {x, y, z} ve stupních podle názvu; undefined při chybě.
JoltCharacter.get_rotation_eulerJoltCharacter.get_rotation_euler()Světová orientace Characteru: quaternion {x, y, z, w}, nebo Euler {x, y, z} ve stupních podle názvu; undefined při chybě.
JoltCharacterAttachmentSettings.set_bodyJoltCharacterAttachmentSettings.set_body(body)Vrací self, mění pouze nastavení pro příští attachment_attach. Position je místní v m; rotation očekává struct XYZW a kopíruje složky; Euler XYZ ve stupních zruší předchozí quaternion. Validace proběhne při attachment_attach, živý attachment se tím nepřenastaví.
JoltCharacterAttachmentSettings.set_positionJoltCharacterAttachmentSettings.set_position(x,y,z)Vrací self, mění pouze nastavení pro příští attachment_attach. Position je místní v m; rotation očekává struct XYZW a kopíruje složky; Euler XYZ ve stupních zruší předchozí quaternion. Validace proběhne při attachment_attach, živý attachment se tím nepřenastaví.
JoltCharacterAttachmentSettings.set_rotationJoltCharacterAttachmentSettings.set_rotation(rotation)Vrací self, mění pouze nastavení pro příští attachment_attach. Position je místní v m; rotation očekává struct XYZW a kopíruje složky; Euler XYZ ve stupních zruší předchozí quaternion. Validace proběhne při attachment_attach, živý attachment se tím nepřenastaví.
JoltCharacterAttachmentSettings.set_rotation_eulerJoltCharacterAttachmentSettings.set_rotation_euler(x,y,z)Vrací self, mění pouze nastavení pro příští attachment_attach. Position je místní v m; rotation očekává struct XYZW a kopíruje složky; Euler XYZ ve stupních zruší předchozí quaternion. Validace proběhne při attachment_attach, živý attachment se tím nepřenastaví.