Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Relying on Time.frameCount for synchronization

Discussion in 'Scripting' started by liortal, Dec 4, 2014.

  1. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    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 ?
     
  2. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Have an integer instead? timesHit++, then you will know if it was the first time or not.
     
  3. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    This will not work, since if i check for:

    Code (CSharp):
    1. void OnCollisionEnter( .. )
    2. {
    3. if (timesHit == 0)
    4. {
    5.      // this will miss cases where timesHit == 1 (since it was JUST SET TO 1 in the same update frame).
    6. }
    7. }
     
  4. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    I don't think I've fully understood your problem then. Can you maybe re-phrase?
     
  5. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    Code (CSharp):
    1. public class ObjectA : MonoBehaviour
    2. {
    3.     public bool IsHit;
    4.  
    5.     void OnCollisionEnter2D(Collision2D other)
    6.     {
    7.         IsHit = true;
    8.     }
    9. }
    10.  
    11. public class ObjectB : MonoBehaviour
    12. {
    13.     void OnCollisionEnter2D(Collision2D other)
    14.     {
    15.         var a = other.gameObject.GetComponent<ObjectA>();
    16.  
    17.         if (a != null)
    18.         {
    19.             // ONLY DO THIS IF A IS ****NOT HIT**** YET!
    20.             if (!a.IsHit)
    21.             {
    22.                 // DoSomething
    23.             }
    24.         }
    25.     }
    26. }
    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
     
  6. A.Killingbeck

    A.Killingbeck

    Joined:
    Feb 21, 2014
    Posts:
    483
    Ok, why not then flip around your current logic so ObjectA finds the component ObjectB and calls the DoSomething method directly?
     
  7. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,555
    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).