RunLater 주의사항

펑크랜드에서 자주 사용되는 메소드인 RunLater의 주의사항에 대해 알아봅니다.

RunLater 사용


RunLater함수는 실행 순서를 순차적으로 제어하는데 사용 됩니다. 아래는 예시 코드입니다.

--2초 뒤 Hello, World 출력하기
Client.RunLater(function()
 print("Hello, World") 
end, 2)

위와 같이 n초 뒤 첫번째 파라미터로 넘겨진 익명함수를 실행하게 됩니다. 이를 사용하여 특정 시간이 지난 후에 원하는 작업을 수월하게 제어할 수 있습니다.

시간 간격 보장 문제


RunLater 함수는 시간이 경과한 후에 함수를 실행하기 때문에, 게임의 프레임 속도에 영향을 받지 않습니다. 따라서, 정확한 시간 간격을 보장하지 않습니다. 아래 예시를 살펴보겠습니다.

-- 1초마다 메시지 출력
local startTime = os.time()

local function printMessage()
    local currentTime = os.time()
    local elapsedTime = currentTime - startTime
    print("경과 시간: " .. elapsedTime .. "초")
end

local function runLaterExample()
    Client.RunLater(function()
        printMessage()
        runLaterExample()
    end, 1)
end

runLaterExample()

위의 예제에서는 1초마다 경과 시간을 출력하는 함수를 RunLater를 사용하여 반복적으로 실행하도록 설정하였습니다. 하지만 RunLater 함수는 정확한 시간 간격을 보장 받지 않기 때문에, 실제로는 1초 보다 조금 더 긴 시간이 경과할 수 있습니다.

성능 문제


RunLater 함수는 게임의 메인 스레드에서 실행되므로, 오래 걸리는 작업을 실행하면 게임의 성능에 영향을 줄 수 있습니다. 만약 RunLater를 이용해 오래 걸리는 작업을 해야 한다면, 별도의 처리가 필요할 수 있습니다.

-- 5초 후에 오래 걸리는 작업 실행
Client.RunLater(5, function()
    -- 오래 걸리는 작업
    for i = 1, 1000000000 do
        -- 작업 수행
    end
end)

위의 예제에서는 5초 후에 오래 걸리는 작업을 실행하도록 설정하였습니다. 이 작업은 매우 오래 걸리는 작업이므로, 게임의 성능에 부정적인 영향을 줄 수 있습니다.

아래 예제에서는 그 중, 오래 걸리는 작업을 여러 단계로 나누어 처리하고, 각 단계마다 짧은 시간 동안 작업을 수행한 후 다음 단계로 넘어가는 예제를 확인해 보겠습니다.

local totalIterations = 1000000000
local iterationsPerFrame = 1000000
local currentIteration = 0

local function performWork()
    for i = 1, iterationsPerFrame do
        -- 작업 수행
        currentIteration = currentIteration + 1
        if currentIteration >= totalIterations then
            -- 작업 완료
            print("작업이 완료되었습니다.")
            return
        end
    end

    -- 다음 프레임에 작업 계속 수행
    Client.RunLater(performWork, 0)
end

-- 첫 번째 프레임에서 작업 시작
performWork()

Lua스크립트는 별도로 다중 스레드 기능을 제공하지 않음으로, 다른 방법을 사용하여 오래 걸리는 작업을 처리할 수 있습니다.

위의 예제에서는 오래 걸리는 작업을 100만 번씩 나누어 처리하도록 설정하였습니다. 각 프레임마다 100만 번의 작업을 수행하고, 작업이 완료되지 않았다면 다음 프레임에 작업을 계속 수행하도록 설정합니다.

유효성 보장 문제


n초 뒤에 실행되는 RunLater는 대기 이후 동작의 유효성을 보장할 수 없습니다. 예를 들어, 내가 접근하려는 개체가 n초 뒤에는 파괴되었을 수 있기 때문입니다.

local text = Text()
Client.RunLater(function()
    text.text = "Hello, World"
end, 2)

text = nil
print(text.text)

위 예제는 2초 뒤에 Text 개체의 속성에 접근합니다. 하지만, 2초 사이에 Text 개체가 파괴되었다면 에러가 날 수 있습니다. 따라서, RunLater 안에서 개체에 접근하려면 유효성 검사를 해주는 것이 좋습니다.

local text = Text()
Client.RunLater(function()
    if text ~= nil then
        text.text = "Hello, World"
    end
end, 2)

위와 같이 객체가 파괴된 후에도 RunLater 함수가 실행되는 경우를 대비하여 유효성 검사를 해주는 것이 좋습니다. 이러한 방법을 사용하여 객체가 파괴되는 경우에도 유효성을 보장할 수 있습니다.

Last updated