How to make player walk toward tool until the certain range before pick up

How do I make player “walk” toward the tool until they’re in a certain range before picking the tool up
right now they kinda just instant teleport to it

local RS = game:GetService("ReplicatedStorage")
local Event = RS:FindFirstChild("PickUp")

local MaxPickupDistant = 10 -- max detect range
local takeDistant = 5 -- if item outside this range > player walk toward it until in range then > pick up
Event.OnServerEvent:Connect(function(player, item)
	local ItemDistant = player:DistanceFromCharacter(item.Handle.Position)
	if ItemDistant <= MaxPickupDistant then
		if ItemDistant >= takeDistant then
			local rootPart = player.Character:FindFirstChild("HumanoidRootPart")
			if rootPart then
				rootPart.CFrame = CFrame.new(item.Handle.Position)
				item.Handle.CanCollide = false
				item.Parent = player.Character
			end
		else
			return
		end
	end
end)

2 Likes

Two solutions here:

  1. You could teleport the tool to the player instead which is much smoother then teleporting the player.
  2. My other solution would be to use the Humanoid:MoveTo(). Should be very simple to integrate in since your code already does all the checks needed.

If you want to be unique you could also Lerp the tools CFrame to the Characters hand. It would look like they’re using the force and give a cool effect. Of course if your going for realism it would not be ideal.

I kinda want the player to walk toward the tool (I’ll add animation later) to sell the illusion of stuggling the charater is experiencing in a fight sort of like they try to reaching out for something to defend themself
Can you please give me some example of how to use the MoveTo function

cuz when I tried to use it I just end up with error
image

local RS = game:GetService("ReplicatedStorage")
local Event = RS:FindFirstChild("PickUp")

local MaxPickupDistant = 10 -- max detect range
local takeDistant = 5 -- if item outside this range > player walk toward it until in range then > pick up
Event.OnServerEvent:Connect(function(player, item)
	local ItemDistant = player:DistanceFromCharacter(item.Handle.Position)
	if ItemDistant <= MaxPickupDistant then
		if ItemDistant >= takeDistant then
			local rootPart = player.Character:FindFirstChild("HumanoidRootPart")
			if rootPart then
				rootPart:MoveTo(item.Handle.Position)
				item.Handle.CanCollide = false
				item.Parent = player.Character
			end
		else
			return
		end
	end
end)

update: I think I got it to work but it kinda just do a little step toward the item intead of walking all the way to it

local RS = game:GetService("ReplicatedStorage")
local Event = RS:FindFirstChild("PickUp")

local MaxPickupDistant = 10 -- max detect range
local takeDistant = 5 -- if item outside this range > player walk toward it until in range then > pick up
Event.OnServerEvent:Connect(function(player, item)
	local ItemDistant = player:DistanceFromCharacter(item.Handle.Position)
	if ItemDistant <= MaxPickupDistant then
		if ItemDistant >= takeDistant then
			local hum = player.Character:FindFirstChild("Humanoid")
			if hum then
				hum:MoveTo(item.Handle.Position)
			end
		else
			item.Handle.CanCollide = false
			item.Parent = player.Character
		end
	end
end)

MoveTo is a function of the Humanoid, not HumanoidRootPart.

Just saw your new reply.
Try making a new part for where the player should walk to and see if that changes the weird bug.

I tried using repeat until player is in range of the takeDistant but the same still happen

is there an alternative way for player to get to the item location (not teleporting) while also playing an animation?

local RS = game:GetService("ReplicatedStorage")
local Event = RS:FindFirstChild("PickUp")

local MaxPickupDistant = 10 -- max detect range
local takeDistant = 5 -- if item outside this range > player walk toward it until in range then > pick up
Event.OnServerEvent:Connect(function(player, item)
	local ItemDistant = player:DistanceFromCharacter(item.Handle.Position)
	if ItemDistant <= MaxPickupDistant then
		if ItemDistant >= takeDistant then
			local rootPart = player.Character:FindFirstChild("Humanoid")
			if rootPart then
				-- if item is out of takeDistant's range player character MoveTo item until in range of takeDistant
				local moveTo = item.Handle.Position
				local moveToCFrame = CFrame.new(moveTo)
				local moveToPosition = moveToCFrame.Position
				rootPart:MoveTo(moveToPosition)
				-- if item is still out of range after player walked to it > repeat
				repeat
					wait(0.1)
					ItemDistant = player:DistanceFromCharacter(item.Handle.Position)
				until ItemDistant <= takeDistant
				if ItemDistant <= takeDistant then
					item.Handle.CanCollide = false
					item.Parent = player.Character
				end
			end
		else
			return
		end
	end
end)

