Почему я продолжаю получать ошибку «попытка проиндексировать ноль с помощью Ca sh» в моем скрипте? - PullRequest
1 голос
/ 08 мая 2020

Для небольшого контекста, я делаю Tycoon на Roblox, чтобы проверить свои знания в lua. Все работало нормально, пока я не попробовал сделать статистику лидеров. Первый сценарий, который выполняет функцию Tycoon, находится здесь:



     local TycoonInfo = script.Parent:WaitForChild("TycoonInfo")
        local OwnerValue = TycoonInfo:WaitForChild("Owner")
        local Buttons = script.Parent:WaitForChild("Buttons")
        local Purchases = script.Parent:WaitForChild("Purchases")

        local Objects = {}

        function validateHitByOwner(Hit)
            if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
                local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
                if Player and OwnerValue.Value==  Player then
                    return true
                end
            end
            return false
        end

        for i,v in pairs(Buttons:GetChildren()) do
            local Object = Purchases:FindFirstChild(v.Object.Value)
            if Object then
                Objects[Object.Name] = Object:Clone()
                Object:Destroy()

                if v:FindFirstChild("Dependency") then
                    coroutine.resume(coroutine.create(function()
                        v.Button.Transparency = 1
                        v.Button.BillboardGui.Enabled = false
                        v.Button.CanCollide = false
                        if Purchases:WaitForChild(v.Dependency.Value,90000) then
                            v.Button.Transparency = 0
                            v.Button.CanCollide = true
                            v.Button.BillboardGui.Enabled = true
                        end
                    end))
                end
                local DB = false
                v.Button.Touched:Connect(function(Hit)
                    if validateHitByOwner(Hit)then
                        if DB == false then
                            DB = true
                            if v.Button.Transparency == 0 then
                                local Purchased = DoPurchase(Hit,v,v.Price.Value,Objects[v.Object.Value])
                                if Purchased then
                                    warn("Purchased")
                                else
                                    warn("Can't purchase")
                                end
                            end
                            DB = false
                        end
                    end
                end)
            end
        end

        function DoPurchase(Hit,Button,Cost,Object)
            if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
                local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
                if Player and OwnerValue.Value == Player then
                    local name = game.Players:GetChildren()
                    local CashValue = game.Players.name.leaderstats.Cash -- Error here
                    if CashValue then
                        if CashValue.Value >= Cost then
                            CashValue.Value = CashValue.Value - Cost
                            Object.Parent = Purchases
                            Button:Destroy()
                            return true 
                        end 
                    end
                end
            end
            return false
        end

Следующий сценарий, который составляет таблицу лидеров и назначает игрока, который недавно присоединился к случайному доступному Tycoon, находится здесь:



     function FindEmptyTycoon()
            for i,v in pairs(workspace.Tycoons:GetChildren()) do
                if v.TycoonInfo.Owner.Value == nil then
                    return v
                end
            end
            return nil
        end


        game.Players.PlayerAdded:Connect(function(Player)
            local Tycoon = FindEmptyTycoon()
            Tycoon.TycoonInfo.Owner.Value = Player 


            local stats = Instance.new("Folder",Player)
            stats.Name = "leaderstats"

            local Cash = Instance.new("IntValue",stats)
            Cash.Name = "Cash"
        end)

И затем скрипт, который хранится во всех покупаемых предметах, чтобы дать игроку деньги, находится здесь:


function giveCash(player)
    wait(3.33)
    local Cash = player.leaderstats.Cash
    Cash.Value = Cash.Value + 2
end

Кстати, эти скрипты являются версиями оригинальных скриптов. которые я пытался отредактировать, чтобы они действительно работали, и я думаю, что уже близко к исправлению ошибок. Оригинальные скрипты можно найти здесь (в порядке появления):

local TycoonInfo = script.Parent:WaitForChild("TycoonInfo")
local OwnerValue = TycoonInfo:WaitForChild("Owner")
local Buttons = script.Parent:WaitForChild("Buttons")
local Purchases = script.Parent:WaitForChild("Purchases")

local Objects = {}

