LinearVelocity becoming Inconsistent at high speeds

Hello. I’ve encountered a really annoying behavior with LinearVelocity that I just can’t seem to fix.
At high velocity values, the movement from LinearVelocity becomes highly inconsistent at the start and end of the movement, veering off course. I have no clue why this is happening and any insight on what might be causing this would be greatly appreciated.

I’ve included some videos of the behavior at low and high speeds.

Low Speeds (30): Watch Low-Speed Movement | Streamable

High Speeds (500): Watch High-Speed Movement | Streamable

As you can see, at 500 Studs/Second the LinearVelocity begins making the character perform elliptical movements, which is highly inconsistent and not what I want.
500 might seems like an absurd extreme, however I intend to use LinearVelocity in a Dash System so I require consistent and smooth movements at high speeds using LinearVelocity.

Here is the relevant code I use. Its a LocalScript located within StarterPlayerScripts:

local Players = game:GetService("Players")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Camera = workspace.CurrentCamera
local LocalPlayer = Players.LocalPlayer
local Character = Players.LocalPlayer.Character

local SPEED = 500

function XZVectors()
	local Up = Camera.CFrame.UpVector
	local Right = Camera.CFrame.RightVector
	local Look = Camera.CFrame.LookVector
	return (Up*Vector3.new(1, 0, 1)).Unit, (Right*Vector3.new(1, 0, 1)).Unit, (Look*Vector3.new(1, 0, 1)).Unit
end

local DIRECTIONS = {
	[Enum.KeyCode.W] = function()
		local _, _, Look = XZVectors()
		return Look
	end,
	[Enum.KeyCode.A] = function()
		local _, Right = XZVectors()
		return -Right
	end,
	[Enum.KeyCode.S] = function()
		local _, _, Look = XZVectors()
		return -Look
	end,
	[Enum.KeyCode.D] = function()
		local _, Right = XZVectors()
		return Right
	end,
}

local Keys = {
	[Enum.KeyCode.W] = {
		Held = false,
	},
	[Enum.KeyCode.A] = {
		Held = false
	},
	[Enum.KeyCode.S] = {
		Held = false
	},
	[Enum.KeyCode.D] = {
		Held = false
	},
}

local function Update()
	local vector = Vector3.zero
	for key, keyData in pairs(Keys) do
		if keyData.Held then
			vector += DIRECTIONS[key]()
		end
	end

	if vector == Vector3.zero then
		LocalPlayer.Character.LinearVelocity.PlaneVelocity = Vector2.zero
		LocalPlayer.Character.LinearVelocity.Enabled = false
		return
	end
	vector = vector.Unit
	LocalPlayer.Character.LinearVelocity.PlaneVelocity = Vector2.new(vector.X, vector.Z)*SPEED
	LocalPlayer.Character.LinearVelocity.Enabled = true
	
	local visualizer = Instance.new("Part")
	visualizer.Size = Vector3.new(1, 1, 1)
	visualizer.Anchored = true
	visualizer.CanCollide = false
	visualizer.Transparency = 0.5
	visualizer.Color = Color3.new(1, 0, 0)
	
	visualizer.CFrame = CFrame.new(LocalPlayer.Character.HumanoidRootPart.Position)
	visualizer.Parent = workspace
	
	task.defer(function()
		task.wait(3)
		visualizer:Destroy()
	end)
end

local function input(InputObject: InputObject, gameProcessedEvent: boolean)
	if gameProcessedEvent then
		return
	end

	if InputObject.UserInputType ~= Enum.UserInputType.Keyboard then
		return
	end

	if not DIRECTIONS[InputObject.KeyCode] then
		return
	end

	if InputObject.UserInputState == Enum.UserInputState.Begin then
		Keys[InputObject.KeyCode].Held = true
	elseif InputObject.UserInputState == Enum.UserInputState.End then
		Keys[InputObject.KeyCode].Held = false
	end
end

UserInputService.InputBegan:Connect(input)
UserInputService.InputEnded:Connect(input)
RunService.Heartbeat:Connect(Update)

And here are the settings I use for the LinearVelocity:

	LinearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Plane
	LinearVelocity.PrimaryTangentAxis = Vector3.new(1, 0, 0)
	LinearVelocity.SecondaryTangentAxis = Vector3.new(0, 0, 1)
	LinearVelocity.MaxPlanarAxesForce = Vector2.new(30000, 30000)
	LinearVelocity.Parent = LocalPlayer.Character
	LinearVelocity.ForceLimitMode = Enum.ForceLimitMode.PerAxis

I greatly appreciate any advice or insights on how I should go about fixing this, or what could be causing the problem.

Here is a Place File that demonstrates the Problem (I modified the script to be within StarterCharacter, which is something I probably should’ve done already :sweat_smile:):
LinearVelocity Inconsistencies.rbxl (53.8 KB)

1 Like

Solved.
For some strange reason, setting LinearVelocity.ForceLimitMode = Enum.ForceLimitMode.PerAxis in Plane mode produces this behavior, but setting LinearVelocity.ForceLimitMode = Enum.ForceLimitMode.Magnitude does not. I have 0 clue why this is the case and would greatly appreciate any explanation.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.