Hey so I’ve satrted working on my first game, been stuck on this for over a week and google/godot docs didn’t have a solution that seemed relevant
The game is about a cat stealing food. The Aim and launch of the character is like in angry birds and the cat gets stuck to the wall/platform before launching again.
I want to make my CharacterBody2D fall through the platforms when it moves, so I’ve tried to make so once the cat jumps, the platforms disappear
But the issue is: to try and do this, I found that even regarding of my script, if I change the layers/masks in the inspector, the cat STILL bumps into the platforms (platforms are on layer 2, Cat on mask 3 and layer 1)
Which according to everyone I talked to is supposed to work?
I found this issue (#65193):
This bug seemed like it might be it, but even if I change both the source and the node in the main game scene, the masks still don’t work and the Cat collides with the platforms regardless.
Anyone got any idea what this could be?
(adding The script of the Cat/Player, in case it might be the thing causing the issue)
extends CharacterBody2D
@onready var game: Node2D = $".."
@onready var timer_aim_delay: Timer = $Timer_aim_delay
@onready var background: StaticBody2D = $"../Background"
var speed = 9000
var click_position = Vector2()
var target_position = Vector2()
func _physics_process(delta: float) -> void:
if Input.is_action_just_released("AimCat"):
click_position = get_global_mouse_position()
if position.distance_to(click_position) > 3:
target_position = (position - click_position).normalized()
velocity = target_position * speed
move_and_collide(velocity * delta)
func _Input(event : InputEvent):
if (event.is_action_released("AimCat") && is_on_floor()):
set_collision_mask_value(2, false)
timer_aim_delay.start()
func _on_timer_aim_delay_timeout() -> void:
set_collision_mask_value(2, true)
what mask are the platforms on? and what time is the timer set for? try setting it to a minute and see what happens, it could just be timing out faster than expected. There might also be more going on, would you be okay with sending a screenshot of your scene tree?
I’m having trouble understanding what you’re trying to accomplish. Your code turns the collision mask off when you shoot the cat. It then goes on when the timer expires. Based on what you’re describing, your issue seems like a feature, not a bug, based on how you coded it.
I’m curious how long your timer is set for, but whatever it is, you’re going to have have problems. If I shoot the cat at the floor, the timer isn’t going to expire fast enough and the cat is going to go through the floor. The amount of time that the cat takes to hit its target is variable.
I’d recommend you just make them both AreaBody2Ds and connect the collision code. If the cat is passing through the bottom, let it, if it’s coming from the bottom, stop its progress. That way you’re not relying on something you cannot control, which is time.
(sorry for late reply, been feeling sick last couple of days)
To clarify my intention:
What I want to do is to have the player move down through the platforms
I tried to use the timer to delay the movement, so that the player won’t get stuck. But for some reason even when I turn off mask 2 for the player, it fails to pass through them (which I understand is just not something that’s suppose to happen in godot?)
And yeah, I considered using area2d, I just ran into another problem because area2d does not allow one-side collisions (which I want, like having the cat jump on top of the counter/cabinet and then drop down through it.
I placed the floor as another node and on layer 3 (player is on mask 3)
I will try some checks following what you suggested when I’m feeling a bit better, thanks
these are the layers:
layer 1: player
layer 2: background (the platforms: furniture, countertop, bed, etc)
layer 3: game boarders (ceiling, floor, walls)
I’m not even sure the issue is in the script, because the player still bumps into in the platforms when the player’s mask2 is off
@ninetailsrabbit in reading the Godot Documentation for 3 and 4, what you said was true in 3 with set_collision_layer_bit(), but in 4, set_collision_layer_value() does away with that ambiguity, and @nevuereuven is using it correctly.
There’s another way you could do this that might work:
Add a second Area2D node to your cat and enable only mask 5 (or another layer you haven’t used.) Add a second collision detection node to it.
Add your ground to layer 5.
Disable the first collision detection node on your cat.
Connect the on_body_entered signal from the Area2D and turn collision detection back on for the first collision detection node.
This way you will be sure to turn it on and off at the right time, but you don’t have to change the value - which seems to be the issue you’re experiencing.
I do this in 3D with the animation player so that weapons only damage an enemy when they are being swung, and the player can’t damage things just because they’re walking around with their weapon out.
Okay, so I tried, but so far it showed no change (as in, the cat does not move down through the platforms)
What I did was add an Area2D called “collision_masker”, add the On_body_entered signal to try and get it to work, nothing really changed though
I am new to coding in general, so I’m obviously missing something
this is the new code:
extends CharacterBody2D
@onready var game: Node2D = $".."
@onready var timer_aim_delay: Timer = $Timer_aim_delay
@onready var background: StaticBody2D = $"../Background"
@onready var collision_masker: Area2D = $Collision_masker
var speed = 12000
var click_position = Vector2()
var target_position = Vector2()
func _physics_process(delta: float) -> void:
if Input.is_action_just_released("AimCat"):
click_position = get_global_mouse_position()
if position.distance_to(click_position) > 3:
target_position = (position - click_position).normalized()
velocity = target_position * speed
move_and_collide(velocity * delta)
func _on_collision_masker_body_entered(body: Node2D) -> void:
set_collision_mask_value(2, false)
func _Input(event : InputEvent):
if (event.is_action_released("AimCat") && is_on_floor()):
timer_aim_delay.start()
func _on_timer_aim_delay_timeout() -> void:
set_collision_mask_value(2, true)
Is it possible for you to put your project up on GitHub, or provide a zipfile of the project through cloud storage like Google Drive? It’d be easier to take a look at the whole project at this point and try a few things.
So turns out I was using “Visibility” layers and mask and not the “Collision” ones. (there were a bunch of other problems as well obviously)
I knew I was missing something stupidly basic
Awesome! Glad you figured it out! Layers and masks are confusing no matter how long you’ve been programming, trust me. What we pay for in confusion, we get back in performance. All layer and mask detection is done by our GPU, which means that the average video card can handle literally millions of collisions per second.