Help with CFrame Rotation

I am trying to make a function that takes a part and splits it up into a grid. My code works for grid parts that are at either a 0deg, 90deg, 180deg, or 360deg rotation. How can I get my code to work for diagonal parts as well.

I will provide the code and an image of the current results.

local function CreateGrid(gridpart)
	
	local TileSize = Vector3.new(2,0.25,2)
	
	-- create folder for physical tiles
	
	local TileFolder = Instance.new("Folder")
	TileFolder.Name = "Tiles"
	TileFolder.Parent = gridpart
	
	-- calculate amount of grid tiles and position
	
	local xAmount,xOffset
	local zAmount,zOffset
	
	xAmount = gridpart.Size.X / TileSize.X
	zAmount = gridpart.Size.Z / TileSize.Z
	
	if xAmount % 1 ~= 1 then
		--if it doesnt divide equally
		xOffset = (xAmount % 1)
		xAmount = math.floor(xAmount)
	else
		xOffset = 0
		xAmount = math.floor(xAmount)
	end
	
	if zAmount % 1 ~= 1 then
		--if it doesnt divide equally
		zOffset = (zAmount % 1)
		zAmount = math.floor(zAmount)
	else
		zOffset = 0
		zAmount = math.floor(zAmount)
	end
	
	-- add physical tiles to grid

	for xCount = 0,xAmount-1,1 do
		for zCount = 0, zAmount-1,1 do
			--wait()
			local Tile = Instance.new("Part")
			Tile.Size = TileSize
			Tile.Transparency = 0.6
			Tile.Anchored = true
			Tile.BrickColor = BrickColor.Random()
			Tile.CFrame = CFrame.new( (((gridpart.Position.X) - (gridpart.Size.X / 2)) + (Tile.Size.X / 2) + (xOffset) + (xCount * Tile.Size.X)) , (gridpart.Size.Y + Tile.Size.Y / 2) , (((gridpart.Position.Z) - (gridpart.Size.Z / 2)) + (Tile.Size.Z / 2) + (zOffset) + (zCount * Tile.Size.Z)))
			Tile.Parent = TileFolder
			
			local Settings = Instance.new("Folder")
			Settings.Name = "Settings"
			Settings.Parent = Tile
			
		end
	end
	
end


CreateGrid(workspace.GridPart1)
CreateGrid(workspace.GridPart2)
CreateGrid(workspace.GridPart3)

1 Like

I would do it by setting the tile CFrame to be the CFrame of the part (So it gets the rotation) then move it to the spot you’re going for.

Can you provide some pseudocode for this, I am setting the CFrame of the Tile, but I am not really sure how to do this whole rotation thing.

This code broke it, don’t use it. Trying to fix it and do what I meant.

Not sure if this could work, but you could do the exact thing that you’re doing, but group all of the parts into a model after they’re made and set the center part to the PrimaryPart of the model. Weld all of the other parts to the PrimaryPart and use :SetPrimaryPartCFrame to set the CFrame of the model to the CFrame of the bigger part.

Inefficient option, but depending on your use-case, performance might not matter at all. If you want to divide the bigger part into smaller ones while adjusting for rotation, you’d have to do some more complex math.

That could be a possible solution, besides the fact there might not always be a exact center tile.

I’m trying to find how to do it with your code, but what my code was supposed to do was rotate the parts before moving it, so that it would be set in the right spot.

You could always set the PrimaryPart to a random part and do the same thing, but adjust the CFrame that you use for :SetPrimaryPartCFrame to account for the offset between the CFrame of the bigger part and the PrimaryPart.

Your current one doesn’t rotate at all, so if you rotate a part instead of sizing it differently, it doesn’t match properly.


This is what happened with the code that I just copied from your original post.

Here you go, this actually works with any rotation.

--			Tile.CFrame = gridpart.CFrame * CFrame.new(
--				(((gridpart.Position.X) - (gridpart.Size.X / 2)) + (Tile.Size.X / 2) + (xOffset) + (xCount * Tile.Size.X)),
--				(gridpart.Size.Y + Tile.Size.Y / 2),
--				(((gridpart.Position.Z) - (gridpart.Size.Z / 2)) + (Tile.Size.Z / 2) + (zOffset) + (zCount * Tile.Size.Z)))
local function CreateGrid(gridpart)
	
	local TileSize = Vector3.new(2,0.25,2)
	
	-- create folder for physical tiles
	
	local TileFolder = Instance.new("Folder")
	TileFolder.Name = "Tiles"
	TileFolder.Parent = gridpart
	
	-- calculate amount of grid tiles and position
	
	local xAmount,xOffset
	local zAmount,zOffset
	
	xAmount = gridpart.Size.X / TileSize.X
	zAmount = gridpart.Size.Z / TileSize.Z
	
	if xAmount % 1 ~= 1 then
		--if it doesnt divide equally
		xOffset = (xAmount % 1)
		xAmount = math.floor(xAmount)
	else
		xOffset = 0
		xAmount = math.floor(xAmount)
	end
	
	if zAmount % 1 ~= 1 then
		--if it doesnt divide equally
		zOffset = (zAmount % 1)
		zAmount = math.floor(zAmount)
	else
		zOffset = 0
		zAmount = math.floor(zAmount)
	end
	
	-- add physical tiles to grid

	for xCount = -(xAmount / 2), xAmount / 2 - 1, 1 do
		for zCount = -(zAmount / 2), zAmount / 2 - 1, 1 do
			--wait()
			local Tile = Instance.new("Part")
			Tile.Size = TileSize
			Tile.Transparency = 0.6
			Tile.Anchored = true
			Tile.BrickColor = BrickColor.Random()
			Tile.CFrame = gridpart.CFrame * CFrame.new(
				(xCount * Tile.Size.X) + xOffset + 1,
				(gridpart.Size.Y / 2),
				(zCount * Tile.Size.Z) + zOffset + 1)
			Tile.Parent = TileFolder
			
			local Settings = Instance.new("Folder")
			Settings.Name = "Settings"
			Settings.Parent = Tile
			
		end
	end
	
end


CreateGrid(workspace.GridPart1)
CreateGrid(workspace.GridPart2)
CreateGrid(workspace.GridPart3)

Any

1 Like

I ended up solving it by setting the position relative to the grid part, like so:

Tile.CFrame = gridpart.CFrame * CFrame.new( (gridpart.Size.X / 2) - (Tile.Size.X / 2) - (xOffset) - (xCount * Tile.Size.X) ,(gridpart.Size.Y + Tile.Size.Y)/2, (gridpart.Size.Z / 2) - (Tile.Size.Z / 2) - (zOffset) - (zCount * Tile.Size.Z) )

That’s exactly what I was saying, when I had that though it broke. So I fixed it, and also simplified all your code and math a little.

1 Like