Heartbeat too slow, task.spawn too fast what else?

Im making an plugin that convert mesh into union and it im trying to get it running as fast as possible whitout causing too much lag.

Heartbeat is not fast enough and task.spawn() freeze the game for 15 second and it crash my graphic card because of some bios problems.

I did look on the dev hub but all the script that are supposed to run faster than wait() are using heartbeat so it would be too slow.

local Selection = game:GetService("Selection")
local RunService = game:GetService("RunService")
local UIS = game:GetService("UserInputService")
local ToolBar = plugin:CreateToolbar("Union Tweaks")
local ExecuteButton = ToolBar:CreateButton("Mesh To Union", "Convert Mesh", "fgfg")
local InputS
local Open = false
local Converting = false

ExecuteButton.Click:Connect(function()
	if Open then
		Open = false
		InputS:Disconnect()
	else
		Open = true

		InputS = UIS.InputBegan:Connect(function(Input)
			if Input.KeyCode == Enum.KeyCode.T then
				if Converting then
					Converting = false
				else
					Converting = true
					local SelectedObject = Selection:Get()
					if #SelectedObject > 0 and SelectedObject[1]:IsA("MeshPart") then
						CreateGeometry(SelectedObject[1], 0.01)
					end
				end
			elseif Input.KeyCode == Enum.KeyCode.X then
				Converting = false
			end
		end)	
	end		
end)

function CreateGeometry(Mesh, Quality)
	local BasePosX = Mesh.Position.X - Mesh.Size.X / 2
	local BasePosY = Mesh.Position.Y - Mesh.Size.Y / 2
	local BasePosZ = Mesh.Position.Z - Mesh.Size.Z / 2
	local Indicator = Instance.new("Attachment", Mesh)
	Indicator.Name = "Indicator"
	Indicator.WorldPosition = Vector3.new(BasePosX, BasePosY, BasePosZ - 0.1)
	
	while Converting do
		RunService.Heartbeat:Wait()
		local RayOrigin = Indicator.WorldPosition
		local RayDirection = Vector3.new(0, 0, Mesh.Size.Z + 0.1)

		local raycastParams = RaycastParams.new()
		raycastParams.FilterDescendantsInstances = {Mesh}
		raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
		local RaycastResult = workspace:Raycast(RayOrigin, RayDirection, raycastParams)
		if RaycastResult then
			local Point = Instance.new("Attachment", Mesh)
			Point.Name = "Point"
			Point.WorldPosition = RaycastResult.Position
		end
		Indicator.WorldPosition = Vector3.new(Indicator.WorldPosition.X + Quality, Indicator.WorldPosition.Y, Indicator.WorldPosition.Z)
		if Indicator.WorldPosition.X >= Mesh.Position.X + Mesh.Size.X / 2 then
			Indicator.WorldPosition = Vector3.new(BasePosX, Indicator.WorldPosition.Y + Quality, Indicator.WorldPosition.Z)
		end
	end
end

It is a test code so some thing will be modified or removed.

1 Like

Maybe try other RunService events such as Stepped or RenderStepped?

It says that it will run the same amount of frame that you have like heartbeat, i will try it out but i really dont think it will change something.

Edit : It just dont work cause it is in studio

don’t use this if you don’t need to

you talking about this line?
why not use task.wait()

It hang your game and crash my graphic card which i then need to restart 2 time my computer
reinstall the driver and then patch the driver 30 minute in total.

You said that was task.spawn, not task.wait.

2 times!?!?

studio crashing shouldn’t cause that much damage :eyes:

1 Like

Honestly it sounds like you need to only yield once every few loops:

local i = 0
while true do
   i+=1
   if i%15 == 0 then
      i=0
      wait()
   end
   -- do stuff
end
1 Like

Yields the current thread until the given duration (in seconds) has elapsed and then resumes the thread on the next Heartbeat step. So yeah no because if it is less than the Heartbeat then it will resume it on the next one.

task.wait() is very accurate, it is good wait() was deprecated

you shouldn’t need to worry

1 Like