Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to make a part face the closest side of another part?

Alright, so before beginning this post:

  • this is absolutely not the most efficient way to do this

  • i want to understand why THIS method is not working, not for a more efficient method

  • this project does NOT include the top and bottom surfaces of the init part

Alright so: I have a part which I will drag around my Baseplate - and a reference part which stays in a single position on the Baseplate. I don't want to use cf.new(vector,vector) at the closest side - I just want it to FACE the closest side, not the middle of the closest side.

Currently this is what I have, and I feel the issue lies in my handling of rotations toward the end:

local init_part = workspace.Init
local ref_part = workspace.Ref

local points = {}

local sub_x = init_part.Size.X / 2
local sub_z = init_part.Size.Z / 2

local two, four = init_part.Position + Vector3.new(sub_x,0,0), init_part.Position - Vector3.new(sub_x,0,0)
local one, three = init_part.Position + Vector3.new(0,0,sub_z), init_part.Position - Vector3.new(0,0,sub_z)

function determine_closest_side(from_part)
	local one_dist = (from_part.Position - one).Magnitude
	local two_dist = (from_part.Position - two).Magnitude
	local three_dist = (from_part.Position - three).Magnitude
	local four_dist = (from_part.Position - four).Magnitude
	
	local distances = {one_dist, two_dist, three_dist, four_dist}
	table.sort(distances)
	
	local closest = distances[#distances]
	
	if one_dist == closest then
		return one
	elseif two_dist == closest then
		return two
	elseif three_dist == closest then
		return three
	else
		return four
	end
end

while wait(1) do
	local cframe_construct = CFrame.new(init_part.Position, determine_closest_side(ref_part))
	
	local part = Instance.new("Part")
	part.CFrame = cframe_construct
	part.Anchored = true
	
	local y_orientation = part.Orientation.Y
	local solved_orientation = y_orientation - math.pi
	
	ref_part.CFrame = CFrame.new(ref_part.Position) * CFrame.Angles(0,solved_orientation,0)
end

If you want to experiment with this:

  1. Make two parts in Workspace

  2. Name one part Ref, and the other part Init

  3. Put this script in SSS

  4. Drag Ref around the Init part in Run mode.

Hopefully this is a decent explanation - but if you have further questions just make a comment.

1 answer

Edit: So this I have tested, it uses dot products to calculate the vector perpendicular to the original part (I'm pretty sure it was the original part, couldn't tell for sure because of the rate the parts kept spawning in).

while wait(1) do
    local cframe_construct = CFrame.new(init_part.Position, determine_closest_side(ref_part))

    local part = Instance.new("Part")
    part.CFrame = cframe_construct
    part.Anchored = true
	part.Parent = workspace --just added this in so I could see where the parts were for testing purposes

	local v = init_part.Orientation
	local u = ref_part.Orientation
	local lookVector = Vector3.new(v-(u*v:Dot(u)/u:Dot(u))) --dot product magic that gets a perpendicular vector to the original part

    ref_part.CFrame = CFrame.new(ref_part.Position) * CFrame.Angles(lookVector.X,lookVector.Y,lookVector.Z)
end


2 comments

0

The orientation being incorrect does not involve the length of the yielding between happenings. If it did I would use RunService.

0

So I'm not sure if this got it to face the right part, but it did face towards a part when I moved it around in a circle.

This discussion is preserved as it was. New answers, comments, and votes are closed.