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)
You could teleport the tool to the player instead which is much smoother then teleporting the player.
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
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)
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)