передача дополнительного параметра функции, когда функция вызывается через событие, т.е. :Connect()

Я пытаюсь преобразовать свою безымянную функцию, чтобы она лучше работала с использованием ООП, и у меня возникли некоторые трудности, поскольку я полагался на определенную область. Любые предложения, старый и новый код ниже:

СТАРЫЙ КОД - РАБОТАЕТ

for _,portal in pairs(script.Parent:GetChildren())do
    if portal:IsA("Script") then continue end
    portal.Touched:Connect(function(part)
        local HRP = part.Parent:FindFirstChild("HumanoidRootPart")
        if not HRP then return end
        local DestinationName = portal:FindFirstChildOfClass("Attachment").Name
        local Destination = script.Parent:FindFirstChild(DestinationName):FindFirstChild(portal.Name)
        HRP.CFrame = Destination.WorldCFrame
    end)
end

НОВЫЙ КОД - ОШИБКИ OBVS

local function portalTouched(part,portal)
    local HRP = part.Parent:FindFirstChild("HumanoidRootPart")
    if not HRP then return end
    local DestinationName = portal:FindFirstChildOfClass("Attachment").Name
    local Destination = script.Parent:FindFirstChild(DestinationName):FindFirstChild(portal.Name)
    HRP.CFrame = Destination.WorldCFrame
end

for _,portal in pairs(script.Parent:GetChildren())do
    if portal:IsA("Script") then continue end
    portal.Touched:Connect(portalTouched(portal))
end

Проблема с подключением функций к событиям заключается в том, что вы не можете передать какие-либо дополнительные параметры. Как мне обойти эту проблему? Любые и все предложения приветствуются!


person Theo    schedule 18.07.2020    source источник


Ответы (1)


Вы можете использовать функцию более высокого порядка, которая вызывается с portal, а затем возвращает функцию, которая может использовать параметр из объемлющей функции:

local function portalTouched(portal)
    return function(part)
        -- We can use portal in this function
        local HRP = part.Parent:FindFirstChild("HumanoidRootPart")
        if not HRP then return end
        local DestinationName = portal:FindFirstChildOfClass("Attachment").Name
        local Destination = script.Parent:FindFirstChild(DestinationName):FindFirstChild(portal.Name)
        HRP.CFrame = Destination.WorldCFrame
    end
end

for _,portal in pairs(script.Parent:GetChildren())do
    if portal:IsA("Script") then continue end
    portal.Touched:Connect(portalTouched(portal))
end
person ankurbohra04    schedule 18.07.2020
comment
Никогда раньше не слышал об этом методе, это лучшая практика? Не могли бы вы также объяснить, как это работает немного подробнее, поскольку я не знал, что вы можете анализировать дополнительные параметры с помощью Connect (функция) - person Theo; 18.07.2020
comment
Ну, это скорее предпочтение, чем вопрос или практика, вы можете пойти любым путем в зависимости от того, хотите ли вы анонимную функцию или короткую краткую строку, как указано выше. - person ankurbohra04; 18.07.2020
comment
Дополнительные параметры на самом деле не передаются из соединения, мы используем замыкание. Переменные из включающих функций доступны внутренним функциям, мы используем это для предоставления переменных без получения переменных в качестве параметров. Так как нам нужно придать событию функцию и мы не можем возиться с параметрами, мы манипулируем его окружением, делаем это с помощью функции более высокого порядка — функции, которая принимает или отдает функцию. Используя такую ​​функцию, мы можем ввести portal в возвращаемую анонимную функцию, не будучи параметром возвращаемой функции. - person ankurbohra04; 18.07.2020