|
|
|
 |
Reply From: |
timothybrentwood |
You want your structure to be:
Area2D
>Camera2D
>CanvasLayer
By limit do you mean the limit
properties of the camera e.g. left_limit
? If that’s the case, you need to bound your level area with some kind of collision object so the Area2D
can’t go any further once it hits the bounds.
Yeah, I mean those limits. What would be the best way to prevent the area from going somewhere? By code?
If you’re randomly generating your levels you’re going to need to instance them using code. If you’re designing them in the editor I would either use Area2D
s or StaticBody2D
s.
timothybrentwood | 2021-05-12 22:06
I’ve tried connecting a KinematicBody2D to my player character to serve as the camera’s hitbox, and as a parent for all the camera stuff. Problem is, the kinematicbody just moves through StaticBodies because it wants to stay with its parent, the player character, no matter what.
I’m probably supposed to have the Area2D collide with the StaticBodies, but I have no clue how…
Your structure should be:
Player (KinematicBody2D)
>CollisionShape2D
>Camera2D
>CanvasLayer2D
The camera’s extents should be limited by the limit
properties. If you’re using a TileMap
for a background this code will set those for you, just pass it a TileMap
:
Camera2D.gd
...
func set_extents(tile_map:TileMap) -> void:
var tile_rect = tile_map.get_used_rect()
var cell_size = tile_map.cell_size
limit_left = tile_rect.position.x * cell_size.x
limit_top = tile_rect.position.y * cell_size.y
limit_right = tile_rect.end.x * cell_size.x
limit_bottom = tile_rect.end.y * cell_size.y
Otherwise, you can hard-code the values into that function that suit your level - or set them via the Editor.
The Player collision_layer
is set to like Layer 1
and collision_mask
is set to like Layer 2
, and the opposite for your StaticBody2D
s. You want the StaticBody2D
s to have their collision_layer
as Layer 2
and their collision_mask
as Layer 1
. This allows them to “see” each other in order to collide with each other.
Think of the collision_layer
as the “I am a Layer 1” and the collision_mask
as “I am looking to collide with a Layer 2”
timothybrentwood | 2021-05-13 14:00
I understand collision layers and masks, I just don’t understand how to prevent an Area2D from going somewhere. I’ll try to explain my problem with a little more detail:
There is a Camera2D connected to my player. There’s also an Area2D, connected to the Camera2D. This Area needs to always be where the camera is, even when hitting the camera’s limits. Currently, when the Camera2D hits a limit, the Area2D just keeps moving, but I want it to stop at the camera’s limit.
I’m sorry if I’m just being really dumb and confusing right now, heh.
Umm it really depends on your game… Like does this Area2D
actually collide with anything? What’s the purpose of it? And how does it move?
You could make the Area2D
only collide with the boundaries of your level then check get_overlapping_bodies().empty()
in the _physics_process()
before moving the Area2D
. You could also make a RayCast2D
as a child of the Area2D
that performs the same task I laid out above if you need to check collisions of other things with that Area2d
. Outside of that, I would need more information about the Area2D
to offer you a better solution.
timothybrentwood | 2021-05-14 02:23
I am using an Area2D so I can accurately know when certain stuff is on screen / is in range of my player (I am making a 2D platformer). But currently, when an object is to the right of the screen and the camera hits a left limit, the object thinks it’s off screen. I suppose both the raycast and get_overlapping_bodies().empty() may work, but I don’t know how I’d prevent the Area from moving then.
I might just be overcomplicating stuff though.
Also, I’m sorry for the late reply.
You are over-complicating things, that’s why I asked for clarification. It’s perfectly fine though! 
There’s a VisibilityNotifier2D
node that’s built exactly for that purpose. They emit the screen_exited
, screen_entered
, signals when they show on/exit from screen. Attach those nodes as children of your objects that you need to be notified of when they enter screen, connect the signals and you now know when those objects are on screen. Here’s a quick demo on how to use it: https://youtu.be/WEt2JHEe-do?t=1714
The Area2D
should just be a child of the Player - it will move along side the player and act as another collision shape for the player. Disable it from colliding with terrain and it can act as a pickup radius.
timothybrentwood | 2021-05-15 17:12
Oh, I probably should have mentioned this before, the visibility notifiers weren’t always accurate. I tried looking online for solutions but the only thing I could find was on the documentation site (https://docs.godotengine.org/en/stable/classes/class_visibilitynotifier2d.html):
Note: For performance reasons, VisibilityNotifier2D uses an approximate heuristic with precision determined by ProjectSettings.world/2d/cell_size. If you need precise visibility checking, use another method such as adding an Area2D node as a child of a Camera2D node.
And now I’m having this issue.