Menu
CoddyTech

Слои и LayerMask

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 36 из 63.

Каждый GameObject находится на одном слое, выбранном в меню Layer в верхней части Inspector. В Unity их 32: несколько встроены (0 Default, 2 Ignore Raycast, 4 Water, 5 UI), а свои можно задать в Tags and Layers, начиная с User Layer 3. LayerMask — это набор слоёв, по одному биту на слой. Передайте его в raycast после maxDistance, и луч будет игнорировать все коллайдеры на слоях, не входящих в набор.

Этот игрок должен прыгать с земли, а не с голов врагов. Разместите полы на слое Ground, а скрипту задайте поле LayerMask, которое Inspector покажет как меню, где можно отметить Ground:

[SerializeField] private LayerMask groundMask;

bool IsGrounded()
{
    return Physics.Raycast(transform.position, Vector3.down, 1.1f, groundMask);
}

Маска, содержащая только Ground, также не даст проверке обнаружить игрока. Луч пропускает коллайдер, внутри которого он начинается, но не другие коллайдеры игрока, например коллайдер дочернего объекта; кроме того, проверки перекрытия из следующего урока обнаруживают собственный коллайдер игрока, поэтому проверка у ног без маски всегда сообщала бы, что игрок стоит на земле. Поместите игрока и его дочерние объекты на слой Player и исключите Player из масок, используемых проверками. В коде LayerMask.GetMask("Ground", "Platform") создаёт маску по именам слоёв, а ~ перед маской инвертирует её, включая все слои, которых в ней не было.

challenge icon

Задание

Средне

Разведчик должен сообщать, что находится впереди, но LookAhead() всегда возвращает Lantern. Его луч проходит сквозь тело Разведчика, внутри которого начинается, а затем попадает в фонарь, который Разведчик держит перед собой. Разведчик и его фонарь находятся на слое Player. Исправь LookAhead() в Spotter:

  • Создай в коде маску всех слоёв, кроме Player, с помощью LayerMask.GetMask.
  • Передай её в лучевой запрос, сохранив его range, чтобы луч прошёл сквозь фонарь и сообщил о первом объекте за ним.

Нажми Play и поворачивай разведчика стрелками: в Console будут выводиться объекты, которые он видит. Затем нажми Check.

Попробуйте сами

using UnityEngine;

public class Spotter : MonoBehaviour
{
    public float range = 10f;
    private string last = "";

    void Update()
    {
        string seen = LookAhead();
        if (seen != last)
        {
            Debug.Log("Ahead: " + seen);
            last = seen;
        }
    }

    // Имя первого объекта впереди в пределах range или "nothing".
    public string LookAhead()
    {
        if (Physics.Raycast(transform.position, transform.forward, out RaycastHit hit, range))
        {
            return hit.collider.name;
        }
        return "nothing";
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Физика и игровой процесс