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

How do I position a part in between 2 points?

I was experimenting with some stuff and this is my code. It just sees for a hit and then gets p1 and p2, 2 points..

and then I want to just make a part in btw those points and stretch it, (much like a measurement tool)

So, Here's my script: I am not able to get it to work :/ the only problem is the position and IDK how to position it perfectly.

tool = script.Parent
handle = tool.Handle
p = game.Players.LocalPlayer
m = p:GetMouse()

tool.Equipped:connect(function()
	local p1
	local p2
	tool.Activated:connect(function()
		if not p1 then
			p1 = m.Hit.p
		else 
			p2 = m.Hit.p
		end
		
		if p1 and p2 then
			local part = Instance.new("Part", game.Workspace)
			local dist = (p1-p2).magnitude
			print("Distance :"..dist)
			part.CFrame = CFrame.new(p1.X, p2.Z)
			part.Size = Vector3.new(dist,1,1)
		end
	end)
end)


1 comment

0

Distance :22.704313278198 13:11:57.696 - Players.Player1.Backpack.Tool.LocalScript:20: bad argument #1 to 'new' (Vector3 expected, got number) 13:11:57.697 - Script 'Players.Player1.Backpack.Tool.LocalScript', Line 20 13:11:57.697 - Stack End

2 answers

✓ Accepted answer

Not to change your scripting habits, but I find it a lot more professional to capitalize more often and be more specific with your variables. This will greatly improve your reputation and give that "Wow, that scripter is really organized!" factor.

Tool = script.Parent
Handle = Tool:WaitForChild("Handle")
Player = game.Players.LocalPlayer
-- You don't need the mouse. The ".Equipped" event comes with the Mouse argument.

Tool.Equipped:connect(function (Mouse)
	local Point1
	local Point2
	Tool.Activated:connect(function ()
		if not Point1 then
			Point1 = Mouse.Hit.p
		else
			Point2 = Mouse.Hit.p
		end
		if Point1 and Point2 then
			local Visual = Instance.new("Part", workspace)
			local Distance = (p1 - p2).magnitude
			print("Distance: " .. Distance)
			Visual.Anchored = true
			Visual.CanCollide = true
			Visual.FormFactor = Enum.FormFactor.Custom
			-- More precise formfactor!
			Visual.Size = Vector3.new(1, 1, Distance)
			-- I found out that the Z axis works better in this demonstration
			Point1 = nil
			Point2 = nil
			-- This is to reset both of points
			game:GetService("Debris"):AddItem(Visual, 5)
			-- Ya gotta destroy it
		end
	end)
end)

You know what's the awesome thing about CFrame? You could have your part point to a particular direction if both of the points are Vector3 properties.

You'll need the first point (starting point).

Visual.CFrame = CFrame.new(Point1)

You'll need the second point (the direction it is pointing to).

Visual.CFrame = CFrame.new(Point1, Point2)

The problem with this is that the central position of Visual will always be on Point1. That's not what you want. What you want is a visual measuring tape.

You can do this by calculating the mean (the average) of both Point1 and Point2 components (X, Y, & Z). Because you need to position Visual in between Point1 and Point2.

function Mean(a, b)
	local solution = (a + b) / 2
	return solution
end

-- ...

Visual.CFrame = (
	Vector3.new(
		Mean(Point1.X, Point2.X),
		Mean(Point1.Y, Point2.Y),
		Mean(Point1.Z, Point2.Z)
	), Point2)

Your final script should be this:

Tool = script.Parent
Handle = Tool:WaitForChild("Handle")
Player = game.Players.LocalPlayer

function Mean(a, b)
	local solution = (a + b) / 2
	return solution
end

Tool.Equipped:connect(function (Mouse)
	local Point1
	local Point2
	Tool.Activated:connect(function ()
		if not Point1 then
			Point1 = Mouse.Hit.p
		else
			Point2 = Mouse.Hit.p
		end
		if Point1 and Point2 then
			local Visual = Instance.new("Part", workspace)
			local Distance = (p1 - p2).magnitude
			print("Distance: " .. Distance)
			Visual.Anchored = true
			Visual.CanCollide = true

			Visual.CFrame = CFrame.new(Vector3.new(Mean(Point1.X, Point2.X), Mean(Point1.Y, Point2.Y), Mean(Point1.Z, Point2.Z)), Point2)

			Visual.FormFactor = Enum.FormFactor.Custom
			Visual.Size = Vector3.new(1, 1, Distance)
			Point1 = nil
			Point2 = nil
			game:GetService("Debris"):AddItem(Visual, 5)
		end
	end)
end)

