How could I find the the point on the object that is the closest to the player’s HumanoidRootPart position? This point shouldn’t be limited to just be on the corners or vertices, but rather anywhere along the surface.
Example (probably not accurate, just done by sight)
local Part = workspace.Part
local GetCorners = function(Inst)
local Corners = {}
local Pos = Inst.CFrame
local Size = Inst.Size
local frontFaceCenter = (Pos + Pos.LookVector * Size.Z/2)
local backFaceCenter = (Pos - Pos.LookVector * Size.Z/2)
local topFrontEdgeCenter = frontFaceCenter + frontFaceCenter.UpVector * Size.Y/2
local bottomFrontEdgeCenter = frontFaceCenter - frontFaceCenter.UpVector * Size.Y/2
local topBackEdgeCenter = backFaceCenter + backFaceCenter.UpVector * Size.Y/2
local bottomBackEdgeCenter = backFaceCenter - backFaceCenter.UpVector * Size.Y/2
Corners.topFrontRight = (topFrontEdgeCenter + topFrontEdgeCenter.RightVector * Size.X/2)
Corners.topFrontLeft = (topFrontEdgeCenter - topFrontEdgeCenter.RightVector * Size.X/2)
Corners.bottomFrontRight = (bottomFrontEdgeCenter + bottomFrontEdgeCenter.RightVector * Size.X/2)
Corners.bottomFrontLeft = (bottomFrontEdgeCenter - bottomFrontEdgeCenter.RightVector * Size.X/2)
Corners.topBackRight = (topBackEdgeCenter + topBackEdgeCenter.RightVector * Size.X/2)
Corners.topBackLeft = (topBackEdgeCenter - topBackEdgeCenter.RightVector * Size.X/2)
Corners.bottomBackRight = (bottomBackEdgeCenter + bottomBackEdgeCenter.RightVector * Size.X/2)
Corners.bottomBackLeft = (bottomBackEdgeCenter - bottomBackEdgeCenter.RightVector * Size.X/2)
return Corners
end
local GetClosestCorner = function(Inst, Corners)
local ClosestCorner = nil
for i,v in pairs(Corners) do
local Magnitude = (Inst.Position - v.Position).Magnitude
if (ClosestCorner == nil) then
ClosestCorner = v
end
if (Magnitude < (Inst.Position - ClosestCorner.Position).Magnitude) then
ClosestCorner = v
end
end
return ClosestCorner
end
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.CharacterAdded:Connect(function(Char)
local Root = Char:WaitForChild("HumanoidRootPart")
task.spawn(function()
while true and task.wait() do
local Corners = GetCorners(Part)
local ClosestCorner = GetClosestCorner(Root, Corners)
for i,v in pairs(Part:GetChildren()) do
if (v.Name == "CORNER_VISUAL") then
v:Destroy()
end
end
for i,v in pairs(Corners) do
local VisualPart = Instance.new("Part")
VisualPart.Size = Vector3.new(1, 1, 1)
VisualPart.Anchored = true
VisualPart.CanCollide = false
VisualPart.Transparency = 0.5
VisualPart.CFrame = v
if (ClosestCorner == v) then
VisualPart.Color = Color3.fromRGB(0, 255, 0)
else
VisualPart.Color = Color3.fromRGB(255, 0, 0)
end
VisualPart.Name = "CORNER_VISUAL"
VisualPart.Parent = Part
end
end
end)
end)
end)
local Character = script.Parent
function Get(V:BasePart?)
for _,d in workspace:GetChildren() do
if d:IsA("BasePart") and d:GetAttribute("Figure") == true then
if (d.Position - V.Position).Magnitude <= 7 then
return true,d
else
return false,d
end
end
end
end
function Create(State:boolean?,Part:BasePart?,v)
if State then
if not Part:FindFirstChild("LookATT") then
local ATT = Instance.new("Attachment")
ATT.Visible = true
ATT.Position = Part.CFrame:ToObjectSpace(v.CFrame).LookVector
ATT.Name = "LookATT"
ATT.Parent = Part
end
else
pcall(function()
Part:FindFirstChild(
"LookATT"
):Destroy()
end)
end
end
task.spawn(function()
while true do
task.wait()
for _,v in Character:GetChildren() do
if v:IsA("BasePart") then
local bool,Inst = Get(v)
print(bool,Inst)
Create(bool,Inst,v)
end
end
end
end)
Are you looking for something similar to this? Figure attribute is used as a whitelist so objects like baseplate dont account for the loop.
My approach for this is probably using raycast. When using raycast, store all valid raycast results in a table and compare the magnitude between whatever position you are comparing to the part you are checking. Be sure the whitelist parameter is only that specific part or the collision of the raycast may hit something else returning a false result. More raycast = more accuracy.