Pet following system issue

  1. What do you want to achieve?

    I want to make the pet look at the player while keeping its movement.
    cool

    So far, I only got the pet to move and stick next to the player.
    bad

  2. What is the issue?
    I can’t make the pet look at the player.

  3. What solutions have you tried so far?

RunService.RenderStepped:Connect(function()
	local c = math.sin(6 * time() + 1.6)
	local c1 = math.cos(6 * time() + 1.6)
	Pet.CFrame = Pet.CFrame:Lerp(
		HRoot.CFrame
			* CFrame.Angles(c1/3, 0, 0)
			* CFrame.new(0, c/3 , 0)
			* CFrame.new(Pet.Position, HRoot.Position + Vector3.new(3,0,3)),
		0.1
	)
end)

I have tried using CFrame.new(pos, lookat) which ended up looking like this.
fail
Then I thought I can calculate the Y angle using Pet and hroot’s position.

function atan2Normalized(x,y) 
	local result = math.atan2(y, x)
	return result >= 0 and result or (result + math.pi*2)
end

RunService.RenderStepped:Connect(function()
	local c = math.sin(6 * time() + 1.6)
	local c1 = math.cos(6 * time() + 1.6)
	Pet.CFrame = Pet.CFrame:Lerp(
		HRoot.CFrame
			* CFrame.Angles(c1/3, math.rad(57 * -atan2Normalized(Pet.Position.X - HRoot.Position.X, Pet.Position.Z - HRoot.Position.Z)), 0)
			* CFrame.new(3, c/3 , 3),
		0.1
	)
end)

but it still didn’t work.
epic fail

Now I’m all out of ideas on how to fix this. :pensive:

2 Likes

Not super advanced in lerping etc but did you mean to use CFrame.lookAt?

1 Like

CFrame.lookAt() is basically CFrame.new(pos, lookat)

2 Likes

Have you tried using BodyGyros?

I thought physics movers couldn’t move anchored parts.

I think it is suggested to use CFrame.lookAt
image

2 Likes

I think you can try Cframe.lookat

1 Like

It still does the same thing as CFrame.new(pos, lookAt)

Try using align orientation and connect it with two attachments in the pet and the player’s head

1 Like

Align orientation didn’t work, I might well as just stay with this.

You could try tweeting it.

local tweenInfo = TweenInfo.new(0.1, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, 0, false, 0)
		 	
local tween = TweenService:Create(Object.Head, tweenInfo, {CFrame = character.Head.NeckRigAttachment.CFrame:ToWorldSpace(character.Head.CFrame * CFrame.new(2, 1, 1))} )

This is what I used…

1 Like

Have you tried:

Pet.CFrame = CFrame.new(Pet.Position, Vector3.new(HRoot.Position.X,Pet.Position.Y,HRoot.Position.Z))

But use BodyGyro so it wont affect its position, just the lookat Position.(The pet has to be unanchored)

1 Like

Your model is incorrectly aligned. Front of the model is not the “face” of the pet. Otherwise
CFrame.new(pos, lookat) would work. Best solution is to re-do the model. If that is not possible for any reason, you could use CFrame.Angles

CFrame.new(pos, lookat) * CFrame.Angles(0,math.pi/2,0)
--or (I can never remember what direction this rotates)
CFrame.new(pos, lookat) * CFrame.Angles(0,math.pi*3/2,0)

I hope this helps!

2 Likes

Hi, put this in StarterCharacterScripts. You can customize the sensitivity of the position lerp and the angle lerp by changing 0.03 to any higher number if you want.

local RunService = game:GetService'RunService'
local Players = game:GetService'Players'
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character
local RootPart = Character:WaitForChild'HumanoidRootPart'

local PetOffset = Vector3.new(0, 0, 5)

wait(3)

local Pet = Instance.new("Part", Character)
Pet.Size = Vector3.new(2, 2, 3)
Pet.CFrame = CFrame.new(RootPart.Position + PetOffset)
Pet.Anchored = true
Pet.CanCollide = false

local Position = Pet.Position
local Angle = CFrame.new()
RunService.RenderStepped:Connect(function()
	Position = Position:Lerp(RootPart.Position + PetOffset + Vector3.new(0, math.sin(tick() * 5 % math.pi * 2), 0), 0.03)
	local LookAt = CFrame.new(Pet.Position, RootPart.Position) * CFrame.Angles(math.rad(math.cos(tick() * 5 % math.pi * 2)) * 30, 0, 0)
	LookAt = LookAt - LookAt.p
	Angle = Angle:Lerp(LookAt, 0.03)
	Pet.CFrame = CFrame.new(Position) * Angle
end)

Yes! That works! but I just don’t know how to make it only rotate on the X and Y-axis though. I tried only using X and Y on the CFrame.Angles() but this happens.

Show your code for the rotation.

local Position = Pet.Position
local Angle = CFrame.new()
RunService.RenderStepped:Connect(function()
	Position = Position:Lerp(RootPart.Position + PetOffset + Vector3.new(0, math.sin(tick() * 5 % math.pi * 2), 0), 0.1)
	local LookAt = CFrame.new(Pet.Position, RootPart.Position) * CFrame.Angles(math.rad(math.cos(tick() * 5 % math.pi * 2)) * 30, 0, 0)
	LookAt = LookAt - LookAt.p
	Angle = Angle:Lerp(LookAt, 0.1)
	local x,y,z = Angle:ToEulerAnglesXYZ()
	Pet.CFrame = CFrame.new(Position) * CFrame.Angles(x,y,0)
end)

So what’s the problem the gif looks correct on only x and y? Try changing the sensitivity of the lerp if the bobbing is too aggresive.

As you can see on the video, the pet’s x and y axis is somewhat combined-ish.

Then add delays between the rotation of the x axis and then rotation of the y axis?