Part can't leave the borders

Hello!
I am trying to recreate a machine we have at my work ( an cnc machine) but the part won’t stay in between the ‘machine park’. I’ve tried using booleans which caused the whole script to malfunction. The machine is powered by a UI with just 2 scripts (1 local script for the buttons and 1 script for the remote events). Does anybody have tips on how I could do this?

video of what I mean:

The script I’ve tried:

--[[ CNC AXLE LIMITS ]]

local MachineHead = game.Workspace.MachineHead

local Main = script.Parent

local AxleLimits = Main.AxleLimits

local MaxXaxle = AxleLimits.MaxXaxle
local MaxYaxle = AxleLimits.MaxYaxle
local MaxZaxle = AxleLimits.MaxZaxle

local MinXaxle = AxleLimits.MinXaxle
local MinYaxle = AxleLimits.MinYaxle
local MinZaxle = AxleLimits.MinZaxle

MachineHead.Changed:Connect(function()
	print("Machine head current position: ", MachineHead.Position)
	if MachineHead.Position == Vector3.new(6, MachineHead.Position.Y, MachineHead.Position.Z) then
		MaxXaxle.Value = true
	elseif MachineHead.Position == Vector3.new(MachineHead.Position.X, 2.6, MachineHead.Position.Z) then
		MaxYaxle.Value = true
	elseif MachineHead.Position == Vector3.new(MachineHead.Position.X, MachineHead.Position.Y, 50) then
		MaxZaxle.Value = true
	else
		MaxXaxle.Value = false
		MaxYaxle.Value = false
		MaxZaxle.Value = false
		
		MinXaxle.Value = false
		MinYaxle.Value = false
		MinZaxle.Value = false
	end
end)

[ main scripts ]

The button script:

--[[ CNC MACHINE BUTTONS ]]

local UIS = game:GetService("UserInputService")

local Main = script.Parent

Main.Draggable = true

local ButtonEvents = Main.ButtonsEvents

local EmergencyButton = Main.EmergencyButton
local EmergencyButtonEnabled = Main.EmergencyButtonEnabled

local AxleButton = Main.AxleButton
local RotarySelectorSwitchTwisting = AxleButton.RotarySelectorSwitchTwisting

local SelectedAxleValue = Main.SelectedAxleValue

local PlusButton = Main.PlusButton
local PlusButtonEvent = ButtonEvents.PlusButtonEvent

local MinusButton = Main.MinusButton
local MinusButtonEvent = ButtonEvents.MinusButtonEvent

--[[ EMERGENCY BUTTON ]]

EmergencyButton.MouseButton1Click:Connect(function()
	if EmergencyButtonEnabled.Value == false then
		EmergencyButtonEnabled.Value = true
	else
		print("Emergency button already enabled!")
	end
end)

EmergencyButton.MouseButton2Click:Connect(function()
	if EmergencyButtonEnabled.Value == true then
		EmergencyButtonEnabled.Value = false
	else
		print("Emergency button already disabled!")
	end
end)

--[[ AXLE BUTTON ]]

AxleButton.MouseButton1Click:Connect(function()
	local X = 0
	local Y = 35
	local Z = 75
	
	if AxleButton.Rotation == X then
		wait(0.25)
		AxleButton.Rotation = Y
		SelectedAxleValue.Value = "Y"
		RotarySelectorSwitchTwisting:Play()
	elseif AxleButton.Rotation == Y then
		wait(0.25)
		AxleButton.Rotation = Z
		SelectedAxleValue.Value = "Z"
		RotarySelectorSwitchTwisting:Play()
	end
end)

AxleButton.MouseButton2Click:Connect(function()
	local X = 0
	local Y = 35
	local Z = 75
	
	if AxleButton.Rotation == Z then
		wait(0.25)
		AxleButton.Rotation = Y
		SelectedAxleValue.Value = "Y"
		RotarySelectorSwitchTwisting:Play()
	elseif AxleButton.Rotation == Y then
		wait(0.25)
		AxleButton.Rotation = X
		SelectedAxleValue.Value = "X"
		RotarySelectorSwitchTwisting:Play()
	end
end)

local RepeatValue = script.RepeatValue

--[[ PLUS BUTTON / KEYCODE ]]

PlusButton.MouseButton1Down:Connect(function()
	RepeatValue.Value = true
	while RepeatValue.Value == true do
		if EmergencyButtonEnabled.Value == false then
			PlusButtonEvent:FireServer(SelectedAxleValue.Value)
		else
			print("Emergency button active!")
		end
		wait(0.01)
	end
end)

PlusButton.MouseButton1Up:Connect(function()
	RepeatValue.Value = false
end)

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.KeypadPlus then
		RepeatValue.Value = true
		while RepeatValue.Value == true do
			if EmergencyButtonEnabled.Value == false then
				PlusButtonEvent:FireServer(SelectedAxleValue.Value)
			else
				print("Emergency button active!")
			end
			wait(0.01)
		end
	end
