Floating RayCast (Grid doesnt stick to the ground)

2024-05-06 19-13-45
The clip above is the problem, Basically it floats and it doesnt place on the ground like shown in the clip below
2024-05-06 19-13-59
The clip above is my goal (example is the roblox block movement)

This is the code snippet that needs changing

module.ProcessRayCast = function(first, second, RP)
	local RC = workspace:Raycast(first,(second - first) * 2, RP)
	if RC then
		local Touched : BasePart = RC.Instance
		local ProperPos = (RC.Position+(RC.Normal * module.grid/2))
		local gridas = module.grid
		local PositionX = math.round(ProperPos.X / gridas) * gridas
		local PositionY = math.round(ProperPos.Y / gridas) * gridas
		local PositionZ = math.round(ProperPos.Z / gridas) * gridas
		local pos = Vector3.new(PositionX,PositionY,PositionZ)
		return RC, pos
	end
end

The module.grid is 5, by the way

4 Likes
module.ProcessRayCast = function(first, second, RP)
    local RC = workspace:Raycast(first, (second - first) * 2, RP)
    if RC then
        local Touched = RC.Instance
        local ProperPos = RC.Position + (RC.Normal * module.grid / 2)
        local gridas = module.grid
        local PositionX = math.floor(ProperPos.X / gridas) * gridas
        local PositionY = math.floor(ProperPos.Y / gridas) * gridas
        local PositionZ = math.floor(ProperPos.Z / gridas) * gridas
        local pos = Vector3.new(PositionX, PositionY, PositionZ)
        return RC, pos
    end
end
6 Likes

isnt this the same script without the “()” in ProperPos???

3 Likes

@Dodoslayerlid Has my script been able to solve your problem?

Normally, the functions remain exactly the same. !

3 Likes

You just made it organized??? It did not fix anything, Because everything is the exact same. Thanks atleast. You also replaced math.round with math.floor which broke it

2 Likes

Still need help, I am not able to progress :confused:

2 Likes

It might be an issue regarding where the baseplate is compared to your grid. Try +/- a number on the Y axis or setting the Y axis to the location + the Y size of the block / 2.

4 Likes
module.ProcessRayCast = function(first, second, RP)
	local RC = workspace:Raycast(first, (second - first) * 2, RP)
	if RC then
		local Touched = RC.Instance
		local ProperPos = RC.Position + (RC.Normal*module.grid/2)
		local gridas = module.grid
		local PositionX = math.round( ProperPos.X / gridas) * gridas
		local PositionY = math.round( ProperPos.Y / gridas) * gridas
		local PositionZ = math.round( ProperPos.Z / gridas) * gridas
		if RC.Normal.X ~= 0 then
			PositionX = ProperPos.X
		end
		if RC.Normal.Y ~= 0 then
			PositionY = ProperPos.Y
		end
		if RC.Normal.Z ~= 0 then
			PositionZ = ProperPos.Z
		end
		local pos = Vector3.new(PositionX, PositionY, PositionZ)
		return RC, pos
	end
end

this is my new script it does work now just when now building from the side of the block it will be offset???

2 Likes

PositionY needs to be calculated by using Raycast downwards to the terrain to find the ground level. So makes sure that the hit position is properly grounded. Adjust the -10 value in Vector3.new(0, -10, 0) as needed to match the height of the ground

module.ProcessRayCast = function(first, second, RP)
    local RC = workspace:Raycast(first, (second - first) * 2, RP)
    if RC then
        local Touched : BasePart = RC.Instance
        local ProperPos = (RC.Position + (RC.Normal * module.grid / 2))
        local gridas = module.grid
        local PositionX = math.round(ProperPos.X / gridas) * gridas
        -- adjusting Y position to be at ground level
        local PositionY = math.round(workspace.Terrain:GetCell((ProperPos + Vector3.new(0, -10, 0))).Position.Y / gridas) * gridas
        local PositionZ = math.round(ProperPos.Z / gridas) * gridas
        local pos = Vector3.new(PositionX, PositionY, PositionZ)
        return RC, pos
    end
end

Try using this version it should solve it

4 Likes

is that chatgpt because i’ve seen that result before, I am not using terrain and it returns an error saying “Argument 3 missing or nil”

2 Likes

Without actually testing your code: It appears your current implementation is to have it snap to global coordinates. Which could cause some incongruity if the baseplate is not also aligned to the grid. There are a couple approaches to this that depend on your constraints

The simplest one would be to shift the grid down or the baseplate up. This assumes the only surface you want to build off of is your baseplate.

A more complicated solution with coordinates and orientation relative to the baseplate would probably use some sort of CFrame:inverse() magic (this is probably how Roblox’s editor does this, by aligning the bottom of the part with the surface of the raycast hit)

3 Likes

I have tried moving the baseplate but that wont fix the problem (it will rise again). I’m very bad with CFrames so can you write me an example of what u are saying??

3 Likes

Turn CanQuery off and position the part at mouse.Hit.Position. So don’t use raycast. Maybe use mousefilteeeer. OR USE CAMERAVIEWPORTMOUSE THINGY DONT REMEMBER THE EXACT SYNTAX FOR IT AND GET THE MOUSE FROM THERE.

4 Likes

Switching to mouse.hit.position wont really fix the raycasting problem and will make it worse, Raycasting is better (it has built in features)

2 Likes

Ok. If we start with Vector3, it is just cframe without rotation. Consider the points A=(1,1,1) and B=(2,3,4). You want to align B with A, so you assume that point A is the origin and work from there. This means you add the inverse of A to B (i.e. you subtract: B-A = (1,2,3))
Generalizing this to CFrame, if A and B were now CFrames, which would represent some point on the surfaces of the parts you are trying to connect, you “multiply”: B*A:inverse() so that you get a new CFrame that is now localized for A. From here you can apply your usual transformations: snapping it to a grid

3 Likes

How will this help me with the offset??? What do you mean by “localized”. I’m fairly confused how to even use this. Something new i got is literally Cframe:inverse is -CFrame without rotations???. I’m not working with rotations though

2 Likes

I apologize if I can’t address your problem directly. I don’t have a computer right now to work on, which is why I resort to describing everything abstractly. You mentioned that changing the baseplate positions will still result in the part “floating” so it seemed like it is relative to the baseplate but has an incorrect offset. In your code: return RC, pos
you could try changing it to: return RC, pos - Vector3.new(0,1,0) and try varying that number until it makes contact

2 Likes

Its okay!
This will result into problems. Like when the part is placed on another different grid block it will still float (It only fixed the problem for baseplate)

2 Likes

Try rounding the raycast position rather than the raycast position + normal.

4 Likes

the rounding itself is the thing that makes it float. A solution i thought of which i couldnt do is basically getting the block’s position and doing some magic to get the offset to put on the rounding to fix the floating

1 Like