nvm I figure out what I want now lol
since when player about to pick up an item they’ll have to face said item anyway I’ll just apply force to player using BodyVelocity

Here’s a code if anyone want to replicate what I make
server:
(Create remoteEvent inside ReplicatedStorage and name it “PickUp”)

local RS = game:GetService("ReplicatedStorage")
local Event = RS:FindFirstChild("PickUp")

local Anim = Instance.new("Animation")
Anim.AnimationId = "rbxassetid://120839434392194"

local MaxPickupDistant = 14 -- max detect range
local takeDistant = 5 -- if item outside this range > player walk toward it until in range then > pick up
Event.OnServerEvent:Connect(function(player, item)
	local ItemDistant = player:DistanceFromCharacter(item.Handle.Position)
	local Track = player.Character.Humanoid:LoadAnimation(Anim)

	if ItemDistant <= MaxPickupDistant then
		if ItemDistant >= takeDistant then
			local rootPart = player.Character:FindFirstChild("HumanoidRootPart")
			if rootPart then
				local BV = Instance.new("BodyVelocity")
				BV.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
				BV.Parent = rootPart
				BV.Velocity = CFrame.new(rootPart.Position, item.Handle.Position).LookVector * 30
				Track:Play()
				wait(.3)
				BV:Destroy()
				item.Handle.CanCollide = false
				item.Parent = player.Character
			end
		elseif ItemDistant <= takeDistant then
			item.Handle.CanCollide = false
			item.Parent = player.Character
			Track:Play()
		end
	end
end)

Local:
(Create a screenGUI and name it “MarkerGUI” then put imagelabel under it
set the ScreenUi size to {1, 100},{1, 100} and image size to {1, 0},{1, 0})

local UIS = game:GetService("UserInputService")
local RPS = game:GetService("ReplicatedStorage")
local CS = game:GetService("CollectionService")
local RS = game:GetService("RunService")
local SGUI = game:GetService("StarterGui")

local Event = RPS:FindFirstChild("PickUp")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local Marker = SGUI:FindFirstChild("MarkerGUI")
local character = player.Character or player.CharacterAdded:Wait()
local maximumDistance = 14

UIS.InputChanged:Connect(function()
	if mouse.Target then
		if (mouse.Target.Position - character.HumanoidRootPart.Position).Magnitude > maximumDistance then
			Marker.Enabled = false
			Marker.Adornee = nil
			return 
		else
			if mouse.Target.Parent:HasTag("Item") then
				Marker.Enabled = true
				Marker.Parent = mouse.Target.Parent:FindFirstChild("GrabBox")
			else
				Marker.Enabled = false
				Marker.Adornee = nil
			end
		end
	end
end)

RS.RenderStepped:Connect(function()
	if Marker.Enabled == true then
		Marker:FindFirstChild("ImageLabel").Rotation = Marker:FindFirstChild("ImageLabel").Rotation + 1
		wait(.2)
	end
end)

UIS.InputEnded:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E then
		if mouse.Target then
			if mouse.Target:IsA("Part") and mouse.Target.Name == "GrabBox" then
				if mouse.Target.Parent:HasTag("Item") then
					local item = mouse.Target.Parent
					if item then
						Event:FireServer(item)
					end
				end
			end
		end
	end
end)

Highlight code (optional) (create a new highlight then put it under the script)

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local mouse = player:GetMouse()

local CollectionService = game:GetService("CollectionService")
local runService = game:GetService("RunService")
local inputService = game:GetService("UserInputService")

local maximumDistance = 14

mouse.Move:Connect(function()

	if not mouse.Target then script.Highlight.Adornee = nil  return end
	if (mouse.Target.Position - character.HumanoidRootPart.Position).Magnitude > maximumDistance then script.Highlight.Adornee = nil return end
	if CollectionService:HasTag(mouse.Target, "Hightlightable") then
		script.Highlight.Adornee = mouse.Target
		return
	elseif CollectionService:HasTag(mouse.target.Parent, "Hightlightable") then
		script.Highlight.Adornee = mouse.Target.Parent
		return
	end

	script.Highlight.Adornee = nil

end)

1 Like

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