How to rotate the players velocity relative to a part

I’ve made a rail grinding script and I want to make the player have their momentum “rotate” in the direction of the next rail they touch/grind on

The issue is that the player doesn’t maintain their speed when a new rail is turned in a different direction

video example:

I’ve tried searching for ways to rotate the players velocity, but the ones I’ve found aren’t what I’m looking for and I don’t think I can edit them to my liking in order to fit it into the script

this is the script. It goes into a normal script inside of a part

local p = script.Parent.Ptravel
local valuepart = script.Parent.Ptravel
local mainp = script.Parent.Part
script.Parent.VisualRail.Touched:Connect(function(t)
	print("TOUCHED")
	local h=t.Parent:FindFirstChild'HumanoidRootPart'

	if h:FindFirstChild("RailVelocity") == nil and h:FindFirstChild("RailWeldConstraint") == nil then
		local b = Instance.new("BodyVelocity")
		b.Name = ("RailVelocity")
		
		b.Parent = h


		local weld = Instance.new("WeldConstraint")
		p.Position = h.Position
		weld.Name = ("RailWeldConstraint")
		weld.Parent = h
		weld.Part0 = h
		weld.Part1 = p

		local objv1 = Instance.new("ObjectValue")
		objv1.Value = valuepart

		objv1.Parent = h
		objv1.Name = ("RailOwner")

		wait(2)

	elseif h:FindFirstChild("RailOwner").Value ~= valuepart then

		h:FindFirstChild("RailWeldConstraint"):Destroy()
		h:FindFirstChild("RailVelocity"):Destroy()
		h:FindFirstChild("RailOwner"):Destroy()



	end
	repeat wait()  until not h or not h.Parent or not script or not script.Parent or not p.Parent.Part.PrismaticConstraint or p.Parent.Part.PrismaticConstraint.CurrentPosition >= p.Parent.Part.PrismaticConstraint.UpperLimit or h.Parent:WaitForChild("Humanoid").Health<=0
	h:FindFirstChild("RailWeldConstraint"):Destroy()
	h:FindFirstChild("RailVelocity"):Destroy()
	h:FindFirstChild("RailOwner"):Destroy()


end)

make the body velocity relative to the attachment (nevermind, i was thinking about linear velocity)

so then what do I do in order to make this work

well, first of all body movers are deprecated, you could use linear velocity then use relative to attachment, cause body velocity is always relative to the world axis, meaning it only pushes you in one direction.

Or you could also find a way to make the velocity relative to a direction, instead of an axis.

You could add an attachment to the part, then use Linear Velocity RelativeToAttachment and LineVelocity to get the part moving, then you could weld the HumanoidRootPart to the part.

local attachment = Instance.new("Attachment", part)

local lv = Instance.new("LinearVelocity", attachment)
lv.Attachment0 = attachment
lv.RelativeTo = Enum.ActuatorRelativeTo.Attachment0
lv.MaxForce = 12500
lv.VelocityConstraintMode = Enum.VelocityConstraintMode.Line
lv.LineDirection = part.CFrame.LookVector 
lv.LineVelocity = 25

local rootWeld = Instance.new("WeldConstraint", HumanoidRootPart)
rootWeld.Part0 = HumanoidRootPart
rootWeld.Part1 = part

I’m not exactly sure where to put this in my script, and even then this script looks like it turns the players velocity around in a fixed direction rather than the next direction they’re going

(in depth explanation of what I mean)

if the player is moving forwards on rail A and the next rail (rail B) points to the left, when the player touches rail B they go to the left.

If the player goes on that same rail but instead moves backwards rail B, when they touch rail A (which points to the right) they should go to the right

I might regret this action in the future, but from my experience, using deprecated body movers are going just fine for me. If there are any bigger issues that using deprecated stuff creates please inform me, otherwise I just want to rotate the players velocity (while fitting the description of the in depth explanation I described)