How would I move a player but with collisions in play?

Hi, so as in the title, I want to move the player forward 15 studs, but with TweenService you can noclip through walls. How could I go about making this?

You can raycast first 15 studs ahead to detect if there is a wall ahead, if so then you can tween from that position to where the raycast hit.

Otherwise maybe using Body position though it’ll also cause weird reaction forces if you slam against the wall.

Ok i will see what I can do with this.

question, is this how I would find the direction that I want the ray to go?

local direction = humanoidRootPart.CFrame.LookVector

or would it be

local direction = humanoidRootPart.Position + humanoidRootPart.CFrame.LookVector

Yeah this is the one that goes. The bottom one gets the endpoint position of where the ray will end up if raycasted from the humanoid root part.

@puppy_kingg you can simply use :Move() or :MoveTo() methods.

None of them are ideal for short distances, but they are cheaper than use or raycasting.

I’ve taken a look at sample code that comes with :MoveTo() documentation, but I think the following version is a little more up to date.

Code here
local Players = game:GetService("Players")

local character = Players.LocalPlayer.Character or Players.LocalPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hrp = character:WaitForChild("HumanoidRootPart")

local reached = false

local function movePlayer(position)
	reached = false; local connection
	
	if (typeof(position) ~= "Vector3") then
		warn("Given value is not a vector value."); return;
	end
	
	connection = humanoid.MoveToFinished:Connect(function()
		reached = true
	end)
	
	repeat
		humanoid:MoveTo(position)
		wait(1)
	until reached or not humanoid.Parent
	
	connection:Disconnect()
end

-- Use example:
movePlayer(hrp.Position + Vector3.new(0,0,-500))

Here is the code for freezing player, so they can’t walk away customly:

local CAS = game:GetService("ContextActionService")

local function freezeMovement(freeze)
	if (not freeze) then CAS:UnbindAction("FreezeControls"); return; end
	CAS:BindActionAtPriority(
		"FreezeControls",
		function() return Enum.ContextActionResult.Sink; end,
		false, Enum.ContextActionPriority.High.Value +1,
		unpack(Enum.PlayerActions:GetEnumItems())
	)
end

freezeMovement(true) -- false to unfreeze!

EDIT @puppy_kingg

Glad I could help. For such short distances - positions that player can reach in up to 8 seconds - you don’t really have to include a loop and connections. That will be more memory friendly. @dthecoolest also had a good idea. You can still include raycasting to make sure there is no obstacle preventing player from reaching given destination.

Check out the following.

PS: I know it’s a little weird to cast ray one stud under humanoidRootPart center, but that way we know that player can likely walk over the obstacle. Ray from root part is casted at 3 studs, while obstacle may be 2.8 studs high, meaning players still can’t continue their path. Cast a little lower, but remove it if there are big terrain differences.

Code
local Players = game:GetService("Players")
local CAS = game:GetService("ContextActionService")

local character = Players.LocalPlayer.Character or Players.LocalPlayer.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hrp = character:WaitForChild("HumanoidRootPart")

local function freezeMovement(freeze)
	if (not freeze) then CAS:UnbindAction("FreezeControls"); return; end
	CAS:BindActionAtPriority(
		"FreezeControls",
		function() return Enum.ContextActionResult.Sink; end,
		false, Enum.ContextActionPriority.High.Value +1,
		unpack(Enum.PlayerActions:GetEnumItems())
	)
end

local function movePlayer(position)
	if (typeof(position) ~= "Vector3") then
		warn("Given value is not a vector value."); return;
	end
	
	local raycastResult = workspace:Raycast(
		hrp.Position + Vector3.new(0,-1,0),
		Vector3.new(0,0,-math.abs(position.Z))
	)
	if (raycastResult) then print("Obstacle found!") return; end
	
	freezeMovement(true)
	humanoid:MoveTo(position)
	humanoid.MoveToFinished:Wait()
	freezeMovement(false)
end

wait(3)
movePlayer(hrp.Position + Vector3.new(0,0,-15))

Perhaps add cancelling after a short period of time, just in case player by some chance gets stuck somewhere.

This is really good, I forgot moveto doesnt forget about collisions, thanks!