Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.
No autocomplete on event.button_index ?ThomoI'm a bit confused as to why Godot sometimes does not suggest any code.
For example, when checking for a left click on the chest, nothing is suggested after writing `event.`, which would definitely throw me off and make me think I'm trying to write something that does not exist if I was on my own.
Even writing `event.button_` does not make any autocomplete hint pop up.
I've had this happen when setting the shader outline parameter, where it would not autocomplete `canvas_group.material.` with `set_shader_parameter()`, which I fixed by switching the code a bit and manually telling godot that the material was a ShaderMaterial like this:
```gdscript
@onready var canvas_group: CanvasGroup = $CanvasGroup
@onready var canvas_material: ShaderMaterial = canvas_group.material
```
And then using `canvas_material.set_shader_parameter("line_thickness", new_thickness)`
Would there be a way to "fix" the autocomplete in the case of event.button_index ?67Apr. 08, 2024
Extra challenge: close the chest after opening itmatteoscopelAs a personal challenge, I wanted to make it so that I can close again the chest after opening it. I wanted to do it without using any variable, like we did in this chapter. I've written the following function. It works! Do you think there would be a cleaner way of doing this?
```gdscript
func open() -> void:
if animation_player.assigned_animation == "open":
animation_player.play_backwards("open")
animation_player.queue("RESET")
else:
animation_player.play("open")
```25Jul. 05, 2024
L5.P2 problem.RossBCIf you actually use event.is_released() instead of event.is_pressed(), you fail the practice.
The way it's worded, we are supposed to be checking on button release to clear the queue.
The only time it succeeds is when the only code you change/add is queue.free() and leave event.is_pressed() as it is.104Apr. 08, 2024
Child Parent Relationship milk_manWhy do we write the following code:
```gdscript
if event is InputEventMouseButton:
```
event is a variable of type **InputEvent**, meaning it's the parent of the more specific type **InputEventMouseButton**. Shouldn't the order be **child is parent**, so like this:
```gdscript
if InputEventMouseButton is event:
```
I'm confused, bc in another example where the use of **is** is explained, it says that the **Sprite2D** is a more specific version of **Node2D**, so we write **Sprite2D is Node2D**, child is parent, not parent is child41Oct. 01, 2024
is there a typesafe way to access/play animations without using strings?inferior-gnatSeems a bit brittle to use the string "open" to play the animation. As mentioned in the lesson, changing the animation name in the panel would break everything.21Jun. 01, 2024
Is this a better way to write the code considering readibility and autocomplete?Lucas PscheidtAbout the code where you talked about the _input_event() function:
func _input_event(viewport: Node, event: InputEvent, shape_index: int):
var event_is_mouse_click: bool = (
event is InputEventMouseButton and
event.button_index == MOUSE_BUTTON_LEFT and
event.is_pressed()
)
if event_is_mouse_click:
pass
I personally found it a little bit confusing and hard to use this function in this way because it does not give us the autocomplete suggestion for the "button_index". It would require a lot of practice and use of this function to know and remember to write this, in my opinion. For teaching purpose, wouldn't be better to write the code in a way which could suggest the autocomplete for that object? Like in this way that I came up with (it also uses one less line of code and I found personally better to read):
func _input_event(viewport: Node, event: InputEvent, shape_index: int):
if event is InputEventMouseButton:
var event_left_mouse_click: bool = event.button_index == MOUSE_BUTTON_LEFT
var event_is_pressed = event.is_pressed()
if event_left_mouse_click and event_is_pressed:
pass
Just a suggestion to make it easier for beginners to understand, but I don't know if everything is fine with it, so please correct me if I am wrong. 51May. 31, 2024
is or == ?SebI was curious, I tried : `event == InputEventMouseButton`
and nothing happened. So, yes, "is" is different from == ;)
The lecture says it "checks if a value is of a specific type", which I found hard to understand.
I read the documentation of "InputEventMouseButton", it's a class. So if I understand correctly, "is" checks that "event" is of the class "InputEventMouseButton" whatever the values of its different properties are. Is that correct?
I also tried to read [https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is) which both helped and lost me XD.
Anyway, I was happy like a child when the chest did animate on click. :)11Apr. 16, 2024
event_is_mouse_click: first check needed?HollowIs it necessary to check if the event is of type InputEventMouseButton if we have the second check which already determines if it is the left mouse button?81Apr. 08, 2024
What is the difference of _input_event(), _input() and _unhandled_input()?SebabeI'm just wondering what the main difference is between these methods and when to use which one?11Apr. 01, 2024
Difference between get_viewport() and viewport in _input_eventold-fashioned-mouseHello, quick question. I was wondering what the difference between what `get_viewport()`returns and the `_input_event` viewport parameter was (if there is one)? As far as I understand `get_viewport` returns the nodes current viewport anyway (in the case of multiple windows)?
Thanks!11Mar. 23, 2024
Limitation of not using $ with node names each timeHardRockI noticed something that seems very odd to me. If I access the AnimationPlayer with $, then I get hints about the available animations as I type `.play()`, and so I don't have to know their names and type them, just select them from a list. This is very convenient, and would be even more so if I'd have many animations.
If however I access the AnimationPlayer through a variable (defined like this `@onready var animation_player: AnimationPlayer = $AnimationPlayer`) or even directly with get_node() (like this: `(get_node("AnimationPlayer") as AnimationPlayer)`) I don't get any hints for existing animations, which is a bummer.
At first I thought that perhaps Godot does a deeper check on the AnimationPlayer instance when it is being accessed with $ (the code for this syntactic sugar could differ from what get_node() does, which may affect the hint system), but then realized that in the @onready example $ is used to get the AnimationPlayer, so I would expect the hint system to work in the same way in that case with the resulting variable, as it does with $ directly. Then there's the case with get_node() that also doesn't provide name hints for animations, even though it should do the same thing as $, as far as I understand at this point. Basically I have no logical explanation why, but node access with $ provides the most hints in practice.
I don't really expect an answer for this, it's just something I found interesting and as I work in QA I started experimenting with ways of accessing nodes, to see if perhaps the hint system reacts differently. :)10Oct. 23, 2024
Simpler way of checking for left clickHardRockIs there any reason for checking for left click in 3 steps like done in this lesson, other than for teaching us the implementation details of events?
After checking how the various methods of the InputEvent class work, I settled on using `event.is_action_pressed("left_click")` instead. As I understand it this method also guarantees that a mouse event occured, that it was the left button and that it was pressed.30Oct. 23, 2024
input_event or Input.is_action_pressed() questionsPurpleSunriseI have a couple of questions about the input_event function.
Does it work ONLY for mouse clicking or for keys as well? I tried to implement it on a test project. I have a CharacterBody2D and an Area2D with a placeholder sprite. I thinking I am missing some steps and I am quite confused.
Let's say I want that when the CharacterBody2D collision shape enters in the Area2D collision shape the Area2D emits a signal of area_entered(_on_area_entered) and then I define a function
```gdscript
@onready var animation_player : AnimationPlayer = $AnimationPlayer
func _ready():
area_entered(_on_area_entered)
func _on_area_entered(area_that_entered):
if Input.is_action_just_pressed("confirm"):
jump()
func jump():
animation_player.play("jump")
```
It's simple but I thought it would work but it didn't. I tried with changing with body_entered signal but no luck. Maybe this is too advanced for me at this point but I was curious on how I could achieve this in a simple way. Do I need an input_event for this?
I checked the collision layers as well. The CharacterBody2D is on layer 1 and detects masks 1 and 5. The Area2D is on layer 1 and detects layer 1.
I would be happy to have the situation clearer if possible! Thank you!40Oct. 23, 2024
Question about 2 animation in one animation nodeHazlarHi !
I created the interpolations to make the chest more bouncy when the mouse hovers over it and when it comes out. I wanted to reproduce this interpolation in an animation track to include it at the end of the opening of the chest, keeping the animation_player node that we created then clicking on new and giving an animation name.
However, by doing this, I notice that where I invoke the "*landing_chest*" animation, the "*open*" one does not happen.
In the "*open*" animation, we modify the position of the *TOP* sprite, in that of the "*landing_chest*" I modify both *LOCK* and *BOTTOM*. So when the open animation is launched at the end of it, the lid of the chest is on the ground. Then I launch *landing_chest* but the chest remains on it, while in the track I did not modify the *TOP* sprite, it is supposed to remain on the ground in the "*open*" repository.
Here is the script, I removed the optional parts.
```gdscript
extends Area2D
@onready var canvas_group: CanvasGroup = $CanvasGroup
@onready var animation_player: AnimationPlayer = $AnimationPlayer
func _input_event(viewport: Viewport, event: InputEvent, shape_idx: int) -> void:
var event_is_mouse_click : bool = (
event is InputEventMouseButton and
event.button_index == MOUSE_BUTTON_LEFT and
event.is_pressed()
)
if event_is_mouse_click:
open()
func open() -> void:
var tween := create_tween()
animation_player.play("open")
animation_player.play("landing_chest")
input_pickable = false
```
I compressed the Chest folder if textually it is not precise enough: [https://we.tl/t-bDMjOdsWC0](https://we.tl/t-bDMjOdsWC0)
Thanks in advance50Oct. 15, 2024
You can click on the chest even if it is not visibleram876Hello! I tried placing the chests on top of each other and clicking on one opens both. Then I also created another Area2D object. The same behavior, you can click on the chest, even if it is blocked by another object. Is it possible to check in a simple way whether the chest is blocked at the point of mouse click or not?20Oct. 14, 2024
Disabling a collision in the open functionram876Hi. When the collision was turned off, I got a similar result
```gdscript
$CollisionShape2D.disabled = true
```10Oct. 14, 2024
Thinking about accessibility and control remappingPaul```gdscript
func _input_event(viewport: Viewport, event: InputEvent, shape_index: int):
var event_is_mouse_click: bool = (
event is InputEventMouseButton and
event.button_index == MOUSE_BUTTON_LEFT and
event.is_pressed()
```
Not that I have any idea about putting front-end remapping in place at this stage, but with that, and accessible design in mind, is this sort of code flexible? It reads to me that it's 'hard-coded' to expect a left mouse click and nothing else.
Would you require a different approach if you knew you intended to support multiple input methods or editable controls in your game?10Sep. 14, 2024
Same result using a signal, not sure which approach is betternervous-woodpeckerI saw we have access to the `input_event` signal on the parent object type `CollisionObject2D` so my instinct was to use that approach right away. That worked and is way less code.
`input_event.connect(_on_input_event)`
`...`
`func _on_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:`
` if event.is_action_pressed("left_click"):`
` animation_player.play("open")`
What's difference? Thanks!
30Sep. 12, 2024
is_open variable and best practicesdweipertI wouldn't say using a `is_open` variable is not best practice.
Certainly depends on the use-case.
If you'd like to check from the outside whether a chest was opened or not your definetely need a variable to keep track of that. Or a function `is_open()` that you can call that then checks whether `input_pickable` is `true` or `false`.
Using `is_open` does feel more like a state check to me and then I wouldn't expect to have to call a function and instead check the property. So the variable does feel to me like best practice.
I say this with 15 years programming experience, albeit full-stack web languages.
I'm only now starting to get into game dev with the actual intent to maybe build a complete game. So maybe the experiences built in the game dev field produce different expectations and best practices when actually completing a game start to finish.
Looking forward to hear your thoughts :)30Sep. 12, 2024
Alternative way to prevent chest from opening again (Not a question) Abdul Hannan AhmedHi!
I found an alternate way to prevent the chest from opening again. I just wanted to ask if that solution was viable or not?
```gdscript
func open() -> void:
animation_player.play("open")
$CollisionShape2D.disabled = true
```
Thanks in advance!10Sep. 03, 2024
L5.P1 AnimationPlayer Nodebig-hearted-emuL5.P1's door_open.tscn has an AnimationPlayer Node that only has a "rotation" track that is 0.001 seconds long. (0.5.1 win)
When doing the practice, on the first attempt I only read the MISSION without opening the instructions and go from there. When I checked the AnimationPlayer for the name of the animation track and saw "rotation" I thought that was it. I imagined we'd have to do the animation ourselves.
It fails the test.
The practice completes correctly when playing the "open" animation, but the track is not in the AnimationPlayer Node. I'm a bit confused as to what "open" animation is playing then?40Aug. 05, 2024
Is there a way to keep "Chest" instances from overlapping incorrectly?Turned_Into_A_FrogI noticed that if I have 3 chests; their tree order is (Chest, Chest2, Chest3) and their placement from background to foreground is (Chest3, Chest2, Chest). So when I activate the animation they overlap in a weird way due to draw order, Is there a way to make the overlap based on position? or is this more of a level design and tree organization issue?
10Aug. 02, 2024
is_released vs is_action_releasedIronEvaHey, I made a mistake and used the is_action_released by accident, but I was curious as to what the differences are as they both came up in the auto-completion popup.
I tried looking online and couldn't find anything about the difference between the two.
Bit of a guess here, but is it to do with input mapping?
P.S
One thing I know is this, I am terrible at looking up what things do in Godot.
20Jul. 16, 2024
Are these two the same?miniature-gazelleif event_is_mouse_click:
if event_is_mouse_click == true:
Are these two the same? if yes, shouldn't we use it like that cause it makes it a lot more clear what it does, at least for a newbie like me :D20Jul. 14, 2024
Question about _functionHazlarHello,
The input_event function is a function that is neither called in a context like func _process() or ready() , so is it a "passive" function like ready() or "active" like _process(). Because ready is called once, and process() is triggered continuously but here it is between the two, and I do not think that this state exists right?
Just for the correction the shape_index parameter is named on my side by the godot autocompletion as shape_idx .
Thanks !30Jul. 10, 2024
A few questions about the Viewport parameter and operators.Nikita Myshkin```gdscript
func _input_event(viewport: Viewport, event: InputEvent, shape_idx: int) -> void:
```
1.I set the `Viewport` parameter for the Node location and the work has not changed in any way. Do I understand correctly that the Viewport covers the entire area of the window, and the `Node` covers only the `Node` node? Then which one is better to use?
2.If I change `is` to `==` then the chest stops opening. What is the fundamental difference? After all, as I understand it, `is` and `==` are the same thing.30Jun. 26, 2024
How to Make Multiple AnimationPlayers Play Animations Independently in Godot Using C#?jadecui666I tried to recreate a tutorial's animation functionality using C#. I created a chest scene with an `open` animation in the AnimationPlayer. Then, I placed multiple instances of this chest scene in the main scene. However, when I click on a single chest, all the `open` animations play simultaneously.
It's worth noting that when I write the same logic using GDScript, this issue does not occur. Each chest instance's animation plays independently. Does this mean there are differences in how C# and GDScript handle AnimationPlayer?
```gdscript
using Godot;
using System;
namespace GdquestCsharp.chest_level
{
public partial class Chest : Area2D
{
CanvasGroup _canvasGroup;
AnimationPlayer _animationPlayer;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
_canvasGroup = GetNode<CanvasGroup>("CanvasGroup");
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
SetOutlineThickness(3);
this.MouseEntered += OnMouseEntered;
this.MouseExited += OnMouseExited;
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
}
public override void _Input(InputEvent @event)
{
base._Input(@event);
if (@event is InputEventMouseButton mouseButton && mouseButton.Pressed && mouseButton.ButtonIndex == MouseButton.Left && InputPickable)
{
Open();
}
}
private void OnMouseEntered()
{
var tween = CreateTween();
tween.TweenMethod(Callable.From<float>(SetOutlineThickness), 3.0f, 6.0f, 0.08f);
}
private void OnMouseExited()
{
var tween = CreateTween();
tween.TweenMethod(Callable.From<float>(SetOutlineThickness), 6.0f, 3.0f, 0.08f);
}
private void SetOutlineThickness(float thickness)
{
_canvasGroup.Material.Set("shader_parameter/line_thickness", thickness);
}
private void Open()
{
_animationPlayer.Play("open");
InputPickable = false;
}
}
}
```20Jun. 19, 2024
Click starting outside the balloon but releasing inside it still works.GrahamIn the instructions for L5.P2, you say this:
> This is useful for cases like pressing confirmation buttons: you generally don't want to confirm an action if the player clicks and drags the mouse outside the button area before releasing it.
This made me think to try - what if i clicked and dragged the mouse from outside the balloon into the balloon then released it, what would stop it from popping? The answer of course is, *nothing*.
My default logic would be to check when the mouse enters the Area2D if the mouse button left is already being pressed, and if so, don't do anything else. Would that be the best way to go about that?30May. 01, 2024
Exercise 2 - Cannot call method 'queue_free' on a null valueNekrysWhen I tested this on the BallonPop node alone, it works like a charm, the balloon only 'pops' when I release the button.
Issue is that when I run the code on the main scene (PopTheBalloon) it gives me the title error!
here is a copy of the code:
```gdscript
extends Area2D
@onready var canvas_group: CanvasGroup = $CanvasGroup
func _input_event(viewport: Node, event: InputEvent, shape_index: int):
var event_is_mouse_release: bool = (
event is InputEventMouseButton
and event.button_index == MOUSE_BUTTON_LEFT and
event.is_released()
)
if event_is_mouse_release:
canvas_group.queue_free()
```30Apr. 27, 2024
_input_event() on own projectsHermundureAs an example, if I would like in an Old-School-RPG (like Dungeon Master) want to open the inventory of a character after klicking on his portrait in the main screen, would I use _input_event() for such a task or is the lesson about _input_event() more of a middle point to learning another concept of achieving likeminded tasks?20Apr. 19, 2024
Why no mouse_click event?AlainThere is a `mouse_entered` and a `mouse_exited`, is there a specific reason why there is no `mouse_click` event?
It would be a nice shortcut to the conditional checking code that we have to put in `input_event``10Apr. 17, 2024
Why use AnimationPlayer = $AnimationPlayerkooky-seahorseJust checking if there's a reason we use
*animation_player: AnimationPlayer = $AnimationPlayer*
because when dragging animation player from the scene tree it inputs as
*animation_player: $AnimationPlayer*
- this is also consistent with the previous @onready we made for the canvas_group so wasn't sure if it was a best practice thing or if its needed to make the code work.10Apr. 11, 2024
Ballon Pop PracticeAJ StudiosI was able to pass the practice however the ballon won't disappear when I click on it. I checked the practice solution and the script is the same as mine. So the green checkmarks are present but the ballon node won't be freed. 70Apr. 04, 2024
Combining boolean expressions in variablesRaspiI wonder, when executing and assigning a var an expression like that, when you call the variable, when is this evaluated? Only during the variable assignment or every time is called?
```javascript
var event_is_mouse_click: bool = (
event is InputEventMouseButton and
event.button_index == MOUSE_BUTTON_LEFT and
event.is_pressed()
)
```
I imagine the result in assigned and not re-evaluated in every check, right? If I want to re-evaluate that I'd have to move thins into a method. Is that right?10Apr. 01, 2024
Possible typo?MartinBCould just be me, sometimes I have trouble reading things but there's a part just after adding the input event function. It says this:
*Godot call the `_input_event()` function whenever:*
Is it 'Godot **calls...'** instead?10Mar. 30, 2024
Can't use current_animation == "open" to prevent chest animationGurkI tried using the current animation property to test if the animation does not play when clicked, but it did play again.
It seems the current_animation property only gets the "open" value during the playing duration, before and after it will stay with an empty string. It seems that this condition will not prevent the chest from opening again, but prevent the open animation during its play.
Reading the documentation it seems there is another possibility, I had to use the property "assigned_animation" that gets the last played animation.
```gdscript
func open() :
if(animation_player.assigned_animation != "open"):
animation_player.play("open")
```30Mar. 23, 2024
Lesson Q&A
Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.