Global_Position behavior inconsistencies #11227
Replies: 1 comment 6 replies
-
First, I want to get something out of the way: Also, where does it say to "Don't ask why this works", I can't find that. Anyway, you are correct that But since GDScript act as a dynamic language, And there is, as you might guess, a type of Now, let us look at the documentation of
There is a logic to it. To make sense of it, have a look a the documentation of
Did you catch the difference? The Well, in the case of I'm going to give you another reason to avoid I'm going to guess this is oversight (I imagine that input emulation usually takes care of it, and the use case is rare enough, that it never came up). Yet, this means, that if you want to write your code in a way that will handle both mouse and touch (without relying on input emulation) you are going to avoid Why does And finally, what to do about it... Renaming to At first I was going to say that a warning might not be great because there are legitimate use cases. But given that the use case is rare enough, and there aren't touch counterparts, I can't rule it out as an option. In fact, unless the Godot team has other plans... My current opinion is that if it is necesary we could add methods with better names (and also for touch events to bring them on par), and the property can be deprecated. I hope somebody from the Godot team can comment. |
Beta Was this translation helpful? Give feedback.
-
I recently encountered a situation where global_position did not behave as the global_position in any intuitive sense.
When you are in an _input() function and call the global_position value as a property of the event, you do not get the global_position relative to anything within your scene. If the root node moves, or a camera moves, the InputEvent.global_position does not change. This was explained to me as having something to do with the input being a node shooting off from root in a separate tree from the scene nodes, but it also seems possible that through each frame the game moves the global position before it starts placing any nodes from the scene tree, and then moves it back, and the incongruency arises from the timing of the calls.
Whatever the reason, one would expect that if you were to move a camera node that is child only to the scene's parent node, and have a visible object that moves on the screen, then calling InputEvent.global_position if the event is being triggered at that target should not be changing, but it does.
Here is the code to elucidate what I mean. You can examine the attached project file for your own testing.
test.zip
Parent of the scene is a Node2D
It has a child Node2D with the following script:
second child to the parent is a Camera2D with the following code:
and finally, a third child that's the default godot texture/image so you can see the effects of the camera moving.
The expected behavior I think for pretty much every user except those intimately familiar with the deep inner cores of the engine, is that as the camera moves and you keep on your mouse to click on the image, the position should change as you move, but the global position should stay the same- barring some margins of error for accuracy of the mouse. Alternatively, if you keep the mouse in the same spot and just move the camera as you click, the expectation is that the position shouldn't change, and the global should.
This does not happen.
No matter what you do, the global_position and position when called from the event stay the same value.
You can of course use the get_global_mouse_position() method and this works with the expected behavior above. However, this sort of betrays the fact that this lack of clarity on these properties exists.
I suggest a couple things.
Before any changes to the actual engine, clarity in the InputEvent class's documentation about global_position being a callable property seems like a good start. It doesn't seem to be an actual intrinsic property to the event(I think?), but you can call it, and it exists as a value. I would write out a proposal of the documentation itself, but I truly do not comprehend what is happening or why it would behave this way. It is a black box to me.
And more seriously, some indication to the user that this property is effectively entirely different from global_position in any other context. This could be a straight up error and not allowing the thing to compile? I'm not sure about that one as it might break an existing project that uses this, maybe there's a use case here that is way beyond my comprehension of the situation, but it seems like the position property should cover everything you'd want to do with positions from an InputEvent, as position and global_position values appear to never diverge, or at least don't diverge for any expected or intuitive reason.
Alternatively, renaming it to something else, such as viewport_position, seems like another fair solution. This may brick something within the engine with co-dependencies that are beyond my technical comprehension, so if I were the one modifying the engine I'd definitely be anxious about this, but honestly this would be my preferred solution as a game developer, and not an engine developer.
But the last solution I have in mind, and it seems like the softest-hand approach that would still technically be considered a solution, is to simply throw up a yellow warning when InputEvent.global_position is used inside an _input() function. It warns the user that "calling the global_position property on an InputEvent does not behave as expected", and can direct the user to new documentation explaining this incongruent behavior.
I'm sure there are a great many things about this property that I don't know that I don't know. I think that's part of the issue in general- the information is not easily available in the documentation where you'd expect to find it. Or it could be arcanely devised this way on purpose to address some other equally confounding issue. One of those comments in the code that says "Don't ask why this works" My primary perspective here is one of a game developer. I think with that lens, the current behavior almost rises to bug status, but with enough ambiguity on it that I refrained from reporting it as such.
I really would like to hear what people who are more knowledgeable about this entire piece of the system have to say about it. I would love to receive a cogent reply detailing exactly why it is this way and why it makes sense, if it is indeed behaving exactly as intended.
Beta Was this translation helpful? Give feedback.
All reactions