Frame Accurate Collision Detection

Currently I am trying to make a 2D game similar to Smash Bros in mechanics. For this I need hitbox data down the individual frames of animation so that they can be balanced accordingly. To do this, I have set up a number of child objects sorted underneath the player, each with a polygon collider2D attached(see image below) and a simple script sending info to the debugger about which hitbox has hit the enemy(see script below). Then I would enable and disable these child objects in the animation window to sync up with the frames of the animation(see image below again).

The childed objects and the animation window

The simple script attached to each hitbox

       public float damage;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    void OnTriggerStay2D(Collider2D other)
        {
        if (other.gameObject.tag == "Enemy")
            {
            Debug.Log("" + damage);
            }
        }
}

Note that I set each hitbox to a different ‘damage’ number so that I would come out with which hitbox was hitting and in what order.

So far, everything works as intended. the animator turns them off and back on again in the right order, the debug script is firing; what could possibly be going wrong? Something very simple actually. You see, the end game product is intended to be at 60fps, so I turned up the animation sample rate to 60, and now none of the old debug lines are coming through. What’s worse is that even at a sample rate of 15, each of the hitboxes only registered in the log twice, instead of the 4 times each of them was supposed to. This suggests to me that unity’s collision detection is not accurate enough to detect such rapid changes in collision detection. Is this the case, or is something else going on?

I sincerely hope I am wrong on this, because otherwise I am going to have to scrap all of my work in unity and try to find another engine that has more precise collision detection. If anyone knows anything about this subject, I would be ecstatic to hear about it and what can be done to fix it, if anything.

Hi, is the physics engine setup to run at at least 60 fps ? This is setup in the project settings / time / Fixed Timestep. Enter “1/60” to make it run at 60 fps. Even then, I doubt this will fix your problem, let me explain:

Edit: the Animator Component’s “Update Mode” can be changed to “Animate Physics” to be animated during fixedUpdate. I didn’t know that when writing the next part of this answer.

Unity’s physics engine runs at a fixed framerate. It has some advantages but the problem is that sometimes there will be 2 or more calls to update between 2 calls of FixedUpdate. That is, 2 call to animation updates (that are sync to Update) and 1 call to the physics engine & collisions callbacks (in sync with FixedUpdate). Try with a physics engine that runs 90 or 120 time a second if possible for your targeted hardware, it may be enough.

The alternative and difficult to implement solution would be to check the hit collisions yourself during LateUpdate (= just after the animation engine had run) using Physics2D.OverlapCircle kind of functions. Doing so would be high framerate proof, but not low framerate proof (as animation and update system would only run at, say, 20 fps so you may miss some collisions, that’s why fixed step physics are better). You could then call your collision check code from FixedUpdate too in case of low framerate, calling Animator.Update() to update animations before checking collisions. Well, it’s a little complicated to explain, I hope the 120 fps physics is possible with your game (I can provide more info if you want to try that ‘LateUpdate’ path).

@dns
Ok, I’ve switched over to doing PlayInFixedTime and set the fixed timestep to 60fps, and it fixed the bug of registering the same hitbox more than once, but it didn’t fix any of the other problems. Hitboxes still randomly aren’t being checked and won’t get checked on repeated attacks.

Also, I’ve already tried doing Enter/Leave, they don’t work since the hitboxes are being enabled when the enemy is already inside of them, and since the physics is set to 60fps with the animation, it means there is literally no time in which an entity could exit or enter the hitbox. I tried that before I even posted this problem here. :stuck_out_tongue:

I feel like we’re getting closer to fixing it, but we’re still not there yet.

(also, I’m using the Animator, so I don’t have access to the old Legacy options on it, but since PlayInFixedUpdate seems to have fixed it regardless, its a bit of a moot point)