end)

UIS.InputEnded:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.KeypadPlus then
		RepeatValue.Value = false
	end
end)

--[[ MINUS BUTTON / KEYCODE ]]

MinusButton.MouseButton1Down:Connect(function()
	RepeatValue.Value = true
	while RepeatValue.Value == true do
		if EmergencyButtonEnabled.Value == false then
			MinusButtonEvent:FireServer(SelectedAxleValue.Value)
		else
			print("Emergency button active!")
		end
		wait(0.01)
	end
end)

MinusButton.MouseButton1Up:Connect(function()
	RepeatValue.Value = false
end)

UIS.InputBegan:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.KeypadMinus then
		RepeatValue.Value = true
		while RepeatValue.Value == true do
			if EmergencyButtonEnabled.Value == false then
				MinusButtonEvent:FireServer(SelectedAxleValue.Value)
			else
				print("Emergency button active!")
			end
			wait(0.01)
		end
	end
end)

UIS.InputEnded:Connect(function(Input)
	if Input.KeyCode == Enum.KeyCode.KeypadMinus then
		RepeatValue.Value = false
	end
end)

The remote events script:

--[[ CNC MACHINE BUTTONS EVENTS ]]

local MachineHead = game.Workspace.MachineHead

local Main = script.Parent

local ButtonsEvents = Main.ButtonsEvents

local PlusButtonEvent = ButtonsEvents.PlusButtonEvent
local MinusButtonEvent = ButtonsEvents.MinusButtonEvent

local EmergencyButtonEnabled = Main.EmergencyButtonEnabled

PlusButtonEvent.OnServerEvent:Connect(function(Player, SelectedAxleValue)
	if SelectedAxleValue == "X" then
		MachineHead.Position = Vector3.new(MachineHead.Position.X + 0.1, MachineHead.Position.Y, MachineHead.Position.Z)
	elseif SelectedAxleValue == "Y" then
		MachineHead.Position = Vector3.new(MachineHead.Position.X, MachineHead.Position.Y + 0.1, MachineHead.Position.Z)
	elseif SelectedAxleValue == "Z" then
		MachineHead.Position = Vector3.new(MachineHead.Position.X, MachineHead.Position.Y, MachineHead.Position.Z + 0.1)
	end
end)

MinusButtonEvent.OnServerEvent:Connect(function(Player, SelectedAxleValue)
	if SelectedAxleValue == "X" then
		MachineHead.Position = Vector3.new(MachineHead.Position.X - 0.1, MachineHead.Position.Y, MachineHead.Position.Z)
	elseif SelectedAxleValue == "Y" then
		MachineHead.Position = Vector3.new(MachineHead.Position.X, MachineHead.Position.Y - 0.1, MachineHead.Position.Z)
	elseif SelectedAxleValue == "Z" then
		MachineHead.Position = Vector3.new(MachineHead.Position.X, MachineHead.Position.Y, MachineHead.Position.Z - 0.1)
	end
end)
1 Like

You must also take in count part’s size. Divide it by 2 and you will get half of the size, because if we will do full size, the part will stop way too far.
Condition checks are unecessary, because we have math.clamp.

math.clamp?

.clamp limits a value to the defined range.
Parameters:

  • x - the number to clamp
  • min - the starting value of the range
  • max - the end value of the range

Returns:

  • If min <= x <= max (in range of the values), returns x
  • If x < min, returns min
  • If x > max, returns max

Example (I did this with X only, but I am sure you can re-implement this for every axis):

local Borders = [insert the path of those 4 parts that represent boundaries]
local xBorderMin = Borders:WaitForChild("XMin") --should be the part that has a lesser x position
local xBorderMax = Borders:WaitForChild("XMax") --should be the part that has a greater x position
...
local NewX = MachineHead.Position.X + 0.1
MachineHead.Position = Vector3.new(math.clamp(NewX, xBorderMin.Position.X + MachineHead.Size.X, xBorderMax.Position.X - MachineHead.Size.X), MachineHead.Position.Y, MachineHead.Position.Z)

Do I need to put that inside the remote events?

Yes. Paste the lines before ... in the start of the script, and the ones after in your .OnServerEvent.

Alrighty, will try it out now and see what it does.

I get this error when trying it…

1 Like

Are you sure that your xBorderMax is the one with the greater Position.X? Try printing out them.

print(xBorderMin.Position, xBorderMax.Position)

image
This is what it printed

You confused the XMin and XMax. Rename them.

So it moves but I think that I still don’t have a clue on what you meant with the deviding the machine head because it does something odd:

What exactly is wrong? Is it moving by itself?

