Задержка действий с использованием ECS Decentraland
Как заставить действие произойти с задержкой, но после тайм-аута?
setTimeout()
функция не работает в сценах Decentraland, так есть ли альтернатива?
Например, я хочу, чтобы сущность ждала 300
миллисекунды после того, как это щелкнуло прежде, чем я удаляю это из двигателя.
3 ответа
Для этого вам нужно создать:
- Пользовательский компонент для отслеживания времени
- Группа компонентов для отслеживания всех объектов с задержкой в сцене
- Система, которая обновляет таймеры для всех этих компонентов в каждом кадре.
Это звучит довольно сложно, но как только вы создали одну задержку, реализация другой задержки займет всего одну строку.
Компонент:
@Component("timerDelay")
export class Delay implements ITimerComponent{
elapsedTime: number;
targetTime: number;
onTargetTimeReached: (ownerEntity: IEntity) => void;
private onTimeReachedCallback?: ()=> void
/**
* @param millisecs amount of time in milliseconds
* @param onTimeReachedCallback callback for when time is reached
*/
constructor(millisecs: number, onTimeReachedCallback?: ()=> void){
this.elapsedTime = 0
this.targetTime = millisecs / 1000
this.onTimeReachedCallback = onTimeReachedCallback
this.onTargetTimeReached = (entity)=>{
if (this.onTimeReachedCallback) this.onTimeReachedCallback()
entity.removeComponent(this)
}
}
}
Группа компонентов:
export const delayedEntities = engine.getComponentGroup(Delay)
Система:
// define system
class TimerSystem implements ISystem {
update(dt: number){
for (let entity of delayedEntities.entities) {
let timerComponent = entity.getComponent(component)
timerComponent.elapsedTime += dt
if (timerComponent.elapsedTime >= timerComponent.targetTime){
timerComponent.onTargetTimeReached(entity)
}
})
}
}
// instance system
engine.addSystem(new TimerSystem())
Как только все эти части будут на месте, вы можете просто сделать следующее, чтобы отложить выполнение вашей сцены:
const myEntity = new Entity()
myEntity.addComponent(new Delay(1000, () => {
log("time ran out")
}))
engine.addEntity(myEntity)
С опозданием на несколько лет, но выбранный ОП ответ устарел, потому что вы можете выполнить отсрочку:
import { Delay } from "node_modules/decentraland-ecs-utils/timer/component/delay"
const ent = new Entity
ent.addComponent(new Delay(3 * 1000, () => {
// this code will run when time is up
}))
Используйте функцию utils.Delay() в библиотеке utils. Эта функция просто берет время задержки в миллисекундах и функцию, которую вы хотите выполнить.
Вот полная документация, объясняющая, как добавить библиотеку + как использовать эту функцию, включая пример кода: