Анатомия скрипта
Вот базовый скрипт. Мы можем узнать о структуре скрипта PlayCanvas из него.
var Rotate = pc.createScript('rotate');
Rotate.attributes.add('speed', { type: 'number', default: 10 });
// инициализация кода, вызываемая один раз для каждой сущности
Rotate.prototype.initialize = function() {
this.local = false; // выберите локальное вращение или мировое вращение
};
// код обновления, вызываемый каждый кадр
Rotate.prototype.update = function(dt) {
if (this.local) {
this.entity.rotateLocal(0, this.speed * dt, 0);
} else {
this.entity.rotate(0, this.speed * dt, 0);
}
};
// метод swap вызывается для горячей перезагрузки скрипта
// наследуйте состояние вашего скрипта здесь
Rotate.prototype.swap = function(old) {
this.local = old.local;
};
Мы разберем каждый раздел сценария
Методы сценария
Объявление типа сценария
var Rotate = pc.createScript('поворот');
Эта строка создает новый ScriptType с именем 'rotate'. Имя скрипта используется для идентификации скрипта в компонентах скрипта. Каждый
ScriptType, объявленный в проекте, должен иметь уникальное имя. Возвращаемая функция Rotate
- это функция javascript, которая
готова к расширению своего прототипа стандартным набором методов. В некотором роде это похоже на наследование классов.
Атрибуты скрипта
Rotate.attributes.add('speed', { type: 'number', default: 10 });
Эта строка объявляет атрибут скрипта. Атрибут скрипта является свойством экземпляра скрипта и он доступен в пользовательском интерфейсе
редактора. Это позволяет настраивать отдельные сущности в редакторе. В приведенном выше примере атрибут называется "speed" и будет
доступен в коде скрипта как this.speed
. Это число и по умолчанию инициализируется значением 10.
Атрибуты автоматически наследуются от нового экземпляра скрипта при горячей замене кода.
Инициализация
// инициализация кода, вызываемого один раз для каждой сущности
Rotate.prototype.initialize = function() {
// локальное вращение или мировое вращение
this.local = false;
};
Метод initialize
вызывается для каждой сущности, к которой прикреплен сценарий. Он вызывается после завершения загрузки приложения и
построения иерархии сущностей, но до первого цикла обновления или отрисовки кадра. Метод initialize
вызывается только один раз для
каждой сущности. Вы можете использовать его для определения и инициализации переменных-членов экземпляра сценария. Если сущность или сценарий
отключены при запуске приложения, метод инициализации будет вызван в первый раз, когда сущность будет включена.
Когда сущность клонируется с использованием метода entity.clone
, метод initialize
в сценарии вызывается только тогда,
когда клонированная сущность добавляется в иерархию сцены; при условии, что и сущность, и сценарий включены.
Если у компонента сценария есть несколько прикрепленных сценариев, метод initialize
вызывается в порядке сценариев на компоненте.
Обновление
// код обновления, вызываемый каждый кадр
Rotate.prototype.update = function(dt) {
if (this.local) {
this.entity.rotateLocal(0, this.speed * dt, 0);
} else {
this.entity.rotate(0, this.speed * dt, 0);
}
};
Метод обновления вызывается для каждого кадра; он вызывается в каждой сущности, которая имеет включенный компонент сценария и включенный
экземпляр сценария. Каждому кадру передается аргумент dt
, содержащий время, в секундах, с момента последнего кадра.
Если у компонента сценария есть несколько прикрепленных сценариев, update
вызывается в порядке сценариев на компоненте.
Обмен
// метод swap вызывается для горячей перезагрузки скрипта
// наследуйте состояние вашего скрипта здесь
Rotate.prototype.swap = function(old) {
this.local = old.local;
};
Метод swap
вызывается при добавлении ScriptType с тем же именем в реестр. Это происходит автоматически во время запуска, когда
скрипт изменяется во время выполнения из редактора. Этот метод позволяет поддерживать "горячую перезагрузку кода" во время работы
вашего приложения. Это очень полезно, если вы хотите итерировать код, который занимает некоторое время для достижения во время работы вашего
приложения. Вы можете вносить изменения и видеть их, не перезагружая и не прогоняя множество настроек или восстанавливая состояние игры.
Методу swap
передается старый экземпляр скрипта в качестве аргумента, и вы можете использовать его для копирования состояния из
старого экземпляра в новый. Вы также должны убедиться, что события отписываются и подписываются заново.
Если вы не хотите поддерживать горячую замену кода, вы можете удалить метод swap, и движок не будет пытаться обновить скрипт.
Дополнительные методы: postInitialize и postUpdate
Есть еще два метода, которые вызываются движком для скриптов, если они присутствуют. postInitialize
вызывается для всех скриптов,
которые его реализуют, после того как все скрипты были инициализированы. Используйте этот метод для выполнения функций, которые предполагают,
что все скрипты инициализированы. postUpdate
- это метод обновления, который вызывается после обновления всех скриптов. Используйте
это для выполнения функций, которые предполагают, что все скрипты обновлены. Например, камера, которая отслеживает другую сущность, должна
обновлять свою позицию в postUpdate
, чтобы другая сущность завершила свое движение за кадр.
События
Экземпляры скриптов генерируют ряд событий, которые можно использовать для реагирования на определенные обстоятельства.
state и enable/disable
Событие state
срабатывает, когда состояние выполнения экземпляра скрипта изменяется с включенного на отключенный или наоборот.
Состояние экземпляра скрипта может быть изменено путем включения/отключения самого скрипта, компонента, которому принадлежит скрипт, или
сущности, к которой прикреплен компонент скрипта. Событие enable
срабатывает только при изменении состояния с отключенного на
включенный, а событие disable
срабатывает только при изменении состояния с включенного на отключенный.
Rotate.prototype.initialize = function () {
this.on("state", function (enabled) {
// воспроизвести звуковой эффект, когда Entity включается или отключается
if (enabled) {
this.entity.sound.play("bell");
} else {
this.entity.sound.play("horn");
}
});
};
или эквивалент с использованием enable
и disable
Rotate.prototype.initialize = function () {
this.on("enable", function () {
this.entity.sound.play("bell");
});
this.on("disable", function () {
this.entity.sound.play("horn");
});
};
уничтожить
Событие destroy
возникает при уничтожении экземпляра скрипта. Это может произойти из-за удаления скрипта из компонента путем вызова
метода destroy()
, или из-за удаления компонента скрипта из Entity, или потому что Entity, к которому он был прикреплен, был
уничтожен.
Rotate.prototype.initialize = function () {
this.on("destroy", function () {
// удалить слушатель событий DOM при уничтожении объекта
window.removeEventListener("resize", this._onResize);
});
};
attr и attr:[name]
События attr
и attr:[name]
возникают при изменении значения объявленного атрибута скрипта. Это может произойти в
процессе выполнения приложения или при изменении значения через редактор. Событие attr
возникает для каждого измененного атрибута.
Событие attr:[name]
возникает только для определенного атрибута, например, если у вас есть атрибут с именем "speed",
событие attr:speed
будет вызвано при изменении скорости.
Rotate.prototype.initialize = function () {
this.on("attr:speed", function (value, prev) {
// атрибут скорости изменился
});
};
Issue Tracker
Новая функция: Tutorial Thumbnail
Описание
Добавить возможность загрузки изображения-превью для урока.
Задачи
- Добавить поле для загрузки изображения в форму создания/редактирования урока
- Отображать загруженное изображение на странице урока
- Отображать изображение-превью в списке уроков
Исправление ошибки: Entity не сохраняется
Описание
При создании новой Entity, она не сохраняется в базе данных.
Задачи
- Исправить ошибку сохранения Entity
- Добавить тесты для проверки сохранения Entity
Улучшение: Material Asset
Описание
Добавить возможность просмотра и редактирования Material Asset в Material Inspector.
Задачи
- Добавить вкладку Material Asset в Material Inspector
- Реализовать функционал редактирования Material Asset
Улучшение: Shader Editor
Описание
Добавить возможность просмотра и редактирования шейдеров в Shader Editor.
Задачи
- Добавить вкладку Shader Editor в Node Inspector
- Реализовать функционал редактирования шейдеров
Улучшение: Texture Inspector
Описание
Добавить возможность просмотра и редактирования текстур в Texture Inspector.
Задачи
- Добавить вкладку Texture Inspector в Graph Inspector
- Реализовать функционал редактирования текстур
Улучшение: Graph Editor
Описание
Добавить возможность просмотра и редактирования графов в Graph Editor.
Задачи
- Добавить вкладку Graph Editor в Assets
- Реализовать функционал редактирования графов