No its moving outside its borders (the keypad can also be used to move it so that’s why it moves itself)

You didn’t add borders for Y and Z. I only provided you with the solution for X.

Fixed X setting:

local NewX = MachineHead.Position.X + 0.1
MachineHead.Position = Vector3.new(math.clamp(NewX, xBorderMin.Position.X + MachineHead.Size.X/2, xBorderMax.Position.X - MachineHead.Size.X/2), MachineHead.Position.Y, MachineHead.Position.Z)

If you want to add the borders to more axis, just change this part up a bit. Of course, also define the parts that represent limits.

It keeps going over the minimal axle, I know I have to add the other 2 axles but I’ll add it in a sec :slight_smile:

wait nevermind, I’m dumb haha, the minus button never changed, So sorry!!

1 Like

I’ve added the other axles but it gives the same errors like before but if I switch them it still gives the errors…
image of X, Y and Z print

the script I did

local Borders = game.Workspace.MachinePark
local xBorderMin = Borders:WaitForChild("XMin") --should be the part that has a lesser x position
local xBorderMax = Borders:WaitForChild("XMax") --should be the part that has a greater x position
local yBorderMin = Borders:WaitForChild("YMin")
local yBorderMax = Borders:WaitForChild("YMax")
local zBorderMin = Borders:WaitForChild("ZMin")
local zBorderMax = Borders:WaitForChild("ZMax")

print(xBorderMin.Position, xBorderMax.Position)
print(yBorderMin.Position, yBorderMax.Position)
print(zBorderMin.Position, zBorderMax.Position)

PlusButtonEvent.OnServerEvent:Connect(function(Player, SelectedAxleValue)
	if SelectedAxleValue == "X" then
		local NewX = MachineHead.Position.X + 0.1
		MachineHead.Position = Vector3.new(math.clamp(NewX, xBorderMin.Position.X + MachineHead.Size.X/2, xBorderMax.Position.X - MachineHead.Size.X/2), MachineHead.Position.Y, MachineHead.Position.Z)
	elseif SelectedAxleValue == "Y" then
		local NewY = MachineHead.Position.Y + 0.1
		MachineHead.Position = Vector3.new(MachineHead.Position.X, math.clamp(NewY, yBorderMin.Position.Y + MachineHead.Size.Y/2, yBorderMax.Position.Y - MachineHead.Size.Y/2), MachineHead.Position.Z)
	elseif SelectedAxleValue == "Z" then
		local NewZ = MachineHead.Position.Z + 0.1
		MachineHead.Position = Vector3.new(MachineHead.Position.X, MachineHead.Position.Y, math.clamp(NewZ, zBorderMin.Position.Z + MachineHead.Size.Z/2, zBorderMax.Position.Z - MachineHead.Size.Z/2))
	end
end)

MinusButtonEvent.OnServerEvent:Connect(function(Player, SelectedAxleValue)
	if SelectedAxleValue == "X" then
		local NewX = MachineHead.Position.X - 0.1
		MachineHead.Position = Vector3.new(math.clamp(NewX, xBorderMin.Position.X + MachineHead.Size.X/2, xBorderMax.Position.X - MachineHead.Size.X/2), MachineHead.Position.Y, MachineHead.Position.Z)
	elseif SelectedAxleValue == "Y" then
		local NewY = MachineHead.Position.Y - 0.1
		MachineHead.Position = Vector3.new(MachineHead.Position.X, math.clamp(NewY, yBorderMin.Position.Y + MachineHead.Size.Y/2, yBorderMax.Position.Y - MachineHead.Size.Y/2), MachineHead.Position.Z)
	elseif SelectedAxleValue == "Z" then
		local NewZ = MachineHead.Position.Z - 0.1
		MachineHead.Position = Vector3.new(MachineHead.Position.X, MachineHead.Position.Y, math.clamp(NewZ, zBorderMin.Position.Z + MachineHead.Size.Z/2, zBorderMax.Position.Z - MachineHead.Size.Z/2))
	end
end)

You are most likely confusing the Min and Max parts. If you do not want for that to happen, here’s a quick solution:

local NewX = MachineHead.Position.X + 0.1
local min, max = xBorderMin, xBorderMax
if xBorderMin.Position.X > xBorderMax.Position.X then
  min, max = max, min --swap min and max if min is more than max
end
MachineHead.Position = Vector3.new(math.clamp(NewX, min.Position.X + MachineHead.Size.X/2, max.Position.X - MachineHead.Size.X/2), MachineHead.Position.Y, MachineHead.Position.Z)

it won’t change if I change its name it still prints out the exact same error

So euhm I still feel dumb after them, The axles of roblox is different with the once we use at work and that’s why it didn’t work, Thank you so much for the help! I’ll put you in the credits of the game! :smiley:

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