Multiple instances of an object colliding with another object get ignored


#1

If the scene has multiple instances of an object which collide with another object around the same time, with the “Trigger Once” set, then some of the collisions are ignored.

The scene setup:

Here’s the code. NPO has a Tween behaviour attached:

The bevahiour, when the NPO collision with block is quite separate, looks like:

However, if the NPO instances are a little out of line, and collide with the block one after the other, the second collision is ignored:

[EDIT]

My work around for this is to add a variable to NPO and set/unset it depending on whether collision is detected. Not ideal, but it works for now:


I don't understand this
For Each Object Problem or Something Else?
#2

I think you might need a Nested “For each Block” that has your collision in it.


#3

As far as I see this is intended behavior. You are telling it trigger once while the condition is true. You do the test 1 time, it is true. So the second time (for the second object) it doesn’t do it again.

Though I agree there should be a better way to do such a rudimentary task, but I can’t find a good solution on the top of my mind.

The only one I currently can think of is making the trigger once use a different uid on each iteration of the events, but it is problematic for many reasons (breaking change, breaks hot reload, potentially reusage of same UIDs causing very weird bugs, big occupation of memory for all UIDs to generate at runtime…)


#4

The thing that is confusing is that I’m iterating though each NPO. I would have thought that the NPO & Block collision detection would be tested for each NPO iterated, rather than a blanket detection that covers all. So for me, it doesn’t work as expected or should.

Otherwise, what’s the point of having a for-each repeat block, if it’s not using the instance of the current iteration?


#5

I think you misunderstood the problem. The problem is not the collisions or the for each, it is the trigger once.

The way it works is every single one of them get an UID attached to them. Then, when they are called, they store their UID in a storage of all the UID of the trigger once that have been called. If after 2 frames it hasn’t been called again, it is deleted from that storage. While it is in that storage, it will return false as a condition.

Therefore, as you have one trigger once, it will be shared for every iteration. If it is once called, it’s uid will be stored, and for the next block the trigger once uid will still be in the storage, therefore it won’t trigger again.


#6

@arthuro555, sorry but I feel like I’m still not clear on this. Please bear with me, as I’d like to understand how GDevelop works under the hood, because that means I better understand the limitations I’m working with.

So, correct me if I’m wrong here, my understanding of what you wrote is that if an object is part of an event with a trigger once on it, the object’s UID is stored (for at least 2 frames) as being part of that event trigger. If the object’s UID is in the list of UIDs that triggered the event, it returns false for the event.

If I understand that bit, then it doesn’t explain why another object of the same type, but with a different UID is ignored. It’s UID shouldn’t be on the triggered list. If I’m grasping your explanation correctly, then it seems like the object type ID is added to the list, not the object UID.

Again, apologies if this is a pain. I really do want to understand how it works because otherwise I’m developing with the wrong understanding, and getting frustrated because things don’t work as I thought they would do.


#7

No, no, you got me wrong. The event has it’s own UID, it doesn’t take it from the object or idk, every single trigger once event has a UID attributed at compilation time.


#8

Gotcha. I [incorrectly] believed it was the objects that played the part, not the event itself.

Thanks for clearing that up :slight_smile:


#9

@arthuro555, I’ve had a bit of a think about this, and there’s still a bit that doesn’t sit right with me:

I get that the Collision detection event has it’s own ID, and that’s what determines whether the trigger-once collision check is ignored. However, the issue I now have it that it’s within a Repeat for each instance of an object type. Each iteration concerns itself with a specific object. So the trigger-once collision detection event should have a different UID for each iteration of the Repeat block, because each iteration is dealing with a different set of objects.

But it doesn’t, which I think makes the behaviour a bug.


#10

It is the trigger once that has a uid, not the other conditions. As I said multiple times now, no, the UIDs are generated at compiltion time and not while iterationg over objects at runtime. The UID is in no way bound to the objects.


#11

Sorry, I’ve been a little ambiguous and made some mistakes with what I referred to.

What I’ve been trying to get at is:

It would appear that, inside a repeat block, the trigger-once UID should not be used by itself to determine whether an event condition should be deemed false. That should be determined by the trigger-once UID combined with the object’s UID. Because for each iteration of the repeat block, this combination is unique.