Слои и 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") создаёт маску по именам слоёв, а ~ перед маской инвертирует её, включая все слои, которых в ней не было.
Задание
СреднеРазведчик должен сообщать, что находится впереди, но 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";
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Погоня за монетами
Катящийся мячМонеты для сбора