Predicting player placement in a rust style building system

  1. What do you want to achieve? Keep it simple and clear!
    I want to create a rust-style building system where the script predicts the likely position for the player’s next structure, I want it to be based on the players mouse position.

  2. What is the issue? Include screenshots / videos if possible!
    I have no clue how to predict where the player is going to place the next build at

  3. What solutions have you tried so far? Did you look for solutions on the Creator Hub?
    I searched on Youtube and dev forums, I only found how to create an attachment placement system

This is what I have so far ( an attachment placement system )

local players = game:GetService("Players")
local replicatedStorage = game:GetService("ReplicatedStorage")
local runService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")

local plr = players.LocalPlayer
local char = plr.Character

local mouse = plr:GetMouse()

local function UnitRay()
	local ur = plr:GetMouse().UnitRay
	return ur.Origin, ur.Direction * 10000
end

local wall = replicatedStorage:WaitForChild("cae").Part

local clonedSample = wall:Clone()
clonedSample.Parent = workspace
clonedSample.Anchored = true
clonedSample.CanCollide = false
clonedSample.Transparency = 0.5

local GTP = false
local Attachment = nil

runService.RenderStepped:Connect(function(dt)
	local origin, dir = UnitRay()
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = {char, clonedSample}

	local raycast = workspace:Raycast(origin, dir, params)

	if raycast and raycast.Instance then
		local raycastinstance = raycast.Instance
		local hitPos = raycast.Position

		local nearestAttachment = nil

		for _, attachment in pairs(raycastinstance:GetChildren()) do
			if attachment:IsA("Attachment") and attachment.Name == "WallSideSocket" then
				local attachmentPos = attachment.WorldPosition
				local flatDistance = Vector3.new(hitPos.X, 0, hitPos.Z) - Vector3.new(attachmentPos.X, 0, attachmentPos.Z)

				if flatDistance.Magnitude < 2 then
					nearestAttachment = attachment
					Attachment = attachment

					local wallCFrame = raycastinstance.CFrame * CFrame.new(attachmentPos)
					wallCFrame = wallCFrame * CFrame.new(-clonedSample.WallSideSocket.WorldPosition)
					wallCFrame = wallCFrame * CFrame.Angles(0, math.rad(attachment.Orientation.Y), 0)

					clonedSample.CFrame = wallCFrame
					GTP = true
					clonedSample.Color = Color3.fromRGB(0, 255, 0)
				end
			end
		end

		if nearestAttachment == nil then
			local downRay = Ray.new(hitPos + Vector3.new(0, 10, 0), Vector3.new(0, -100, 0))
			local rayHit, rayPosition = workspace:FindPartOnRay(downRay, clonedSample)

			if rayHit then
				clonedSample.CFrame = CFrame.new(
					hitPos.X,
					rayPosition.Y + clonedSample.Size.Y / 2,
					hitPos.Z
				)
			else
				clonedSample.CFrame = CFrame.new(hitPos.X, hitPos.Y + clonedSample.Size.Y / 2, hitPos.Z)
			end

			GTP = false
			clonedSample.Color = Color3.fromRGB(255, 0, 0)
		end
	end
end)

UIS.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.E then
		if GTP == true then
			if Attachment ~= nil then
				local final = clonedSample:Clone()
				final.Position = Attachment.WorldPosition
				final.Parent = workspace
				final.Anchored = true
				final.Color = Color3.fromRGB(255, 255, 255)
			end
		end
	end
end)

I suppose use the building it self and if it’s colliding in physics (requires CanCollide to true ) or Raycast or ArePartsTouchingOthers and other similarly as GetPartsInPart.

GetPartBoundsInRadius and GetPartBoundsInBox can be used as…

for example build chest but it processes as block version of it (nope, this requires manually coding to get this, result feature).

Client sends, server checks if it’s vaild to anti-cheat and then proccesses the position and what is supposed to be build on client’s request

found a solution, I ended up creating invisible placeholder walls and checking if the player’s mouse hits them. it lets me predict where the next wall will snap and ensures valid placement.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.