Looking to improve efficiency on pet code

Any help would be greatly appreciated!

I have a pet that follows the player, on the ground, but also rotates according to the normal of the surface, but at the same time still looks towards the player.

Currently there is an AlignPosition and an AlignOrientation in the pet that smoothly follows a part.

The way I’m currently doing this is by have the pet part, the part that the pet is aligned to, and a fakepart that rotates a lot to find the one rotation where it will be looking at the player.

Currently find this super inefficient since at least I’ll be doing one ray per frame and AT MOST it’ll be 37. Usually being around 10-25 rays a frame.

if p and pet and fakePart then 
	local ray = Ray.new((c.PrimaryPart.CFrame * CFrame.new(0,50,6.8)).p,Vector3.new(0,-500,0)) --first ray, to find placement behind player
	local hit, pos, norm = workspace:FindPartOnRayWithIgnoreList(ray,{pet,p,fakePart})
	if hit and pos and norm then
		p.CFrame =  CFrame.new(pos, pos+norm) * CFrame.Angles(math.rad(-90),math.rad(0),0) * CFrame.new(0,pet.Size.Y/2,0) --set according to surface normal then rotate to be upright then move up according to pet size
		fakePart.CFrame = p.CFrame -- this is a fakePart that i will be rotation a maximum of 36 times (meaning 36 Ray casts that frame.
		for i = 0,360,10 do -- rotate the fake part around to find the a rotation that is looking towards the player
			local newRay = Ray.new(fakePart.Position,((fakePart.CFrame*CFrame.new(0,0,-50)).p-fakePart.Position).unit*15) --raycast from fakepart forward
			local hit,pos,norm2 = workspace:FindPartOnRayWithIgnoreList(newRay,{pet,p,fakePart})
			if hit and hit.Parent and hit.Parent.Name == player.Name then --if the hit is the in the character then set the part cframe to fakeparts cframe, which now inclues the surface normal rotation + w.e rotation was necessary to look at player
				p.CFrame = fakePart.CFrame * CFrame.Angles(0,math.rad(10),0)
				break
			end
			fakePart.CFrame = fakePart.CFrame * CFrame.Angles(0,math.rad(10),0)
		end			
	end
end

Here are gifs that depict movement
Movement with fakepart to find orientation looking at player
Movement without finding orientation

I would love to not have to raycast so many times to get the desired affect, shown in the first gif.

1 Like

I think this belongs in #help-and-feedback:code-review

5 Likes

Whoops, skipped my eye! Will see if I can get it moved.

There is no reason to be using rays to face the direction of the player, as this can be achieved by using some simple CFraming:

(Code for facing Direction of player, not following)

local Pet = (Pet or the "fakepart" in this case)
local HumanoidRootPart  = game.Players.LocalPlayer.Character.HumanoidRootPart 
Pet.CFrame =  CFrame.new(Pet.Position, Vector3.new(HumanoidRootPart.Position.X,  Pet.Position.Y, HumanoidRootPart.Position.Z))---Set CFrame of the pet so that it faces towards the player while still maintaining height and position 

( you can add extra “animation” stuff, lerping and tweening etc.)

in your case, even though i would personally recommend using the TweenService or using CFrame to have a pet follow the player, using the code i provided to have the"fakepart" “look at” the player should work more efficient than using rays

Resource:

Or you can use a directional vector and discard the Y value. You may or may not need to use a different kind of constraint, I have not looked into that.

pseudocode for getting the lookvector and dropping the Y value:
lookvector = (humanpos - petpos).unit
lookvector = lookvector * Vector3.new(1, 0, 1)