so, any ideas? not sure what to do about this one…
local vehiclesLocation = {
"428toyotacamry",
"751chevroletcamaro",
"136bugattiveyron"
}
Let’s start with the above; assume that vehiclesLocation
is reffering to where all the cars will be stored (in perhaps a folder in workspace). So in the code, you won’t need to actually create this table; it’s only for vanilla Lua testing purposes.
What do you do when you want to make a new serial? I’ve thought about it and decided that math.random(100, 999)
should work well. Why 100 to 999 you ask? Because all of the possible numbers generated will have 3 digits in them; it’ll make things much easier. Then to actually generate a string of the name of the plane/vehicle you’re spawning in, I’ve made this function:
local function getNewSerial(vehicleName)
local newSerial = math.random(100, 999)
local alreadyUsed = false
for i, v in pairs(vehiclesLocation) do
if newSerial == tonumber(string.sub(v, 1, 3)) then
alreadyUsed = true
break
end
end
if alreadyUsed == false then
return tostring(newSerial) .. vehicleName
else
return getNewSerial(vehicleName)
end
end
The getNewSerial
function should generate a random number between 100 and 999, then check if it’s already being used; if it is, it will recursively call itself to generate a number once again. Once it has a unique serial number, it will return the number and the name together in a single string (to be used for the name of the model). Keep in mind, where it says vehicleLocation
you’ll want to replace it with something along the lines of, folderWhereCarsAre:GetChildren()
. After that, you’ll also want to replace where it says v
with v.Name
instead.
Here’s example usage of the function:
local newName = getNewSerial("BlueFighter")
newlySpawnedPlane.Name = newName
Let me know if there’re any questions.
Here’s how i incorporated it into the old script:
local vehiclesLocation = {
}
local function getNewSerial(vehicleName)
local newSerial = math.random(1, 5)
local alreadyUsed = false
for i, v in pairs(vehiclesLocation) do
if newSerial == tonumber(string.sub(v, 1, 3)) then
alreadyUsed = true
break
end
end
if alreadyUsed == false then
return tostring(newSerial) .. vehicleName
else
return getNewSerial(vehicleName)
end
end
db1 = true
function regenerate()
if not db1 then
return
else
db1 = false
local Vehiclesinspawn = script.Parent:GetChildren()
for i, v in ipairs(Vehiclesinspawn) do
if string.match(v.Name, "BlueFighter") then
if (v.PlaneSeat.CFrame.p-Spawn.CFrame.p).magnitude <= Range then
v:Destroy()
end
end
end
Vehicle = OldVehicle:Clone()
local newName = getNewSerial("BlueFighter")
Vehicle.Name = newName
Vehicle.Parent = script.Parent
Vehicle.Values.Owner.Value = script.Buyer.Value
local regentime = 0
regentime = 15
However i did a test between 1 and 5, and of eight attempts i got (1x1, 2x1, 3x0, 4x1, 5x3) so the serials are the same on a chance. Why?
edit: I think it’s because the vehicles don’t get put into vehiclelocation. How should i put them there
You keep getting the same serial numbers?
My bad; I believe this has to do with how math.random()
works. When you want to generate a pseudorandom number using it, you need to use math.randomseed(seed)
. In this case, a good seed would be os.time() or tick(). And think of the seed like the starting point of the pseudorandom number generator; if you give it the same starting point, it will calculate the same number over and over again.
Try simply placing math.randomseed(os.time())
at the top of your script, and let me know how it goes.
nonono, i think your code did it correctly, its just that my script never entered the vehicle into VehicleLocation so the serials never get checked. how could i do this?
Right there I said you’ll need to replace vehicleLocation
with the folder/area the vehicles are in (and use :GetChildren()), and v
in the code with v.Name
. Sorry if I wasn’t being clear.
So what was the issue with just checking the range of the the vehicles that have been spawned in?
Another way you could do this is with collectionservice, which I’d say is probably a more suitable solution. The issue with the random number thing you have now is that it’s not guaranteed that each name is unique. With collection service you can tag vehicles that are freshly spawned and then remove that tag when they leave spawn. You then just need to use collectionservice:GetTagged(“InSpawn”) to get the vehicle(s) that need to be destroyed.
right so I tried that, and there are no errors, warnings, etc. everything works fine now except that i still get the same serial occasionally. Here is the code:
Really appreciate all your help thus far.
I see now; it’s because of how I designed the code to work.
if newSerial == tonumber(string.sub(v.Name, 1, 3)) then
alreadyUsed = true
break
end
The above code from the script is what is causing this. It’s not “wrong” per se, it’s just that it checks the first three characters with string.sub
, which is meant for numbers with three digits between 100 and 999. So if it’s checking for three digits, but the number is only in the first digit, the script will never realize that it’s the same number of course. Being even clearer, it’s basically checking, “is ‘5bl’ equal to 5?” And of course it’s not. I hope it clarifies the issue.
If you’d like to test the code with digits greater than or less than three, you’ll just need to change the parameters in string.sub()
. In this case with single digit numbers, here’s what you’ll want to change it to:
-- Gets the range of the first character to the first character in v.Name
if newSerial == tonumber(string.sub(v.Name, 1, 1)) then
I CAN’T BELIEVE I DIDN’T REALIZE THIS
regardless
this is very epic, thank you @MJTFreeTime, very cool
It’s been a while but I think it’s necessary to clarify some misinformation:
Disproving statements without good reason can serve to be misinformation and confuse readers, and that’s likely not to be the reason it didn’t work.
All obj.Name:match(toFind)
was used for in my provided (and given intentionally vague) example (it was an example model after all) was to return a boolean indicating whether an object contained the substring “bluefighter” in its name and thus whether its serial was preceded by “bluefighter” (since the only possible strings that can occur in this environment are those preceded by serials) so the object could be added to an array. If I’m not wrong that’s exactly what you asked for; to get all objects that contain in their name the specified string.
It also could’ve been that the code I provided was executed without necessary edits (e.g changing the string to match, in mine all characters were all lowercase).
Again this post was just needed to prevent potentially incorrect information, it doesn’t require a response.