Character does a weird flick-back post lerping sequence

I’ve been making a mantling system very recently and it’s been going quite well

It works by emitting a forward raycast from the character and then emitting a downward raycast to find a ledge, if there is a ledge then the character is lerped into that target position

To not struggle with roblox collisions, i got the idea to split the lerping into 2 parts;

  1. Lerp player upwards until they’re at the same height as the target position
  2. Lerp player forward until they’re at target position

All of that works very well, except for one thing;
Post-mantle, the character does a really weird sudden flickback, which triggers the anti-cheat (anti-teleport) and I have no idea as to why it happens

I tried increasing the height of the target position slightly to account for slight offsets, but that didn’t change anything

I am now making the character’s legs non-collidable, but that doesn’t work either
I am out of ideas, and I need help

-- Helper functions;
local function SetLegsCollidability(character: Model, state: boolean)
	for _, limb: BasePart in character:GetChildren() do
		if limb.Name == 'Right Leg' or limb.Name == 'Left Leg' then
			limb.CanCollide = state
		end
	end
end

-- Main functions;
local function GetMantleTarget(origin: Vector3, direction: Vector3): Vector3
	local forwardResult = workspace:Raycast(origin, direction * mantleLength, mantleParams)
	local forwardPos = if forwardResult then forwardResult.Position else origin + Vector3.new(0, 2, 0) + direction * mantleLength 
	
	local downOrigin = forwardPos + Vector3.new(0, ledgeHeightCheck, 0)
	local downResult = workspace:Raycast(downOrigin, Vector3.new(0, -10, 0), mantleParams)
	if not downResult then return nil end
	
	return downResult.Position
end

local function MantlePlayer(player: Player, target: Vector3)
	local character = player.Character
	local root = character.PrimaryPart
	
	local startPosition = root.Position
	local targetPosition = target + Vector3.new(0, 10, 0)
	local midPosition = Vector3.new(startPosition.X, targetPosition.Y, startPosition.Z)
	
	local elapsed = 0
	local heartbeat: RBXScriptConnection = nil
	
	SetLegsCollidability(character, false)
	heartbeat = rService.Heartbeat:Connect(function(dt)
		elapsed += dt
		
		local alpha = math.clamp(elapsed / mantleTime, 0, 1)
		local upAlpha = alpha / 0.5
		local forwardAlpha = (alpha - 0.5) / 0.5
		
		local current = if alpha < 0.5 then startPosition:Lerp(midPosition, upAlpha) else midPosition:Lerp(targetPosition, forwardAlpha)
		local lookAt = root.CFrame.LookVector + root.Position
		
		root.CFrame = CFrame.lookAt(current, lookAt)
		if alpha < 1 then return end
		
		heartbeat:Disconnect()
		SetLegsCollidability(character, true)
	end)
end

I ended up working my way around this by setting the root’s AssemblyLinearVelocity to zero post lerping, aswell as anchoring the root for the duration of the lerp

it’s not perfect, but it works like i want it to

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