Need Assistance Making Predictive Building Tool

I want to achieve a predictive building system similar to that of roblox bedwars. There were some big problems I’ve been constantly running into:

  1. I don’t know how I could use raycasting (unless I have a bunch of invisible parts, in which case that would most likely lag my game as I have hundreds of different block positions that I want players to be able to place blocks in) to predict a singular point in the game that someone would likely be wanting to place a block just based off of the mouse and/or the player.
  2. I tried following a youtube tutorial that seems like it had potential, but again, I ran into a similar problem: they detected if the part that is being clicked on is named “Block”, and if so, it clones it and places it on top, below, or to the side of that block based off of which face was clicked. The problem with this method is that I would still need to make at least a few hundred blocks (potentially causing lots of lag for players in the experience) in order to allow building off of the walls and floor (and off of blocks already placed down).

I don’t know if I could modify one of these methods to somehow use less blocks, or somehow make a system for getting the closest 4x4x4 block on an infinite grid just based off of a single reference block and its position, but if anyone knows something that might help, I really would appreciate it.

For reference, this is the default map, or “arena”:


3 Likes

You wouldn’t have to make a ton of blocks to lag your game, in fact, in the code that you were following along with in that YouTube video could be modified to just create a part using the Instance.new() function. Then you could also create a tool that deletes the selected part so that you won’t have a multitude of unnecessary parts in the game.

1 Like

I don’t believe you’re fully comprehending what I’m saying. At least from my understanding, the youtube video required there to be a bunch of parts named “Block”, to detect if that’s what you’re clicking on, and if so it clones itself on top of the original or to the side of it. So yes, I do believe that means I would need a bunch of blocks to begin with- redo the walls and floor of my map to be consisting of a bunch of 4x4x4 parts named “block”, so that they are all surfaces which you can build from.

If you don’t believe me, try out the code yourself.

Hmm, okay, I understand what you were saying now, I watched the video and I think this modified version will work a little better:

Client

script.Parent.Equipped:Connect(function(mouse)
mouse.Button1Down:Connect(function()
if mouse.Target.Name ~= “Block” then return end
script.Parent.RemoteEvent:FireServer(mouse.Target, mouse.TargetSurface)
end)
end)

Server

script.Parent:WaitForChild(“RemoteEvent”)
script.Parent.RemoteEvent.OnServerEvent:Connect(function(player, target, target_surface)
local rayOrigin = target.Position
local rayDirection = (0,0,4)
local rayDirection2 = (0,0,-4)
local rayDirection3 = (0,4,0)
local rayDirection4 = (0,-4,0)
local rayDirection5 = (4,0,0)
local rayDirection6 = (-4,0,0)
local block_clone = workspace.Block:Clone()
block_clone.Parent = workspace
if target_surface == Enum.NormalId.Back then
block_clone.Position = target:Raycast(rayOrigin, rayDirection).Position
elseif target_surface == Enum.NormalId.Front then
block_clone.Position = target:Raycast(rayOrigin, rayDirection2).Position
elseif target_surface == Enum.NormalId.Top then
block_clone.Position = target:Raycast(rayOrigin, rayDirection3).Position
elseif target_surface == Enum.NormalId.Bottom then
block_clone.Position = target:Raycast(rayOrigin, rayDirection4).Position
elseif target_surface == Enum.NormalId.Right then
block_clone.Position = target:Raycast(rayOrigin, rayDirection5).Position
elseif target_surface == Enum.NormalId.Left then
block_clone.Position = target:Raycast(rayOrigin, rayDirection6).Position
end
end)

It didn’t work- I am trying to make it so you can only place a block in each 4x4x4 stud box, and not in between, but the problem is the baseplate/ground is all one piece, so when it detects what part I hit, and gets the position, the position will always be the center of the baseplate, and will only place on top of the center of it. I want to fix this without making the baseplate out of a bunch of 4x4x4 blocks.

Anyways, here is the video of me trying your script:

1 Like

Here’s how my game is set up as of rn:

StudioPic1

Client Script:

script.Parent.Equipped:Connect(function(mouse)
	mouse.Button1Down:Connect(function()
		if mouse.Target.Name ~= "Block" and mouse.Target.IsA("Part") then return end
		script.Parent.RemoteEvent:FireServer(mouse.Target, mouse.TargetSurface)
	end)
end)

Server Script:

script.Parent:WaitForChild("RemoteEvent")
script.Parent.RemoteEvent.OnServerEvent:Connect(function(player, target, target_surface)
	local block_clone = game.ReplicatedStorage.Stone:Clone()
	print (block_clone.Name)
	block_clone.Parent = workspace
	block_clone.Name = "Block"
	if target_surface == Enum.NormalId.Back then
		block_clone.Position = target.Position + Vector3.new(0,0,4)
	elseif target_surface == Enum.NormalId.Front then
		block_clone.Position = target.Position + Vector3.new(0,0,-4)
	elseif target_surface == Enum.NormalId.Top then
		block_clone.Position = target.Position + Vector3.new(0,4,0)
	elseif target_surface == Enum.NormalId.Bottom then
		block_clone.Position = target.Position + Vector3.new(0,-4,0)
	elseif target_surface == Enum.NormalId.Right then
		block_clone.Position = target.Position + Vector3.new(4,0,0)
	elseif target_surface == Enum.NormalId.Left then
		block_clone.Position = target.Position + Vector3.new(-4,0,0)
	end
end)

Ok, so essentially you’re going to remove this whole block of code because this has to do with piggybacking off of the already placed blocks and building on from there. What you want to do is place freely on the baseplate’s surface without having to press on the already added blocks. I’m going to be completely honest with you I’ve never done a placement system before so here’s a video to help:

P.S. Put the remote event in ReplicatedStorage

The remote event would not go in ReplicatedStorage based off of the script you gave before.

And yes, I did use your script in the video, but then I guess I reverted it back before putting the code here, so my bad.
In the server script, it’s highlighting the raydirections as if something is incorrect about them.

Also, when I run it, this error gets printed out to the console as soon as the game loads, and I’m unable to even place blocks off of the existing grey test blocks I had from before.

I believe these directions have to be vector3’s, so I made them as such. Once I did that, the error I was getting changed to this (and note that I clicked on the ground to place the block on, but it placed the block way off in the distance):

1 Like

Is this why this script wouldn’t work?:

When we fire the event, it calls mouse.Target, which returns a part (in this case the part being selected is the ground) but the problem with that is you’re then raycasting from inside the ground part (in the server script) which is creating a ray starting at the center of the ground (the position of the ground) and then going straight up by 4 studs.

In theory, it would be a good idea, but only if the center of the ground part was directly below where we were clicking.

2 Likes

I fixed the script- it now works for building off of the ground, but now I need to look into making the predictive part of the building tool (which is crucial for the bridging mechanic).

Here’s some footage of it working now:

I’m a little confused about what you mean by this, could you please elaborate?

Like this: (notice even though the cursor is not pointing at a block within range that you can build off it, it still predicts that you want to place the block in front of the one already placed)
image

That may have to be used by using raycasting on a certain surface of the block but through the mouse hover function rather than the mouse click. So changing the trigger from the local script but keeping the rest of both scripts the same. But also adding Vector3 on the raydirections

For my building tool, I used mouse.hit not raycasting. But I don’t know if what you said is true, because it’s still not hovering over a face- it’s hovering over the void, and it’s predicting that the player wants to build in front of the block already placed in front of them.

In the case of the screenshot you showed above, I think the most understandable solution is probably the fact that since it is a first-person game they manipulate the direction that the player’s head is facing in comparison to what the closest part is before extending it where it would fall in the void

For example, look at this diagram I made forgive my artistic abilities, lol.


We can use a script to get the current CFrame of the player’s head when the trigger for placing a block is called. We then know that the same face/direction of the player’s face will be the same face/direction that the last block’s end will be (the part of the block we can not see). We can then calculate where the location will be with the script we had earlier for placing a block but only this time we are not going off of where are mouse’s target is, but where the character’s head currently is.

It’s not a first-person game- my apologies for the confusion- you’re just able to zoom into first-person just as in any other third-person game. I know for a fact it does not use the direction the head is facing, as you can tell from this video I took. I’m not facing the right side- I’m facing forwards, but when my mouse is aiming to the right, it predicts that I want to place it off the side of the block that is the edge of the cliff.

As I’ve searched through forums and things about this exact topic- a building system with bridging prediction- I have found people who think that it could easily be done with making invisible blocks on the sides of all blocks that you build. The only thing is, this is not the case- that’s not how the building system should work, based off of bedwars, as you can see below. Doing something like that would end up causing a result unlike the one seen in the picture below, and would instead select a block that you most likely did not intend to select.

Ok, I found this video that I think you would find helpful with your predictive system: https://youtube.com/shorts/xjy-XIQC4kc?si=j5R9qv6ILG6UN8X5

Thank you. I ended up doing something like this, and it works.

1 Like