vehiclelayouts.meta explicado: asientos, puntos de entrada y animaciones

Por Nilo3D · Actualizado:

vehiclelayouts.meta describe cómo usan los peds un vehículo: qué asientos tiene, por dónde se suben y qué animaciones se reproducen al entrar, al estar sentados y al salir. Un vehículo elige un layout por nombre en el campo layout de vehicles.meta. Con un layout personalizado, un vehículo add-on consigue su propia postura de conducción o su propia animación de entrada sin cambiar ningún otro vehículo.

¿Qué es un layout de vehículo?

Un layout es una lista con nombre de asientos y puntos de entrada. Cada asiento empareja una definición de asiento (qué bone, qué vecinos) con una definición de animación de asiento (qué clips se reproducen en él). Cada punto de entrada empareja una definición de puerta con una definición de animación de entrada. Todo se referencia por nombre, así que un layout puede reutilizar piezas de los layouts originales.

Este es el LAYOUT_STANDARD original, el que usan los coches por defecto, reducido a sus dos asientos delanteros:

<Item type="CVehicleLayoutInfo">
  <Name>LAYOUT_STANDARD</Name>
  <Seats>
    <Item>
      <SeatInfo ref="SEAT_STANDARD_FRONT_LEFT" />
      <SeatAnimInfo ref="SEAT_ANIM_STANDARD_FRONT_LEFT" />
    </Item>
    <Item>
      <SeatInfo ref="SEAT_STANDARD_FRONT_RIGHT" />
      <SeatAnimInfo ref="SEAT_ANIM_STANDARD_FRONT_RIGHT" />
    </Item>
  </Seats>
  <EntryPoints>
    <Item>
      <EntryPointInfo ref="ENTRY_POINT_STANDARD_FRONT_LEFT" />
      <EntryPointAnimInfo ref="ENTRY_POINT_ANIM_STANDARD_FRONT_LEFT" />
    </Item>
    <Item>
      <EntryPointInfo ref="ENTRY_POINT_STANDARD_FRONT_RIGHT" />
      <EntryPointAnimInfo ref="ENTRY_POINT_ANIM_STANDARD_FRONT_RIGHT" />
    </Item>
  </EntryPoints>
  <LayoutFlags>StreamAnims UseDoorOscillation UseLeanSteerAnims UseSteeringWheelIk</LayoutFlags>
  <BicycleInfo ref="NULL" />
  <AnimRateSet ref="STD_LOW_ANIM_RATE_SET" />
  <HandsUpClipSetId>busted_vehicle_std</HandsUpClipSetId>
  <SteeringWheelOffset x="0.000000" y="0.350000" z="0.320000" />
</Item>

¿Cómo está estructurado vehiclelayouts.meta?

El elemento raíz es CVehicleMetadataMgr. Contiene una lista por cada tipo de definición. Un archivo solo necesita las listas a las que añade algo. Los nombres que referencia pero no define se toman de los archivos del propio juego.

ListaTipo de elementoQué define
VehicleLayoutInfosCVehicleLayoutInfoEl layout: asientos, puntos de entrada, flags.
VehicleSeatInfosCVehicleSeatInfoUn asiento: bone, enlaces para cambiar de asiento, flags del asiento.
VehicleSeatAnimInfosCVehicleSeatAnimInfoAnimaciones que se usan estando en un asiento, configuración de drive-by.
VehicleEntryPointInfosCVehicleEntryPointInfoUna forma de entrar: bone de la puerta, lado, a qué asientos da acceso.
VehicleEntryPointAnimInfosCVehicleEntryPointAnimInfoAnimaciones para subir y bajar por un punto de entrada.
ClipSetMapsCClipSetMapListas con nombre de clip sets a las que apuntan los anim infos.
VehicleDriveByInfos, VehicleDriveByAnimInfosApuntar y disparar desde un asiento.
AnimRateSets, BicycleInfos, VehicleExtraPointsInfos, EntryAnimVariations, VehicleCoverBoundOffsetInfos, VehicleExplosionInfosVelocidades de animación, pedaleo de bicicletas, posiciones de entrada extra, variaciones de entrada, configuraciones de cobertura y de explosión.

¿Cuáles son los campos de un layout?

CampoSignificado
NameEl nombre del layout que se usa en el campo layout de vehicles.meta.
SeatsUn elemento por asiento, cada uno con una referencia a un SeatInfo y a un SeatAnimInfo.
EntryPointsUn elemento por cada forma de entrar, cada uno con una referencia a un EntryPointInfo y a un EntryPointAnimInfo.
LayoutFlagsFlags de comportamiento separados por espacios (ver abajo).
BicycleInfoConfiguración de pedaleo para bicicletas; si no, NULL.
AnimRateSetConjunto de velocidades de animación para entrar y salir.
HandsUpClipSetIdClip set de la postura de manos arriba (por defecto busted_vehicle_std).
SteeringWheelOffsetPosición del volante que se usa para colocar las manos (por defecto 0, 0.35, 0.32).
FirstPersonAdditiveIdleClipSets, FirstPersonRoadRageClipSetsClip sets de reposo y de furia al volante en primera persona.

