Block Placement system issues

I’m making a block placement system, and the problem I’m currently having is kind of complex to explain.

Basically to put it simple when I hover over a block I placed down it snaps to the normal of the raycast. And it works for “Blocks”, but if theres for example a 8x16 brick with a y size of 2 even if the size is 2 and the numbers are all even the part won’t position properly.

Here’s a example of the problem im having:

As you can clearly see the block placement is fine, but when I try to place the blocks onto a platform, it doesn’t work well. I’m already aware that the snap system I made is meant to keep the part in one position, but the problem is

  1. it doesn’t position it correctly on the sides
    and
  2. i don’t want this but I don’t know what to do

Here is the function I’m currently using:

local function ActivateBuildMode()
	Character = Player.Character
	if Character and Character.Parent and Character.Humanoid.Health > 0 then
		
		local CanBuild = (BuildMode and Player.Character and Player.Character:FindFirstChild("Humanoid") and Player.Character.Humanoid.Health > 0 and Character and Character:FindFirstChild("HumanoidRootPart"))
		while CanBuild do
			if Mouse and Mouse.Target and (Mouse.Hit.Position - Character.HumanoidRootPart.Position).Magnitude < 100 then
				local Origin = workspace.CurrentCamera.CFrame.Position
				local Goal = Mouse.Hit.Position
				local lookAt = CFrame.new(Origin, Goal).LookVector * 50
				local Params = RaycastParams.new()
				Params.FilterDescendantsInstances = {ReferenceBlock, Player.Character}
				local Raycast = workspace:Raycast(Origin, lookAt, Params)
				if Raycast and Raycast.Instance then
					ReferenceBlock.Parent = game.Workspace.ReferenceBlocks
					if not Raycast.Instance:IsDescendantOf(game.Workspace.PlayerBuildingBlocks) then
						local x, y, z = RoundToIncrement(Raycast.Position.X, 2), RoundToIncrement(Raycast.Position.Y, 2), RoundToIncrement(Raycast.Position.Z, 2)
						ReferenceBlock.CFrame = CFrame.new(Vector3.new(x, y, z) + (Raycast.Normal)) * CFrame.Angles(0, math.rad(Angle), 0)
					else
						ReferenceBlock.CFrame = CFrame.new(Raycast.Instance.Position + (Raycast.Normal*2))
					end
				end
			else
				ReferenceBlock.Parent = nil
			end
			RS.Stepped:Wait()
		end
		ReferenceBlock.Parent = nil
		
	end
end
2 Likes

This looks like the part responsible for that, so, you are moving the block by normal * 2, which moves it 2 studs, thus it “works” with the smaller one, to fix it, you should use normal * partSize / 2 where partSize will be the size of the part on the axis parallel to the normal.

Do you know how I can get the axis so I can do that? I’m a little lost on how I’d be able to determine which axis it is.

U have the normal, just check which of the components isn’t 0, you can also simply do:

Raycast.Instance.Position + (Raycast.Normal * Raycast.Instance.Size / 2)

To account for normals not aligned to 1 axis.

1 Like

It doesn’t quite work but it does on one axis, even though I did checks for each axis. I don’t know if this is what you meant but here’s the updated code:

local function ActivateBuildMode()
	Character = Player.Character
	if Character and Character.Parent and Character.Humanoid.Health > 0 then
		
		local CanBuild = (BuildMode and Player.Character and Player.Character:FindFirstChild("Humanoid") and Player.Character.Humanoid.Health > 0 and Character and Character:FindFirstChild("HumanoidRootPart"))
		while CanBuild do
			if Mouse and Mouse.Target and (Mouse.Hit.Position - Character.HumanoidRootPart.Position).Magnitude < 100 then
				local Origin = workspace.CurrentCamera.CFrame.Position
				local Goal = Mouse.Hit.Position
				local lookAt = CFrame.new(Origin, Goal).LookVector * 50
				local Params = RaycastParams.new()
				Params.FilterDescendantsInstances = {ReferenceBlock, Player.Character}
				local Raycast = workspace:Raycast(Origin, lookAt, Params)
				if Raycast and Raycast.Instance then
					ReferenceBlock.Parent = game.Workspace.ReferenceBlocks
					local AxisScale
					if Raycast.Normal.X > 0 or Raycast.Normal.X < 0 then
						AxisScale = Raycast.Instance.Size.X
					elseif Raycast.Normal.Y > 0 or Raycast.Normal.Y < 0 then
						AxisScale = Raycast.Instance.Size.Y
					else
						AxisScale = Raycast.Instance.Size.Z
					end
					if not Raycast.Instance:IsDescendantOf(game.Workspace.PlayerBuildingBlocks) then
						local x, y, z = RoundToIncrement(Raycast.Position.X, 2), RoundToIncrement(Raycast.Position.Y, 2), RoundToIncrement(Raycast.Position.Z, 2)
						ReferenceBlock.CFrame = CFrame.new(Vector3.new(x, y, z) + (Raycast.Normal * AxisScale)) * CFrame.Angles(0, math.rad(Angle), 0)
					else
						ReferenceBlock.CFrame = CFrame.new(Raycast.Instance.Position + (Raycast.Normal * AxisScale))
					end
				end
			else
				ReferenceBlock.Parent = nil
			end
			RS.Stepped:Wait()
		end
		ReferenceBlock.Parent = nil
		
	end
end

And the results from the change you suggested:

EDIT: Also I did divide it by 2 and that resulted in something weird let me show you real quick:

1 Like

You should remove that (switch to old code) and just put what I gave you in here. I’m pretty sure it’ll do the job.

Well some things to consider about this approach:

  1. I tried, it resulted in a much more complex issue. Basically it is halfway through whatever I put it on.
  2. The problem with that method is that the block is stationary and I can’t move it around the platform. It works with blocks though it’s just that i’m right back where I started.

Here’s the code:

I think to fix the current issue as seen in the video i’d need to scale with the size of the block so a simple +1 to it would work. But I don’t really know where to add that +1 or *2 or whatev.

1 Like

Ah yes, also add half the object being placed, since when u add the half of the main object, ur setting the center, so just move it, do size * normal / 2 again

I’m not sure if I’m following on this, could you explain differently what I should do? How would I add half the size so it scales the position correctly?

local totalSize = ReferenceBlock.Size + Raycast.Instance.Size
Raycast.Instance.Position + (Raycast.Normal * totalSize / 2)
2 Likes

Ohh that makes sense I’ll give that a try

Phenomenal, thanks so much for the help! I don’t quite know how I’ll make it go across the platform with increments but I’ll try to figure it out appreciate it so much bro!

EDIT: No longer need help on that 2nd part solved the issue on my own!!

1 Like

Lovely. Glad I was able to help :).

1 Like

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