Working on pet following script, two problems at the moment

Most likely. Note: I am a beginner at lua, and this code is from a tutorial

Since you’re doing this on the server, there will always be latency, especially with animations like this.

The only way to make it more reactive would be to animate these pets on the client.

Maybe something like this could work

local players = game.Players
local tweenService = game:GetService('TweenService')
local RunService = game:GetService('RunService')

local pet = script.Parent


players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		local humanoidRootPart = character.HumanoidRootPart
		local newPet = pet:Clone()
		newPet.Parent = character
	end)
	
	RunService.Heartbeat:Connect(function()
		if player.Character then
			local character = player.Character
			local humanoidRootPart = character.HumanoidRootPart
			
			if character:FindFirstChild('Pet') then
				local pet = character['Pet']
				local targetCFrame = humanoidRootPart.CFrame 
					+ humanoidRootPart.CFrame.LookVector * -2 -- IDK A MORE EFFICIENT WAY TO DO THIS BIT, IF YOU KNOW, PLEASE POINT IT OUT XD
					+ humanoidRootPart.CFrame.RightVector * 2
					+ humanoidRootPart.CFrame.UpVector * -1

				local tween = tweenService:Create(
					pet, TweenInfo.new(.5),
					{
						CFrame = targetCFrame
					}
				)

				tween:Play()
			end
		end
	
	end)
end)

oh yea the 0.5 in TweenInfo.new(.5) is the time it takes for the tween to complete. Just adjust it to change the timings

This is amazing, thank you, but i dont want to just steal this code from you… so, is it farfetched for me to ask you to explain how this works?

Sure!

You probably know what players.PlayerAdded line does.
After that, I set up an event for when the character of the player is added (so probably when the player first joins the game or respawns).
Then, I spawn the pet.

RunService.Hearbeat is an event that runs every frame
see RenderStepped, Stepped, or Heartbeat - #2 by rogchamp for more info.

Basically, every frame, it checks if the player has a character (if it exists), then we set up the necessary variables. Then, it checks if the pet has been spawned yet. If it hasn’t, thats okay because it might spawn next frame.

If it has, then we tween it towards the desired spot.

I dont know a better way to offset the humanoidRootPart cframe but basically, CFrame.lookVector is the vector for the direction part is looking in. UpVector and RightVector are self-explanatory (vertical and horizontal vectors perpendicular to the part’s lookvector)

if you want to learn more about tween service you should look up a tutorial on it.

basically, i create a tween on the pet part, giving it 0.5 seconds (there are more properties of TweenInfo you should explore them

I actually liked the first way you were doing this. That can be super smooth; you just need to make that a client script. I also wouldn’t worry about pets hitting things. They all do, and it’s too much of a headache to not let them.

local rns=game:GetService("RunService")
while true do rns.Stepped:Wait()
	bodyPos.Position = humanrootpart.Position + Vector3.new(3,1,3)
	bodyGyro.CFrame = humanrootpart.CFrame
end

Thank you! This really helps alot!

yea, but

Don’t give it CanCollide, make that false.
Just saying I’ve tried many different ways to make a pet follow you. That technique is ultra smooth if you get it down right.

I my loop for the pet I update it like this:

bp.Position=hrp.Position-(hrp.CFrame.RightVector*4.1)
bg.CFrame=CFrame.new(hrp.Position,hrp.CFrame.LookVector
			*10000)*CFrame.Angles(0,math.rad(-3),0)
rns.Stepped:Wait()

hrp is the humanoidRootPart
bp is the body position
bg is the body Gyro

Why not just use a Align Position Constraint? You don’t even need script much when using it and the only down side to using it is that the pet is always gonna be behind the character.

I set it up that way so I could add more pets. This one is to the left side.
When you see this pet movement it will make your jaw drop how smooth it really is and how it moves with you. You can already tell from his video …

I’m sure there are other ways not saying that. But I never found anything as smooth as this.

this code works well other than a little bit of lag which might just be my computer, because i dont see the lag in your video, so I don’t know if you can help me with that. I just ran into another problem though, my pet kills itself when I join the game

video of pet killing itself:

as you can see I had the block/pet was in the workspace, but then I joined the game and it was gone

Its because you have its collision set to false, its probably falling through the basepart.
I would anchor it until the script starts working when the player joins

but when i get in the game it isn’t even in the workspace at all? I anchored it and it still dissapeared by the way.

Can you post your most recent code?

Nevermind, I made a new cube and gave it the script and it worked perfectly.

so this is great, but the pet is still a bit laggy. I dont know if this is fixable, but if it is please inform me.
also, how can i have multiple pets at the same time using this code? I have tried duplicating the pet and changing the x,y, and z (RightVector, UpVector, and LookVector), but it still only shows one pet.

YOOOOO
I’m sorry for the long wait,
I got a bit carried away with other stuff.
Anyways I fixed lag and also added multiple pet.
I updated the system a bit. Basically you have Vector3Value inside the pets, call them ‘Offset’, this is so you can have different pets in different positions (this is just one of the ways to do this).
image
To fix the lag, I tweaked the script a little and made it a LocalScript inside StarterCharacterScripts.

local players = game.Players
local tweenService = game:GetService('TweenService')
local RunService = game:GetService('RunService')

local pets = {workspace:WaitForChild('Pet1'), workspace:WaitForChild('Pet2')}

local player = players.LocalPlayer
local character = player.Character
local humanoidRootPart = character.HumanoidRootPart


for i, pet in pairs(pets) do
	local newPet = pet:Clone()
	newPet.Parent = character
	
	local offset = {newPet.Offset.Value.X, newPet.Offset.Value.Y, newPet.Offset.Value.Z}

	RunService.Heartbeat:Connect(function()
		local targetCFrame = humanoidRootPart.CFrame 
			+ humanoidRootPart.CFrame.LookVector * offset[3] -- IDK A MORE EFFICIENT WAY TO DO THIS BIT, IF YOU KNOW, PLEASE POINT IT OUT XD
			+ humanoidRootPart.CFrame.RightVector * offset[1]
			+ humanoidRootPart.CFrame.UpVector * offset[2]

		local tween = tweenService:Create(
			pet, TweenInfo.new(.5),
			{
				CFrame = targetCFrame
			}
		)

		tween:Play()
	end)
end

This works real smooth

If you wanna give the player more pets while the game is running, just use remove events or something to update the pets table. Also you may wanna increase the tween time (0.5 is too quick as running it on a localscript is really smooth), maybe try 0.75 or something