function validateHitByOwner(Hit)
    if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
        local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
        if Player and OwnerValue.Value==  Player then
            return true
        end
    end
    return false
end

for i,v in pairs(Buttons:GetChildren()) do
    local Object = Purchases:FindFirstChild(v.Object.Value)
    if Object then
        Objects[Object.Name] = Object:Clone()
        Object:Destroy()

        if v:FindFirstChild("Dependency") then
            coroutine.resume(coroutine.create(function()
                v.Button.Transparency = 1
                v.Button.BillboardGui.Enabled = false
                v.Button.CanCollide = false
                if Purchases:WaitForChild(v.Dependency.Value,90000) then
                    v.Button.Transparency = 0
                    v.Button.CanCollide = true
                    v.Button.BillboardGui.Enabled = true
                end
            end))
        end
        local DB = false
        v.Button.Touched:Connect(function(Hit)
            if validateHitByOwner(Hit)then
                if DB == false then
                    DB = true
                    if v.Button.Transparency == 0 then
                        local Purchased = DoPurchase(Hit,v,v.Price.Value,Objects[v.Object.Value])
                        if Purchased then
                            warn("Purchased")
                        else
                            warn("Can't purchase")
                        end
                    end
                    DB = false
                end
            end
        end)
    end
end

function DoPurchase(Hit,Button,Cost,Object)
    if Hit and Hit.Parent and Hit.Parent:FindFirstChild("Humanoid") then
        local Player = game.Players:GetPlayerFromCharacter(Hit.Parent)
        if Player and OwnerValue.Value == Player then
            local CashValue = game.ServerStorage.PlayerCash:FindFirstChild(Player.Name)
            if CashValue then
                if CashValue.Value >= Cost then
                    CashValue.Value = CashValue.Value - Cost
                    Object.Parent = Purchases
                    Button:Destroy()
                    return true
                end
            end
        end
    end
    return false
end
function FindEmptyTycoon()
    for i,v in pairs(workspace.Tycoons:GetChildren()) do
        if v.TycoonInfo.Owner.Value == nil then
            return v
        end
    end
    return nil
end


game.Players.PlayerAdded:Connect(function(Player)
    local Tycoon = FindEmptyTycoon()
    Tycoon.TycoonInfo.Owner.Value = Player


    local stats = Instance.new("BoolValue",Player)
    stats.Name = "leaderstats"
    stats.Parent = game.ServerStorage

    local Cash = Instance.new("IntValue",stats)
    Cash.Name = Player.Name
    Cash.Value = 0
    Cash.Parent = game.ServerStorage.PlayerCash
end)
local amount = 2
local timedelay = 2.33
local currencyname = "Cash"
wait(1)
while true do
    wait(timedelay)
    for i,v in pairs(game.ServerStorage.PlayerCash:GetChildren()) do
        if v:FindFirstChild("leaderstats") and v then
            v.leaderstats[currencyname].Value = v.leaderstats[currencyname].Value + amount
        end
    end
end

1 Ответ

1 голос
/ 08 мая 2020
local name = game.Players:GetChildren()

Почему вы храните список детей Players в переменной с именем name? Эта функция возвращает таблицу. name было бы более подходящим для строки.

local CashValue = game.Players.name.leaderstats.Cash -- Error here

game.Player s is https://developer.roblox.com/en-us/api-reference/class/Players

Я не могу понять game.Players.name и даже меньше game.Players.name.leaderstats

Возможно, вы имели в виду Player.leaderstats?

Я ожидал появления сообщения об ошибке для Players.name.leaderstats, прежде чем столкнуться с ошибкой для game.Players.name.leaderstats.Cash

name is не свойство игроков, поэтому вам не должно быть разрешено индексировать Players.name

Я не эксперт по Roblox, но, как я вижу, ваш код настолько не работает, что вам действительно следует начать с простых руководств, а не с исправления этот код.

Думаю, вам следует начать все сначала и убедиться, что вы понимаете, как правильно используется Instance.new и тому подобное.

Также поможет использование лучших имен переменных.

...