A part on track chasing another part

I want Part 1 (Green) to be on a track, kind of like a train, and I want Part 1 to always try to get as close as possible to Part 2 (Red), Part 2 is able to move anywhere unlike Part 1

But keep in mind, Part 1 has to stay on track no matter what.

I have no idea how to go about this and would love to hear anyone who might have an idea of how to achieve this. No script needed, just an explanation.

I recreated the example in studio. This is a relatively simple way to do what you’re looking for.

Here’s the place file
TrackExample.rbxl (39.5 KB)

And here’s the code I wrote to do it:

local tracks = workspace.Tracks:GetChildren();

local track_rays = {};

for _, track in pairs(tracks) do
	local p1 = track.CFrame * CFrame.new(0, 0, track.Size.Z / 2);
	
	local ray = Ray.new(p1.Position, track.CFrame.LookVector);
	table.insert(track_rays, { Length = track.Size.Z, Line = ray });
end

local function clamp_magnitude(v: Vector3, max: number)
	return v.Unit.Magnitude ~= v.Unit.Magnitude and Vector3.zero or v.Unit * math.min(v.Magnitude, max);
end

while task.wait() do
	local start = workspace.Train.Position;
	local goal = workspace.Goal.Position;
	local closest_point = nil;
	local shortest_distance = 0;
	
	for _, track_data in pairs(track_rays) do
		local point = track_data.Line:ClosestPoint(goal);
		
		point = track_data.Line.Origin + clamp_magnitude((point - track_data.Line.Origin), track_data.Length);
		
		local distance = (goal - point).Magnitude;
		if (not closest_point or distance < shortest_distance) then
			shortest_distance = distance;
			closest_point = point;
		end
	end
	
	workspace.Train.Position = closest_point;
end

Making it move smoothly along the tracks is very doable, but I felt this answered your question and that’s a fair bit more work.

redid it with an align position and walls.
TrackExample.rbxl (42.6 KB)

1 Like

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