Hello again!
I post here quite often, but there’s nothing to do if I can’t find a solution.
So…
I want to do the following: If a player drives into a certain area and gets up from the driver’s seat, the car will be welded to that area.
And then when the player gets in the car again, the car is released.
I want to do such a thing for a ferry crossing game.
So far, I’ve tried to use values, put several functions in each other, and so on.
However, I’m not so good at scripting yet, and the only result I got was that the game crashed.
Here is a picture of the area where cars should weld. They should be welded to the same green part.
And script (probably just a bad joke)
local TouchedPart = nil
script.Parent.Touched:Connect(function(hit)
if hit.Name == "CarDeckArea" then
TouchedPart = hit
script.Parent:GetPropertyChangedSignal("Occupant"):Connect(function(plr)
if script.Parent.Occupant == nil then
local Weld = Instance.new("WeldConstraint")
Weld.Name = "CarDeckWeld"
Weld.Part0 = script.Parent
Weld.Part1 = TouchedPart
else
if script.Parent.Occupant ~= nil then
if script.Parent:FindFirstChild("CarDeckWeld") then
script.Parent:WaitForChild("CarDeckWeld"):Destroy()
end
end
end
end)
else
script.Parent.TouchEnded:Connect(function(hit)
if hit.Name == "CarDeckArea" then
return
end
end)
end
end)
The Spatial Query API is a better option to use for this than Touched & TouchEnded. Every time the seat occupant changes, check to see if the player got up. If they did then query with GetPartsInPart along the lines of this snippit:
-- first, make an array of CarDeckWeld parts to use as a filtered list
local FilterList = {ship.CarDeckWeld1, ship.CarDeckWeld2}
-- second, create OverlapParams object for the query
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = FilterList
-- third, handle occupant changed
car.Seat:GetPropertyChangedSignal("Occupant"):Connect(function(plr)
if script.Parent.Occupant == nil then
local overlappingParts = workspace:GetPartsInPart(car.BoundingPart, params)
if #overlappingParts > 0 then
local Weld = Instance.new("WeldConstraint")
Weld.Name = "CarDeckWeld"
Weld.Part0 = car.BoundingPart
Weld.Part1 = overlappingParts[1]
end
end
end)
where car.BoundingPart is a part in the car, sized so it contains the entire car. that will ensure any part of the car can be parked on a CarDeckWeld part and still trigger the weld.
CollectionService is perfect for that. You can tag the green parts with an identifier, then get an array of all those tagged parts in the game using the GetTagged method.
I like this plugin for assigning tags in studio without needing to set them from code.
Edit: You dont have to manually make your FilterList array this way; you can retrieve it right from GetTagged():
-- assumes the green parts are tagged with "CarDeckWeld"
local FilterList = CollectionService:GetTagged("CarDeckWeld")
You’re passing a value to a method that wants a reference to an object. I’d have to see the line of code that error is kicking from to be able to say anything more specific than that, sorry. A value is data, like in a variable. Something like workspace:GetPartsInPart("carPart", params) could kick that, because the string “carPart” cannot be cast to an object reference like the method is expecting.
local car = script.Parent
local CollectionService = game:GetService("CollectionService")
-- first, make an array of CarDeckWeld parts to use as a filtered list
local FilterList = CollectionService:GetTags("CarDeckWeld")
-- second, create OverlapParams object for the query
local params = OverlapParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = FilterList
-- third, handle occupant changed
car.DriveSeat:GetPropertyChangedSignal("Occupant"):Connect(function(plr)
if script.Parent.Occupant == nil then
local overlappingParts = workspace:GetPartsInPart(car.Body.BoundingPart, params)
if #overlappingParts > 0 then
local Weld = Instance.new("WeldConstraint")
Weld.Name = "CarDeckWeld"
Weld.Part0 = car.Body.BoundingPart
Weld.Part1 = overlappingParts[1]
end
end
end)
The GetTags(part) method is given a part, and returns an array of all the tag strings that have been tagged to that part. It can’t cast the string value "CarDeckWeld" to the part object it needs, which is what the error is saying.
You want to use GetTagged() instead. This method takes in a string tag and returns an array of all the parts that have that tag assigned to them.
Verify GetTagged is returning the populated array of CarDeckWeld parts, as well as GetPartsInPart is correctly returning queried parts.
local FilterList = CollectionService:GetTags("CarDeckWeld")
print(FilterList)
local overlappingParts = workspace:GetPartsInPart(car.Body.BoundingPart, params)
if #overlappingParts > 0 then
-- ...
else
warn("No CarDeckWeld parts inside of car's BoundingPart")
end
This suggests the issue is with the tag on the CarWeldParts. Double check your spelling is identical to the string passed to GetTagged, and that there’s no leading or trailing spaces.
Everything should be working then. It’ll weld the car.Body.BoundingPart to the first overlapping part returned from GetPartsInPart. Could you have forgotten to weld the BoundingPart to the rest of the car body perhaps?