Важный нюанс! Чтобы **Physics.Raycast** попадал своим лучом на GameObject, необходимо на GM повесить компонент Box Collider. В противном случае луч будет проходить сквозь GM.
<br>
Метод позволяет получить world-позицию, имея позицию точки на экране игры.
Например, игрок мышкой кликает на игровой объект, а нам нужно по позиции мышки узнать куда игрок хочет нажать в игровом мире.
Метод **Physics.Raycast** бьет лучом в стрелку мышки и выдает положительный результат, если луч коснулся коллайдера (collider) игрового объекта.
<br>
Нам нужно получить позицию мышки в пикселях.
```csharp
var mousePosition = Input.mousePosition;
```
Нам нужно получить луч. Метод создает луч, в котором началом является позиция камеры, а направлением точка в 3D-пространстве(World-пространстве), исходя из mousePosition.
```csharp
var ray = mainCamera.ScreenPointToRay(mousePosition);
```
<br>
Если мы хотим обрабатывать только конкретные коллайдеры игровых объектов, то можно использовать слои. Метод **Raycast** будет игнорировать игровые объекты, у которых не указан какой-либо слой из layers.
Лучше всего брать слои из инспектора, сериализовав поле в скрипте. В инспекторе будет выпадающий список со всеми слоями в Unity-проекте.
```csharp
[SerializeField] private LayerMask layers;
```
<br>
Если мы будем использовать слои, то необходимо указать дистанцию работы луча. Указывать приходится из-за того, что невозможно указать слой в методе, не указав дистанцию.
```csharp
var maxDistance = 10000f;
```
<br>
При вызове метода идет проверка, касается ли луч игрового объекта, у которого есть слой из указанных в layers. Возвращает true/false
hitInfo лучше вынести за метод, создав поле в классе, чтобы 60 раз в секунду не инициализировался (структуры всегда инициализируются при определении). Бессмысленная инициализация может занимать время, особенно, если структура содержит много параметров)
```csharp
bool haveHit = Physics.Raycast(ray, out var hitInfo, maxDistance, layers);
```
<br>
Если мы хотим игнорировать слои, указанные в layers, то нужно приписать «~».
```csharp
bool haveHit = Physics.Raycast(ray, out var hitInfo, maxDistance, ~layers);
```
<br>
Если haveHit имеет значение true, то в hitInfo записывается информация о касании. Из hitInfo мы достаем позицию касания.
```csharp
if (haveHit)
{
UnitGhostPosition = hitInfo.point;
}
```
<br>
[Официальная документация](https://docs.unity3d.com/2021.3/Documentation/ScriptReference/Physics.Raycast.html)