Minecraft-like R6 Crouching where the player cant fall of an edge of a part

No all you have to do is just weld the player to the block if they aren’t touching it

Any examples from both of you of how?

But then they wouldn’t be able to move.

Your best bet would probably be to:

  • Create a custom movement system, which would make it easier for future additions
  • Send raycasts every RenderStepped when crouching, and if there is no part detected under the player then teleport the player back to where they were last frame.

Is there some way for an example or a tutorial on how to do this?
I’m not the best scripter by far.

I have made a self-made movement system but its more of a minecraft “Spectator / Creative” flying thing? Here it is if you want to look at it: My custom roblox game - Roblox

Is this what you’re looking for

Kind of, just instead of him floating in the air, when you’re on the edge of a block you stop while crouching.

Do you have a picture or video clip of what you want to do

Ok, so basically what you have to do is:
Every render step create a variable that consists of two merged vectors, a vector 0,-3.1,0 and a normalized humanoid walk direction velocity vector(excluding the humanoidrootpart Y axis) multiplied by 0.1, then do a raycast from the humanoidroot part to that direction. if there is no raycast result, set the walkspeed to 0, otherwise set it to 16

Sounds like a good idea. I’m not the best scripter, do you have any examples, code source, or step-by-step instructions on how to script this?

Thanks! :smile:

I explained everything. To see how it works in code, just search for individual phrases from my previous post, I would recommend developer.roblox.com and YouTube to do that.

Yes, pretty much. Just only when you’re holding shift.

it works but you have to let go to move in the other direction
works good in first person though

local Visualize = true


local Character = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
local Humanoid = Character:WaitForChild("Humanoid")
game.Players.LocalPlayer.CharacterAdded:Connect(function(_Character)
	Character = _Character
	HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
	Humanoid = Character:WaitForChild("Humanoid")
end)
game:GetService("RunService").RenderStepped:Connect(function()
	if Character ~= nil and HumanoidRootPart ~= nil and Humanoid ~= nil then
		if game:GetService("UserInputService"):IsKeyDown(Enum.KeyCode.LeftShift) then
			local rayDirections = {
				(((HumanoidRootPart.CFrame + Vector3.new(0,-10,0)) + HumanoidRootPart.CFrame.LookVector * 7) - HumanoidRootPart.Position).Position,
				(((HumanoidRootPart.CFrame + Vector3.new(0,-10,0)) - HumanoidRootPart.CFrame.LookVector * 7) - HumanoidRootPart.Position).Position,
				(((HumanoidRootPart.CFrame + Vector3.new(0,-10,0)) + HumanoidRootPart.CFrame.RightVector * 7) - HumanoidRootPart.Position).Position,
				(((HumanoidRootPart.CFrame + Vector3.new(0,-10,0)) - HumanoidRootPart.CFrame.RightVector * 7) - HumanoidRootPart.Position).Position,
			}
			local Ungrounded = false
			for _, rayDirection in pairs(rayDirections) do
				local rayOrigin = HumanoidRootPart.Position
				local raycastParams = RaycastParams.new()
				raycastParams.FilterDescendantsInstances = {Character}
				raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
				local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
				if raycastResult then
					Humanoid.WalkSpeed = 16
					if Visualize then
						local dist = (rayOrigin - raycastResult.Position).Magnitude
						local part = Instance.new("Part", workspace)
						part.Anchored = true
						part.CanCollide = false
						part.Color = Color3.fromRGB(255,0,0)
						part.Size = Vector3.new(0.1, 0.1, dist)
						part.CFrame = CFrame.new(rayOrigin, raycastResult.Position)*CFrame.new(0, 0, -(dist/2))
					end
				else
					Ungrounded = true
				end
			end
			Humanoid.WalkSpeed = (Ungrounded) and 0 or 16
		else
			Humanoid.WalkSpeed = 16
		end
	end
end)
3 Likes

Would this be a local script? if so, just in Workspace?

localscript wont run in workspace, put it in playerstarter scripts or whatever its called as a localscript

I do like it. A bit buggy, but It’s better than nothing.

Also, how would I make those Rays transparent?

Also, also, It did crash my studio once.

1 Like

read the script and figure it out… the variable is part
and if you want to turn them off the toggle var is “Visualize” at the top

1 Like

A more optimized and correct way

local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local LocalPlayer = Players.LocalPlayer
local Character: Model = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid: Humanoid = Character:WaitForChild("Humanoid")
local RootPart: BasePart = Character:WaitForChild("HumanoidRootPart")

local Debug = true

local CrouchEnabled = true
local IsCrouching = false
local NormalHeight = 2
local CrouchHeight = 1
local NormalWalkSpeed = 16
local CrouchWalkSpeed = 8

local function SetupCharacter(NewCharacter)
	Character = NewCharacter
	Humanoid = Character:WaitForChild("Humanoid")
	RootPart = Character:WaitForChild("HumanoidRootPart")
	NormalHeight = Humanoid.HipHeight
	NormalWalkSpeed = Humanoid.WalkSpeed

	Filter = RaycastParams.new()
	Filter:AddToFilter(Character)
end

SetupCharacter(Character)

local function ToggleCrouch(ActionName, InputState)
	if not CrouchEnabled then return end

	if InputState == Enum.UserInputState.Begin then
		IsCrouching = not IsCrouching

		if IsCrouching then
			Humanoid.HipHeight = CrouchHeight
			Humanoid.WalkSpeed = CrouchWalkSpeed
		else
			Humanoid.HipHeight = NormalHeight
			Humanoid.WalkSpeed = NormalWalkSpeed
		end
	end
end

ContextActionService:BindAction("Crouch", ToggleCrouch, false, Enum.KeyCode.LeftControl)

LocalPlayer.CharacterAdded:Connect(SetupCharacter)

local function SetCrouchEnabled(Enabled)
	CrouchEnabled = Enabled

	if not CrouchEnabled and IsCrouching then
		IsCrouching = false
		Humanoid.HipHeight = NormalHeight
		Humanoid.WalkSpeed = NormalWalkSpeed
	end
end

local function IsOnEdge(): boolean
	local Offset = Humanoid.MoveDirection * .1
	local Direction = Vector3.new(0, -3.5, 0)
	local Rayresult = workspace:Raycast(RootPart.Position + Offset, Direction, Filter)

	if Debug then
		local DebugPart = Instance.new("Part")
		DebugPart.Size = Vector3.new(1, .25, 1)
		DebugPart.Color = (Rayresult and Rayresult.Instance) and Color3.new(0.34902, 1, 0) or Color3.new(1, 0.027451, 0.027451)
		DebugPart.CanCollide = false
		DebugPart.CanQuery = false
		DebugPart.Anchored = true
		DebugPart.Material = Enum.Material.SmoothPlastic
		DebugPart.Transparency = .75
		DebugPart.Position = Rayresult and Rayresult.Position or (RootPart.Position + Offset + Direction)
		DebugPart.Parent = workspace
		
		task.delay(.1, function() DebugPart:Destroy() end)
	end

	return not (Rayresult and Rayresult.Instance)
end

RunService.RenderStepped:Connect(function()
	if IsCrouching and Humanoid and Humanoid.FloorMaterial ~= Enum.Material.Air and IsOnEdge() then
		local MoveDirection = Humanoid.MoveDirection
		
		if MoveDirection.Magnitude > 0 then
			Humanoid.WalkSpeed = 0
		end
	else
		Humanoid.WalkSpeed = IsCrouching and CrouchWalkSpeed or NormalWalkSpeed
	end
end)