My Try To Replicate Karlson Movement

I used the tutorial dani made for his movement and tried remaking it in roblox
here is my try
feel free to change it

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart: BasePart = character:WaitForChild("HumanoidRootPart")
local camera = workspace.CurrentCamera
local userInput = game:GetService("UserInputService")
local runService = game:GetService("RunService")

local Rad2Deg = 180 / math.pi
local Deg2Rad = math.pi / 180

-- Movement variables
local moveSpeed = 700
local maxSpeed = 20
local grounded = false
local jumpForce = 110
local jumpCooldown = 0.25
local readyToJump = true
local crouching = false
local counterMovement = 0.175
local threshold = 0.01
local maxSlopeAngle = 35

-- Crouching and sliding
local crouchScale = Vector3.new(1, 0.5, 1)
local playerScale = humanoidRootPart.Size
local slideForce = 400
local slideCounterMovement = 0.2

-- Input variables
local xInput, yInput = 0, 0
local jumping = false
local crouching = false

-- Gravity and movement vectors
local normalVector = Vector3.new(0, 1, 0)

-- Camera rotation variables
local xRotation = 0
local sensitivity = 50
local sensMultiplier = 1

function DeltaAngle(currentAngle, targetAngle)
	local difference = targetAngle - currentAngle
	local delta = (difference + 180) % 360 - 180
	return delta
end

-- Function to reset jump
local function ResetJump()
	readyToJump = true
end

-- Function to detect input
local function GetInput()
	xInput = userInput:IsKeyDown(Enum.KeyCode.D) and -1 or userInput:IsKeyDown(Enum.KeyCode.A) and 1 or 0
	yInput = userInput:IsKeyDown(Enum.KeyCode.W) and 1 or userInput:IsKeyDown(Enum.KeyCode.S) and -1 or 0

	jumping = userInput:IsKeyDown(Enum.KeyCode.Space)
	crouching = userInput:IsKeyDown(Enum.KeyCode.C)
end

local function FindVelRelativeToLook()
	local lookAngle = humanoidRootPart.Orientation.Y
	local moveAngle = math.atan2(humanoidRootPart.Velocity.X, humanoidRootPart.Velocity.Z) * Rad2Deg

	local u = DeltaAngle(lookAngle, moveAngle)
	local v = 90 - u

	local magnitude = humanoidRootPart.Velocity.Magnitude
	local yMag = magnitude * math.cos(u * Deg2Rad)
	local xMag = magnitude * math.cos(v * Deg2Rad)

	return Vector2.new(xMag, yMag)
end

local function Jump()
	if grounded and readyToJump then
		readyToJump = false

		humanoidRootPart:ApplyImpulse(Vector3.new(0, 1, 0) * jumpForce * 1.5)
		humanoidRootPart:ApplyImpulse(normalVector * jumpForce * 0.5)

		local vel = humanoidRootPart.Velocity
		if humanoidRootPart.Velocity.Y < 0.5 then
			humanoidRootPart.Velocity = Vector3.new(vel.X, 0, vel.Z)
		elseif humanoidRootPart.Velocity.Y > 0 then
			humanoidRootPart.Velocity = Vector3.new(vel.X, vel.Y / 2, vel.Z)
		end

		wait(jumpCooldown)
		ResetJump()
	end
end

local function CounterMovement(floatX, floatY, Mag, dt)
	if not grounded or jumping then
		return
	end

	if crouching then
		humanoidRootPart:ApplyImpulse(-humanoidRootPart.Velocity.Unit * slideCounterMovement * moveSpeed * dt)
		return
	end

	local velocity = humanoidRootPart.Velocity
	local rightVector = humanoidRootPart.CFrame.RightVector
	local lookVector = humanoidRootPart.CFrame.LookVector

	if math.abs(Mag.X) > threshold then
		if floatX > 0 and Mag.X > 0 or floatX < 0 and Mag.X < 0 then
			humanoidRootPart:ApplyImpulse(moveSpeed * rightVector * dt * -Mag.X * counterMovement)
			print("cm x")
		end
	end

	if math.abs(Mag.Y) > threshold then
		if floatY > 0 and Mag.Y > 0 or floatY < 0 and Mag.Y < 0 then
			humanoidRootPart:ApplyImpulse(moveSpeed * lookVector * dt * -Mag.Y * counterMovement)
			print("cm y")	
		end
	end
		
	local speed = math.sqrt(math.pow(velocity.X, 2) + math.pow(velocity.Z, 2))
	if speed > maxSpeed then
		local fallout = humanoidRootPart.Velocity.Y
		local norm = humanoidRootPart.Velocity.Unit
			
		humanoidRootPart.Velocity = Vector3.new(norm.X, fallout, norm.Z)
	end
end

-- Handle movement using BodyVelocity
local function Movement(dt)
	humanoidRootPart:ApplyImpulse(Vector3.new(0, -1, 0) * dt * 10)

	-- Calculate player direction based on camera look direction
	local mag = FindVelRelativeToLook()
	local xMag, yMag = mag.X, mag.Y

	--CounterMovement(xInput, yInput, mag, dt)

	if readyToJump and jumping then
		Jump()
	end

	if crouching and grounded and readyToJump then
		humanoidRootPart:ApplyImpulse(Vector3.new(0, -1, 0) * dt * 3000)
		return
	end

	if (xInput > 0 and xMag > maxSpeed) then xInput = 0 end
	if (xInput < 0 and xMag < -maxSpeed) then xInput = 0 end
	if (yInput > 0 and yMag > maxSpeed) then yInput = 0 end
	if (yInput < 0 and yMag < -maxSpeed) then yInput = 0 end

	local Multiplier = 1
	local MultiplierV = 1

	if not grounded then
		Multiplier = 0.5
		MultiplierV = 0.5
	end

	if grounded and crouching then
		MultiplierV = 0
	end

	humanoidRootPart:ApplyImpulse(humanoidRootPart.CFrame.LookVector * yInput * moveSpeed * dt * Multiplier * MultiplierV)
	humanoidRootPart:ApplyImpulse(humanoidRootPart.CFrame.RightVector * xInput * moveSpeed * dt * Multiplier)
end

-- Function to check if player is grounded
local function CheckGround()
	-- Use raycasting to check if the player is grounded
	local rayOrigin = humanoidRootPart.Position
	local rayDirection = Vector3.new(0, -1, 0) -- Ray pointing downwards
	local ray = Ray.new(rayOrigin, rayDirection * 5) -- Length of ray (adjust as needed)
	local hit, hitPosition = workspace:FindPartOnRayWithIgnoreList(ray, {character})

	if hit then
		grounded = true
	else
		grounded = false
	end
end

-- Main game loop
runService.RenderStepped:Connect(function(dt)
	GetInput()
	CheckGround()

	-- Handle movement
	Movement(dt)
end)

edit: make everything except HumanoidRootPart massless

2 Likes

You could’ve included a video, you expect everyone to create a script and paste it just to test it?

I dont expect anything at all
and Im too lazy to make a video