vehiclelayouts.meta explicado: assentos, pontos de entrada e animações

Por Nilo3D · Atualizado:

O vehiclelayouts.meta descreve como os peds usam um veículo: quais assentos ele tem, por onde eles entram e quais animações tocam ao entrar, ficar sentado e sair. Um veículo escolhe um layout pelo nome no campo layout do vehicles.meta. Com um layout personalizado, um veículo add-on ganha sua própria pose de pilotagem ou animação de entrada sem mudar nenhum outro veículo.

O que é um layout de veículo?

Um layout é uma lista nomeada de assentos e pontos de entrada. Cada assento junta uma definição de assento (qual bone, quais vizinhos) com uma definição de animação de assento (quais clips tocam nele). Cada ponto de entrada junta uma definição de porta com uma definição de animação de entrada. Tudo é referenciado pelo nome, então um layout pode reaproveitar partes dos layouts originais.

Este é o LAYOUT_STANDARD original, o padrão dos carros, resumido aos dois assentos da frente:

<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>

Como o vehiclelayouts.meta é estruturado?

O elemento raiz é CVehicleMetadataMgr. Ele guarda uma lista para cada tipo de definição. Um arquivo só precisa das listas em que adiciona algo. Os nomes que ele referencia mas não define vêm dos arquivos do próprio jogo.

ListaTipo do itemO que define
VehicleLayoutInfosCVehicleLayoutInfoO layout: assentos, pontos de entrada, flags.
VehicleSeatInfosCVehicleSeatInfoUm assento: bone, links de troca de assento, flags do assento.
VehicleSeatAnimInfosCVehicleSeatAnimInfoAnimações usadas enquanto se está em um assento, configuração de drive-by.
VehicleEntryPointInfosCVehicleEntryPointInfoUma entrada: bone da porta, lado, a quais assentos ela dá acesso.
VehicleEntryPointAnimInfosCVehicleEntryPointAnimInfoAnimações de entrar e sair por um ponto de entrada.
ClipSetMapsCClipSetMapListas nomeadas de clip sets para as quais os anim infos apontam.
VehicleDriveByInfos, VehicleDriveByAnimInfosMirar e atirar de um assento.
AnimRateSets, BicycleInfos, VehicleExtraPointsInfos, EntryAnimVariations, VehicleCoverBoundOffsetInfos, VehicleExplosionInfosVelocidades de animação, pedalada de bicicleta, posições extras de entrada, variações de entrada, configurações de cobertura e de explosão.

Quais são os campos de um layout?

CampoSignificado
NameO nome do layout usado no campo layout do vehicles.meta.
SeatsUm item por assento, cada um com uma referência SeatInfo e uma SeatAnimInfo.
EntryPointsUm item por entrada, cada um com uma referência EntryPointInfo e uma EntryPointAnimInfo.
LayoutFlagsFlags de comportamento separadas por espaço (veja abaixo).
BicycleInfoConfiguração de pedalada para bicicletas, senão NULL.
AnimRateSetConjunto de velocidades de animação para entrar e sair.
HandsUpClipSetIdClip set da pose de mãos para cima (padrão busted_vehicle_std).
SteeringWheelOffsetPosição do volante usada para posicionar as mãos (padrão 0, 0.35, 0.32).
FirstPersonAdditiveIdleClipSets, FirstPersonRoadRageClipSetsClip sets de idle e de road rage em primeira pessoa.

Algumas das flags de layout, com o que os nomes dizem: NoDriver, StreamAnims, WarpIntoAndOut, BikeLeansUnlessMoving, UseSteeringWheelIk, UseLeanSteerAnims, MustCloseDoor, AutomaticCloseDoor, DisableJackingAndBusting, UseDoorOscillation, WarpInWhenStoodOnTop. O schema define 32 no total. Comece pelas flags do layout original mais próximo do seu veículo e mude uma de cada vez.

Como se definem os assentos e os pontos de entrada?

Um assento fica preso a um bone do modelo do veículo, e um ponto de entrada a um bone de porta. Se o modelo não tiver o bone que a definição indica, aquele assento ou aquela porta não tem como funcionar. Estes são o assento do motorista e a porta do motorista originais de um carro:

