Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do I detect if an object is currently in collision with another object multiple times per frame?

Discussion in 'Scripting' started by TotallyRealHuman, Oct 22, 2020.

  1. TotallyRealHuman

    TotallyRealHuman

    Joined:
    Jun 8, 2020
    Posts:
    1
    Hey, I'm pretty new to unity and I want to write a certain line of code which detects whether a certain object is colliding and if it is, move it to a different position. I want that line to run multiple times per frame, so I don't think OnCollisionEnter() would work. Finally, if this is possible at all, I want to detect said collision from a script attached to a separate gameObject. Is this possible? If so, then how?
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,070
    OnCollisionEnter() frequency is dictated by the physics fixed time interval, so it's bound to get triggered regardless of your framerate or Update method. By default, the fixed rate is 50 UPS (updates per second; 0.02 seconds interval). And unlike your regular display framerate, which can stretch dynamically, this fixed update is fixed.

    While you can make your own collision detection, there is no easier or more convenient way for a beginner, or even advanced programmer, for that matter, to detect collisions, if it involves using non-primitive colliders and 3D transformations such as rotation and scale. Unity's collision solution is a general purpose one and quite inobtrusive. It's not the fastest in the world, but can be quite optimal if used with care, and I'm talking about lightly to moderately populated physics sandboxes. In games that use static colliders for detecting non-rigid overlaps and other volume contacts in a forceless manner, you cannot possibly implement a better solution on your own. It's just a waste of time.

    Collision detection systems are typically heavy lifters, employing data structures such as octrees, using serious math, and serious algorithms to make them as fast and resourceful. It's a serious business to get one rolling.

    You cannot detect some object's collisions from other objects, due to the way the system is implemented, but you can make a dedicated collision detection script (using OnCollisionEnter and similar event methods just as usual), that you can attach to anything, with a sole job to notify other systems about its state. In turn you get what you wanted, so that you can make centralized state machines if you wish to handle several different collisions in some special place.

    For this I'd recommend learning more about events in general, how events are implemented in C#, and then Unity's own event system if you're interested. Because the general event-based design is the best way to ensure a non-coupled distribution of "news" throughout your game, and then reacting to them where and when this is appropriate.

    In other words, you make certain objects to "speak" about some changes, and some other objects act as "listeners". And you can make all kinds of things with this design, while not mixing the responsibilities of either object into one big mess.
     
    Last edited: Oct 22, 2020
    jjbish likes this.
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,070
    Regarding detecting collisions multiple times per update, I'm not sure if you can do that. I'm inclined to say no, but I'm not really sure. I'm also not sure why would you need that.
     
  4. leadtuna

    leadtuna

    Joined:
    Nov 27, 2021
    Posts:
    1
    I had this same problem, and found an answer, as long as know whether or not they're colliding from the get-go.
    void OnTriggerEnter () {
    isColliding = true;
    }

    void OnTriggerExit () {
    isColliding= false;

    }
    These things naturally only trigger when the objects either enter or exit the collision, so you can't know whether or not they're colliding until that happens, but otherwise it's fine. Also, there is an OnTriggerStay(), but I couldn't get that to work
     
  5. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,364
    Very informative.

    If you wanted to figure out if you're detecting multiple collisions per frame, add a counter to leadtuna's approach.

    Code (csharp):
    1. public int counter;
    2. void OnTriggerEnter() { counter += 1; }
    3. void Update()
    4. {
    5.     if (counter > 5)
    6.         DealWithRepeatedHits();
    7.     counter = 0;
    8. }
    9.