Criar veículos ágeis e estáveis no Roblox Studio exige compreender o solucionador PGS (Projected Gauss-Seidel). Usar os antigos BodyMovers causa travamentos, colisões imprevisíveis e lag no multiplayer.
A física atual do Roblox funciona com base em restrições (Constraints): SpringConstraints para amortecimento, CylindricalConstraints nas rodas, AlignOrientation contra capotamentos e Network Ownership dinâmico.
1. O Solucionador PGS e Estrutura de Baugrupos (Assemblies)
Como peças soldadas viram um único corpo rígido:
- Assemblies e RootPriority: Peças soldadas formam um único Assembly. Ajuste
RootPriorityno chassi para fixar a peça principal. - CustomPhysicalProperties: Alta fricção nos pneus (1.5) e chassi com centro de massa baixo evitam capotagens.
- Uso de Massless: Ative
Massless = trueem peças estéticas para não desequilibrar o centro de gravidade.
2. Suspensão com SpringConstraints
Amortecimento eficiente para qualquer terreno:
- FreeLength vs CurrentLength:
FreeLengthé o tamanho natural da mola para permitir curso vertical. - Stiffness e Damping: Rigidez suporta o peso e amortecimento corta oscilações contínuas.
- CylindricalConstraint: Previne folgas laterais e força a roda a se mover apenas verticalmente.
3. Restrições Modernas: AlignOrientation & AlignPosition
Substituição definitiva dos antigos BodyMovers:
- Fim dos BodyMovers: Entravam em conflito com o solver PGS, derrubando o desempenho.
- AlignOrientation Antiatolamento: Nivela a inclinação do veículo automaticamente, mantendo a direção livre.
- Responsiveness: Valores entre 15 e 30 garantem inclinação realista nas curvas.
-- Delegação de Network Ownership ao Piloto
local VehicleSeat = script.Parent.VehicleSeat
local Chassis = script.Parent.Chassis
VehicleSeat:GetPropertyChangedSignal("Occupant"):Connect(function()
local occupant = VehicleSeat.Occupant
if occupant then
local character = occupant.Parent
local player = game.Players:GetPlayerFromCharacter(character)
if player then
-- Delega o cálculo da física ao piloto
local success, err = pcall(function()
Chassis:SetNetworkOwner(player)
end)
if not success then
warn("Erro ao definir Network Owner:", err)
end
end
else
-- Piloto saiu: devolve a posse ao servidor
task.wait(0.2)
if not VehicleSeat.Occupant then
pcall(function()
Chassis:SetNetworkOwner(nil)
end)
end
end
end)
4. Network Ownership e Latência no Multiplayer
Acabando com o efeito elástico (rubberbanding):
- Latência de Entrada: Física no servidor gera atraso nas manobras do piloto.
- SetNetworkOwner(player): Quando o piloto sentar, execute
Chassis:SetNetworkOwner(player)para cálculo local. - Checagem no Servidor: Monitore velocidades suspeitas para barrar trapaças.
5. CollisionGroups e Otimização de Física
Mantendo 60 FPS estáveis mesmo em servidores cheios:
- Filtro de Colisão: Desative colisões entre rodas e pedestres para evitar bugs de arremesso.
- Desligar CanTouch/CanQuery: Remova checagens em peças internas do veículo.
- Modo de Espera (Sleep): Devolva o Network Ownership ao servidor (nil) quando o carro ficar vazio.
Frequently Asked Questions
Por que meu carro engasga ao dirigir no multiplayer?
A física está sendo calculada no servidor. Chame Chassis:SetNetworkOwner(player) para rodar o cálculo localmente sem latência.
Como evitar que o carro capote em curvas fechadas?
Deixe peças superiores como Massless para rebaixar o centro de massa e use AlignOrientation.
Qual a proporção ideal entre Stiffness e Damping?
Geralmente Damping fica entre 10% e 20% do valor de Stiffness para amortecer os impactos com firmeza.
Por que não usar BodyVelocity e BodyGyro hoje em dia?
São instâncias antigas que causam instabilidade no solver PGS. Migre para AlignOrientation ou LinearVelocity.
Como CollisionGroups melhoram a performance do jogo?
Ao impedir colisões desnecessárias entre peças mecânicas internas e pedestres, centenas de cálculos são economizados.