Any improvements that should be made to this R6 foot plant module?

The code below is made by x_o, I just modified it

local module = {}

local jumpPower = 40

local stances = {
	["None"] = {0.9, CFrame.new(0, -1, 0), 1},
	["Sprint"] = {1.3, CFrame.new(0, -1.1, 0), 0.8},
	["Crouch"] = {0.5, CFrame.new(0, -2, 0) * CFrame.Angles(-math.pi / 12, 0, 0), 0.5},
	["Prone"] = {0.3, CFrame.new(0, -2.4, 0) * CFrame.Angles(-math.pi / 2.1, 0, 0), 0}
}

local RunService = game:GetService("RunService")

local atn2, acs, floor = math.atan2, math.acos, math.floor
local pi = math.pi

local function LerpNumber(a, b, t)
	return a + (b - a) * t
end

local function IsNAN(x)
	return x ~= x
end

function module.new(Character, stride, defaultSpeed, cycleSpeed)
	local Connection
	local direction = Vector3.new(0, 0, -1)
	local left, right = 0, pi
	local rhipcf, lhipcf
	local Lefthit
	local LeftfootPosition
	local Righthit
	local RightfootPosition
	local BlacklistParams = RaycastParams.new()
	BlacklistParams.FilterType = Enum.RaycastFilterType.Blacklist
	BlacklistParams.IgnoreWater = true
	local humanoid = Character:FindFirstChildWhichIsA("Humanoid") or Character:WaitForChild("Humanoid", 3) or nil
	if humanoid.Health <= 0 or humanoid:GetState() == Enum.HumanoidStateType.Dead then return end
	local torso = Character:FindFirstChild("Torso") or Character:WaitForChild("Torso", 3) or nil
	local state = Character:FindFirstChild("State") or Character:WaitForChild("State", 3) or nil
	local hrp = Character:FindFirstChild("HumanoidRootPart") or Character:WaitForChild("HumanoidRootPart", 3) or nil
	if torso == nil or hrp == nil then return end
	local lefthip = torso:FindFirstChild("Left Hip") or torso:WaitForChild("Left Hip", 3) or nil
	local leftshoulder = torso:FindFirstChild("Left Shoulder") or torso:WaitForChild("Left Shoulder", 3) or nil 
	local rightshoulder = torso:FindFirstChild("Right Shoulder") or torso:WaitForChild("Right Shoulder", 3) or nil
	local righthip = torso:FindFirstChild("Right Hip") or torso:WaitForChild("Right Hip", 3) or nil
	local rootjoint = hrp:FindFirstChild("RootJoint") or hrp:FindFirstChild("Root Hip") or hrp:WaitForChild("RootJoint", 3) or hrp:WaitForChild("Root Hip", 3) or nil
	local l, e = lefthip.C1.Y, righthip.C1.Y
	lhipcf = CFrame.new(lefthip.C0.X, -l, lefthip.C0.Z)
	rhipcf = CFrame.new(righthip.C0.X, -e, righthip.C0.Z)
	Connection = RunService.Heartbeat:Connect(function(deltaTime)
		if Character ~= nil and humanoid ~= nil and humanoid.Health > 0 and rootjoint ~= nil and torso ~= nil and lefthip ~= nil and righthip ~= nil and RunService:IsRunning() then
			BlacklistParams.FilterDescendantsInstances = {Character, workspace.Projectiles, workspace.Humanoids, workspace.Humanoids.Boltons, workspace.Humanoids.Trojans, workspace.Camera}
			local lerp10 = math.min(deltaTime * 10, 1)
			local velocity = Vector3.new(torso.Velocity.X, 0, torso.Velocity.Z)
			if velocity.magnitude > 0.1 then
				direction = direction:Lerp(velocity.Unit, deltaTime * 10)
			end
			
			local climbing = humanoid:GetState() == Enum.HumanoidStateType.Climbing
			if climbing then
				velocity += Vector3.new(0, torso.Velocity.Y, 0)
				direction = torso.CFrame.LookVector
			end
			
			right = (right + (velocity.magnitude / defaultSpeed) * deltaTime * cycleSpeed) % (pi * 2)
			left = (left + (velocity.magnitude / defaultSpeed) * deltaTime * cycleSpeed) % (pi * 2)
			-- LEANING
			local localVelocity = hrp.CFrame:VectorToObjectSpace(velocity) * 0.2
			rootjoint.C0 = rootjoint.C0:Lerp(stances[state.Value][2], lerp10)
			rootjoint.C1 = CFrame.new(0, -1, 0) * CFrame.Angles(math.rad(localVelocity.Z), math.cos(right) * 0.1 - math.rad(localVelocity.X) * 2, math.rad(-localVelocity.X)):Inverse()
			local up = (velocity.Magnitude / defaultSpeed)
			
			-- RIGHT LEG
			local hip = (torso.CFrame * rhipcf).Position
			local ground = (torso.CFrame * CFrame.new(rhipcf.X, rhipcf.Y * 3, 0))
			if state.Value == "Prone" or climbing then
				ground = ground * CFrame.new(0, 0, -stride / 2)
			end
			ground = ground.Position
			local desiredPosition = (CFrame.new(ground, ground + direction) * CFrame.Angles(-right, 0, 0) * CFrame.new(0, 0, -stride / 2)).Position
			local distance = math.min((hip - desiredPosition).Magnitude, 3)
			local ray = Ray.new(hip, CFrame.new(hip, desiredPosition).LookVector * LerpNumber(3, distance, up))
			local hit1, footPosition1 = game.Workspace:FindPartOnRayWithIgnoreList(ray, BlacklistParams.FilterDescendantsInstances)
			if hit1 then
				if hit1.CanCollide == false then
					table.insert(BlacklistParams.FilterDescendantsInstances, hit1)
				end
			end
			distance = (hip - footPosition1).Magnitude
			local offset1 = (torso.CFrame * rhipcf):PointToObjectSpace(footPosition1)
			local x1, y1 = math.atan2(offset1.Z, offset1.Y), math.atan2(offset1.X, offset1.Y)
			righthip.C0 = rhipcf * CFrame.Angles(x1, 0, 0) * CFrame.Angles(0, 0, y1) * CFrame.Angles(0, pi, 0)
			if distance < 2 then
				local angle = -math.acos(distance / 2)
				local newCF1 = righthip.C0 * CFrame.Angles(-angle, 0, 0) * CFrame.new(0, -0.6, 0) * CFrame.Angles(angle * 1.6, 0, 0) * CFrame.new(0, 0.6, 0)
				righthip.C0 = newCF1
			end
			
			-- LEFT LEG
			local hip = (torso.CFrame * lhipcf).Position
			local ground = (torso.CFrame * CFrame.new(lhipcf.X, lhipcf.Y * 3, 0))
			if state.Value == "Prone" or climbing then
				ground = ground * CFrame.new(0, 0, -stride / 2)
			end
			ground = ground.Position
			local desiredPosition = (CFrame.new(ground, ground + direction) * CFrame.Angles(-left, 0, 0) * CFrame.new(0, 0, -stride / 2)).Position
			local distance = math.min((hip - desiredPosition).Magnitude, 3)
			local ray = Ray.new(hip, CFrame.new(hip, desiredPosition).LookVector * LerpNumber(3, distance, up))
			local hit, footPosition = game.Workspace:FindPartOnRayWithIgnoreList(ray, BlacklistParams.FilterDescendantsInstances)
			if hit then
				if hit.CanCollide == false then
					table.insert(BlacklistParams.FilterDescendantsInstances, hit)
				end
			end
			distance = (hip - footPosition).Magnitude
			local offset = (torso.CFrame * lhipcf):PointToObjectSpace(footPosition)
			local x, y = math.atan2(offset.Z, offset.Y), math.atan2(offset.X, offset.Y)
			lefthip.C0 = lhipcf * CFrame.Angles(x, 0, 0) * CFrame.Angles(0, 0, y) * CFrame.Angles(0, pi, 0)
			if distance < 2 then
				local angle = -math.acos(distance / 2)
				local newCF = lefthip.C0 * CFrame.Angles(-angle, 0, 0) * CFrame.new(0, -0.6, 0) * CFrame.Angles(angle * 1.6, 0, 0) * CFrame.new(0, 0.6, 0)
				lefthip.C0 = newCF
			end
		else
			if Connection ~= nil then
				Connection:Disconnect()
				Connection = nil
			end
		end
	end)
end

return module

The code above is the whole foot planting module, I’m not satisfied with how messy the code looks like, it uses FindPartOnRayWithIgnoreList instead of WorldRoot:Raycast, because FindPartOnRay still returns positions even if the cast isn’t successful, while WorldRoot:Raycast doesn’t return positions unless the cast is successful

The changes I have done is just variables & the parameter

(Character model is not made by me)


Any optimizations that can be used for this?

1 Like

Only using WaitForChild should suffice here.

This constructor contains a lot of logic. Maybe you can separate this logic into methods. This will generally improve the maintainability and readability of your code.

Also, consider using the Maid or Janitor class for this module to prevent potential memory leakage.

2 Likes