So i’ve used the pet following script form this guy : How to create a pet system that dynamically generates positions
the problem with this is that is soo lagy
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Network = require(game.ReplicatedStorage.FrameWork.Main.Network)
warn(Network)
local Characters = {}
Characters.__index = Characters
function Characters:new()
warn("Setting up character...")
local PlayerData = Network.Invoke("GetData")
warn(PlayerData)
if not PlayerData or not PlayerData.Characters then
warn("Failed to get PlayerData or Pets is missing!")
return nil
end
local self = setmetatable({
Characters = PlayerData.Characters
}, Characters)
return self
end
function Characters.Follow()
--getting RunService
local RunService = game:GetService("RunService")
--Congiurable values
local maxPetsPerRow = 3 --how many pets can be in one row
local distancebetweenColumns = 5 --gap between columns
local distanceBetweenRows = 3 --gap between rows
local behindPlayerDistance = 3 --distance from player
local floatHeight = 3 --height above the ground
local smoothness = 4 --how fast the pet gets into position
--Main function to change Position formations
function Characters.GridPositionGen(numOfPets, petIndex, playerHrp) :Vector3
--lua for loop starts at 1
petIndex -= 1
local temp = maxPetsPerRow
if numOfPets < maxPetsPerRow then
maxPetsPerRow = numOfPets
end
local horizontalOffset = 0
if petIndex - maxPetsPerRow*math.floor(numOfPets/maxPetsPerRow) < 0 then
horizontalOffset = (petIndex%maxPetsPerRow * distancebetweenColumns) - ((maxPetsPerRow-1)*distancebetweenColumns)/2
else
maxPetsPerRow = numOfPets - maxPetsPerRow*math.floor(numOfPets/maxPetsPerRow)
horizontalOffset = petIndex%maxPetsPerRow * distancebetweenColumns - ((maxPetsPerRow-1)*distancebetweenColumns)/2
maxPetsPerRow = temp
end
local backwardsOffset = playerHrp.Position - playerHrp.CFrame.LookVector*behindPlayerDistance - playerHrp.CFrame.LookVector*distanceBetweenRows*(math.floor(petIndex/maxPetsPerRow))
local offset = backwardsOffset + playerHrp.CFrame.RightVector*horizontalOffset
maxPetsPerRow = temp
return offset
end
function Characters.CheckForFloor(offset:Vector3, filter:{Instance})
--raycast from the offset downwards to detect the floor
local rayParams = RaycastParams.new()
rayParams.FilterDescendantsInstances = filter
rayParams.FilterType = Enum.RaycastFilterType.Blacklist
local ray = workspace:Raycast(offset + Vector3.new(0, 5, 0), Vector3.new(0, -9999, 0), rayParams)
if ray then
--If the ray hit a floor it will return the Y coord + floatHeight
return ray.Position.Y + floatHeight
else
--If the ray didn't hit a floor is will return nil and print a warning
warn("no floor detected")
return
end
end
--Goes through a player's pet folder and put the pets at the correct position
function Characters.RenderPets(petsFolder, player, deltaTime)
--checks if the player's character spawned yet and if deltaTime was given else don't
--render this player's pets
if not player.Character or not player.Character.HumanoidRootPart then return end
if not deltaTime then print("no deltaTime given") return end
--getting the players's Character and HumanoidRootPart
local char = player.Character
local hrp = char:WaitForChild("HumanoidRootPart")
--loop through each pet of the folder to lerp them
--into eh correct position
for i, v in pairs(petsFolder:GetChildren()) do
--getting the offset from the player, note we have to subtract 1 from i as it starts from 1
--but we need it to start from 0 otherwise every pet 1 space off
local offset = Characters.GridPositionGen(#petsFolder:GetChildren(), i, hrp)
--Getting the distance we need from the floor so the pet will stay at a constant height from
--the floor
local verticalPos = Characters.CheckForFloor(offset, {char, petsFolder}) or hrp.CFrame.Position.Y
--the or is for if the ray did not hit the floor, the pet will be at character Y position
offset = Vector3.new(offset.X, verticalPos, offset.Z)
--creating the CFrame where the pet should be
local c = CFrame.new(offset, offset + hrp.CFrame.LookVector)
--Lerping the pet to the target CFrame so its more smooth
v.PrimaryPart = v:WaitForChild("HumanoidRootPart")
if v.PrimaryPart and v.PrimaryPart.CFrame then
v:SetPrimaryPartCFrame(v.PrimaryPart.CFrame:Lerp(c, smoothness*deltaTime))
end
end
end
RunService.Heartbeat:Connect(function(deltaTime)
for i, player in pairs(game.Players:GetPlayers()) do
if not workspace.Pets:FindFirstChild(player.Name.."-Pets") then continue end
Characters.RenderPets(workspace.Pets:FindFirstChild(player.Name.."-Pets"), player, deltaTime)
end
end)
end
Characters.Follow()
return Characters
this is the script