Attempt to get length of a Instance value

Hello, recently I’ve been trying to make a script that will track what tycoons are open and spawn in a arrow so the player may follow it and claim there tycoon. I’m not sure exactly what I’m doing wrong, but I keep getting the same error no matter how I change it up. So I was wondering if I could get any insights from the community on what I’m doing wrong. Thanks in advance for the help and support! :smile:

local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:Wait()

--[[arrow.Parent = game.Workspace:FindFirstChild("TutorialArrows")
arrow.Name = player.Name.. "'s"

game:GetService("RunService").RenderStepped:Connect(function()
	arrow.PrimaryPart.CFrame = CFrame.new(char.HumanoidRootPart.Position, game.Workspace.Noob.HumanoidRootPart.Position)
end)--]]

print("HI")

local arrow = script.Parent:Clone()
arrow.Parent = game.Workspace:WaitForChild("TutorialArrows")
arrow.Name = player.Name.. "'s"

for _,v in pairs(game.Workspace["Heza's"].Tycoons:GetChildren()) do
	--print(v.Name)
	if --[[v:IsA("Model") and--]] v:FindFirstChild("Owner") then
		--print(v.Name)
		if v.Owner.Value == nil or "" then
			local selected = v[math.random(1,#v)]
			print(selected)
		end
	end
end
1 Like

I believe your error occurs here:

Not sure what you want to do here, but you are trying to get the length of instance v with the # . If you’re trying to get the children of Tycoons, use a for loop instead:

local v = game.Workspace["Heza's"].Tycoons:GetChildren()

for i=1,#v do
  --print(v[i].Name)
	if --[[v[i]:IsA("Model") and--]] v[i]:FindFirstChild("Owner") then
		--print(v[i].Name)
		if v[i].Owner.Value == nil or "" then
			local selected = v[math.random(1,#v)]
			print(selected)
		end
	end

(sorry, I’m not exactly too sure what you are trying to do)

3 Likes

Apologies that was my fault.

So basically, I am trying to find out which tycoons are open, by cycling through all of them located in a specific folder called Tycoons. I’m checking to see if the owner value is not named after any player that has already claimed it. Once I find that out, I wanted to pick one of those at random and have a arrow pointing towards it.

2 Likes

The issue with doing this for your use case is you’re getting a random tycoon, but you’re not checking if the random tycoon you just got doesn’t have an owner. Instead, here is a similar approach you could do.

Keep in mind you could just do this all inside the loop with the tycoon variable instead of storing it as a global variable selectedTycoon, but to showcase exactly what’s going on I thought it’d be easier.

local arrow = script.Parent:Clone()
arrow.Parent = game.Workspace:WaitForChild("TutorialArrows")
arrow.Name = player.Name.. "'s"

local selectedTycoon = nil

for i, tycoon in pairs(game.Workspace["Heza's"].Tycoons:GetChildren()) do
	if tycoon:FindFirstChild("Owner") then
		if tycoon.Owner.Value == nil or tycoon.Owner.Value == "" then
			selectedTycoon = tycoon
			print("We have selected Tycoon # "..i)
			break; -- breaks the loop so we dont have to keep finding every single tycoon value thats unclaimed, just the first
		end
	end
end

if selectedTycoon then
	
	-- selectedTycoon is the tycoon object in this case, you can program the arrows to point to it by refrencing it.
end
2 Likes

Instead of writing #v to get the number of children, you need to write out the whole thing game.Workspace["Heza's"].Tycoons:GetChildren()

This is because the variable V is an instance inside the folder (I assume) called Tycoons. So you would get the error: attempted to get length of an instance.

You can only use # to get the length of a table/array or a dictionary (I think).

2 Likes

As other people are saying this is where the error occurs. “v” is the tycoon model and what you are trying to do is first, v[number] this is going to look for a child with that name since “v” is a instance, not a table. Then you’re doing math.random(1,#v) you are trying to get a random value between “1” and amount of things inside a table, again “v” is not a table and therefore not possible, if you want to get the amount of children you have to do #v:GetChildren() this would work but probably error, “(number) is not a valid member of (instance name)”

2 Likes

Ahh I see, would this incorporate the idea of it randomly choosing one, or would it only choose the first one it sees?

1 Like

Ahh I see makes sense, that makes sense. How would I change this so that it would pick a random one each time given it meets the requirements?

2 Likes

Makes sense thank you my friend.

1 Like

The implementation I provided will only pick the first one that it sees which is opened, however you could use something like the following to pick a random one:

local arrow = script.Parent:Clone()
arrow.Parent = game.Workspace:WaitForChild("TutorialArrows")
arrow.Name = player.Name.. "'s"


local openTycoons = {}

for i, tycoon in pairs(game.Workspace["Heza's"].Tycoons:GetChildren()) do
	if tycoon:FindFirstChild("Owner") then
		if tycoon.Owner.Value == nil or tycoon.Owner.Value == "" then
			table.insert(openTycoons, 1, tycoon) -- put every open tycoon into the table
		end
	end		
end

local randomPick = openTycoons[math.random(#openTycoons)] -- get random tycoon from table
print(randomPick)

2 Likes

Ahh I see this is amazing, I just tested this out however and I’ve gotten the same result 5 times, the result being: Robber.

1 Like

Nevermind I just tested it again and it changed, what are the chances to get the same one w/ 7 others 5 times in a row haha. Apologies. Thank you so much for the help! :smile:

2 Likes

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