Hi, Im currently making a simple 2d game for my school project, and recently I decided to add animated textures to some stuff, and I have been wandering if there is a way to animate my CollisionShape2D to match current frame of my AnimatedSprite2D.
In theory I could set a timer for frame changes (every frame is exactly 0.25 seconds for me) and make a signal to function that would cycle different collision shapes (turning all, but the necessary one off), but I think if animation starts from any frame but first (or 0th as you will), my hitboxes will break, as I am not making an instance of animated sprite, but just having it spawn randomly on my map
Personally I try to limit myself to single collision shapes for animated sprites, with the only exception being when some of my actors change modes (e.g. my octopus boss goes from floating mode to spinning mode) I give them a collision shape for each mode and then disable the shapes accordingly.
That said, I try to stick to rectangles wherever possible, and I guess because the shapes are roughly aligned with my actor’s central masses, they tend to work across the sprites’ various frames.
However, each collision shape I use tends to need testing against all the relevant collisions it interacts with, so the more shapes I give an actor, the more effort it is to test it.
If your game needs precision, or if the frames are significantly different from each other, then you could have shapes for the different frames and enable them accordingly, possibly listening to the frame_changed signal. I guess an alternative would be to change the shape’s dimensions and position, once again by listening to frame_changed, or maybe using an AnimationPlayer, but that sounds like a lot of work.
Keen to hear others thoughts on this, though, as it’d be good to know what’s a normal approach to changing collision shapes.
If I understand correctly, your Area2D has 8 CollisionPolygon2Ds, and you’re using the current frame to copy the polygons from 1-7 into.
Based on your current approach, I’d be tempted to ditch the polygon copy, and instead have a loop, disabling all the polygons except for the one related to the current frame, along these lines:
var frame_count = ...
for x in frame_count:
get_node("$Area2D/hitbox_" + str(x)).disabled = (x != C_frame)
I’d probably then swap out those get_node calls, instead using something like _ready to store those nodes in an array, and then reference the array in the above for loop.
The key advantage would be the code would be resilient to changes in the frame count.