Объекты и сцены
Всё в вашем проекте строится на двух идеях: вещи, состоящие из компонентов, и сцены, решающие, когда эти вещи появляются. Эта страница про то и другое.
Редактор называет их объектами, потому что именно так они выглядят на экране. Движок и скриптовый API называют их entity. Разницы нет — на этой странице entity используется там, где важно отличие от компонентов, и объект во всех остальных местах.
Два отношения, и это не одно и то же
Почти всё непонимание этого движка идёт из путаницы двух вещей, которые обе выглядят как «внутри».
Entity СОСТОИТ ИЗ компонентов. Компоненты — не дети, а части, определяющие, чем entity является. Каждого вида — не больше одного.
Entity "Лампа"
├── Meta имя, включена ли, видима ли
├── Transform где стоит, как повёрнута, какого размера
├── Model какую 3D-модель рисовать
└── Events на что реагирует
Entity может СОДЕРЖАТЬ другие entity. Это дети, и они сами по себе полноценные entity — у каждого свои компоненты.
Entity "Лампа"
└── Entity "Лампочка" ← отдельная entity…
├── Transform ← …со своими компонентами
└── Light
Вместе настоящая сцена выглядит так — компоненты слева от каждой entity, дети с отступом под ней:
Entity "Гостиная" ◆ Anchor ← вот это СЦЕНА: у неё есть якорь
│
├── Entity "Лампа" ◆ Transform ◆ Model ◆ Events
│ └── Entity "Лампочка" ◆ Transform ◆ Light
│
└── Entity "Стол" ◆ Transform ◆ Model ◆ RigidBody ◆ Collider
Всё на этой картинке — вещи одного вида: entity. Сценой, лампой или физическим телом их делает только набор компонентов.
Сдвиньте лампу — сдвинется и лампочка, потому что она внутри. Уберите у лампы компонент модели — лампочка не исчезнет: это композиция, а не вложение.
Если вы ловите себя на вопросе «это должно быть компонентом или дочерним объектом?», ответ такой: компонентом — когда это свойство самой вещи, ребёнком — когда это отдельная вещь, которая должна двигаться вместе с ней.
Entity — это то, что говорят её компоненты
Никакого меню типов объектов нет. Вы собираете нужное из компонентов:
| Дайте entity… | …и получите |
|---|---|
| геометрию + материал | видимую форму |
| ссылку на модель | импортированную 3D-модель |
| компонент света | источник света |
| текстовый компонент | надпись |
| rigid body + коллайдер | то, что может двигать физика |
| якорь | сцену |
| скрипт или патч | поведение |
Скажем, нужен прыгающий мяч. Начните со сферы и материала — уже видно. Добавьте rigid body и коллайдер — он падает и отскакивает. Добавьте скрипт — он что-то делает при приземлении. Каждый компонент добавляет одну способность, а его удаление её забирает.
Три формы, которые вам встретятся
Одна и та же модель entity даёт три вещи, ощущающиеся по-разному, но устроенные одинаково:
| Что это | Есть | Нет |
|---|---|---|
| Сцена | якорь и дети | transform |
| Обычный объект | transform плюс что нужно | якорь |
| Поведение уровня space | скрипт или патч и нет родителя | transform, якорь |
У сцены нет transform, потому что ей негде быть: её положение задаёт то, к чему она привязана в реальном мире. У носителя уровня space его нет, потому что он вообще не в мире — это просто логика, которая продолжает работать.
Нужны три материала на одной модели? Используйте слоты внутри её единственного компонента материала. Нужны два чего-то другого? Используйте дочерние entity — лампа с двумя лампочками это entity лампы с двумя детьми.
У каждой entity также есть имя (по нему вы её находите) и родитель.
Включён и видим — разное
В инспекторе эти два похожи, а ведут себя совершенно по-разному.
Выключенный убирает entity из работающего проекта. Не рисуется, не нажимается, скрипты остановлены, события молчат. Как будто её нет.
Невидимый лишь перестаёт рисоваться и нажиматься. Она на месте: скрипты работают, физика сталкивается.
Итого: невидимая стена, которая всё же преграждает путь? Невидимая. Приз, который появится позже? Выключен, пока не понадобится.
Родители и дети
Entity образуют дерево. Сдвиньте родителя — дети поедут следом, сохраняя положение относительно него. Так собирается всё составное. Кузов машины с привязанными четырьмя колёсами едет как одна машина.
Entity без родителя сидит в корне своей сцены.
Дети тоже, и их дети. Если что-то надо сохранить — сначала вытащите наружу.
Сделать entity ребёнком собственного потомка нельзя — редактор откажется, вместо того чтобы запутать дерево.
Сцены и якоря
Сцена — это entity с якорем, и якорь отвечает на один вопрос: когда этому появиться?
| Якорь | Ваша сцена появляется, когда… |
|---|---|
image | камера узнаёт печатную картинку |
qr | отсканирован QR-код |
geo | посетитель оказался в определённом месте |
face | обнаружено лицо |
surface | посетитель ставит её на пол, стену, потолок или стол |
panorama | открывается панорамное окружение |
3d | сразу — обычная 3D-сцена, без всякого AR |
Позиционирование по отсканированной карте реального места — это опция якоря surface, а не отдельный тип. Настройте сцену surface, а потом включите VPS.
Несколько сцен, один маркер
Сцены с общим триггером (та же картинка, тот же QR-код, то же место) образуют группу, и одновременно показывается только одна сцена из группы.
Так работает история: один и тот же постер открывает первую главу, а позже — вторую, потому что вы переключили активную сцену в группе.
Показ и скрытие при обнаружении — это просто пара событий, которые редактор заводит за вас
(on-detect показывает, on-lost скрывает). Это обычные события, так что их можно менять —
например, чтобы контент оставался на экране после ухода маркера из кадра, что посетители обычно
предпочитают контенту, исчезающему от малейшего дрожания руки.
У сцен surface три отдельные настройки
Их часто путают, поэтому вот они рядом:
- Какие поверхности принимать — пол, стена, потолок, стол.
- Как размещается контент — автоматически на найденной поверхности или там, где нажал посетитель.
- Какой движок трекинга — актуально только в вебе; нативные приложения всегда используют собственный платформенный.
Поведение, которое переживает сцену
Дайте entity поведение и никакого родителя — и она перестанет принадлежать какой-то одной сцене: она принадлежит всему space. Она работает, пока сцены сменяются, и слышит каждое событие, где бы оно ни произошло.
Именно там место счётчику очков, глобальному контроллеру или «запомнить, что выбрал посетитель». Скрипт внутри сцены останавливается в тот же момент, что и она.
Как редактор подписывает объекты
Вы увидите подписи вроде model, primitive, text. Редактор определяет их по тому, что несёт объект, в таком порядке:
ссылка на splat → splat
model + скиннинг → animated model
model → static model
video → video ← проверяется раньше геометрии
text → text
audio → audio
light → light
geometry → primitive
всё остальное → object
Это объясняет небольшой сюрприз: плоскость с видео подписана video, а не primitive. И это же объясняет, почему материал и геометрию можно править только у примитивов и статических моделей.
Дальше: Компоненты — чем на самом деле управляет каждый из них.