Пользовательские компоненты JavaScript

Продолжаем с того места, где остановились в Начало работы.

Обзор 

Цель этого руководства — познакомить вас с добавлением пользовательской логики в ваш проект.

Мы создадим два скрипта, которые позволяют подсчитывать количество кадров, на которые объект был осмотрен.

Один скрипт будет добавлен в камеру и будет посылать лучи, чтобы проверить, смотрим ли мы на конкретный объект. Другой будет добавлен в объект для отображения количества кадров.

Перезагрузка JavaScript 

Чтобы сделать наш рабочий процесс максимально гладким, редактор будет автоматически отслеживать изменения в ваших JavaScript-файлах и обрабатывать их после сохранения.

Если у вас работает приложение в браузере, оно даже перезагрузит страницу с изменёнными источниками.

Создание компонента JavaScript 

Щёлкните правой кнопкой мыши по пустому пространству в “Обозревателе ресурсов” и добавьте новый компонент JavaScript.

Скриншот: Начало работы JS - Добавить компонент

Назовите компонент counting-gaze.js.

При двойном щелчке по файлу он откроется с помощью приложения, которое вы настроили для открытия .js файлов в вашей системе.

Код 

И, наконец, наполним компонент жизнью. Следующий код посылает луч в сцену каждый кадр:

import {Component} from '@wonderlandengine/api';

export class CountingGaze extends Component {
    static TypeName = 'counting-gaze';

    origin = [0, 0, 0];
    dir = [0, 0, 0];

    init() {
        console.log('Counting gaze initialized');
    }

    update() {
        /* Получите перевод этого объекта и сохраните его в "origin" */
        this.object.getPositionWorld(this.origin);
        /* Получите направление этого объекта и сохраните его в "dir" */
        this.object.getForwardWorld(this.dir);

        /* Отправьте луч в сцену и посмотрите, если он попадает и объект в
         * группе столкновения "1" или "2" */
        const rayHit = this.engine.scene.rayCast(
            this.origin, this.dir, (1 << 1) | (1 << 2));
        if(rayHit.hitCount > 0) {
            for(let i = 0; i < rayHit.hitCount; ++i) {
                let o = rayHit.objects[i];

                // TODO: Далее мы будем увеличивать счетчик на
                // попавшемся объекте вместо этого!
                console.log('Raycast hit object:', o.name);
            }
        }
    }
}

Пока что мы просто выводим в консоль имена объектов, которые мы ударяем с помощью луча.

Добавление компонента к объекту 

Этот компонент не запускается автоматически. Нам нужно прикрепить его к камере!

Снимок экрана: Начало работы JS - Добавить пользовательский компонент

Запуск 

Чтобы посмотреть компонент в деле, используйте “Упаковать” и “Открыть в браузере”.

Если вы откроете консоль JavaScript в своем браузере с помощью Ctrl + Shift + C, вы заметите, что компонент был инициализирован.

Снимок экрана: Начало работы JS - Компонент инициализирован в консоли

Однако имена объектов не выводятся в консоль. this.engine.scene.rayCast() использует систему коллизий, которая работает только с collider компонентами. Чтобы луч ударял по чему-либо, нам нужно добавить больше компонентов!

Столкновение 

Добавьте дочерний элемент к объекту “почтовый ящик”, как показано на следующем скриншоте. Добавьте компонент collision к этому новому дочернему объекту.

Установите радиус, например, на 0.15.

Снимок экрана: Начало работы JS - Коллайдер

С этой настройкой мы можем “Упаковать” и убедиться, что луч работает.

Подсчет и отображение 

Нам нужно отслеживать счетчик и наконец отобразить его с текстовым компонентом.

Добавьте “текстовый” компонент к нашему “Коллайдер” объекту и измените текст на “0”.

Затем добавьте новый JavaScript-файл с именем gaze-counter.js.

import {Component, Property} from '@wonderlandengine/api';

export class GazeCounter extends Component {
    static TypeName = 'gaze-counter';
    static Properties = {
        msg: Property.string('i')
    };

    count = 0;

    init() {
        console.log('Gaze counter initialized');
    }

    start() {
        this.textComp = this.object.getComponent('text');
    }

    update() {
        this.textComp.text = `${this.msg} ${this.count}`;
    }
}

Вы заметите свойство msg здесь. Редактор автоматически сгенерирует поле ввода для него, когда мы добавим компонент к объекту “Коллайдер”:

Снимок экрана: Начало работы JS - Параметры компонента

Наконец, замените комментарий // TODO в counting-gaze.js на следующий:

    const counterComp = o.getComponent('gaze-counter');
    if(counterComp) {
        counterComp.count++;
    }

Результат 

“Упакуйте” и проверьте браузер. Теперь вы увидите окончательный результат!

Снимок экрана: Начало работы JS - результат

Резюме 

Wonderland Engine позволяет использовать любую JavaScript библиотеку, которая работает в браузере.

С автоматической перезагрузкой, рабочий процесс позволяет проводить очень быстрые итерации.

Найдите Wonderland Engine JavaScript API reference здесь и много небольших уроков.