Looks like you're not logged in

Login or Register to continue

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.

  • This one was a bit toughmiserly-dugongYesterday I happily said I finally understood setter functions! but today was a tough reality check. I know nothing! But I think I get it a little more now. Hopefully I won't bite my own words tomorrow again... 1 0 Feb. 20, 2025
  • typo in func collect_item()CGQQLI think you want: ```gdscript var is_audio_longer := _audio_stream_player.stream.get_length() > _animation_player.get_current_animation_length() ``` not ```gdscript var is_audio_longer := _audio_stream_player.stream.get_length() > _animation_player.current_animation.length() ``` in func collect_item(). current_animation.length() returns the length of the string of the animation name. 1 0 Feb. 15, 2025
  • why do you set item 2 times?silent-meerkatwhy do we do item = value in the set_item func and then set_item(item) in _ready? dosnt it do the same thing? dosnt it just set value as item and then back item as value? 1 0 Feb. 15, 2025
  • body_entered not workingoliver_gzzHey there, it seems that I got stuck in the most simple thing: the body_entered signal, I've reduced the code in the PickUp scene to see if nothing was messing with the signal, but still, is not working when the player is touching the pickup element. here's the code: **`@tool`** **`class_name PickUp extends Area2D`** **`@export var item: Item = null: set = set_item`** **`@onready var _pickup_sprite : Sprite2D = %Sprite2D`** **`@onready var _sound_player : AudioStreamPlayer2D = %AudioStreamPlayer2D`** **`# Called when the node enters the scene tree for the first time.`** **`func _ready():`** **` set_item(item)`** **` body_entered.connect(func(body: Node2D):`** **` if body is Player:`** **` print("touching element")`** **` )`** **`func set_item(value:Item):`** **` item = value`** **` if _pickup_sprite != null:`** **` _pickup_sprite.texture = item.texture`** **` if _sound_player != null:`** **` _sound_player.stream = item.sound_on_pickup`** 1 0 Feb. 11, 2025
  • Is it possible to put a particle effect in a resource?EndeiosI tried to add a GPUParticles2D to the item, but I got that `Parse Error: Node export is only supported in Node-derived classes, but the current class inherits "Resource".` So i just put the color for the time being :) Is it at all possible to put a particle effect in a resource? Or it is just a good idea to keep it in the pick up? Or should I just get the "interesting" values from the resource as strings or numbers and apply them on _ready? ```gdscript class_name Item extends Resource ## Texture to display for this item @export var texture:Texture2D = null ## Color to use for particles @export var color:Color = Color.WHITE ## Sound to play on pickup @export var pick_up_sound:AudioStream = null func use(player:Player)->void: pass ``` ```gdscript class_name HealingItem extends Item @export var healing_amount:int = 0 func use(player:Player)->void: player.health +=healing_amount ``` ```gdscript @tool class_name PickUp extends Area2D @export var item:Item = null @onready var sprite: Sprite2D = %Sprite @onready var collision_area: CollisionShape2D = %CollisionArea @onready var audio_player: AudioStreamPlayer = %AudioPlayer @onready var animation_player: AnimationPlayer = %AnimationPlayer @onready var particles: GPUParticles2D = %Particles var _picked_up : bool = false # Called when the node enters the scene tree for the first time. func _ready() -> void: if item != null: sprite.texture = item.texture particles.modulate = item.color play_floating_animation() if Engine.is_editor_hint(): return body_entered.connect(pick_up_item) func pick_up_item(entered:Node): if entered is not Player: return if not _picked_up: _picked_up = true item.use(entered) audio_player.stream = item.pick_up_sound audio_player.play() animation_player.play("wobble") var tween := create_tween() tween.tween_property(sprite, "modulate:a", 0, 1.0 ) set_deferred("monitoring",false) particles.emitting = true particles.one_shot = true audio_player.finished.connect(func (): queue_free() ) # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: update_configuration_warnings() if Engine.is_editor_hint(): return func _get_configuration_warnings() -> PackedStringArray: var warnings :Array[String]=[] if item == null: warnings.append("You need to specify an item resource") return warnings func play_floating_animation() -> void: var position_offset := Vector2(0, 4) var animation_duration := randf_range(0.5,1.5) var tween := create_tween() tween.set_trans(Tween.TRANS_SINE) tween.tween_property(sprite, "position", position_offset, animation_duration) tween.tween_property(sprite, "position", -1 * position_offset, animation_duration) tween.set_loops() ``` 2 0 Feb. 10, 2025
  • Invalid assignment of property or key 'texture' with value of type 'CompressedTexture2D' ....SpookyDoomSo my script ended up pretty close to the reference one but I ultimately ended up having one error on starting the game I could not figure out why it happened. The setter function in my `pickup.gd`file looked like this: ```gdscript func set_item_type(new_item : Item) -> void: item_type = new_item if Engine.is_editor_hint(): update_configuration_warnings() if new_item.item_texture != null: # set the new item texture item_sprite.texture = new_item.item_texture # ... rest of code ``` My idea was that `if new_item.item_texture != null` should check if the resource actually has a texture assigned in the first place before assigning anything to the sprite texture (same for the AudioStream). On starting the game I get this error, though: > *Invalid assignment of property or key 'texture' with value of type 'CompressedTexture2D' on a base object of type 'Nil'.* You, on the other hand, simply check if there is an ItemSprite and an AudioStream to assign something to, right? Why do I get that error and why do you check only for the existence of the destination nodes instead? 1 0 Feb. 07, 2025
  • my solutions, not sure about setterSootyAfter seeing the solution at the end of the lesson, why is the setter used? the pickup is setup and you assign a sprite, sound etc in the main game scene so its not going to change via code? is this simply for displaying the item in editor with the @tool function? This was my code which didn't use the setter class_name Pickup extends Area2D @export var item : Item = null @onready var sprite_2d: Sprite2D = %Sprite2D @onready var audio_stream_player_2d: AudioStreamPlayer2D = %AudioStreamPlayer2D func _ready() -> void: sprite_2d.texture = item.texture audio_stream_player_2d.stream = item.item_pickup_sound body_entered.connect(func(body : Player)-> void: if body is Player: item.use(body) audio_stream_player_2d.play() set_deferred("monitoring", false) audio_stream_player_2d.finished.connect(func() -> void: queue_free() ) ) 1 0 Feb. 05, 2025
  • My code + questionsmilk_manHere is my code item.gd: ```gdscript class_name Item extends Resource @export var texture: Texture2D @export var sound: AudioStream # virtual function, exists to be overridden func use(player: Player) -> bool: return true ``` healing_item.gd: ```gdscript class_name HealingItem extends Item @export var healing_amount := 1 func use(player: Player) -> bool: var is_health_full: bool = false if player.current_health == player.max_health: is_health_full = true return is_health_full player.current_health += healing_amount return is_health_full ``` pickup.gd: ```gdscript @tool class_name Pickup extends Area2D @export var item: Item: set = set_item @onready var _sprite: Sprite2D = %Sprite2D @onready var _audio: AudioStreamPlayer2D = %AudioStreamPlayer2D var tween: Tween func _ready() -> void: if Engine.is_editor_hint(): return set_item(item) play_floating_animation() body_entered.connect(func(body_that_entered: Node2D) -> void: if body_that_entered is Player: # check if player health is full, if not, run code if item.use(body_that_entered) == false: _audio.play() if tween != null: tween.kill() play_disappearing_animation() # another way of handling playing audio and queue_free, different with bullets set_deferred("monitoring", false) await _audio.finished queue_free() ) func set_item(value: Item) -> void: item = value if _sprite != null: _sprite.texture = item.texture if _audio != null: _audio.stream = item.sound func play_floating_animation() -> void: tween = create_tween().set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE) var duration := randf_range(0.8 , 1.2) tween.set_loops() tween.tween_property(_sprite, "position:y", -15, duration) tween.tween_property(_sprite, "position:y", 0, duration) func play_disappearing_animation() -> void: tween = create_tween().set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_SINE) tween.tween_property(_sprite, "scale", Vector2.ZERO, 0.3) ``` I used tweens for the animation instead of AnimationPlayer, bc I thought the animations were simple enough. Also I changed the use() function signature to return a bool and also check within the function if player current health is equal to max health. If it is, the function returns false, thus the player is unable to pickup the item. Now here are my questions: - Is the way I implemented the logic (to prevent the player from picking up the healing item if is current health is equal to max health) good enough? How would you do it? I thought about emitting a signal, but it just wouldn't work. Also thought of checking player current health with max health within the pickup script instead, but that would in turn make the pickup scene less scalable, for example if we were to use a Speed Item - Now bc in my script, the function `use()` now returns a bool, I was afraid that I couldn't just call the function anymore, that I had to store or do something with the returned value, but to my surprise you can still just call `item.use(body_that_entered)` no problem. I used to program a bit in C, and if I remember correctly (could be wrong), that if a function wasn't void, you couldn't just call it, you had to do something with the returned value. Does Gdscript differ in that regard? - Last question. the item variable is of type **Item**, but can still accept objects of type **HealingItem**. And if we do assign a HealingItem object, we have access to properties shared by both Item and HealingItem. What confuses me is the following, our item variable can't access the healing_amount property of HealingItem, which makes sense, but we can access the overriden use() function from HealingItem? How does that work? 4 0 Feb. 04, 2025
  • Suggestion: Scene SetupNeepersCan you please also provide the scene set up? I am confused on whether I should be setting up the pickup item directly in the item scene or if I should be adding the pickup scene to my main game scene and setting it there? 1 0 Jan. 31, 2025
  • Resources, a bit confusingPurpleSunriseHello, I still don't understand resources quite well. I managed to make everything work but I want to make sure I got the meaning of using resources right. First my code: ```gdscript @tool class_name Pickup extends Area2D @export var item : Item = null : set = set_item @onready var sprite_2d: Sprite2D = %Sprite2D @onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer # Called when the node enters the scene tree for the first time. func _ready() -> void: set_item(item) if Engine.is_editor_hint(): return body_entered.connect(func(body : Node)->void: if body is Player: item.use(body) set_deferred("monitoring", false) audio_stream_player.play() var tween := create_tween() tween.tween_property(sprite_2d,"scale", Vector2(0,0), 0.3) await audio_stream_player.finished queue_free() ) # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(_delta: float) -> void: pass func set_item(pickup : Item)->void: item = pickup if sprite_2d != null: sprite_2d.texture = item.display_image if audio_stream_player != null: audio_stream_player.stream = item.pickup_sound ``` I created a pickup scene. This pickup item could be anything right? It could be a speed boost, a healing item, a power up. You can chose what type of item it will be from the dropdown menu in the inspector, and so far I think I got it. I make a resource that extends from the blueprint Item resource and override the `use()` function and give that pickup properties like speed boost amount, power boost amount etc. In other words, Item resource is just a blueprint that I will never use on a pickup, I would use resources created from that blueprint. And any pickup type resource extends from that blueprint and can have new functions, properties etc. Then you can put a bunch of pickup items in the scene and you can set the type of pickup for each item choosing the resource from the dropdown menu. Then you need to set up each pickup's texture and sound and other properties (unless you don't duplicate an already set one i guess?). But since every items runs from one script, all the items have to be have functions in common to work as it is now. For example all pickups have to have a use() function for example? Or does it mean that in that pickup script, once I have many items, I'll have to check if an item is a certain type and them call certain functions specific for that item? Also, in this case, since I know that more or less all the audio length are longer than the animation of disappearing I just wait the audio to finish before freeing the item, but I guess if I had a large amount of item, it would be better to check both the animation and the audio to be finished before freeing the item? I also tried to use to @tool annotation to update the sprite in the editor, but I had to reload the scene every time to make it update. Is it normal or maybe I set something wrong? Lastly, something about monitoring and monitorable. Monitoring basically means that the area2d detects things and run signals like body_entered etc. Monitorable means that let other physics objects to detect the area and run signals they have in the script? Sorry for the poor explanation but I hope it makes sense. I am sorry for the very long confused questions, I hope I can get some help with this because it looks like such a powerful tool I would like to learn how to use! I think I am almost there but I need to understand the purpose a bit more! thank you! 7 0 Jan. 26, 2025
  • no sound is played when I collect my itemsPixAngelAll is in the title. I still have the same code as you : ```gdscript func set_item(value : Item): item = value if sprite_2d != null and item != null: sprite_2d.texture = item.texture if audio_stream_player_2d != null: audio_stream_player_2d.stream = item.so ``` I added in my func _ready connection : ```gdscript body_entered.connect(func(body : Node) -> void: if body is Player: item.use(body) audio_stream_player_2d.play() queue_free() ) ``` Did i miss something? 8 0 Jan. 16, 2025
  • How can I make the sprite change in the editor?DMKAs in your questions and troubleshooting, even if you change the texture property of the healing item, it will not be changed in the editor. But creating a setter function in the HealingItem script is impossible, so how should I go about doing this? 1 0 Jan. 15, 2025
  • Found a typoDMK> For a single kind of item, for example, if you exclusively make healing items in your game, **exploring** properties like which image... exploring -> exporting Also, a space is missing in: > Notice how the `use()` function is [empty]() in the base `Item` resource. This is because the base item resource only defines a generic **[type](https://school.gdquest.com/glossary/type)and.....** 1 0 Jan. 15, 2025
  • Challenge idea: consume health items only when they actually heal the playerHardRockWith a minor modification to the `use()` function (there are probably other ways as well) this is an easy change to make and adds a bit of extra quality of life for the player, since they won't have to avoid healing items when they are at max HP. 1 0 Jan. 05, 2025
  • Crash due to animationram876Hello! I've encountered an error that I don't understand. I added an idle animation for the pickup sprite. If you add pickup to the level, then everything works fine. But after restarting, the editor crashes if you switch to this scene. I realized that the problem with enabling animation was only after much trial and error. When running from the command line, it outputs the following information: ```gdscript CrashHandlerException: Program crashed with signal 11 Engine version: Godot Engine v4.3.stable.official (77dcf97d82cbfe4e4615475fa52ca03da645dbd8) Dumping the backtrace. Please include this when reporting the bug to the project developer. [1] error(-1): no debug info in PE/COFF executable [2] error(-1): no debug info in PE/COFF executable [3] error(-1): no debug info in PE/COFF executable [4] error(-1): no debug info in PE/COFF executable [5] error(-1): no debug info in PE/COFF executable [6] error(-1): no debug info in PE/COFF executable [7] error(-1): no debug info in PE/COFF executable [8] error(-1): no debug info in PE/COFF executable [9] error(-1): no debug info in PE/COFF executable [10] error(-1): no debug info in PE/COFF executable [11] error(-1): no debug info in PE/COFF executable [12] error(-1): no debug info in PE/COFF executable [13] error(-1): no debug info in PE/COFF executable [14] error(-1): no debug info in PE/COFF executable [15] error(-1): no debug info in PE/COFF executable [16] error(-1): no debug info in PE/COFF executable [17] error(-1): no debug info in PE/COFF executable [18] error(-1): no debug info in PE/COFF executable [19] error(-1): no debug info in PE/COFF executable -- END OF BACKTRACE -- ``` And sometimes, after several restarts, the scene starts, but the idle animation does not start, and the following message is constantly printed on the command line: ```gdscript ERROR: Condition "!has_animation(p_name)" is true. at: make_animation_instance (scene/animation/animation_mixer.cpp:1909) ``` My pickup script is almost identical to yours. 4 0 Dec. 31, 2024
  • Bullet Boosterram876Hello! I couldn't figure out how to make a booster that increases the damage for bullets. Bullets are created dynamically on the stage and I do not know how to write the use() function in this case. I tried writing `var bullet :=player.get_node("WeaponPivot/WeaponAnchor/Weapon")` in the booster. And storing the bullet in a variable in weapon. But I couldn't get this variable in the booster. What should I do in these situations? 5 0 Dec. 30, 2024
  • Something odd about the example provided in the lessonCptnNuggetsHi there, a question related to your example about the use of ressources. You propose this code : ```gdscript class_name Pickup extends Area2D @export var item: SpeedItem = null ``` But that means constraining the item variable to the SpeedItem class. Doesn't that goes against the design pattern you propose ? Shouldn't it be this instead : ```gdscript class_name Pickup extends Area2D @export var item: Ressource = null ``` I'm curious if I misunderstood something or if it's just a typo ? Furthermore, to enhance readability (for me, not saying it's better ^^ just the way my mind works), would the following be possible ? Create a class "Item extends Ressource" which would implement properties and functions shared between all items (ie, in your example, use() and display_image) with properties set to null and functions to "pass". Then, for each item type, the class would extend the "Item" class instead of the general "Ressource" one, and overload the functions as needed ? Would this be a valid approach ? Would there be drawbacks ? The 2 adantages I see are that this Item class would inform on necessary functions/properties when creating a new Item further down the line, plus the Pickup class would then be more readable like this : ```gdscript class_name Pickup extends Area2D @export var item: Item = null ``` 4 0 Dec. 20, 2024
  • Did you used the set_deferred() in pickup script, because the monitoring property is related to physics/collision?◆ LPI was confused because we didn't use anything in the _physics_process() here. But it did helped in stopping the player character from unintentional healing because it could keep entering the pickup's area while the pickup audio is playing. 4 0 Dec. 18, 2024
  • Update texture in editor via @toolKetan```gdscript @tool extends Area2D class_name Pickup @export var item: Item = null: set = set_item @onready var sprite_2d: Sprite2D = $Sprite2D @onready var audio_stream_player: AudioStreamPlayer = $AudioStreamPlayer ``` ```gdscript func _ready() -> void: set_item(item) body_entered.connect(func(body: Node2D) -> void: if body is Player: set_deferred("monitoring", false) item.use(body) queue_free()) func set_item(value: Item) -> void: item = value if sprite_2d != null: sprite_2d.texture = item.texture if audio_stream_player != null: audio_stream_player.stream = item.pickup_sound ``` 9 0 Dec. 17, 2024
  • @onready variables being nullnasty-beeSomething strange just happened to me. Although my scene, script and resources were setup correctly (I double checked and even compared to the solution), Godot gave me an error ("invalid access to property or key 'texture' on a base object of type 'Nil'). I know this means that the @onready variable wasn't referring properly to the sprite, but I could not figure out what the issue was. I ended up restarting the engine, and somehow the issue just fixed itself! The script that was giving me an error before the restart was now working perfectly, without changing anything. This brings me to ask a few questions: 1) I noticed that in your script, you check if the variables are null in the ready function. At first I didn't understand why you would do this since the ready function is supposed to run only when all the children are ready. Is the line added to prevent errors like the one I had or is there another reason? ```gdscript if _sprite_2d != null: _sprite_2d.texture = item.texture if _audio_stream_player != null: _audio_stream_player.stream = item.sound_on_pickup ``` 2) It's not the first time restarting the engine has solved an issue for me. It seems I'm not the only one, as I've seen plenty of people on Reddit suggesting restarting as a solution to encountering a strange bug. This honestly scares me a little. Are my players also going to experience similar issues and need to restart the game, or are these bugs only present while I'm developing the game and playtesting? 2 0 Dec. 15, 2024
  • Using @tool to update the spritePaulI fancied having a go with using `@tool` to get the sprite to update in the editor. I couldn't really remember how this went, and with a bit of looking I determined you have to use a setter function to force the update in the editor. But I was really struggling with the syntax or how to go about actually doing it. I'm thinking you'd need the setter function on the `item` resource (since this is what we are setting the new properties in). Something like: ```gdscript @export var item: Item = null : set = set_item_properties ``` However `item` has a number of properties (`healing_amount`, `item_visual`, `item_sound` in my case as it's the healing item). I couldn't work out how I write a setter function that can take multiple properties, so far I think we've only handled setters on say an `int`, where you know what will be expected. I tried a few things which all just resulted in errors. 9 0 Dec. 14, 2024
  • health bar doesn't update immense-swallowHi, I followed the code, but I'm unsure why my health bar only updates when attacked by the mob but not when picking up items.I feel confused about the Setter function. Could you explain this part in more detail? And is it possible to reduce the time gap between the player's death and reloading the game?Thank you. 2 0 Dec. 10, 2024
  • How to make it so the Healing Pickup resource has pre-defined texture.DargorWith this format, you can set the texture for the Sprite node in the inspector. But how do I make it so that the Healing Pickup always uses the same texture, so that I don't have to choose the texture every time I assign it to the Pickup scene? I tried assigning the texture to a variable inside the Health Pickup script (var image = preload("texture location") and then assigning it to the texture var in the ready function (texture = image) so that the set_item function in the Pickup scene assigns the image, but it doesn't work. 4 0 Dec. 02, 2024
Site is in BETA!found a bug?