Have a little model follow you around (like a pet)

repeat wait() until game.Players.LocalPlayer and game.Players.LocalPlayer.Character

function movePet()
	local character = game.Players.LocalPlayer.Character
 	local pet = character:WaitForChild('Pet').Torso
 	local inc = 0.7
 
  	local base = character['LeftLowerLeg']
  	local dir = CFrame.new(pet.Position, base.Position).lookVector
	pet.CFrame = base.CFrame + (dir * inc)
end

while wait() do
	movePet()
end

Code modified from @Spooks_HD video

Had to modify it to fit my system and even after that it still wasn’t working.

RobloxScreenShot20181217_161341853

In the image, my pet (a snowman) is under my leg. It follows me around, but seems to look like it’s glitching, as it flashes when I move. I’m not sure how to 1. move it back so its following me and not just attached to me and 2. to rotate the model so it’s facing up right instead of on its side.

And third problem I think I might encounter after this that the snowman won’t be facing me, and it might just move at a weird angle, instead of actually facing me and walking to me.

The model is simply called ‘Pet’ and inside it there is a Union called Torso

Another shot showing the glitching (doesn’t show it, but the model is actually glitching from the bottom of the players foot, back up to around the knee area, but it’s doing so incredibly fast, so can’t get a still shot of it)

RobloxScreenShot20181217_162019114

3 Likes

why not using an bodyposition.
it will move around smoothly, and how you calculate the position is quite easy.
just grab the cframe of the Humanoidrootpart then add cframe so it will go to the left back then do .p to grab its position.
rotation is aswell quite easy, all you do is

local X, Y, Z = HumanoidRootPart.CFrame:GetComponents()

and then just rotate the part on its Y axes,

1 Like

Changed up the script to this which seems to kinda work better

local character = game.Players.LocalPlayer.Character
local pet = script.Parent

local rootPart = character['HumanoidRootPart']

local part = Instance.new('Part', rootPart)
part.CanCollide = false
part.Anchored = true
part.Size = Vector3.new(1,1,1)
part.Transparency = 1

local direction = CFrame.new(part.Position, rootPart.Position).lookVector
local increment = direction * 4

while wait() do
  	part.CFrame = rootPart.CFrame + (direction * increment) + Vector3.new(-5, 0, 0)
	part.Rotation = rootPart.Rotation + (direction * increment) + Vector3.new(-1, -2, increment)
	
	pet.Position = part.Position
end

problems I face with this:

RobloxScreenShot20181217_181613953

The snowman is rotated the wrong way, always faces away from the character.

The other problem is when it moves, it kinda ‘staggers’ instead of a smooth movement

Also, just testing with another pet (which uses multiple unions) and that doesn’t work. I’ve put the main union and called it torso, and put the other unions within the torso, welded them. But only the torso follows


On the right shows the Troll model. All the parts are welded

This is just the torso part, however when I open my character model, I can the that all the other unions are still there, just some where off millions of miles away from the actual part
RobloxScreenShot20181217_182419317

Are you running this on the server? I’d suggest running it on the client and use RunService.

I’m just running in PlaySolo

Also just noticed, it sometimes appears in front of me

RenderStepped also seemed to clear away to staggering of the part, but stil get same problems mentioned above

Can you DM me a file of your pet including the script and I’ll have a look when I get home.

Here is a function I use to render pets from the client.

I hook it up to a ChildAdded and a loop when a player first joins to render everyone’s pets.

The upside to “rendering” them locally means that you can update other players pets less often, and also update the further away pets less often.

The downside is that it’s just a tad more complicated.

Hope this helps!

local function renderPet(target,pet)
	
	pet.CanCollide = false
	
	local targetPlr = game.Players:GetPlayerFromCharacter(target)
	
	local bp = Instance.new("BodyPosition")
	local bg = Instance.new("BodyGyro")
	
	bg.D = 750
	bg.MaxTorque = Vector3.new(25000,25000,25000)
	bg.P = 5000
	
	bp.D = 400
	bp.MaxForce = Vector3.new(1250,10000,1250)
	bp.P = 2000
				
	bg.Parent = pet
	bp.Parent = pet
	
	pet.CFrame = target.HumanoidRootPart.CFrame + Vector3.new(0,10,0)
				
	spawn(function()
		
		if not target then
			
			print("Somehow couldn't find the target for: " .. target)
			
		end
		
		local backUpTarg = target
		
		while target do
			
			if target == plr.Character then
				
				wait()
				
			else
				
				wait(.25)
				
				if plr.Character then
				
					local dist = (plr.Character.HumanoidRootPart.Position-target.HumanoidRootPart.Position).magnitude
					
					if dist > 35 then
						
						wait(1.5)
						
					end
				
				end
				
			end
			
			bg.CFrame = target.HumanoidRootPart.CFrame
			bp.Position = CFrame.new(target.HumanoidRootPart.CFrame * Vector3.new(4,2,4)).p
						
		end
		
		print("Loop broken for: " .. backUpTarg)
		
	end)
	
end
9 Likes

Lol he meant if the code is server or client side

Hi, could you explain more of this method?
I’m currently working on my own ‘Pets’ method and your logic seems far better than mine.

My method includes inserting the Pet server-side, setting NetworkOwner to the Player then firing a remote event that handles the movement client side:

Main:WaitForChild("Follow").OnClientEvent:Connect(function(Model)
	
	game:GetService("RunService").RenderStepped:Connect(function()
	
	Model:WaitForChild("HumanoidRootPart").BodyPosition.Position =
		Player.Character:WaitForChild("HumanoidRootPart").Position -
			Player.Character:WaitForChild("HumanoidRootPart").CFrame.LookVector * 5
	
	Model:WaitForChild("HumanoidRootPart").BodyGyro.CFrame =
		CFrame.new(Model:WaitForChild("HumanoidRootPart").Position) 
			* CFrame.fromEulerAnglesXYZ(0, math.rad(Player.Character:WaitForChild("HumanoidRootPart").Orientation.Y), 0)
	
	end)
	
end)

My system/way of doing it is exactly the same as yours. However, you don’t need the OnClientEvent. Just parent the pet to workspace and hook it up to the client. The client can move it due to the ownership being set.

What exactly is meant by ‘Hook it up to the client’?

I thought with it being inserted ServerSide, it’d need to be controlled ClientSide hence the OnClientEvent?

It is being controlled by the client - by setting the ownership