I have been trying to create a building tool where I can freely move the part with my mouse from left to right, up to down, and vice versa. For example, if I use the front sphere to move my part, if I move my mouse in the opposite direction from the front sphere which represents the lookVector of the part that I’d be able to move it in the opposite direction as well. Think of it as the normal Roblox Studio default building tools. My part moves in a jittery motion and the Y axis is very buggy, I am trying to see if I can fix this. This script below is done in a local script and can be tested just by copying it and pasting it into Studio.
The function most important is the one at the bottom that activates while dragging the mouse, I have attempted to use dot products to know which direction the mouse is at relative to the sphere’s position.
local increment = 1 -- stud(s)
local newPart = Instance.new("Part")
local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local tableOfControlSpheres
local function movePartInDirection(part, unitVector)
part.Position = part.Position + (unitVector*increment)
for i, v in pairs(tableOfControlSpheres) do
v.Part.Position = v.Part.Position + (unitVector*increment)
end
end
local function createControls(partForControls)
tableOfControlSpheres = {
["FrontSphere"] = {
RepresentingVector = partForControls.CFrame.LookVector,
Part = nil,
Color = BrickColor.new("Dark blue")
},
["BackSphere"] = {
RepresentingVector = -partForControls.CFrame.LookVector,
Part = nil,
Color = BrickColor.new("Dark blue")
},
["UpSphere"] = {
RepresentingVector = partForControls.CFrame.UpVector,
Part = nil,
Color = BrickColor.new("Bright green")
},
["DownSphere"] = {
RepresentingVector = -partForControls.CFrame.UpVector,
Part = nil,
Color = BrickColor.new("Bright green")
},
["LeftSphere"] = {
RepresentingVector = -partForControls.CFrame.RightVector,
Part = nil,
Color = BrickColor.new("Really red")
},
["RightSphere"] = {
RepresentingVector = partForControls.CFrame.RightVector,
Part = nil,
Color = BrickColor.new("Really red")
}
}
for i, v in pairs(tableOfControlSpheres) do
local sphere = Instance.new("Part")
sphere.Shape = Enum.PartType.Ball
sphere.Size = Vector3.new(1, 1, 1)
sphere.Name = i
sphere.CFrame = partForControls.CFrame + (v.RepresentingVector*2)
sphere.Anchored = true
sphere.CanCollide = false
sphere.BrickColor = v.Color
sphere.Transparency = 0.5
sphere.Parent = partForControls
v.Part = sphere
end
end
local function insertPartIntoWorld(size, pos)
newPart.Size = size
newPart.Position = pos
newPart.Anchored = true
newPart.Parent = workspace
createControls(newPart)
end
insertPartIntoWorld(Vector3.new(2, 2, 2), Vector3.new(0, 5, 0))
local dragging
local rs = game:GetService("RunService")
mouse.Button1Down:Connect(function() -- while dragging part
local target = mouse.Target
if not target then
return
end
local targetInTable = tableOfControlSpheres[target.Name]
if not targetInTable then
return
end
dragging = true
repeat
rs.RenderStepped:Wait()
local mousePos = mouse.Hit.Position
local magnitude = (mousePos - target.Position).Magnitude
if magnitude >= increment then
local representingVector = targetInTable.RepresentingVector
local dotProduct = targetInTable.RepresentingVector:Dot(mousePos - target.Position)
if dotProduct > 0 then
movePartInDirection(newPart, (targetInTable.RepresentingVector))
elseif dotProduct < 0 then
movePartInDirection(newPart, (-targetInTable.RepresentingVector))
end
end
until not dragging
end)
mouse.Button1Up:Connect(function()
dragging = false
end)
EDIT 1: Removed useless code
EDIT 2: Replaced the old problem with the new problem description. I have replaced the dot product with the new better dot product calculation.