Algunos de los flags de layout, con lo que dicen sus nombres: NoDriver, StreamAnims, WarpIntoAndOut, BikeLeansUnlessMoving, UseSteeringWheelIk, UseLeanSteerAnims, MustCloseDoor, AutomaticCloseDoor, DisableJackingAndBusting, UseDoorOscillation, WarpInWhenStoodOnTop. El esquema define 32 en total. Parte de los flags del layout original más parecido a tu vehículo y cambia uno cada vez.

¿Cómo se definen los asientos y los puntos de entrada?

Un asiento está ligado a un bone del modelo del vehículo, y un punto de entrada a un bone de puerta. Si el modelo no tiene el bone que nombra la definición, ese asiento o esa puerta no pueden funcionar. Estos son el asiento del conductor y la puerta del conductor originales de un coche:

<Item type="CVehicleSeatInfo">
  <Name>SEAT_STANDARD_FRONT_LEFT</Name>
  <SeatBoneName>seat_dside_f</SeatBoneName>
  <ShuffleLink>SEAT_STANDARD_FRONT_RIGHT</ShuffleLink>
  <RearSeatLink>SEAT_STANDARD_REAR_LEFT</RearSeatLink>
  <DefaultCarTask>TASK_DRIVE_WANDER</DefaultCarTask>
  <SeatFlags>IsFrontSeat</SeatFlags>
  <HairScale value="-0.2750000" />
</Item>

<Item type="CVehicleEntryPointInfo">
  <Name>ENTRY_POINT_STANDARD_FRONT_LEFT</Name>
  <DoorBoneName>door_dside_f</DoorBoneName>
  <SecondDoorBoneName />
  <DoorHandleBoneName>handle_dside_f</DoorHandleBoneName>
  <WindowId>FRONT_LEFT</WindowId>
  <VehicleSide>SIDE_LEFT</VehicleSide>
  <AccessableSeats>
    <Item ref="SEAT_STANDARD_FRONT_LEFT" />
  </AccessableSeats>
  <VehicleExtraPointsInfo ref="EXTRA_VEHICLE_POINTS_STD_LEFT" />
  <Flags>BlockJackReactionUntilJackerIsReady</Flags>
  <BlockJackReactionSides>
    <Item>SIDE_LEFT</Item>
  </BlockJackReactionSides>
</Item>
CampoSignificado
SeatBoneNameBone al que se engancha el ped. Los coches usan seat_dside_f, seat_pside_f, seat_dside_r y seat_pside_r (lado del conductor y lado del pasajero, delante y detrás).
ShuffleLinkAsiento al que se desliza un ped, por ejemplo del pasajero al conductor.
RearSeatLinkEl asiento que está detrás de este.
SeatFlagsPor ejemplo IsFrontSeat, IsIdleSeat, NoIndirectExit, KeepOnHeadProp, FakeSeat.
DoorBoneName, DoorHandleBoneNameBones de la puerta y de la manilla hacia los que camina el ped y a los que alarga la mano, por ejemplo door_dside_f y handle_dside_f. Se dejan vacíos en los vehículos sin puertas.
WindowIdFRONT_LEFT, FRONT_RIGHT, REAR_LEFT, REAR_RIGHT, MID_LEFT, MID_RIGHT, FRONT_WINDSCREEN, REAR_WINDSCREEN o INVALID.
VehicleSideSIDE_LEFT, SIDE_RIGHT o SIDE_REAR.
AccessableSeatsAsientos a los que se puede llegar desde este punto de entrada. La grafía con a es el nombre real de la etiqueta.

¿Cómo se conectan las animaciones a un asiento?

Las animaciones llegan a un asiento pasando por cuatro enlaces. Cada enlace es una búsqueda por nombre, así que si la cadena se rompe en cualquier punto te quedas con la animación original o con ninguna.

  1. El archivo de animación, un diccionario de clips (.ycd), va en la carpeta stream del resource.
  2. Un clip set en clip_sets.xml le da a ese diccionario un nombre de clip set. Se carga con data_file 'CLIP_SETS_FILE'.
  3. Un CClipSetMap en vehiclelayouts.meta incluye ese nombre de clip set en ClipSetId.
  4. Un anim info de asiento apunta al mapa con InsideClipSetMap (clips que se reproducen estando sentado), y un anim info de punto de entrada con EntryClipSetMap, ExitClipSetMap y CommonClipSetMap.
<?xml version="1.0" encoding="UTF-8"?>
<fwClipSetManager>
  <clipSets>
    <Item type="fwClipSet" key="veh@bike@mybike@front@base">
      <fallbackId />
      <clipDictionaryName>veh@bike@mybike@front@base</clipDictionaryName>
      <clipItems />
      <moveNetworkFlags />
    </Item>
  </clipSets>
  <clipDictionaryMetadatas>
    <Item key="veh@bike@mybike@front@base">
      <streamingPolicy>SP_STREAMING</streamingPolicy>
      <memoryGroup>MG_Vehicle</memoryGroup>
      <streamingPriority>SP_Medium</streamingPriority>
    </Item>
  </clipDictionaryMetadatas>