<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 em que o ped fica preso. Carros usam seat_dside_f, seat_pside_f, seat_dside_r e seat_pside_r (lado do motorista e lado do passageiro, frente e trás).
ShuffleLinkAssento para o qual o ped desliza, por exemplo do passageiro para o motorista.
RearSeatLinkO assento atrás deste.
SeatFlagsPor exemplo IsFrontSeat, IsIdleSeat, NoIndirectExit, KeepOnHeadProp, FakeSeat.
DoorBoneName, DoorHandleBoneNameBones da porta e da maçaneta até onde o ped anda e estende a mão, por exemplo door_dside_f e handle_dside_f. Ficam vazios em veículos sem portas.
WindowIdFRONT_LEFT, FRONT_RIGHT, REAR_LEFT, REAR_RIGHT, MID_LEFT, MID_RIGHT, FRONT_WINDSCREEN, REAR_WINDSCREEN ou INVALID.
VehicleSideSIDE_LEFT, SIDE_RIGHT ou SIDE_REAR.
AccessableSeatsAssentos que podem ser alcançados por este ponto de entrada. A grafia com a é o nome real da tag.

Como as animações se ligam a um assento?

As animações chegam a um assento por quatro ligações. Cada ligação é uma busca por nome, então uma quebra em qualquer ponto da cadeia deixa você com a animação original ou sem nenhuma.

  1. O arquivo de animação, um clip dictionary (.ycd), vai na pasta stream do resource.
  2. Um clip set no clip_sets.xml dá a esse dicionário um nome de clip set. Ele é carregado com data_file 'CLIP_SETS_FILE'.
  3. Um CClipSetMap no vehiclelayouts.meta lista esse nome de clip set em ClipSetId.
  4. Um seat anim info aponta para o map com InsideClipSetMap (clips tocados enquanto sentado), e um entry point anim info com EntryClipSetMap, ExitClipSetMap e 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>

O jogo pede clips a um clip set por nomes fixos, então um dicionário personalizado mantém os nomes de clip do dicionário original que ele substitui e só muda o movimento dentro deles.

Como dar a um veículo uma animação própria?

Crie um layout com um nome novo, copie o layout original que o veículo usaria normalmente e substitua só as referências que você quer mudar. Tudo o que você não redefine continua apontando para as definições originais.

<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>

Depois coloque <layout>LAYOUT_MYBIKE</layout> no vehicles.meta. Como o layout tem nome próprio, nenhum outro veículo do servidor muda. É assim que o Coil S-Cooter ganha a pose de pilotagem em pé e os hoverboards a postura deles: um layout personalizado, clip sets e dicionários de animação personalizados, sem nenhum script.

Duas regras mantêm isso funcionando. Use nomes que nenhum outro resource usa, já que layouts, assentos e clip set maps são buscados pelo nome no jogo inteiro. E o arquivo de layout tem que carregar antes do vehicles.meta, porque o veículo busca seu layout na hora em que é registrado. O FiveM cuida dessa ordem sozinho, como explicado na referência de data_file.

Um exemplo completo de veículo com layout próprio está em como um hoverboard FiveM funciona sem script.

Perguntas frequentes

O que o campo layout do vehicles.meta faz?
Ele indica a entrada do vehiclelayouts.meta que o veículo usa para seus assentos, pontos de entrada e animações. O padrão é LAYOUT_STANDARD.
Preciso de um vehiclelayouts.meta em um carro add-on?
Não. Um carro normal pode usar um layout original como LAYOUT_STANDARD. Você só precisa de um arquivo próprio para assentos personalizados, animações personalizadas ou uma quantidade incomum de assentos.
Como carrego o vehiclelayouts.meta no FiveM?
Liste o arquivo em files no fxmanifest.lua e adicione data_file 'VEHICLE_LAYOUTS_FILE' com o mesmo caminho. Clip sets personalizados são carregados com data_file 'CLIP_SETS_FILE'.
Por que a animação personalizada do meu veículo não toca?
Confira a cadeia em ordem: o .ycd está em stream, o clip set do clip_sets.xml indica esse dicionário, o clip set map do vehiclelayouts.meta indica esse clip set, o anim info do assento ou da entrada referencia o map, e o vehicles.meta usa o nome do seu layout.
Um layout personalizado muda outros veículos?
Não, se ele tiver nome próprio. Só usam o layout os veículos cuja entrada no vehicles.meta aponta para ele.

Fontes

Produtos deste guia

Todos os guias