How to make pet float up and down gently?

  1. What do you want to achieve?

Currently have a script that gives a player a pet and has it floating near it shoulder. I wanted to know 2 things: if the way this pet system is set up as far as how the code makes the pet follow you and float is correct, recommended, and/or conventional? And also wondering how I would make the pet slowly float up and down gently like a cute animation. I don’t exactly want to give each pet a head and torso and rig to give it an actual animation, but rather would like it to be just be tweened or coded in? Have no clue how I would go on about this

  1. What is the issue?

Currently not sure if the wait() part is recommended, and also not sure if the way the code sets up the pet following is correct/recommended

Any tips, extra info, or help on anything and on making the pet float up and down gently.


local pet = script.Parent

function givePet (player)
 if player then
  local character = player.Character
  if character then
   local humRootPart = 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)
   

   newPet.CanCollide = false
   
   while wait() do
    bodyPos.Position = humRootPart.Position + Vector3.new(3, 3, 4)
    bodyGyro.CFrame = humRootPart.CFrame
   end
   
  end
 end
end

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

1 Like

Sine waves!

An easy way you can get something to hover is simply by using math.sin to determine the height of an object

You will need to combine with radian method and RunService for the best effect

local Amplitude = 10 -- Size of wave
local Frequency = 10 -- Speed of wave
RunService.Stepped:Connect(RunTime)
    local SineHeight = math.sin(math.rad(RunTime * Frequency)) * Amplitude
ene
1 Like

Thanks for the tip! Where would this exactly go and how would this work? Inside the wait() loop?

It would probably go something like this

local TargetCFrame;
local Amp = 10
local Fq = 10

while RunService.Stepped:Wait() do
    TargetCFrame = HRP.CFrame:ToWorldSpace(CFrame.new(3, 3 + (math.sin(math.rad(time * Fq)) * A), 4))
end

Couple of notes.

I highly recommend you do not update BodyMovers every frame. They are not supposed to be used that way and they are legacy. Doing it every frame is costly as it will also run on the physics system.

Use Cframe interpolation instead.

wait() is generally frowned upon by developers due to its relative “slowness” and lack of control. It is highly advised to not use it in production code

I am using time instead of RunTime Argument due to the fact that it’s basically the same thing.

ToWorldSpace is a special function that is handy if you want to place Object A relative to Object B.

We are placing the pet relative to the player

1 Like