How to find the closest position to a part

Hello, I don’t wanna waste too much time thinking how to do this cause math gets confusing sometimes so that’s why I need help.

theres a pet and the player.

when the pet’s distance is over a certain amount to the player, meaning the pet is far from the player, then i want the pet to go the closest position to the player.

and I want the pet to be a certain distance away from the player, which is using the distanceFromPlayer variable.

here is some of my code, where i calculate the position that the pet needs to move to.

    local distanceFromPlayer = 10

	local distance = (playerHrp.Position - petHrp.Position).Magnitude
	
	if distance > distanceFromPlayer then
		local random = math.random(-distanceFromPlayer, distanceFromPlayer)
		local pos = playerHrp.Position + Vector3.new(random, 0, random)
		
		local path = pathfinding:CreatePath()
		path:ComputeAsync(petHrp.Position, pos)
		local waypoints = path:GetWaypoints()

I’m still trying to figure the math out

here’s 2 examples of what I want

Your code seems like it would work, aside from the fact you’re using a keyword as a variable (random) so I’d suggest changing that. So what’s the pets behavior with this current code? Do you want the pet to go to a certain position relative to the player?

well yeah my current code works but its getting a random position around the player but that’s not what I want

I want the pet to be within 10 studs away from the player, so when the player moves, the pet moves to the player until its 10 studs away, I’m not trying make the pet not be able to go too close to the player, I just want the pet to always stay near the player

hopefully that makes sense

Okay, I think I get you, you want it to always go to a position within ten studs of the player, but you want it to walk to that position from its current position, so basically walking in a straight line towards the player til it’s within 10 studs (?)

yess that’s exactly what I want

I don’t know if there’s a better way but I just thought of a makeshifty way. Basically using lookVectors, this is probably buggy because I don’t have the devhub open plus it’s late but I promise you the idea is there.

local x = CFrame.lookAt(pos1, pos2) takes two Vector3s. The first is where it’s positioned and the second is where it’s looking at.

You could then use x.lookVector.Unit to get the direction and then multiply it by the distance (10). I don’t know if doing this returns a Vector3 though so you may want to check on devhub.

If pos1 is the torso and pos2 the pet, it would point to the pet, and multiplying it’s lookVector by 10 would put it at 10 studs away.

By pointing to the pet you can ensure its the shortest straight line

local goal = CFrame.lookAt(humanoidRootPart.Position, pet.Position).lookVector.Unit * distance

  1. Create multiple attachments surrounding the player.
  2. Add AlignPosition and AlignOrientation to the Pet
  3. Script the AlignPosition to align it to the closest point.
local petNodes = character.HumanoidRootPart:GetChildren()
local closestPetNode = nil

character.HumanoidRootPart.Changed:Connect(function() -- Checks if the position changed
    for i, v in pairs(petNodes) do
        if closestPetNode == nil then
            closestPetNode = v
        else
            if (pet.Position - v.Position).magnitude > (pet.Position - closestPetNode.WorldPosition).magnitude then
                closestPetNode = v
            end
        end
    end
    
    pet.AlignPosition.Attachment0 = closestPetNode
end)

Note: I have barely any understanding of AlignOrientation and AlignPosition.

ok I tried this but it doesnt seem to be working right

Could you describe it?

LookVector seems to return a CFrame so it might have to do with that

ok I understand what you done, if i cant find the problem, then ill use this code

this is what’s happening

btw I’m just using parts to figure this out, cause its kind of a long process to equip my pet and test it

the green is the player, the blue is the pet

when the game is not running
image

when the game is running
image_2022-10-01_005356469

heres the code

local x = CFrame.lookAt(petHrp.Position, playerHrp.Position)
petHrp.Position = x.lookVector.Unit * 10

That would be because it’s taking into consideration the Y axis as well. You should probably account for the Y axis independently, so, as an example:

local hrpPositionWithoutY = hrp.Position - Vector3.new(0,3,0) local goal = CFrame.lookAt(hrpPositionWithoutY, pet.Position).lookVector.Unit * distance

I’m subtracting 3 studs because the legs are 2 studs tall and the torso is 2 studs tall, but since position refers to the middle of the torso it’s 2 halved which is 1, 2+1 = 3. You should customize that to your liking and should probably account for different heights if your game uses character models with differing heights (like R15)

For those parts you’re testing with you should probably set the Y axis as the same Y as the part it’s following.

Also, the first position should be the player hrp, as the first Vector3 is where the LookVector will be located. Think of LookVector as an arrow; the first Vector3 is where the arrow is coming out of

ah no its not working right, instead of moving in a straight line towards the otherpart(playerHrp), it moves to the right

I’m going to go on studio and try to fiddle with it myself and I’ll let you know

ok thank you, I really appreciate it

Okay so turns out the LookVector is just a direction and its position defaults to the worlds center (0,0,0). So we actually need to add it to the humanoidRootPart’s position so that it’s relative to it.

local player = workspace:WaitForChild("player")
local pet = workspace:WaitForChild("pet")

while wait() do
	local x = CFrame.lookAt(player.Position, pet.Position)
	pet.Position = player.Position + x.LookVector.Unit * 10
end

2 Likes

omg whoa niceee, I have 23 lines of code of me just trying to figure this out, thank you so much!

1 Like

Wait. Did Neptunial solve it? If it was, may you make it the solution? It could help me out, too.

oh yes sorry lol, I forgot to mark it as the solution