1 comment

0

I have come from a world of Javascript programming where we use the 'Camel' syntax, You put the variable's first letter small example - a simple variable like this var lastName = 'string' anyways, thanks so much!

It's simple. CFrame property calls CFrame.new and Vector3.new over it:

tool = script.Parent
handle = tool.Handle
p = game.Players.LocalPlayer
m = p:GetMouse()

tool.Equipped:connect(function()
    local p1
    local p2
    tool.Activated:connect(function()
        if not p1 then
            p1 = m.Hit.p
        else 
            p2 = m.Hit.p
        end

        if p1 and p2 then
            local part = Instance.new("Part", game.Workspace)
            local dist = (p1-p2).magnitude
            print("Distance :"..dist)
            part.CFrame = CFrame.new(Vector3.new(p1.X, p2.Z)) -- You forgot to call Vector3.new over CFrame.
            part.Size = Vector3.new(dist,1,1)
        end
    end)
end)

But it does not work because once generated, the part will fall, so do not forget to anchor it.

tool = script.Parent
handle = tool.Handle
p = game.Players.LocalPlayer
m = p:GetMouse()

tool.Equipped:connect(function()
    local p1
    local p2
    tool.Activated:connect(function()
        if not p1 then
            p1 = m.Hit.p
        else 
            p2 = m.Hit.p
        end

        if p1 and p2 then
            local part = Instance.new("Part", game.Workspace)
            part.Anchored = true -- Anchor the part
            local dist = (p1-p2).magnitude
            print("Distance :"..dist)
            part.CFrame = CFrame.new(Vector3.new(p1.X, p2.Z))
            part.Size = Vector3.new(dist,1,1)
        end
    end)
end)

But there's another problem. With the clicks, the tool starts getting bugged. To prevent it, immediately after the part generation, we will "clear" p1 and p2 so they can be assigned with new values. Who's better than nil value?

tool = script.Parent
handle = tool.Handle
p = game.Players.LocalPlayer
m = p:GetMouse()

tool.Equipped:connect(function()
    local p1
    local p2
    tool.Activated:connect(function()
        if not p1 then
            p1 = m.Hit.p
        else 
            p2 = m.Hit.p
        end

        if p1 and p2 then
            local part = Instance.new("Part", game.Workspace)
			part.Anchored = true
            local dist = (p1-p2).magnitude
            print("Distance :"..dist)
            part.CFrame = CFrame.new(Vector3.new(p1.X, p2.Z))
            part.Size = Vector3.new(dist,1,1)
			p1 = nil
			p2 = nil
        end
    end)
end)

And a thing. When you are trying to set Z, you are setting Y value instead. To correct this, you must to set a value to Y. I recommend to use p1 or p2

tool = script.Parent
handle = tool.Handle
p = game.Players.LocalPlayer
m = p:GetMouse()

tool.Equipped:connect(function()
    local p1
    local p2
    tool.Activated:connect(function()
        if not p1 then
            p1 = m.Hit.p
        else 
            p2 = m.Hit.p
        end

        if p1 and p2 then
            local part = Instance.new("Part", game.Workspace)
			part.Anchored = true
            local dist = (p1-p2).magnitude
            print("Distance :"..dist)
            part.CFrame = CFrame.new(Vector3.new(p1.X, p1.Y, p2.Z))
            part.Size = Vector3.new(dist,1,1)
			p1 = nil
			p2 = nil
        end
    end)
end)

If you want to make the part disappear of the game after a while, I think you can do it by yourself :p. But, because I'm friend:

tool = script.Parent
handle = tool.Handle
p = game.Players.LocalPlayer
m = p:GetMouse()

tool.Equipped:connect(function()
    local p1
    local p2
    tool.Activated:connect(function()
        if not p1 then
            p1 = m.Hit.p
        else 
            p2 = m.Hit.p
        end

        if p1 and p2 then
            local part = Instance.new("Part", game.Workspace)
			part.Anchored = true
            local dist = (p1-p2).magnitude
            print("Distance :"..dist)
            part.CFrame = CFrame.new(Vector3.new(p1.X, p1.Y, p2.Z))
            part.Size = Vector3.new(dist,1,1)
			p1 = nil
			p2 = nil
			wait(3) -- how much seconds do you want?
			part.Parent = nil
        end
    end)
end)

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