First of all. I am not the best programmer so please tell me if there is anything i could do better or so and don’t hate on me. Also this is my first ever post here on the dev forum.
-
What do you want to achieve? Keep it simple and clear!
I want to achive a building/placement system like Plane Crazy. -
What is the issue? Include screenshots / videos if possible!
So basicly this is a placement system that i made a the past couple days and i have had problems with it not snapping if i rotate them and i don’t know how i would make a snapping as well as a grid placement of 1 stud. There is somewhat snapping in it and it snaps on some angles but mostly when i rotate it it won’t snap correctly and moves inside the block.Check this video for a look:
-
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have looked up solutions on the dev forum but i have not found anything that i understand as of my knowledge.
local PosX, PosY, PosZ
local player = game.Players.LocalPlayer
local Mouse = player:GetMouse()
local UIS = game:GetService("UserInputService")
local Part = game.ReplicatedStorage.Objects.Part
local Events = game.ReplicatedStorage.Events
local Place = Events.Place
local Position = CFrame.new()
local Plot = player:FindFirstChild("Plot").Value
local Properties = game.ReplicatedStorage.Properties
local Highlight = Properties.Highlight
local NewHighlight = Highlight:Clone()
NewHighlight.Parent = Part
local NewTexture = Properties.Texture
local Plots = workspace.Plots
NewTexture:Clone()
NewTexture.Parent = Plots[tostring(Plot)].Base
local Builds = workspace.Builds
local UIS = game:GetService("UserInputService")
local Rotation = CFrame.Angles(0, 0, 0)
local RotationY = 0
local RotationX = 0
Part.Parent = game.Workspace
Part.PrimaryPart.CanCollide = false
local Parts = 0
local MaxParts = 10
local CanPlace = true
local function Snap()
local localHit = Part.PrimaryPart.CFrame:pointToObjectSpace(Mouse.Hit.Position)
local roundedX = math.floor(localHit.X / Part.PrimaryPart.Size.X + 0.5) * Part.PrimaryPart.Size.X
local roundedY = math.floor(localHit.Y / Part.PrimaryPart.Size.Y + 0.5) * Part.PrimaryPart.Size.Y
local roundedZ = math.floor(localHit.Z / Part.PrimaryPart.Size.Z + 0.5) * Part.PrimaryPart.Size.Z
local roundedPosition = Vector3.new(roundedX, roundedY, roundedZ)
local worldPos = Part.PrimaryPart.CFrame:pointToWorldSpace(roundedPosition)
PosX = worldPos.X
PosY = worldPos.Y
PosZ = worldPos.Z
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Whitelist
Params.FilterDescendantsInstances = {Plots[tostring(Plot)].PrimaryPart}
local Hit = Mouse.Target
local RaycastResult = workspace:Raycast(Hit.Position + Vector3.new(0, 100, 0), Vector3.new(0, -1000, 0), Params)
if RaycastResult then
local surfaceNormal = RaycastResult.Normal
if RaycastResult.Instance == Part.PrimaryPart then
PosX = PosX + surfaceNormal.X * Part.PrimaryPart.Size.X
PosY = PosY + surfaceNormal.Y * Part.PrimaryPart.Size.Y
PosZ = PosZ + surfaceNormal.Z * Part.PrimaryPart.Size.Z
end
end
end
local function DetectPlot()
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Whitelist
Params.FilterDescendantsInstances = {Plots[tostring(Plot)].PrimaryPart}
local Hit = Mouse.Target
local RaycastResult = workspace:Raycast(Hit.Position + Vector3.new(0, 100, 0), Vector3.new(0, -1000, 0), Params)
if RaycastResult then
NewHighlight.OutlineColor = Color3.fromRGB(100, 255, 100)
CanPlace = true
else
Part.PrimaryPart.Anchored = true
NewHighlight.OutlineColor = Color3.fromRGB(255, 100, 100)
CanPlace = false
warn("Didn't hit anything!")
end
end
local function Move()
Snap()
Part:SetPrimaryPartCFrame(CFrame.new(PosX, PosY, PosZ) * Rotation)
Mouse.TargetFilter = Part
DetectPlot()
end
Mouse.Move:Connect(Move)
Mouse.Button1Down:Connect(function()
if CanPlace == true then
Position = Part.PrimaryPart.CFrame
Place:FireServer("Part", Position)
end
end)
UIS.InputBegan:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.R then
RotationX += 90
Rotation = CFrame.Angles(0, math.rad(RotationX), 0)
Part.PrimaryPart.CFrame *= Rotation
elseif Input.KeyCode == Enum.KeyCode.T then
RotationY += 90
Rotation = CFrame.Angles(math.rad(RotationY), 0, 0)
Part.PrimaryPart.CFrame *= Rotation
end
end)