Outra forma de lidar com colisão ou contato entre objetos é gerar uma área de colisão por código (colisão num sentido amplo) e pegar os objetos que colidiram.
Existem duas principais maneiras - métodos da família Cast e métodos da família Overlap.
Overlap
Métodos Overlap criam uma área de colisão ao redor de um ponto e retornam os objetos presentes nessa área. Um exemplo que podemos ver com muita frequência é na implementação de IA's que precisam varrer um ambiente ao seu redor, como torretas em jogos Tower Defense.
No caso das torretas, geralmente o formato da área é um círculo, mas o Unity nos dá diversas versões desse tipo de método. No código a seguir eu exemplifico o OverlapSphere().
Se você rodar o código em um objeto, você verá constantemente os objetos encontrados pelo OverlapSphere(), que cobre um raio de 5. Veja que esse método retorna a lista de colliders encontrados, semelhante ao OnTrigger. Caso nenhum objeto seja encontrado, a lista será vazia.
Não tem muito segredo aqui, só precisamos informar o centro da esfera e seu raio, o método retornará a lista, e depois varremos a lista para fazer alguma coisa com os objetos.
Cast
Métodos Cast são meio que o oposto dos Overlap, eles lançam uma área de colisão, ao longo de uma distância, na cena, e retornam uma lista de informações de colisão com os objetos atingidos. Que fique claro que isso tudo acontece em um frame apenas.
Assim como o Overlap, o Cast também possui vários formatos, o mais famoso é o Raycast. A seguir vemos um exemplo dele.
A informação de colisão no exemplo está presente na variável hit, passada como parâmetro out, e representa a informação de colisão com o primeiro objeto atingido. Existe também a versão RaycastAll, que retorna uma lista de RaycastHit's. Essa struct, RaycastHit, é similar a classe Collision, mas é destinada a informação de colisão com métodos da família Cast.
Matriz de Colisão
Por último, precisamos ver a matriz de colisão.
Imagine que estamos desenvolvendo um jogo FPS e nosso personagem poderá interagir com alguns objetos de cena, ao olhar para tais objetos. Não precisamos de implementar a interação com todos, apenas com alguns - se implementarmos o código acima, o Raycast irá colidir com todos os objetos desnecessariamente.
A matriz de colisão nos ajuda, nesse caso, a otimizar o uso do Raycast e da física em geral, pois ela serve para definir quais tipos de objetos podem colidir com outros, ou seja, podemos filtrar e organizar as verificações de colisão entre objetos, impedindo, por exemplo, um fogo amigo.
Ela é acessada pelo caminho Edit -> Project Settings -> Physics/Physics 2D
Para selecionar as camadas de colisão que queremos atingir com o Cast (ou Overlap, funciona com ele também), precisamos declarar um LayerMask e selecionar as camadas pelo Inspector, ai sim passamos a variável das camadas por parâmetro. Veja: