Ah, yes. This problem was brought up not too long ago. You can check this thread for some explanation, but in short—I can’t fix it. There’s no way to manually update the world transform of the camera after you move it, so screen_to_world_2d will be using an out-of-date transform.
As long as you don’t need to put your camera on a transformed parent though, there is an easy enough workaround—you just assume that local pos is the same as world pos. I posted a sample project in that other thread, and here are the relevant functions from there:
-- `cam` must be the URL to the camera -script- component.
local function getRealCamScale(cam)
local window = rendercam.window
local orthoScale = rendercam.get_ortho_scale()
local scaledViewArea = go.get(cam, "viewArea") * orthoScale
local scale = scaledViewArea.x / window.x
return scale
end
local function simpleScreenToWorld(x, y, cam, isDelta)
if not isDelta then
local window = rendercam.window
x, y = x - window.x/2, y - window.y/2
end
local scale = getRealCamScale(cam)
x, y = x * scale, y * scale
if not isDelta then
local camPos = go.get_position(cam)
x, y = x + camPos.x, y + camPos.y
end
return x, y
end
local function simpleWorldToScreen(x, y, cam, isDelta)
if not isDelta then
local camPos = go.get_position(cam)
x, y = x - camPos.x, y - camPos.y
end
local scale = getRealCamScale(cam)
x, y = x / scale, y / scale
if not isDelta then
local window = rendercam.window
x, y = x + window.x/2, y + window.y/2
end
return x, y
end
Just use those instead of the usual rendercam.screen_to_world_2d, etc., and I believe it should work, since the local position is updated instantly.
If you need to have a sort of “post-update” function, you can do this by sending a message to a script (probably ‘yourself’) on every update. That’s what the camera does as well. The on_message response will be triggered just after all scripts have been updated.