This is a weird one. To emulate the behavior of the game I'm remaking, the collision of the sprites should be snapped to a 8x8 grid. I can in fact do that, but as soon as I try to move towards anything solid, since the sprite and collision are misaligned, it glitches out. I also tried making a child StaticBody2D and making that its general collision, but since I also want those sprites to collide with copies of themselves, the collision layers and masks end up detecting the sprites themselves, making a whole new issue. What should I do?
#Is it even possible to snap the position of a CollisionShape2D separated from its parent?
1 messages · Page 1 of 1 (latest)
Make the collision and sprites independent of each other?
Yeah!
I'm currently retrying the StaticBody method and it kinda works but also when I move towards a clone of the scene I'm moving or anything with those same properties, it seems to push them around when I should stop in place instead
If it moves why are you using a static body
The staticbody seems to move with the sprite but it does not interfere with the sprite's movement when it's colliding, different from altering the sprite's own collision, at least not in the way I was trying to do
Here, let me show you
Doing it directly:
You probably shouldn't be moving those static bodies
What about AnimatableBody2D
Or characterbody2d actually
Doing with staticbody:
I'm not sure how you have the scene set up
You can see for a brief moment that the player pushes the enemy around
But if the physics bodies are children of the sprites it probably won't work
I think you want to use characterbodies instead
i could try
Just tried and yeah, it still pushes the enemy :c maybe i could use a test_body to see if its colliding and stop any attempts to move if it is?
I don't know without any code
Because staticbodies do not move by default, and neither do characterbodies
For the player itself, I do this right below move_and_slide
move_and_slide()
var target_position = global_position.snapped(Vector2(8,8)) + Vector2(8,8)
body_collision.global_position = target_position```
I use body_collision for its own collisionshape, and static_collision for the Static/CharacterBody. but even if I don't have that logic, both seem to follow the player just fine
So the player isn't a physics node?
What node is it?
Is the physics body a child of the player?
No no the player is a characterbody
Well, setting the global position directly kinda negates using move and slide
Hmm I see
I don't think the Godot physics engine is meant to be used for nodes that move in 8 pixel increments
Would it help if I showed you the behavior I want to mimic?
sure
Hold on let me record
Here, you can see the player (Yellow) gets stopped by the enemy when it tries to move behind it. I tried to look for ways of showing hitboxes on this game but found none so that's all there is to show unfortunately
Sorry I don't really see it
This leads me to believe the collision is snapped because you can see how it stops every 8x8 tile
Right when both are on the top of the screen
the enemy moves fine but the player doesn't
It's fine
Wait I think I have a workaround
I could set a Tileset layer with small 8x8 tiles that are area2Ds with static2d childs. and once the enemy enters the area2d, it turns on the layer which the player collides and disables it when it leaves, and same for the player
Idk how I would do it for player-player interaction or enemy-enemy BUT this seems to be a solid plan overall
Not sure how you disable an entire layer
Like, the tileset tiles all have collision shapes that belong to a physics layer right?
so if you change the physics layer you change all the other tiles that share the physics layer
I was thinking of using scene tiles for this one
okay 👍
and then trigger set_collision_layer_value once needed
I'll still leave this open in case that there's anyone out there with a better solution
WAIT
what if i set a raycast in front of the player that, if it detects another player or an enemy, it stops the player until enough space is freed
that works too
Awesome, I'll test that out
So here's the setup, I have one raycast that detects if there's anything relevant right in front of the player, and if there is, it stops all forward movement until the raycast is no longer touching anything
it works flawlessly but i would also need a way to snap its position
i used raycast.global_position = snapped(floating_position, Vector2(8, 8)) and despite working, since it rounds anything below 4 to 0 and anything above 4 to 8, the snapping occurs before the player gets to move 8 full pixels
other than that yeah i call this a win
i also have a different setup with 2 raycasts, one that detects immediate collision and another that detects the distance of what its colliding with, that one works too but it's not consistent