I am trying to determine where on a game object the user has clicked, in terms of that game object’s local space. (For example, if the user clicks the game object dead on its local origin, I want the returned position to be (0, 0).) I’m using go.world_to_local_position, which I think is what I want, but it’s not returning the position I’d expect. Am I using the function incorrectly?
My actual project uses defold-input’s cursor together with defold-orthographic, but I’m still getting the behaviour in a minimal reproduction project that uses neither. I’m using Defold 1.10.0 on macOS, though as far as I can tell, go.world_to_local_position
hasn’t changed since it was originally merged in last year.
These three green squares’ bottom left corners (marked in red) are at their local origins. Each has a collision shape that covers their sprites. One is placed at world origin, the second is at (250,250), and the third is at (550,0) with Z-rotation of 45.0°.
There is a simple cursor game object with a small kinematic collision object (and a white dot particle sprite) that follows the user’s mouse pointer. It is scripted thus:
function init(self)
msg.post(".", "acquire_input_focus")
self.touching = nil
end
function update(self, dt)
self.touching = nil
end
function on_message(self, message_id, message, sender)
if message_id == hash("collision_response") then
self.touching = message.other_id
end
end
function on_input(self, action_id, action)
if action.x and action.y then
go.set_position(vmath.vector3(action.x, action.y, 0))
end
if action_id == hash("touch") and action.pressed then
print("Click action.x/y: ", action.x, action.y)
local cursor_world_position = go.get_world_position(".")
print("Cursor world position x/y: ", cursor_world_position.x, cursor_world_position.y)
if self.touching then
local object_world_position = go.get_world_position(self.touching)
print("Clicked object: " .. self.touching .. " (object world position: ", object_world_position.x, object_world_position.y, ")")
local click_local_position = go.world_to_local_position(cursor_world_position, self.touching)
print("Object was clicked at local position: ", click_local_position.x, click_local_position.y)
end
end
end
When I run the game and click each square close to each one’s local origin:
DEBUG:SCRIPT: Click action.x/y: 13.5 12.5
DEBUG:SCRIPT: Cursor world position x/y: 13.5 12.5
DEBUG:SCRIPT: Clicked object: [/square_origin] (object world position: 0 0 )
DEBUG:SCRIPT: Object was clicked at local position: 13.5 12.5
DEBUG:SCRIPT: Click action.x/y: 268.5 264.5
DEBUG:SCRIPT: Cursor world position x/y: 268.5 264.5
DEBUG:SCRIPT: Clicked object: [/square_translated] (object world position: 250 250 )
DEBUG:SCRIPT: Object was clicked at local position: 518.5 514.5
DEBUG:SCRIPT: Click action.x/y: 553.5 25.5
DEBUG:SCRIPT: Cursor world position x/y: 553.5 25.5
DEBUG:SCRIPT: Clicked object: [/square_rotated] (object world position: 550 0 )
DEBUG:SCRIPT: Object was clicked at local position: 1103.5 25.5
I’ll be the first to admit that vector math’s not my strong suit, but a click at world (268.5, 264.5) atop a GO that has its own origin at world (250, 250) should mean the click’s at (18.5, 14.5) in that GO’s local space, not (250 + 268.5, 250 + 264.5) = (518.5, 514.5), right?
I feel like I must be missing something obvious. If anyone can set me right, I’d appreciate it.