Pet Following Issue

Can someone help me fix this problem? When a new pet row is added that contains five pets each, the pets will be far away from the character, and the pet row won’t have space for each other.

image
image
image

Local Script

local PetMovementHandler = {}
 
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
 
local PlayerPets = workspace:WaitForChild("PlayerPets")
 
local FullCircle = 1 * math.pi
 
 
local function getXAndZPositions(angle, scalar)
    local x = math.cos(angle) * scalar
    local z = math.sin(angle) * scalar
    return x, z
end
 
function getAngle(touch, center)
    return math.atan2(touch.X - center.X, touch.Z - center.Z)
end
 
 
local function UpdatePetPosition()
 
    for _, Folder in pairs(PlayerPets:GetChildren()) do
        local Player = Players[Folder.Name]
        local Character = Player.Character
 
 
        if Character and Character.PrimaryPart then
            local HumanoidRootPart = Character.HumanoidRootPart
            local PetTable = PlayerPets:WaitForChild(Player.Name):GetChildren()
 
            local XCos = math.cos(5 * time() + 1)/4
            local ZCos = math.cos(7 * time() + 1)/4
            local YSin = math.sin(5 * time() + 1.6)/2
            local YSin2 = math.sin(15 * time() + 1.6)/.5
 
            for Index, Pet in ipairs(PetTable) do
 
                local i = Index
                local radius = math.ceil(i/5) + #PetTable
                local i2 = (i-1)%5 + 1
                local angle = i2 * (FullCircle / #PetTable)
 
                local X, Z = getXAndZPositions(angle, radius) 
                local MainYAngle = Character.Humanoid.MoveDirection.Magnitude > 0 and
                    getAngle(Pet.PrimaryPart.Position, Pet.PrimaryPart.Position + HumanoidRootPart.CFrame.LookVector) or
                    getAngle(Pet.PrimaryPart.Position, HumanoidRootPart.Position) 
                if Pet.CanFly.Value then
                    Pet.PrimaryPart.CFrame = Pet.PrimaryPart.CFrame:Lerp(CFrame.new(HumanoidRootPart.CFrame.p) * CFrame.Angles(0, MainYAngle,0) * CFrame.fromEulerAnglesXYZ(XCos, 0, 0) + Vector3.new(X, YSin, Z), 0.1)
                else
                    --local FloorYAngle = Character.Humanoid.MoveDirection.Magnitude > 0 and -Character.RightUpperLeg.Position.Y + 1 + YSin2 or -Character.RightUpperLeg.Position.Y + .05
                    local FloorYAngle = Character.Humanoid.MoveDirection.Magnitude > 0 and Character.HumanoidRootPart.Size.Y/2 + -2 + YSin2 or Character.HumanoidRootPart.Size.Y/2 + -3.2
                    
                    if Character.Humanoid.MoveDirection.Magnitude > 0 then
                        
                        Pet.PrimaryPart.CFrame = Pet.PrimaryPart.CFrame:Lerp(CFrame.new(HumanoidRootPart.CFrame.Position) 
                            * CFrame.Angles(0, MainYAngle,0) 
                            * CFrame.fromEulerAnglesXYZ(0, 0, ZCos) 
                            + Vector3.new(X ,FloorYAngle, Z),
                            0.1
                        )
                    else
                        Pet.PrimaryPart.CFrame = Pet.PrimaryPart.CFrame:Lerp(CFrame.new(HumanoidRootPart.CFrame.Position) 
                            * CFrame.Angles(0, MainYAngle,0) 
                            * CFrame.fromEulerAnglesXYZ(0, 0, 0) 
                            + Vector3.new(X,FloorYAngle, Z),
                            0.1
                        )
                    end
                end
            end
        end
    end
end
 
function PetMovementHandler:Int()
    RunService.Heartbeat:Connect(UpdatePetPosition)
end
 
return PetMovementHandler

Increase the pet radius per row, remove radius added by total pets. I’ve added constants with descriptive names for each part of the radius equation.

-- old line to compare
local radius = math.ceil(i/5) + #PetTable

local pets_per_row = 5
local base_radius = 3
local radius_per_row = 5
local radius = math.floor(i/pets_per_row) * radius_per_row + base_radius

What about the angle? Do I also need to change it? Sorry for late reply.

I doubt it, how does the sample code look in-game?

I will send a video wait a sec

Sorry I can’t send a video for now only an image with 15 pets equipped

image

The New Script:

local PetMovementHandler = {}

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local PlayerPets = workspace:WaitForChild("PlayerPets")

local FullCircle = 1 * math.pi

local function getXAndZPositions(angle, scalar)
	local x = math.cos(angle) * scalar
	local z = math.sin(angle) * scalar
	return x, z
end

function getAngle(touch, center)
	return math.atan2(touch.X - center.X, touch.Z - center.Z)
end


local function UpdatePetPosition()

	for _, Folder in pairs(PlayerPets:GetChildren()) do
		local Player = Players[Folder.Name]
		local Character = Player.Character


		if Character and Character.PrimaryPart then
			local HumanoidRootPart = Character.HumanoidRootPart
			local PetTable = PlayerPets:WaitForChild(Player.Name):GetChildren()

			local XCos = math.cos(5 * time() + 1)/4
			local ZCos = math.cos(7 * time() + 1)/4
			local YSin = math.sin(5 * time() + 1.6)/2
			local YSin2 = math.sin(15 * time() + 1.6)/.5

			for Index, Pet in ipairs(PetTable) do

				local pets_per_row = 5
				local base_radius = 3
				local radius_per_row = 5
				local radius = math.floor(Index / pets_per_row) * radius_per_row + base_radius 
				
				local angle = Index * (FullCircle / #PetTable)

				local X, Z = getXAndZPositions(angle, radius) 
				local MainYAngle = Character.Humanoid.MoveDirection.Magnitude > 0 and
					getAngle(Pet.PrimaryPart.Position, Pet.PrimaryPart.Position + HumanoidRootPart.CFrame.LookVector) or
					getAngle(Pet.PrimaryPart.Position, HumanoidRootPart.Position) 
				if Pet.CanFly.Value then
					Pet.PrimaryPart.CFrame = Pet.PrimaryPart.CFrame:Lerp(CFrame.new(HumanoidRootPart.CFrame.p) * CFrame.Angles(0, MainYAngle,0) * CFrame.fromEulerAnglesXYZ(XCos, 0, 0) + Vector3.new(X, YSin, Z), 0.1)
				else
					local FloorYAngle = Character.Humanoid.MoveDirection.Magnitude > 0 and Character.HumanoidRootPart.Size.Y/2 + -2 + YSin2 or Character.HumanoidRootPart.Size.Y/2 + -3.2
					
					if Character.Humanoid.MoveDirection.Magnitude > 0 then
						
						Pet.PrimaryPart.CFrame = Pet.PrimaryPart.CFrame:Lerp(CFrame.new(HumanoidRootPart.CFrame.Position) 
							* CFrame.Angles(0, MainYAngle,0) 
							* CFrame.fromEulerAnglesXYZ(0, 0, ZCos) 
							+ Vector3.new(X ,FloorYAngle, Z),
							0.1
						)
					else
						Pet.PrimaryPart.CFrame = Pet.PrimaryPart.CFrame:Lerp(CFrame.new(HumanoidRootPart.CFrame.Position) 
							* CFrame.Angles(0, MainYAngle,0) 
							* CFrame.fromEulerAnglesXYZ(0, 0, 0) 
							+ Vector3.new(X,FloorYAngle, Z),
							0.1
						)
					end
				end
			end
		end
	end
end

function PetMovementHandler:Int()
	RunService.Heartbeat:Connect(UpdatePetPosition)
end

return PetMovementHandler

maybe, if this doesn’t work go back to the old angle script

local angle = (Index % pets_per_row) * (FullCircle / pets_per_row)
1 Like

This is how it looks like

image

Maybe you can expand your math basics, use parts and reflect pets off of those. Maybe it’d be easier for you.

pretty good! I will add that your FullCircle variable actually represents a half circle, maybe you want a quarter circle?

-- replace FullCircle -> PetArc
local PetArc = math.pi / 2

This is much better but pets should have spaces I used the old angle script here

image

local i2 = (Index-1)%5 + 1
				local angle = i2 * (FullCircle / #PetTable)
				local pets_per_row = 5
				local base_radius = 3
				local radius_per_row = 5
				local radius = math.floor(Index / pets_per_row) * radius_per_row + base_radius 
				
				local X, Z = getXAndZPositions(angle, radius) 

It looks like the second row is the bad row.
In your script, make tables for rows. Put a pet in the row, after you did that start doing math with the table.

I’m doing a 180 degree I just forgot to remove 1 * math.pi it should be math.pi only.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.