The Problem:

In Spacebomb I wanted to create a circular arena that would contain the player, the enemies and the bombs. Unity’s physics focuses on preventing colliders from overlapping so to contain objects within a circle I had to create my own solution.

Solution One – Restrict Movement Based On Distance From Centre:

I positioned the sprite that represented the walls so that its centre was (0, 0, 0). This meant that I would know if an object is out of bounds if the magnitude of their position was greater than the radius of the world bounds. If the were out of bounds I applied a force to stop their movement.

The script I used to do this can be found here:

https://gist.github.com/goshdarngames/7177ac4fc14209462438

A playable WebGL demo of the solution can be found here:

https://www.goshdarngames.com/unity-tutorials/circle-confine/solution1

Disadvantages:

Objects stick to the walls until they change direction because of how the script stops them by reducing their speed to 0. This makes mechanics such as objects bouncing off the walls difficult to implement.

Values such as the radius of the circle and size of each object have to be input by hand and can be prone to error.

Solution Two – Create a Hollow Circle Collider With a Script

I posted my problem on reddit and the good folks there alerted me to the fact that Polygon Colliders can be hollow if created from arrays of points.

I used this script to create a hollow polygon collider – it can create a regular polygon with any number of sides, just use a high value (like 100) and it will seem circular to the player:

https://gist.github.com/goshdarngames/d00f1f81040228a06ecf

A WebGL demo of this solution can be found here:

https://www.goshdarngames.com/unity-tutorials/circle-confine/solution2

Advantages

This method uses the Unity physics engine to restrict the movement. This results in simpler (and probably much faster) code especially when you consider how difficult it would be to add bouncing mechanics to Solution One.

Objects no longer stick to the outer wall. They can bounce off it and if you move towards it diagonally you will rub against it rather than stop and rotate.

The size of each object (player, enemies, bombs) does not need to be input manually since the code supports normal Unity colliders.

Disadvantages

The size of the collider must still be input manually. This means if you change the size of the image of the circle you need to ensure that the size of the collider is updated as well.

Conclusion

Solution 2 is much better overall than Solution 1. My personal belief is that it is best to offload any logic to the game engine wherever possible. Generally the engineers who create the engine will write more efficient code than I can.

Demo Project

You can download a demo project with a scene for each solution here:

https://www.goshdarngames.com/unity-tutorials/circle-confine/CircleConfineDemoProject.zip

You can see the code in action in my game Spacebomb:

http://gamejolt.com/games/spacebomb/74308