Experiencing Issues with Tables & Looping

Experiencing Issues with Tables & Looping

Basically, I’ve made a script using the new proximity prompt feature. Problem with this is, though, if I’m using various different prompts, I need to be able to display them all and handle them all. Without having to have independent scripts for each seat, I’ve decided to make one script that handles it all. I will show this script below:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Remotes = ReplicatedStorage.Remotes
local proximityPrompt = {}
local seat = {}

for i,v in pairs(workspace:GetChildren()) do
	if v.Name == "Vehicle" then
		for _,v in pairs(v.Base:GetChildren()) do
			if v:IsA("VehicleSeat") or v:IsA("Seat") then
				table.insert(seat, 1, v)
				table.insert(proximityPrompt, 1,v.ProximityPrompt)
				print(v.ClassName, v.ProximityPrompt.ClassName)
			end
		end
	end
end

for i,v in pairs(proximityPrompt) do
	v.Triggered:Connect(function(player)
		for _, v in pairs(seat) do
			v:Sit(player.Character.Humanoid)
		end
	end)
end

I’m wondering if there’s any work around this to ensure that I can ensure the player can sit down.

2 Likes

Just to be clear, you’re looking to handle all of your seat proximity prompts in a single script? If so, you shouldn’t have to use a table. Could you provide a screenshot of your workspace and vehicle’s hierarchy?

1 Like

image

This alright?

Edit: To clear up, the extra VehiclePrompt shouldn’t be there. It has been deleted.

1 Like

I recommend taking a look into CollectionService . That way, you can just have a single table where the key is the tag and the value is all of the instances in the workspace that are that specific tag.

3 Likes

This should work.

for i,v in pairs(workspace:GetChildren()) do
    if v.Name == 'Vehicle' then
        local base = v:FindFirstChild('Base') -- checks that 'Base' exists
        if base then
            for i2,v2 in pairs(base:GetChildren()) do
                if v2:IsA('VehicleSeat') or v2:IsA('Seat') then
                    local proximityPrompt = v2:FindFirstChildOfClass('ProximityPrompt') -- looks for the ProximityPrompt
                    if proximityPrompt then -- if the proximity prompt exists,
                        proximityPrompt.Triggered:Connect(function(player) -- connect to the function when the proximity prompt is triggered
                            -- here is where your function should go
                        end)
                    end
                end
            end
        end
    end
end

You could also use :GetDescendants() and iterate through that to look for your ProximityPrompt.

Also, as @DumbSkid said, CollectionService is a good utility for this, probably more effective than my solution.

2 Likes

That is fantastic. Now, let’s say if I want to make the player sit in the corresponding seats that correspond with the prompts, how would I do this?

e.g.

for i,v in pairs(workspace:GetChildren()) do
	if v.Name == 'Vehicle' then
		local base = v:FindFirstChild('Base') -- checks that 'Base' exists
		if base then
			for i2,v2 in pairs(base:GetChildren()) do
				if v2:IsA('VehicleSeat') or v2:IsA('Seat') then
					seat = v2
					local proximityPrompt = v2:FindFirstChildOfClass('ProximityPrompt') -- looks for the ProximityPrompt
					if proximityPrompt then -- if the proximity prompt exists,
						proximityPrompt.Triggered:Connect(function(player) -- connect to the function when the proximity prompt is triggered
							seat:Sit(player.Character.Humanoid)
						end)
					end
				end
			end
		end
	end
end

Mainly concerned with seat = v2. That will not work as I’ve tested it and it has provided the following result:
https://gyazo.com/46dd64c7ffbfc951390572d853a52c23

Would be interested to see if you have a solution to this. You’ve been very helpful!

2 Likes

I’m glad I’ve been helpful!

You can just disable the ProximityPrompt with the Enabled property.

So, proximityPrompt.Enabled = false would disable the proximity prompt for that specific seat.

To find out when the occupant leaves, you can use .Changed or :GetPropertyChangedSignal() (which I recommend)

proximityPrompt.Triggered:Connect(function(player)
    if not seat.Occupant then -- just for safety measures, checks that there is no occupant
        seat:Sit(player.Character.Humanoid)
        proximityPrompt.Enabled = false
    end
    seat:GetPropertyChangedSignal('Occupant'):Connect(function() -- when the seat's 'Occupant' property changes
        if not seat.Occupant then -- if the occupant value is nil (no occupant)
            proximityPrompt.Enabled = true -- then enable the proximity prompt
        end
    end
end

Oops, appears I’ve misunderstood your question, one sec.

2 Likes

Yeah I was uh going to do that part later but I’m mainly concerned about the sitting part. See when I press F on the prompt, it sends me to one seat, rather than two separate ones. That’s my main problem right now.

Edit: By the way, I really appreciate the lengths you’re taking to help me out. This will be of great benefit to me in the future to save time and scripts, which will allow me to have an organized structure while scripting as it is vitally important to any scripter.

1 Like

Yep, I misread your question. I’m gonna recreate your hierarchy and see if I can recreate the issue.

1 Like

No worries! Really glad I can help.

Not sure why, but for whatever reason, assigning v2 to a variable appears to create the issue, so you just have to delete that variable and use v2 as your seat variable. You could just rename the loop as well, for i2, seat in pairs...

I made that change here:

for i,v in pairs(workspace:GetChildren()) do
    if v.Name == 'Vehicle' then
        local base = v:FindFirstChild('Base') -- checks that 'Base' exists
        if base then
            for i2,seat in pairs(base:GetChildren()) do
                if seat:IsA('VehicleSeat') or seat:IsA('Seat') then
                    local proximityPrompt = seat:FindFirstChildOfClass('ProximityPrompt') -- looks for the ProximityPrompt
                    if proximityPrompt then -- if the proximity prompt exists,

                        local seat = seat -- this is where you can declare the variable, it shouldn't cause any dysfunction.

                        proximityPrompt.Triggered:Connect(function(player) -- connect to the function when the proximity prompt is triggered
                            if not seat.Occupant then -- just for safety measures, checks that there is no occupant
                                seat:Sit(player.Character.Humanoid)
                                proximityPrompt.Enabled = false
                            end
                            seat:GetPropertyChangedSignal('Occupant'):Connect(function() -- when the seat's 'Occupant' property changes
                                if not seat.Occupant then -- if the occupant value is nil (no occupant)
                                    proximityPrompt.Enabled = true -- then enable the proximity prompt
                                end
                            end)
                        end)
                    end
                end
            end
        end
    end
end

Edit, appears you created the seat variable too early, causing the player to be sat in the wrong seat. I will put where the declaration should go.

2 Likes

Works like a charm! Thanks a lot. This will prove to be very useful for organising lots of my work in a much more efficient manner.

1 Like

No worries!

You’re actually able to declare seat as a variable, I made an edit to the post you marked as solution.

1 Like

Lovely, thanks! :slight_smile:

1 Like