1
\$\begingroup\$

My game is turn-based, so I only need collision to be detected after a specific game event has occurred, so for instance after every PlayerMoveComplete event.

I could just define a MonoBehaviour representing a rectangle and check if player is within its bounds, like:

class MyRect {

 void OnMoveComplete () {
    // if player lies within the specified rectangle
    if (this.Contains(player.transform.position))
       DoSomething();
 }
}

But I like to be able to see and adjust the area inside the editor similar to a Box Collider 2d.

I think I could also use the default box collider 2d implementation like:

collider2D.bounds.Contains(pos)

But I'm not sure if it'd still do all those calculations even if I do not implement any of its message handling methods like OnCollisionEnter2D. If it does it's an overhead for the task.

\$\endgroup\$
1
\$\begingroup\$

I assume you want to optimize the physics. And that was the main reason of this question.

If your game isn't using any physics that depend on frame rate and uses physics only at some points in time defined by game logic - you can turn off physics calculations and simulate them when necessary Physics.Simulate. This will greatly improve the performance of a game that has physics components used in great quantities.

To improve the performance you might as well look at Physics Best Practices - use physics on separate layers, collision matrix will help. Make use of LayerMasks. Use raycasts in an optimized way.

As per your question:

You can cache colliders and use them in components. Code is untested and might contain some typos. As well some of the colliders might not have `bounds.

[RequireComponent(typeof(Collider2D))]
public class Interactable2D : MonoBehaviour
{
    [SerializeField] private Collider2D _collider2D;

    protected virtual void Interact()
    {
        // Do something
    {

    public void Interact(Entity/Collider/Player entity)
    {
        if (this._collider2D.OverlapPoint(entity.transform.position))
            this.Interact();
    }

#if UNITY_EDITOR
    private void Reset()
    {
        this._collider2D = this.GetComponent<Collider2D>();
    }
#endif
}

Collider2D.OverlapPoint

OnCollisionEnter2D - is an event, a message to be totally correct, though, from experience Unity probably caches function reference. It would be unwise to use reflection to call this method or any similar methods like Start or Awake...

It won't be invoked if you don't implement it. Calculations for OverlapPoint will only include calculations necessary to check if point is in bounds.

My own suggestions

I would advise you to use Unity internal physics system instead of handling collision checks with OverlapPoint in case you are going to use it the way I have shown in the script (without additional collision detection). - Because - game engines usually use OcTree(3D), QuadTree(2D) to handle collisions. They separate collision detection in chunks. Because comparing collisions of every Rigidbody/2D with every Collider/2D is O(n*m) (n - quantity of rigidbodies, m - quantity of colliders) - correct me if I am wrong. Which would be highly inefficient.

Without knowing your gameplay mechanics I can't be sure if you can use OverlapPoint efficiently. - I came up with those doubts because you would still need to know somehow against what Entity/Collider/Player... to check collisions.

\$\endgroup\$
  • \$\begingroup\$ OverlapPoint(player.transform.position) point is what I needed. Also thanks for confirming that the message handling methods won't be invoked unless I implement it \$\endgroup\$ – Gayan Weerakutti Mar 8 at 15:39
0
\$\begingroup\$

I think you can use Physics2D.OverlapBox (There are a few variation like Physics2D.OverlapCircle, Physics2D.OverlapArea and so on). Basically it looks for colliders that overlaps within a range. See unity documentation for more info:

  1. https://docs.unity3d.com/ScriptReference/Physics2D.html
  2. https://docs.unity3d.com/ScriptReference/Physics2D.OverlapBox.html

For example, OnCompleteMovement you can just say

//Assuming this is written inside player script
void OnMoveComplete () 
{
    // checks 0.5 radius area around player and if any collision with layer "CheckPoint" found then return that collider info
    Collider2D col = Physics2D.OverlapCircle(transform.position, 0.5f,LayerMask.GetMask("CheckPoint"))
    // if we have hit the checkpoint
    if (col!=null)
       DoSomething();
}
\$\endgroup\$
  • \$\begingroup\$ This is to check if a collider falls within a box area. But mine is to just check whether the player position is within the box area, which can be done with simple arithmetic. And the code will be handled in the box class itself. \$\endgroup\$ – Gayan Weerakutti Feb 7 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.