I’m using the Bounce Behavior to get the enemies in my top down game to bounce off solid objects and change direction. I have the enemies movement based on an object timer. When the enemy collides with a solid object, no matter what its current Direction variable is, I have it bounce off the solid object and then change its animation to match the new direction of travel, to give the illusion of it quickly turning around and changing direction.
This works most of the time. However, sometimes the enemy will bounce off the solid object without its animation changing, making it look like it is now walking backwards. I’ve tried many different things to figure out what is causing this to happen sometimes, but I’m at a point now where I’m just wasting time and needed to ask on here.
Here is the code for both the movement and bouncing:
Bounce (turn around) code
Can anyone tell me what might be making the enemies bounce off solids and sometimes their animation isn’t changing? Thanks in advance!
You are using RandomInRange to change the directions, which is fine.
I think it’s picking the same number 25% of the time though.
For example, if the direction variable is 3, it might be 3 on the next “bounce”.
You need to make sure it picks another variable if it picks the same number, such as first doing RandomInRange into a variable first.
Ok, is there an easy way to make sure it picks a different variable on the next “bounce”? I can think of a long way to do it, but I figure there is a way with an expression of some sort.
Sorry, no expression comes to mind currently. In the meantime, if your long way doesn’t work, just post it here
Is there a way to get this “bounce” effect without using the Bounce behavior? Every time I try to get the enemy to change its Direction variable when in collision with something, the enemy stops moving and its very finnicky.
if you added “points” to the enemy for each “side” of collision (left, right, top, bottom, etc.), you might be able to use an “is colliding with” condition to reverse a direction
(if (enemy’s left collision point) is in collision with “SolidColliders”, move to the right and set animation to the right)
that might work?
Hatchet_Gamer, I have already tried that idea and while it kind of worked, sometimes the enemy would be moving in a certain direction and its point would miss collision with the SolidColliders, thus making it either pass through the solid object or get stuck on it. It was a good idea, but didn’t work how I expected it to.
However, I might have figured something out last night. I disabled the Bounce behavior and just used the separate objects (enemy and SolidColliders) action. Then, I added an object variable “HasTurned”. When the enemy’s direction is 1, for example, and it’s in collision with SolidColliders while HasTurned=false, I set the boolean HasTurned to true I set the direction to the opposite (2, in this case) and change the animation. That way, HasTurned has to be false for the turnaround to work. I then added Wait 0.2 seconds, then set boolean HasTurned to false. That way, the enemy can now turn around again. What was happening was the enemy was in collision with SolidColliders, and the direction variable was being changed, but it was happening so quickly that the enemy had not yet been OUT OF collision with SolidColliders, so it just appeared to get stuck in its initial direction. So I added the HasTurned variable and set a brief delay to give it time to get out of collision with SolidColliders after turning around, and so far this seems to be working. I’ll test more today and get back to you!
Just guessing because I don’t know if your enemy logic is already inside a For Each loop or how many enemies do you have in the scene, but I had similar problems in the past and I solved them running most of the enemy logic inside a For Each loop.
If your enemy animations works perfectly with just one enemy but it fails when you throw many of them in the scene, then your problem is when two enemies bounce off the platform at the same time just one of them changes the animation. That’s why you need to individually check and change the animation for each one.
I also think all those nested “Trigger once” may be causing a problem.
The nested Trigger Once conditions were needed since I was using permanent forces to control the direction and speed of the enemies. With my new testing, I changed all the enemies that will require an animation change when their direction changes to instant forces, and it has been working much better. Therefore, what I’m doing now isn’t using any nested Trigger Once conditions.
However, with the code screenshot posted above, if I deleted the nested Trigger Once conditions the enemy speed would get faster with each passing frame (again, since it was using permanent forces). That was why they were there.
So far, I have things working pretty well after switching the enemy forces to instant if they’re an enemy whose animation will need to change with their direction variable changing. The only thing I have left to work on is regarding when they’re hit. I have it set up to knock the enemy back when they’re hit but not dead, using a permanent force with a timer. I’m noticing that when the enemy is hit against a SolidCollider object and they’re hit timer has been reset/deleted, they sometimes won’t resume their previous direction of travel (I’m pausing their Movement timer when they’re hit, then unpausing the timer when they’re hit timer is reset/deleted if that makes sense). Rather, they will try to change direction a few times really fast then finally go back to normal. I’ll keep testing this and report back when I have more information or if one of you replies in the meantime. Thank you all so much for the ideas and suggestions thus far. You have all been very helpful, and that is one of the best things (among many great things) that GDevelop has going for it…a great community.
I see, I get your point. Anyways I’ll left here a pair of notes:
This is from another post and it explains why is not recommended to use a trigger once inside a For Each loop:
Also, I recommend to use “Trigger once” just at base level, because nested “Trigger once” sometimes can produce unexpected effects. Maybe you can set a boolean variable to know if an enemy has recently changed direction but it have not been updated. I think is a safer approach.
Thank you for this information. I’ll definitely keep that in mind going forward.