Working on pet following script, two problems at the moment

first problem: I have been working on this pet following system for a bit, and i got it to work well, but i created this system intending for the “pet” to not collide with anything, mainly the player. however when I run this script with the CanCollide function off the pet stops folowing me.
is it a problem with my code? i don’t see how that could be the case, but if it is please inform me on how to fix it

code:

local pet = script.Parent

function givepet(player)
	if player then
		local character = player.Character
		if character then
			local humanrootpart = character.HumanoidRootPart
			local newpet = pet:Clone()
			newpet.Parent = character

			local bodyPos = Instance.new("BodyPosition", newpet)
			bodyPos.MaxForce = Vector3.new(math.huge, math.huge, math.huge)

			local bodyGyro = Instance.new("BodyGyro", newpet)
			bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge)

			while wait() do
				bodyPos.Position = humanrootpart.Position + Vector3.new(3,1,3)
				bodyGyro.CFrame = humanrootpart.CFrame
			end
		end
	end
end

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(char)
		givepet(player)
	end)
end)

video of the “pet” when CanCollide is off:

second problem: this isn’t a problem as much as an annoyance, but the pet is also going relatively “slow” if you know what i mean i don’t know why this is.
video of “pet” going slow:

I tried turning up my responsiveness in the AlignPosition function already, but it still looks the same.

4 Likes

wouldn’t it be better to use TweenService and constantly tween the pet to HumanoidRootPart.CFrame + Vector3.new(3, 1, 3)

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.