Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I do a better 'Find Player' script/function?

Asked by 10 years ago

I have tried to make a Find Player function to where it'll find the Player(s), for instance, if a player were to type 'kill/all', it would kill all players, but when I try to do it, the script sometimes Errors and says something like Attempt to compare 'str' (a userdata value), or Attempt to compare 'str' (a nil value), so, I'm stumped on how I can do it. :P Here is in attempt script I tried [To test before asking what I'm supposed to do, and what I'm doing wrong];

local Matches = 0

local function findPlr(plr,str)
if str == "all" then
return plr == game.Players:GetPlayers()
end
for i,v in pairs(game.Players:GetPlayers()) do
if v.Name:lower():find(plr:lower()) then
Matches = Matches + 1
return (v)
end
end
end

findPlr(nil,"all")
print(Matches) --This just keeps saying 0 :/ So confused >_<

And heres a original 'Find Player' function I used;

local function FindPlayer(plr)
for i,v in pairs(game.Players:GetPlayers()) do
if v.Name:lower():find(plr:lower()) == 1 then
return (v)
end
end
return nil
end

FindPlayer("Player")

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
10 years ago

Let's begin by tabbing and spacing your code out:

local Matches = 0

local function findPlr(plr,str)
    if str == "all" then
        return plr == game.Players:GetPlayers()
    end
    for i,v in pairs(game.Players:GetPlayers()) do
        if v.Name:lower():find(plr:lower()) then
            Matches = Matches + 1
            return v
        end
    end
end

findPlr(nil,"all")
print(Matches) --This just keeps saying 0 :/ So confused >_<


First Return

First, consider the second line of the function,

        return plr == game.Players:GetPlayers()

plr is never going to be that list of the current players (even if it is a list), meaning the second line is equivalent to

    return false

( To understand what I mean by that, consider print(game.Worskpace:GetChildren() == game.Workspace:GetChildren()) )

Instead, you want to return the list, not whether or not the list is equal to some value

    return game.Players:GetPlayers()

Multiple Parameters?

Now looking at it, there isn't very much reason to use two parameters to findPlr perhaps. Just using str is probably enough since you aren't seeming to treat them any different -- they're both strings representing the person to find. The only difficulty would be ambiguity in cases where, for example, "Allison" was current playing which does contain "all".


Second Return

Your first return made a list of players. So that you don't have to do more complicated work later to determine if you're dealing with a list or a single player, you should always return a list (even if it's of only one player).

In that case, when looking for a player with a given name

  • Either it doesn't make sense to count how many matches there are, since you're only returning one

  • Or you shouldn't return at all inside the loop since you need to compile the full list

Here's making it work for returning the full list of all players with matching names:

    ...
    local matching = {}
    for i,v in pairs(game.Players:GetPlayers()) do
        if v.Name:lower():find(plr:lower()) then
            table.insert(matching, v)
        end
    end
    return matching
end

findPlr("all") -- A list of all players
findPlr("BlueTaslem") -- {game.Players.BlueTaslem} (if I were playing)
findPlr("odifjsodifjsdoij") -- {}, a list of length 0
0
Lol, Thanks man! It took me a little bit to figure out, but I got finally got the thing to work thanks to your help! :) TheeDeathCaster 2368 — 10y
Ad

Answer this question