Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CanvasLayer's Follow Viewport doesn't translate inputs correctly #35965

Closed
cgbeutler opened this issue Feb 6, 2020 · 14 comments · Fixed by #59682
Closed

CanvasLayer's Follow Viewport doesn't translate inputs correctly #35965

cgbeutler opened this issue Feb 6, 2020 · 14 comments · Fixed by #59682

Comments

@cgbeutler
Copy link

Godot version:
3.2

OS/device including version:
Windows10

Issue description:
Turning on Follow Viewport Enable on a CanvasLayer translates child controls to the right place, but inputs are triggering in the non-follow spot
ViewportBug

Steps to reproduce:
In a Node2D scene, add a centered Camera2D set as the current camera
Add a CanvasLayer with Follow Viewport > Enable set to true
In the CanvasLayer add a button
Hit play. The button will get hover and click events when the mouse is in the top left corner of the screen instead of when the mouse is over the button

Minimal reproduction project:
https://github.com/cgbeutler/FollowViewportBug

@chepulis
Copy link

chepulis commented Feb 12, 2020

I'm experiencing this bug, separately, in my project.

(3.2, MacOS)

@Byteron
Copy link
Contributor

Byteron commented May 8, 2020

Same issue here, using 3.2.1

@renatodex

This comment has been minimized.

@renatodex
Copy link

renatodex commented Oct 30, 2020

@Calinou , do you think you can you help me to know where this needs to be changed? I can make a PR for that, just need some orientation.

@Calinou
Copy link
Member

Calinou commented Oct 30, 2020

@renatodex I don't know why this bug happens, but the CanvasLayer source code is here: https://github.com/godotengine/godot/blob/master/scene/main/canvas_layer.cpp

Either way, it's not like having Control nodes in a CanvasLayer that simulates a pseudo-3D effect is exceedingly common 🙂

If you just want Control nodes to follow the camera as it moves, use a CanvasLayer without enabling Follow Viewport.

@cgbeutler
Copy link
Author

cgbeutler commented Oct 30, 2020

@renatodex Disregard my deleted comment. I forgot what this was about.
Camera2D does work in a strange way. From the Camera2D docs:

This node is intended to be a simple helper to get things going quickly and it may happen that more functionality is desired to change how the camera works. To make your own custom camera node, inherit from Node2D and change the transform of the canvas by setting Viewport.canvas_transform in Viewport (you can obtain the current Viewport by using Node.get_viewport).

I think the camera2D's transform applied on the canvas seems to be the issue.
If you don't use a Camera2D at all and put in the following code:

func _ready():
	var viewport :Viewport = get_viewport()
	viewport.canvas_transform = Transform2D(0, Vector2(100,100))

You get the same error as above. Therefore, it would seem that the viewport's canvas_transform is not being applied to the input events being passed to a canvas layer? Maybe?
You may check the input event code between viewport and canvas layer. I'd guess it's something there.

@cgbeutler
Copy link
Author

Looks like it could be related to make_input_local in CanvasItem:
https://github.com/godotengine/godot/blob/master/scene/main/canvas_item.cpp
It currently does this:

Ref<InputEvent> CanvasItem::make_input_local(const Ref<InputEvent> &p_event) const {
	ERR_FAIL_COND_V(p_event.is_null(), p_event);
	ERR_FAIL_COND_V(!is_inside_tree(), p_event);

	return p_event->xformed_by((get_canvas_transform() * get_global_transform()).affine_inverse());
}

Which, if my tired brain is correct, it shouldn't apply the canvas transform AND the global transform if it's layer is set to "follow viewport"? Maybe? I should get some sleep then come back to it...

@ghost
Copy link

ghost commented Apr 17, 2021

I'm having the same issue in 3.2.3 :/

@kagenash1
Copy link

Still relevant in 3.3

@renatodex
Copy link

renatodex commented Apr 26, 2021 via email

@cgbeutler
Copy link
Author

cgbeutler commented Jan 15, 2022

Just discovered a possible clue:
With this setup (doesn't matter if CanvasLayer has follow_viewport enabled)
image

When a camera is active $RootButton.get_global_mouse_position() returns the correct global position while $CLButton.get_global_mouse_position() seems to return a local mouse position. Pretty sure it shouldn't do that..?

I am definitly to naive to fix this myself. Poking around in the code has only made me more confused about how canvases and transforms work.

@Sauermann
Copy link
Contributor

Here is a MRP for Godot 4: BugCanvasLayerFollow.zip

@mastrio
Copy link

mastrio commented Jun 15, 2023

I'm having this issue in 4.0.3

@Sauermann
Copy link
Contributor

@mastrio I'm unable to replicate the issue in v4.0.3.stable.official [5222a99] and v4.1.beta.custom_build [01453ab].
Please provide a minimal reproduction project, so that we can verify, if this is the same issue. If this is not the same issue, then it would be best to open a new bug-report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants