How to keep an object inside of bounds?

Hello everyone,

I am trying to keep an object in bounds for my placement system, using some “if-else” statements, but when the object is detected that it is out of bounds, the object stops moving. I tried to set to previous position but it just moves the object like crazy.

Here is the video:

Code:

	local x = math.floor(mouse.Hit.X / grid + 0.5) * grid
	--local y = math.floor(mouse.Hit.Y / grid + 0.5) * grid
	local y = 4
	if y <= 4 then
		y = 4
	end
	local z = math.floor(mouse.Hit.Z / grid + 0.5) * grid

	local canvas = game.Workspace.Canvas
	local minX = (canvas.Position.X - canvas.Size.X/2)
	local maxX = (canvas.Position.X + canvas.Size.X/2)
	local minZ = (canvas.Position.Z - canvas.Size.Z/2)
	local maxZ = (canvas.Position.Z + canvas.Size.Z/2)
	local pp = model.PrimaryPart

	local previousPos = CFrame.new()
	if part then
		if pp.Position.X + pp.Size.X/2 >= minX and pp.Position.X - pp.Size.X/2 <= maxX then
			if pp.Position.Z + pp.Size.Z/2 >= minZ and pp.Position.Z - pp.Size.Z/2 <= maxZ then
				model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(CFrame.new(x,y,z) * CFrame.Angles(0, math.rad(rotation * rotationDegree), 
					0), speed))
				previousPos = model.PrimaryPart.CFrame				
			else 
				model:SetPrimaryPartCFrame(previousPos)
			end
		end
	end

Thanks fot the Help!

I’m not every good at reading codes but i can se an if inside another if, maybe making them separate could work

Also Maybe i’m saying the same thing that is in your code but

I guess you should check the primary part CFrame everytime the part moves in the grid like removing from 0,0 to 0,1 1,0 and so on and every time the part goes over the limit coordinates the part goes to his last position, if i’m right this is what your code tries to do but you need a check before storing the last position or it will be teleported to his own position

I know this isn’t much but i hope this can help someways

You will have to clamp the vectors onto the surface using math.clamp()

pseudo code:

local function clampToBounds(vector,base)
    local offset = vector - base.Position
    local sx,sz = base.Size.X, base.Size.Z
    return Vector3.new(math.clamp(offset.X, -sx/2, sx/2),0,math.clamp(offset.Z, -sz/2, sz/2))
end

Denis, I know what you mean; those first two if statements are for the x-axis and z-axis. Those 4 variables I declared above the “… from 0,0 to 0,1 1,0 and so on…”. Tell me if interpreted your answer incorrectly.

1 Like

Dev, I am guessing that the vector is the primary part position, something like this:

		clampToBounds(pp.Position, canvas) --pp is the primaryPart
		model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(CFrame.new(x,y,z) * CFrame.Angles(0, math.rad(rotation * rotationDegree), 
			0), speed))

Another question: I do keep the if statements right?

Yes, but you would have to store the position and set it because my code only returns a vector3, never actually sets it

I am familiar with java and when there is a function that returns, I set to a variable; I am guessing it is the same for Lua? There is also no need for if-statements, right?

Building on previous code:

		local newPos = clampToBounds(pp.Position, canvas)
		model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(newPos * 
			CFrame.Angles(0, math.rad(rotation * rotationDegree), 
			0), speed))
1 Like

That is correct!
aaaaaaaaaaaaaaaaaaaaaaaa

It says that attempt to multiply a Vector3 with an incompatible value type or nil; what is wrong?

When I put CFrame.new(newPos), the part just goes into the floor

Nevermind, I realized the function with clampbounds has a y of 0 (fixed it to 4); now the part does not move at all.

Oh, you will have to add the newPos with the canvas’s position.

I am sorry, but can you help me cause I am confused:

Is this what you meant?
local minX = (canvas.Position.X - canvas.Size.X/2) + newPos

No,CFrame.new(canvas.Position + newpos)

No, that doesn’t seem to work:

		local newPos = clampToBounds(pp.Position, canvas)
		model:SetPrimaryPartCFrame(model.PrimaryPart.CFrame:Lerp(CFrame.new(canvas.Position + newPos) * 
			CFrame.Angles(0, math.rad(rotation * rotationDegree), 
			0), speed))

I fixed the moving issue, but it seems to give me an opposite effect, is there a reason:

Potentially try clamping sx,-sx instead of -sx,sx

Tried that but it gave me an error - I opened a new topic. Please look at it, it has all the updated code and the video above.