Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

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

Asked by 5 years ago
Edited 5 years ago

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

Log in to vote
0
Answered by
SteamG00B 1633 Moderation Voter
5 years ago
Edited 5 years ago

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


0
The orientation being incorrect does not involve the length of the yielding between happenings. If it did I would use RunService. SummerEquinox 643 — 5y
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. SteamG00B 1633 — 5y
Ad

Answer this question