I am working on a pets system, and the parts welded to the PrimaryPart of a pet stick together, but are not sticking to the PrimaryPart. The other parts also show up closer to the player at the origin of the pet.
Video:
Ignore the test pets, they only have one part in the model
I have tried using regular welds as well, to the same issue.
The PrimaryPart is anchored. Unanchoring them will cause the pets to fall into the void and get deleted
This is the script that handles the pets on the ServerSide (I hardly think this script is the issue, but maybe I am wrong):
local Players = game:GetService("Players")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Function to attach pets to a player
local function attachPetsToPlayer(player)
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local petsFolder = Instance.new("Folder", workspace[player.Name])
petsFolder.Name = "Pets"
-- Get equipped pets from player's Pets.EquippedPets
local equippedPetsString = player:WaitForChild("Pets"):WaitForChild("Equipped").Value
local petNames = {}
if equippedPetsString ~= "" then
petNames = string.split(equippedPetsString, ",")
end
-- Clone and setup pets based on equipped pet names
local pets = {}
for i, petName in ipairs(petNames) do
if petName == "Test" then continue end
local petTemplate = ServerStorage.Pets:FindFirstChild(petName)
if petTemplate then
local pet = petTemplate:Clone()
pet.Parent = petsFolder
pet.Name = player.Name .. "_Pet_" .. i - 1
local alignPosition = Instance.new("AlignPosition", pet.PrimaryPart)
local petAttachment = Instance.new("Attachment", pet.PrimaryPart)
local playerAttachment = humanoidRootPart:FindFirstChild("PetAttachment")
if not playerAttachment then
playerAttachment = Instance.new("Attachment", humanoidRootPart)
playerAttachment.Name = "PetAttachment"
end
alignPosition.Attachment0 = petAttachment
alignPosition.Attachment1 = playerAttachment
alignPosition.MaxForce = 100000
alignPosition.Responsiveness = 50
table.insert(pets, pet)
end
end
-- Update pet positions
local runServiceConnection
runServiceConnection = game:GetService("RunService").Heartbeat:Connect(function()
for i, pet in ipairs(pets) do
local circlePosition = humanoidRootPart.Position + Vector3.new(
math.cos(i * (math.pi * 2 / #petNames)) * 8,
0,
math.sin(i * (math.pi * 2 / #petNames)) * 8
)
-- Move the pet to the circle position
pet.PrimaryPart.Position = circlePosition
end
end)
return runServiceConnection
end
Players.PlayerAdded:Connect(function(player)
local currentConnection
player.CharacterAdded:Connect(function()
currentConnection = attachPetsToPlayer(player)
player:WaitForChild("Pets"):WaitForChild("Equipped").Changed:Connect(function()
if currentConnection then
currentConnection:Disconnect()
end
for _, pet in ipairs(petsFolder:GetChildren()) do
if pet.Name:sub(1, #player.Name) == player.Name then
pet:Destroy()
end
end
currentConnection = attachPetsToPlayer(player)
end)
end)
end)
ReplicatedStorage.EquipUnequipPet.OnServerEvent:Connect(function(player, equippedPetsString, petsString)
player.Pets.Owned.Value = petsString
player.Pets.Equipped.Value = equippedPetsString
end)
This is the ClientSide:
local Players = game:GetService("Players")
local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local petsFolder = character:WaitForChild("Pets")
local equippedPets = player:WaitForChild("Pets"):WaitForChild("Equipped")
local numberOfPetsEquipped = string.split(equippedPets.Value, ",")
local petCount = #numberOfPetsEquipped
local circleRadius = 8
local circleSpeed = 0.2
local verticalSpeed = 1
local verticalAmplitude = 0.5
local tweenInfo = TweenInfo.new(
0.1,
Enum.EasingStyle.Linear,
Enum.EasingDirection.Out,
0,
false,
0
)
local function isPlayerMoving()
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
return humanoid.MoveDirection.Magnitude > 0
end
return false
end
local function updatePets()
local equippedPets = player:WaitForChild("Pets"):WaitForChild("Equipped")
local numberOfPetsEquipped = string.split(equippedPets.Value, ",")
local petCount = #numberOfPetsEquipped - 1
for i = 1, petCount do
local pet = petsFolder:FindFirstChild(player.Name .. "_Pet_" .. i)
if pet then
local angle = tick() * circleSpeed + (math.pi * 2 / petCount) * (i - 1)
local circlePosition = humanoidRootPart.Position + Vector3.new(
math.cos(angle) * circleRadius,
0,
math.sin(angle) * circleRadius
)
local verticalOffset = math.sin(tick() * verticalSpeed + i * 0.5) * verticalAmplitude
local targetPosition = circlePosition + Vector3.new(0, verticalOffset, 0)
local goal = {
Position = targetPosition
}
local tween = TweenService:Create(pet.PrimaryPart, tweenInfo, goal)
tween:Play()
if isPlayerMoving() then
local forwardCFrame = CFrame.new(targetPosition, targetPosition + humanoidRootPart.CFrame.LookVector)
pet:SetPrimaryPartCFrame(forwardCFrame)
else
local facePlayerCFrame = CFrame.new(targetPosition, humanoidRootPart.Position)
pet:SetPrimaryPartCFrame(facePlayerCFrame)
end
end
end
end
RunService.Heartbeat:Connect(function()
updatePets()
end)