Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Getting very specific coordinates for a "grid system"?

This code works fine there is no problem with it, my issue is that I want to assure the coordinates I receive which can only be valid in my coordinate system (using the pattern), actually fit in it for example I have a 60,4,60 baseplate and everything in the map is 4,4,4, so everything aligns perfectly. However my issue is when I'm creating this part and the player isn't aligned on the grid properly it places the part in a position where it also isn't aligned properly and this isn't allowed otherwise the idea/game won't work. Here's an example of the issue:

http://gyazo.com/59fa018157256e42ba8be77e8d10c6d7

local function Coordinates(loc)
	local Pattern = ".?%d0?2?4?6?8?" --Allows negative numbers, allows any first digit but second must either be 2,4,6 or, 8 otherwise pattern will reject it.
	
	if math.floor(loc) % 2 == 0 then
		if tostring(math.floor(loc)):match(Pattern) then
			return math.floor(loc)
		end
	elseif math.ceil(loc) % 2 == 0 then
		if tostring(math.ceil(loc)):match(Pattern) then
			return math.ceil(loc)
		end
	end
end

--Received from remote event from userinputservice local script:
local loc = Player.Character.HumanoidRootPart.Position
local X = Coordinates(loc.X)
local Y = 1.93
local Z = Coordinates(loc.Z)

--Part.Position = Vector3.new(X, Y, Z)

Is this method actually viable, or should I use something else?

1 answer

Using :match on tostringed numbers is definitely the wrong way to go.

Numbers are numbers, they are not text. Do not operate on them as though they were text.


You want a function that maps 3D points to points on a grid.

I'm assuming your grid works like this:

  • input in range [0, 4] --> 2 output
  • input in range [4, 8] --> 6 output
  • input in range [8, 12] --> 10 output
  • etc

The first step is to divide by the cell size, four /4:

  • input/4
  • input [-4, 0] --> [-1, 0] (e.g., -0.987, -0.123)
  • input [0, 4] --> [0, 1] (e.g., 0.123, 0.987)
  • input [4, 8] --> [1, 2] (e.g., 1.456, 1.789)
  • input [8, 12] --> [2, 3] (e.g., 2.351, 2.989)
  • etc

Now we can take the floor using math.floor( of these numbers to drop them down to the integer at the beginning of the range:

  • math.floor(input/4)
  • input [-4, 0] --> -1
  • input [0, 4] --> 0
  • input [4, 8] --> 1
  • input [8, 12] --> 2
  • etc

Now you can multiply by 4 to get back to the size of the grid

  • 4*math.floor(input/4)
  • input [-4, 0] --> -4
  • input [0, 4] --> 0
  • input [4, 8] --> 4
  • input [8, 12] --> 8
  • etc

And finally you can add half the cell size (2) in order to get to the middle of the cell:

  • 4*math.floor(input/4) + 2
  • input [-4, 0] --> -2
  • input [0, 4] --> 2
  • input [4, 8] --> 6
  • input [8, 12] --> 10
  • etc

Your function might look like

-- RETURNS a Vector2
function toGrid(input)
	assert(typeof(point) == "Vector3")

	local x = 4*math.floor(input.x/4) + 2
	local y = 4*math.floor(input.x/4) + 2
	return Vector2.new(x, y)
end

-- USAGE:
local cell = toGrid(Player.Character.HumanoidRootPart.Position)

part.Position = Vector3.new(cell.x, 1.93, cell.y)

This discussion is preserved as it was. New answers, comments, and votes are closed.