Mecânicas dinâmicas como correr em paredes e subir em parapeitos tornam qualquer jogo mais empolgante. Tentar criá-las apenas com o Humanoid padrão gera travamentos de colisão e perda de impulso.
Usando as restrições físicas modernas do Luau (`LinearVelocity` e `VectorForce`) em conjunto com Raycasts direcionais, você constrói uma jogabilidade de plataforma AAA estável em qualquer plataforma.
1. Sobrescrevendo Estados do Humanoid para Parkour Fluido
Estruturação da máquina de estados de movimento:
- Desativar Estados de Conflito: Ao correr na parede, desative a escalada padrão e a queda livre para evitar que a animação padrão quebre a física.
- Propriedade de Rede: Configure a propriedade de rede do RootPart para o cliente no servidor, eliminando o atraso de resposta.
- Máquina de Estados: Divida o movimento em estados claros (Andar, Correr, WallRun, Pendurado, Pular).
2. Raycasts Direcionais e Vetor Normal da Parede
Detectando paredes e calculando a trajetória de avanço:
- Sondas Laterais: Dispare raios a partir da cintura e dos ombros (3.5 studs) para identificar paredes verticais.
- Verificação de Inclinação: Garanta que a superfície seja perpendicular ao chão (75° a 105°) para ignorar rampas.
- Produto Vetorial: Use
wallNormal:Cross(Vector3.yAxis)para encontrar a direção que corre paralela à parede.
3. Restrições Físicas: LinearVelocity e VectorForce
Substituindo os antigos BodyMovers por soluções modernas:
- LinearVelocity para Velocidade Constante: Garante impulso contínuo sem ser desacelerado pelo atrito.
- VectorForce Antigravidade: Neutraliza a gravidade de 196.2 studs/s² com uma força vertical proporcional à massa.
- Queda Progressiva: Reduza a força para cima após 2 segundos para criar um arco de queda realista.
-- Controlador de Wall Running no Cliente
local RunService = game:GetService("RunService")
local WallRun = {}
WallRun.__index = WallRun
function WallRun.new(character)
local self = setmetatable({}, WallRun)
self.Char = character
self.RootPart = character:WaitForChild("HumanoidRootPart")
self.Humanoid = character:WaitForChild("Humanoid")
local att = Instance.new("Attachment", self.RootPart)
local lv = Instance.new("LinearVelocity")
lv.Attachment0 = att
lv.MaxForce = 15000
lv.RelativeTo = Enum.ActuatorRelativeTo.World
lv.Enabled = false
lv.Parent = self.RootPart
self.Attachment = att
self.LinearVelocity = lv
self.IsRunning = false
return self
end
function WallRun:CheckWall(side)
local rightVec = self.RootPart.CFrame.RightVector
local rayDir = (side == "Left" and -rightVec or rightVec) * 3.5
local params = RaycastParams.new()
params.FilterDescendantsInstances = {self.Char}
params.FilterType = Enum.RaycastFilterType.Exclude
return workspace:Raycast(self.RootPart.Position, rayDir, params)
end
function WallRun:Start(hitNormal, forwardDir)
self.IsRunning = true
self.LinearVelocity.VectorVelocity = forwardDir * 32 + Vector3.new(0, 4, 0)
self.LinearVelocity.Enabled = true
self.Humanoid:ChangeState(Enum.HumanoidStateType.Physics)
end
function WallRun:Stop()
self.IsRunning = false
self.LinearVelocity.Enabled = false
self.Humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
end
return WallRun
4. Agarre de Bordas e Transição de Subida (Mantle)
Detectando corrimãos e executando a escalada:
- Raycast Duplo: Um raio frontal no peito detecta a parede e outro de cima para baixo localiza a borda exata.
- Fixação com AlignPosition: Trave o avatar na borda ao segurar para permitir que o jogador fique pendurado.
- Curva de Subida Bézier: Ao pressionar pulo, eleve o RootPart em uma curva suave por cima do obstáculo.
5. Controles para Celular e Validação no Servidor
Acessibilidade em telas sensíveis ao toque e segurança:
- Botões Tácteis com bom espaçamento: Mapeie as ações para botões de pelo menos 48x48 pixels no mobile.
- Travamento de Velocidade no Servidor: Monitore a velocidade do jogador entre os quadros para evitar cheats de voo.
- Confirmação de Parede: O servidor executa seus próprios raios para validar a existência da parede utilizada.
Frequently Asked Questions
Por que usar LinearVelocity em vez de BodyVelocity?
BodyVelocity é um recurso antigo e descontinuado. LinearVelocity é moderno, respeita a massa do personagem e evita comportamentos erráticos.
Como manter o personagem na mesma altura durante a corrida na parede?
Aplicando uma força para cima que compense exatamente a gravidade da experiência por meio de VectorForce ou LinearVelocity.
Como calcular o vetor de movimento junto à parede?
Calculando o produto vetorial entre a normal da parede e o vetor vertical para cima (0, 1, 0).
Como o servidor previne trapaças de velocidade no parkour?
Validando se existem paredes reais perto do jogador e limitando o deslocamento máximo permitido por segundo.