Relying on Time.frameCount for synchronization

Hey,

In our game we have different objects that collide with each other. When an object collides with another (for simplicity sake), it sets a public field IsHit = true.

The problem is, when 2 objects collide, i want to see if they hit for the first time or not.
Checking in script whether IsHit = true won’t give a correct result, as it relies on the order of execution (if the first object runs its collision code, it will mark IsHit as true and the 2nd object testing this will not know that this is the first collision).

I was thinking whether i can use Time.frameCount for synchronization, for example, when colliding, mark the frame in which collision occurred and use it when processing collision in other objects.

Is this a safe practice? Or is there a better solution for this problem ?

Have an integer instead? timesHit++, then you will know if it was the first time or not.

This will not work, since if i check for:

void OnCollisionEnter( .. )
{
if (timesHit == 0)
{
     // this will miss cases where timesHit == 1 (since it was JUST SET TO 1 in the same update frame).
}
}

I don’t think I’ve fully understood your problem then. Can you maybe re-phrase?

public class ObjectA : MonoBehaviour
{
    public bool IsHit;

    void OnCollisionEnter2D(Collision2D other)
    {
        IsHit = true;
    }
}

public class ObjectB : MonoBehaviour
{
    void OnCollisionEnter2D(Collision2D other)
    {
        var a = other.gameObject.GetComponent<ObjectA>();

        if (a != null)
        {
            // ONLY DO THIS IF A IS ****NOT HIT**** YET!
            if (!a.IsHit)
            {
                // DoSomething
            }
        }
    }
}

End goa: I would like some code to execute on the first hit between 2 objects, and not anytime afterwards

Upon collision between A and B:

  • If ObjectB’s code runs first, it will see that A was not hit, all fine.
  • If ObjectA’s code runs first, it will be marked as hit, and object B won’t do its thing.

In case 2 i would also like DoSomething to happen

Ok, why not then flip around your current logic so ObjectA finds the component ObjectB and calls the DoSomething method directly?

That is a valid solution, but introduces coupling.

It can be solved using events (e.g: ObjectA notifies anyone who’s interested that something happened).