</fwClipSetManager>

El juego le pide los clips a un clip set por nombres fijos, así que un diccionario personalizado conserva los nombres de clip del diccionario original al que sustituye y solo cambia el movimiento que llevan dentro.

¿Cómo le doy a un vehículo su propia animación?

Crea un layout con un nombre nuevo, copia el layout original que el vehículo usaría normalmente y reemplaza solo las referencias que quieras cambiar. Todo lo que no redefinas sigue apuntando a las definiciones originales.

<CVehicleMetadataMgr>
  <ClipSetMaps>
    <Item type="CClipSetMap">
      <Name>INSIDE_CLIPSET_MAP_MYBIKE_FRONT</Name>
      <Maps>
        <Item>
          <ClipSetId>veh@bike@mybike@front@base</ClipSetId>
          <VarClipSetId>InsideVarClipSet</VarClipSetId>
          <ConditionFlags />
          <InformationFlags />
        </Item>
      </Maps>
    </Item>
  </ClipSetMaps>

  <VehicleSeatAnimInfos>
    <Item type="CVehicleSeatAnimInfo">
      <Name>SEAT_ANIM_MYBIKE_FRONT</Name>
      <DriveByInfo ref="DRIVEBY_BIKE_SCOOTER" />
      <InsideClipSetMap ref="INSIDE_CLIPSET_MAP_MYBIKE_FRONT" />
      <!-- remaining tags copied from the stock seat anim info you start from -->
    </Item>
  </VehicleSeatAnimInfos>

  <VehicleLayoutInfos>
    <Item type="CVehicleLayoutInfo">
      <Name>LAYOUT_MYBIKE</Name>
      <Seats>
        <Item>
          <SeatInfo ref="SEAT_BIKE_FRONT" />
          <SeatAnimInfo ref="SEAT_ANIM_MYBIKE_FRONT" />
        </Item>
      </Seats>
      <EntryPoints>
        <Item>
          <EntryPointInfo ref="ENTRY_POINT_BIKE_FRONT_LEFT" />
          <EntryPointAnimInfo ref="ENTRY_POINT_ANIM_BIKE_SCOOTER_FRONT_LEFT" />
        </Item>
      </EntryPoints>
      <!-- flags and remaining tags copied from the stock layout -->
    </Item>
  </VehicleLayoutInfos>
</CVehicleMetadataMgr>

Después pon <layout>LAYOUT_MYBIKE</layout> en vehicles.meta. Como el layout tiene su propio nombre, no afecta a ningún otro vehículo del servidor. Así es como el Coil S-Cooter consigue su postura de conducción de pie y los hoverboards su postura: un layout personalizado, clip sets personalizados y diccionarios de animación, sin ningún script de por medio.

Para que esto no se rompa hay dos reglas. Usa nombres que ningún otro resource utilice, ya que los layouts, los asientos y los mapas de clip sets se buscan por nombre en todo el juego. Y asegúrate de que el archivo de layouts se carga antes que vehicles.meta, porque el vehículo busca su layout en el momento en que se registra. FiveM se encarga de ese orden por sí solo, como se explica en la referencia de data_file.

Un ejemplo completo de vehículo con su propio layout está en cómo funciona un hoverboard FiveM sin script.

Preguntas frecuentes

¿Qué hace el campo layout de vehicles.meta?
Nombra la entrada de vehiclelayouts.meta que el vehículo usa para sus asientos, puntos de entrada y animaciones. El valor por defecto es LAYOUT_STANDARD.
¿Necesito un vehiclelayouts.meta para un coche add-on?
No. Un coche normal puede usar un layout original como LAYOUT_STANDARD. Solo necesitas tu propio archivo para asientos personalizados, animaciones personalizadas o un número de asientos poco habitual.
¿Cómo cargo vehiclelayouts.meta en FiveM?
Decláralo en files en fxmanifest.lua y añade data_file 'VEHICLE_LAYOUTS_FILE' con la misma ruta. Los clip sets personalizados se cargan con data_file 'CLIP_SETS_FILE'.
¿Por qué no se reproduce la animación personalizada de mi vehículo?
Revisa la cadena en orden: el .ycd está en stream, el clip set de clip_sets.xml nombra ese diccionario, el mapa de clip sets de vehiclelayouts.meta nombra ese clip set, el anim info del asiento o de la entrada referencia el mapa, y vehicles.meta usa el nombre de tu layout.
¿Un layout personalizado cambiará otros vehículos?
No si tiene su propio nombre. Solo lo usan los vehículos cuya entrada de vehicles.meta nombra ese layout.

Fuentes

Productos de esta guía

Todas las guías