Problems with positioning a plane

I am trying to make an infinite plane where a plan is generated near the player’s position. I use this line of code to get the position of where the plane is needed:

Plane.Position += Vector3.new( Player_Position.X - Player_Position.X % 1023 , 0 ,  Player_Position.Z - Player_Position.Z % 1023 ) 

the problem with this code is that it only works how I want it to in the negative axis, and I can’t figure out a way for it to work perfectly on the positive and negative.

If you want to test/use it, put the script into starter player and make the plane 2046x0x2044

Here is the full code:

local RunService = game:GetService("RunService")

function LoadChunk(Render_Distance,Player_Position)
	if workspace:FindFirstChild(Player_Position.X - Player_Position.X%1023 .. "," .. Player_Position.Z - Player_Position.Z%1023) then
		return nil
	else
		local Folder = Instance.new("Folder")
		Folder.Name = Player_Position.X - Player_Position.X%1023 .. "," .. Player_Position.Z - Player_Position.Z%1023
		Folder.Parent = workspace

		local Plane = game.ReplicatedStorage.Levels:WaitForChild("Plane"):Clone()
		Plane.Position += Vector3.new( Player_Position.X - Player_Position.X % 1023 , 0 ,  Player_Position.Z - Player_Position.Z % 1023 )  
		Plane.Parent = Folder
	end
end
LoadChunk(1,Vector3.new(0,0,0))
wait(1)

RunService.Heartbeat:Connect(function()
	repeat wait() until game.Players.LocalPlayer.Character.HumanoidRootPart ~= nil
	LoadChunk(1,game.Players.LocalPlayer.Character.HumanoidRootPart.Position)
end)

if you have further questions about the script please ask.

You also need to make the modulus negative when you’re in the negative axis.

Code:

local RunService = game:GetService("RunService")

local function LoadChunk(Render_Distance,Player_Position)
	local xModulus = Player_Position.X >= 0 and 1023 or -1023
	
	if workspace:FindFirstChild(Player_Position.X - Player_Position.X%xModulus .. "," .. Player_Position.Z - Player_Position.Z%1023) then
		return nil
	else
		local Folder = Instance.new("Folder")
		Folder.Name = Player_Position.X - Player_Position.X%xModulus .. "," .. Player_Position.Z - Player_Position.Z%1023
		Folder.Parent = workspace

		local Plane = game.ReplicatedStorage.Levels:WaitForChild("Plane"):Clone()
		Plane.Position += Vector3.new( Player_Position.X - Player_Position.X % xModulus , 0 ,  Player_Position.Z - Player_Position.Z % 1023 )  
		Plane.Parent = Folder
	end
end
LoadChunk(1, Vector3.zero)

task.wait(1)

RunService.Heartbeat:Connect(function()
	repeat task.wait() until game.Players.LocalPlayer.Character.HumanoidRootPart
	
	LoadChunk(1, game.Players.LocalPlayer.Character.HumanoidRootPart.Position)
end)

I also made an optimized version but it may not work which is why I didn’t replace the first one with it:

--//Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

--//Variables
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()

--//Controls
local HumanoidRootPart = nil

--//Functions
local function OnCharacterAdded(character)
	HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
end

local function OnCharacterRemoving()
	HumanoidRootPart = nil
end

local function LoadChunk(Render_Distance, Player_Position)
	local xModulus = Player_Position.X >= 0 and 1023 or -1023

	if workspace:FindFirstChild(Player_Position.X - Player_Position.X % xModulus ..",".. Player_Position.Z - Player_Position.Z % 1023) then
		return
	else
		local Folder = Instance.new("Folder")
		Folder.Name = Player_Position.X - Player_Position.X % xModulus ..",".. Player_Position.Z - Player_Position.Z % 1023
		Folder.Parent = workspace

		local Plane = ReplicatedStorage.Levels:WaitForChild("Plane"):Clone()
		Plane.Position += Vector3.new(Player_Position.X - Player_Position.X % xModulus, 0, Player_Position.Z - Player_Position.Z % 1023)  
		Plane.Parent = Folder
	end
end

LocalPlayer.CharacterAdded:Connect(OnCharacterAdded)
LocalPlayer.CharacterRemoving:Connect(OnCharacterRemoving)
OnCharacterAdded(Character)

RunService.Heartbeat:Connect(function()
	if not HumanoidRootPart then
		return
	end

	LoadChunk(1, HumanoidRootPart.Position)
end)

You may have to do the same with the Z axis.

Thank you for your help! I will use what you have given me to improve my script. Have a good day.

1 Like

I just saw the second one, I’m going to see what I can do with it

I’ve optimized it a bit more, you can use this if you want to:

--//Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

--//Variables
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local planeTemplate = ReplicatedStorage.Levels:WaitForChild("Plane")

--//Controls
local HumanoidRootPart = nil

--//Functions
local function LoadChunk(Render_Distance, Player_Position)
	local xModulus = Player_Position.X >= 0 and 1023 or -1023

	if workspace:FindFirstChild(Player_Position.X - Player_Position.X % xModulus ..",".. Player_Position.Z - Player_Position.Z % 1023) then
		return
	else
		local Folder = Instance.new("Folder")
		Folder.Name = Player_Position.X - Player_Position.X % xModulus ..",".. Player_Position.Z - Player_Position.Z % 1023
		Folder.Parent = workspace

		local Plane = planeTemplate:Clone()
		Plane.Position += Vector3.new(Player_Position.X - Player_Position.X % xModulus, 0, Player_Position.Z - Player_Position.Z % 1023)  
		Plane.Parent = Folder
	end
end

local function OnCharacterAdded(character)
	HumanoidRootPart = character:WaitForChild("HumanoidRootPart")

	local heartbeatConnection = nil

	heartbeatConnection = RunService.Heartbeat:Connect(function()
		if not HumanoidRootPart then
			heartbeatConnection:Disconnect()
			heartbeatConnection = nil

			return
		end

		LoadChunk(1, HumanoidRootPart.Position)
	end)
end

local function OnCharacterRemoving()
	HumanoidRootPart = nil
end

LocalPlayer.CharacterAdded:Connect(OnCharacterAdded)
LocalPlayer.CharacterRemoving:Connect(OnCharacterRemoving)
OnCharacterAdded(Character)

You can probably optimize it more by substituting the :FindFirstChild with checking a dictionary that has all the loaded chunks.

Thank you, I will see what I can do.

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