Alright so i’ve been trying to make a placement system where you could grab an object, rotate it, weld it and stuff like that.
So the problem here is that i wanted it so the rotation for all object is the same and/or consistent. Example:
I grabbed a plank, then i pressed R to rotate it to (0,45,45). Now i grab another plank and my expectation is that it would also start at (0,45,45) so building is not a pain.
But…
Seems like trying to fix it myself just makes the code overcomplicated. Can anyone help me plz?
local RS = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local RP = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer
local camera = workspace.CurrentCamera
local highlight = RP.Objects.HoverHighlight
local billboard = RP.Objects.BillboardGui
local baseOrientationCFrame = nil
local buttonHighlight = highlight:Clone()
buttonHighlight.FillTransparency = 1
buttonHighlight.OutlineColor = Color3.fromRGB(255, 200, 50)
buttonHighlight.Parent = nil
local isMobile = true
local rotationMode = "Y"
local rotationOffset = CFrame.new()
local SackDebounce = false
local currentTarget = nil
local carrying = false
local range = 12
local carryDistance = 9
local maxCarryDistance = 20
local carrySmooth = 0.09
local throwBoost = 8
local lastVelo = Vector3.new()
local targetPos = nil
local lastTouchPosition = nil
local PC
if UIS.TouchEnabled and not UIS.KeyboardEnabled and not UIS.MouseEnabled then
PC = false
elseif not UIS.TouchEnabled and UIS.KeyboardEnabled and UIS.MouseEnabled then
PC = true
end
local storeConnection
local mouse = player:GetMouse()
local mobileDebounce = false
local axisTemplate = RP:WaitForChild("RotationAxis")
local axisModel
function AttachRotationAxis(target)
if axisModel then
axisModel:Destroy()
end
axisModel = axisTemplate:Clone()
axisModel.Parent = workspace
axisModel.PrimaryPart = axisModel.Mid
axisModel:SetPrimaryPartCFrame(CFrame.new(target.PrimaryPart.Position))
end
function RemoveRotationAxis()
if axisModel then
axisModel:Destroy()
axisModel = nil
end
end
local function updateAxisHighlight()
if not axisModel then return end
axisModel.X.Highlight.Enabled = false
axisModel.Y.Highlight.Enabled = false
axisModel.Z.Highlight.Enabled = false
if rotationMode == "X" then
axisModel.X.Highlight.Enabled = true
elseif rotationMode == "Y" then
axisModel.Y.Highlight.Enabled = true
elseif rotationMode == "Z" then
axisModel.Z.Highlight.Enabled = true
end
end
RS.RenderStepped:Connect(function(dT)
local target = nil
local inFirstPerson = (camera.CameraType == Enum.CameraType.Custom
and (camera.CFrame.Position - camera.Focus.Position).Magnitude < 1.5)
if inFirstPerson then
local rayOrigin = camera.CFrame.Position
local rayDirection = camera.CFrame.LookVector * range
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {player.Character}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local result = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
while result and result.Instance and result.Instance.Name == "Hitbox" do
rayOrigin = result.Position + rayDirection.Unit * 0.01
result = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
end
if result and result.Instance and result.Instance.Parent
and result.Instance.Parent:IsA("Model")
and result.Instance.Parent:FindFirstChild("Pickup") then
target = result.Instance
end
else
local mouseTarget = mouse.Target
if mouseTarget and mouseTarget.Name ~= "Hitbox" then
if mouseTarget.Parent and mouseTarget.Parent:IsA("Model")
and mouseTarget.Parent:FindFirstChild("Pickup") then
target = mouseTarget
end
end
end
if target and target.Parent and target.Parent:IsA("Model") and target.Parent:FindFirstChild("Pickup") then
if not carrying and target.Parent ~= currentTarget then
currentTarget = target.Parent
highlight.Parent = target.Parent
billboard.Parent = target.Parent
billboard.Main.ObjName.Text = string.lower(target.Parent.Name)
billboard.Main.Tag.Text = string.lower(target.Parent.Class.Value)
end
if target.Name == "Button" then
buttonHighlight.Parent = target
else
buttonHighlight.Parent = nil
end
else
if currentTarget ~= nil and not carrying then
player.PlayerGui.BindsUI.Container.StoreBind.Visible = false
player.PlayerGui.BindsUI.MobileButtons.Store.Visible = false
currentTarget = nil
highlight.Parent = nil
billboard.Parent = nil
SackDebounce = false
end
end
if carrying and currentTarget and currentTarget.Parent then
billboard.Parent = nil
if inFirstPerson then
targetPos = camera.CFrame.Position + camera.CFrame.LookVector * carryDistance
else
local screenPos = nil
if isMobile and lastTouchPosition then
screenPos = lastTouchPosition
else
screenPos = UIS:GetMouseLocation()
end
local ray = camera:ScreenPointToRay(screenPos.X, screenPos.Y)
targetPos = ray.Origin + ray.Direction * carryDistance
end
local minY = 0
if targetPos.Y < minY then
targetPos = Vector3.new(targetPos.X, minY, targetPos.Z)
end
local newCFrame = currentTarget.PrimaryPart.CFrame:Lerp(
CFrame.new(targetPos) * baseOrientationCFrame * rotationOffset, carrySmooth
)
currentTarget:SetPrimaryPartCFrame(newCFrame)
currentTarget.PrimaryPart.AssemblyLinearVelocity = Vector3.zero
if (camera.CFrame.Position - currentTarget.PrimaryPart.Position).Magnitude > maxCarryDistance then
DropItem(false)
end
if axisModel then
axisModel:SetPrimaryPartCFrame(currentTarget.PrimaryPart.CFrame)
end
end
end)
UIS.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 then
LeftClick()
end
if input.KeyCode == Enum.KeyCode.R and carrying and currentTarget then
if rotationMode == "X" then
rotationOffset = rotationOffset * CFrame.Angles(math.rad(45), 0, 0)
elseif rotationMode == "Y" then
rotationOffset = rotationOffset * CFrame.Angles(0, math.rad(45), 0)
elseif rotationMode == "Z" then
rotationOffset = rotationOffset * CFrame.Angles(0, 0, math.rad(45))
end
end
if input.KeyCode == Enum.KeyCode.T and carrying and currentTarget then
if rotationMode == "X" then
rotationMode = "Y"
elseif rotationMode == "Y" then
rotationMode = "Z"
else
rotationMode = "X"
end
updateAxisHighlight()
end
end)
UIS.InputEnded:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.UserInputType == Enum.UserInputType.MouseButton1 and carrying then
LeftUnClick()
end
end)
UIS.TouchStarted:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if mobileDebounce then return end
lastTouchPosition = input.Position
LeftClick()
end)
UIS.TouchEnded:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if carrying then LeftUnClick() end
end)
function LeftClick()
if currentTarget ~= nil and currentTarget.Parent then
if currentTarget.ServerOwner.Value == false then return end
baseOrientationCFrame = currentTarget.PrimaryPart.CFrame.Rotation
carrying = true
RP.Remotes.PickupItem:FireServer(currentTarget)
if not currentTarget:FindFirstChild("OriColl") then
local val = Instance.new("StringValue")
val.Parent = currentTarget
val.Name = "OriColl"
val.Value = currentTarget.PrimaryPart.CollisionGroup
end
for _, d in ipairs(currentTarget:GetDescendants()) do
if d:IsA("MeshPart") or d:IsA("Part") then
d.CollisionGroup = "Item"
end
end
AttachRotationAxis(currentTarget)
updateAxisHighlight()
end
end
function LeftUnClick()
carrying = false
if currentTarget then DropItem(true) end
end
function DropItem(AddForce)
if not currentTarget or not currentTarget.Parent then return end
RemoveRotationAxis()
local velocity = Vector3.new(0, 0, 0)
if AddForce then
velocity = (targetPos - currentTarget.PrimaryPart.Position) * throwBoost
end
RP.Remotes.DropItem:FireServer(currentTarget, velocity)
for _, d in ipairs(currentTarget:GetDescendants()) do
if d:IsA("MeshPart") or d:IsA("Part") then
d.CollisionGroup = currentTarget:FindFirstChild("OriColl").Value
end
end
carrying = false
end
UIS.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.Z then
if carrying and currentTarget then
RP.Remotes.WeldItem:FireServer(currentTarget)
elseif currentTarget and not carrying then
RP.Remotes.UnweldItem:FireServer(currentTarget)
end
end
end)
UIS.InputChanged:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.MouseWheel then
carryDistance = math.clamp(carryDistance + input.Position.Z, 5, 15)
end
end)