Hello, so pretty much let’s just say there is a train, and when a train enters it’s last station and hits the termination sensor, the sensor detects this and looks for the value in the train to make sure the train is actually finished for it’s last station.
But the thing is, how would I make it so the script knows where to look for the value?
And keep in mind that the wheels of the train are the parts touching the sensor, so it’s not really the train model. I’ve used :FindFirstDescendant() but it keeps saying “trying to index with nil”.
So any help or ideas on how to do this would be appreciated.
Use :FindFirstAncestor(-- your train's name in game) to find the train model, then use :FindFirstChildWhichIsA("Value", true) to find the value. We add true to the second argument to allow for recursive searching, so say if your value isn’t a direct child of the train model but say a child of a child you can still find it. Hope this helps!
Ah, so this is where it gets tricky. The train names have a letter at the front, and then have two randomized numbers after it, like “A59” to differentiate the train from other trains, so that’s why I couldn’t use those functions.
Also, sorry for not being specific enough but the value is parented right under the carriage model. So pretty much I would also like to look for the carriage.
So that’s why I used FindFirstDescendants() although I switched to GetFirstAncestor() and still doesn’t work.
Could you show an example heirarchy of a train? AKA show all the models expanded so I can see where the wheels and value are relative to the train model
I only have one wheel model expanded so it’s not too messy (it’s the parts that are named glider) and those gliders are the parts that touch the sensors.
(There is way more to that, the model that all of these are parented to is the model that has it’s name randomized for reasons I’ve told above)
Use this to find the train model. Call it when you detect a wheel touching the sensor with the wheel as the argument, not the sensor.
local function FindTrainModel(instance)
local parent = instance:FindFirstAncestorOfClass("Model")
local name = parent.Name
if string.match(name, "A%d+") == nil then -- "A%d+" searches for "A" followed by any number of digits, so you don't have to worry if you want trains with three digit randomized numbers (like A123)
return FindTrainModel(parent)
else
return parent
end
end
Note this will still work even if non-train objects are called A## or if all trains are inside a folder for example.
I wasn’t sure what your value for it being finished is, but I’m sure just calling :FindFirstChildWhichIsA("Value") on the train model (returned by the function above) should work just fine as long as you only have one.
Thank you, but I was kind of asking for how to detect which carriage the wheel is in.
But you gave me another idea, what if I can use string.match or whatever function is suitable to see if the name of the carriage has part of a string in it, like “Control_”?
Oh yeah btw I will use your script for other stuff like signals etc, thanks.
If your Control_# are your carriages, just change the "A%d+" to "Control_%d+" to find the carriage model. Here’s the updated code:
local function FindCarriageModel(instance)
local parent = instance:FindFirstAncestorOfClass("Model")
local name = parent.Name
if string.match(name, "Control_%d+") == nil then
return FindCarriageModel(parent)
else
return parent
end
end
Same follows, you can use :FindFirstChildWhichIsA("Value") on the object returned from FindCarriageModel([insert wheel here]) to find the value, assuming your value is parented to your carriage.
If you want to find the number you can also do something similar, adding this little piece of code in:
local function FindCarriageNumber(wheel)
return tonumber(string.match(FindCarriageModel(wheel).Name, "%d+"))
end
(or you could just make the original function return tonumber(string.match(parent.Name, "%d+")) in the else section (aka instead of return parent))
So basically, I wrote to recursively call itself until it finds a parent that is a model that has the name “Control_#”. It checks if the current parent’s name is “Control_#”, and if it’s not then it calls the function with the new parent, which eventually will reach a parent called “Control_#”.
local is put in front of functions to define the scope of the function. It’s also just how Luau works most of the time, and required in non-module scripts.