Help improving these 2 functions

Hello, I have these to functions in Roblox and I’d like to improve the performance of them.

I actually have a RunService Heartbeat event that calls these functions, and at the moment I think the performance for it is a bit too instense due to lots of raycasts, maths and for loops, would there be any way to improve performance while keeping the same functionality?

The RaycastPantograph function does check to make sure it is raised and not yet but will make sure the train is actually moving before calling this function, it then sets the CFrame of 3 different parts using the numbers that this function returns.

The CheckDerailmentStatus function, there is a for loop looping through each bogie and then calling, passing that bogie as a argument, again before calling the for loop, it’ll check if the train is moving before calling this function.

I’m trying not to have a inbetween time of each call due to when the train has suspension the pantograph may lose contact with the wire above, and for the CheckDerailmentStatus function, I want to apply the emergency brake as soon as it derails.

image

3 Likes

Bumpy bump, anybody got any ideas?

1 Like

Need to post that as text not a picture. Makin me work too hard. Use the </> on the bar …

1 Like

Heres the code written

local function RaycastPantograph(Pantograph)
	local RaycastResult = workspace:Raycast(Pantograph.OriginRay.Position, Pantograph.OriginRay.CFrame.UpVector * 20, RaycastParameters)

	if RaycastResult then
		local Distance: number = (RaycastResult.Distance - 0.6) - (Pantograph.Hand.Size.Y / 2)

		local LowerSize: number = (Pantograph.LowerArm.A.Position - Pantograph.UpperArm.A.Position).Magnitude
		local UpperSize: number = (Pantograph.UpperArm.A.Position - Pantograph.Hand.A.Position).Magnitude

		local Size: number = (LowerSize + UpperSize) / 2
		local SizeSquared: number = Size * Size

		local Angle: number = math.acos((SizeSquared * 2 - (Distance * Distance)) / (2 * SizeSquared))
		local LowerAngle: number = Angle / 2
		local Number: number = -math.deg(LowerAngle) - RaycastResult.Instance.Orientation.X

		return Number, LowerAngle, Angle
	end
end
local function CheckDerailmentStatus(self, Bogie)
	local function CheckPitchAngle(PitchAngle)
		if math.abs(PitchAngle) > 8 then
			self.DerailmentStatus = "Derailed"
		end
	end

	-- Check Tilt orientation
	local TiltOrientation = Bogie.Hinges.Tilt.CurrentAngle
	CheckPitchAngle(TiltOrientation)

	-- Check Turn orientation
	local TurnOrientation = Bogie.Hinges.Turn.CurrentAngle
	CheckPitchAngle(TurnOrientation)
end
1 Like

Can shorten it up and even cut out a few lines but, overall pretty much what you have here. No way to really test this for me and I can’t PM you so … looks good to me.

1 Like

Would performance be better with these modifications?

1 Like

I don’t think so … Not really much optimization possible here. You’re pretty tight as is. I can’t see how you’re calling this stuff so just going off what I can see.

1 Like

This is the code that calls it

self.Connections.Heartbeat = game["Run Service"].Stepped:Connect(function()
		if self.Unit:GetAttribute("PantographState") == "Raised" then
			local HandAngle, LowerAngle, UpperAngle = RaycastPantograph(Pantograph)

			Pantograph.Hand.Motor.C1 = CFrame.Angles(math.rad(HandAngle), 0, 0)
			Pantograph.LowerArm.Motor.C1 = CFrame.Angles(-LowerAngle, 0, 0)
			Pantograph.UpperArm.Motor.C1 = CFrame.Angles(UpperAngle, 0, 0)
		end

		for _, Bogie in self.Bogies do
			CheckDerailmentStatus(self, Bogie)
		end

		if self.DerailmentStatus == "Derailed" then
			self.Train.TrainInformation["Derailment Status"].Value = self.DerailmentStatus
			local Driver = game.Players[self.Train:GetAttribute("Driver")]
			TrainServiceEvent:FireClient(Driver, "ApplyEmergencyBrake")
		end
	end)