What folder do I put this in?

Hi everyone

I have a script that’s supposed to make a pet that follows the player around wherever they go. I’ve been doing this, and I do in fact have a working script. I was going to ask, however, into what folder I should put it in so that it works.

local object = workspace.follow -- insert the object you want to follow the player here
local player = game.Players.LocalPlayer
local speed = 20 -- set the speed at which the object will follow the player

while true do
	local playerPos = player.Character.HumanoidRootPart.Position
	local objectPos = object.Position
	local direction = (playerPos - objectPos).Unit
	local distance = (playerPos - objectPos).Magnitude

	if distance > 5 then -- only moves if distance is greater than 0.1
		object.CFrame = object.CFrame + direction * speed * math.min(distance, 1/60)
	 
	end
	if distance > 10 then 
		object.CFrame = object.CFrame + direction * 30 * math.min(distance, 1/60)
	end

	wait()
end

Thanks!
-mythyx

1 Like

Put in a local script but also have it run for other players to replicate the movement so it’s smooth for all if you are looking for it to be super smooth. Else, if that’s too hard, put it in the server, it’s simple and all can see it, though on the player the object is following, it will lag behind a bit because of ping. Also, CFrames on the server look buggy but not on client. So the best way would be to have a replication system to control the pet smoothly for all players and have the server ignore it, which would also be healthy for the server.

As it is made it looks like a LocalScript for StarterPlayerScripts

yeah that’s exactly what it is.
image

what folder should I put it in for it to replicate for everyone?

I had to play around with the timing and update to get a smooth follow.
Also not a fan of heartbeat…

LocalScript in StarterPlayerScripts

local object = workspace:WaitForChild("follow")
local player = game.Players.LocalPlayer
object.Anchored = true
local speed = 60

local runService = game:GetService("RunService")
runService.Stepped:Connect(function(_, deltaTime)
	local character = player.Character
	if character and character:FindFirstChild("HumanoidRootPart") then
		local playerPos = character.HumanoidRootPart.Position
		local objectPos = object.Position
		local direction = (playerPos - objectPos).Unit
		local distance = (playerPos - objectPos).Magnitude

		if distance > 4 then
			local targetPosition = objectPos + direction * speed * deltaTime
			object.CFrame = CFrame.new(objectPos):Lerp(CFrame.new(targetPosition), 0.2)
		end
	end
end)

can you explain some of your code for me? I’m a little new. All I really need explained is just like why you used .Stepped, but I would appreciate a full explanation.

I also noticed a little bit of a bug, where if you stand on the part, it will follow you and allow you to “fly”. I’ll probably solve this by using the part.Touched:Connect.

Thanks in advance.

Well that got complicated real quick… You could just set the pet to CanCollide=false

local object = workspace:WaitForChild("follow")
local player = game.Players.LocalPlayer
local isTouching = false
object.Anchored = true
local speed = 60

local runService = game:GetService("RunService")
object.Touched:Connect(function(hit)
	if hit.Parent == player.Character then
		local humanoidRoot = player.Character:FindFirstChild("HumanoidRootPart")
		if humanoidRoot and hit:IsA("Part") then
			local pos = humanoidRoot.Position
			local objectPos = object.Position
			local distance = (pos - objectPos).Magnitude
			if distance < 5 then
				local direction = (pos - objectPos).Unit
				object.Position = object.Position - direction * 5
			end
		end
	end
end)

runService.Stepped:Connect(function(_, deltaTime)
	local character = player.Character
	if character and character:FindFirstChild("HumanoidRootPart") then
		local playerPos = character.HumanoidRootPart.Position
		local objectPos = object.Position
		local direction = (playerPos - objectPos).Unit
		local distance = (playerPos - objectPos).Magnitude

		if distance > 4 then
			local targetPosition = objectPos + direction * speed * deltaTime
			object.CFrame = CFrame.new(objectPos):Lerp(CFrame.new(targetPosition), 0.2)
		end
	end
end)

Well I also worked on this a bit, and understandably, we have very different approaches. :smile:
Here’s my code at the moment, what do you think?

local object = workspace:WaitForChild("follow")
local player = game.Players.LocalPlayer
object.Anchored = true
local speed = 60

game:GetService("RunService").Stepped:Connect(function(_, deltaTime)
	local character = player.Character
	if character and character:FindFirstChild("HumanoidRootPart") then
		local playerPos = character.HumanoidRootPart.Position
		local objectPos = object.Position
		local direction = (playerPos - objectPos).Unit
		local distance = (playerPos - objectPos).Magnitude

		if distance > 4 then
			local targetPosition = objectPos + direction * speed * deltaTime
			object.CFrame = CFrame.new(objectPos):Lerp(CFrame.new(targetPosition), 0.2)
		end
	end
	object.Touched:Connect(function(hit)
		if hit and hit.Parent == player then
			object.CFrame = CFrame.new(objectPos)
		end

	end)

end)```

I'll probably end up using your code, and then the Roblox AI to explain what all of it does, combined with the documentation. Hopefully by the end of this I will become fluent in creating part-that-follow-player systems. 

Thanks for your help.
1 Like

RunService.Stepped is like a top of the frame pause. Normally good for pre-physics updates.
RunService.Heartbeat is like a end of the frame pause. Normally good for object updates after physics simulation.

Despite this I find Stepped to be a more consistent. Could just be me.

Alright, the code is a little buggy, but given enough time I can probably debug it.

Thanks for your help!

1 Like