|
|
@@ -33,14 +33,21 @@ export class MoveToPathComp extends ecs.Comp {
|
|
|
class VariableMoveToPathComponent extends ecs.Comp {
|
|
|
/** 延时触发器 */
|
|
|
timer: Timer = new Timer();
|
|
|
+ /** 距离 */
|
|
|
+ distance: number = 0;
|
|
|
+ /** 起点备份 */
|
|
|
+ start: Vec3 | null = null;
|
|
|
/** 终点备份 */
|
|
|
end: Vec3 | null = null;
|
|
|
/** 目标位置 */
|
|
|
target!: Vec3;
|
|
|
|
|
|
+ isComplete: boolean = false
|
|
|
+
|
|
|
|
|
|
reset() {
|
|
|
this.end = null;
|
|
|
+ this.isComplete = false
|
|
|
this.timer.reset();
|
|
|
}
|
|
|
}
|
|
|
@@ -62,50 +69,55 @@ export class MoveToPathSystem extends ecs.ComblockSystem<ecs.Entity> implements
|
|
|
update(e: ecs.Entity) {
|
|
|
let move = e.get(MoveToPathComp);
|
|
|
let mtv = e.get(VariableMoveToPathComponent);
|
|
|
- // let end: Vec3;
|
|
|
|
|
|
console.assert(move.speed > 0, "移动速度必须要大于零");
|
|
|
-
|
|
|
// 如果没有路径点或者已经完成当前路径点的移动,则获取下一个路径点
|
|
|
if ((move.paths && move.paths.length > 0)) {
|
|
|
- if ((mtv.end == null || mtv.timer.update(this.dt))) {
|
|
|
+ if ((mtv.end == null || mtv.isComplete)) {
|
|
|
mtv.reset()
|
|
|
let end = move.paths.shift();
|
|
|
this.prepareMovement(e, move, mtv, end);
|
|
|
}
|
|
|
|
|
|
- } else if (mtv.timer.update(this.dt)) {
|
|
|
+ } else if (mtv.end == null || mtv.isComplete) {
|
|
|
this.exit(e)
|
|
|
}
|
|
|
|
|
|
+
|
|
|
// 执行移动
|
|
|
- if (move.speed > 0 && mtv.end != null) {
|
|
|
+ if (move.speed > 0 && mtv.end != null && !mtv.isComplete) {
|
|
|
let trans = Vec3Util.mul(move.velocity, move.speed * this.dt);
|
|
|
- move.node.translate(trans, move.ns);
|
|
|
- }
|
|
|
+ let start = move.ns == Node.NodeSpace.WORLD ? move.node.worldPosition : move.node.position;
|
|
|
+ let end = Vec3Util.add(start, trans)
|
|
|
+ if (Vec3Util.sub(end, mtv.start).length() > mtv.distance) {
|
|
|
+ this.finishMovement(e, move, mtv);
|
|
|
+ mtv.isComplete = true
|
|
|
+ } else {
|
|
|
+ move.node.translate(trans, move.ns);
|
|
|
+ }
|
|
|
|
|
|
- // 检查是否完成移动到当前目标点
|
|
|
- if (mtv.end != null && mtv.timer.update(this.dt)) {
|
|
|
- this.finishMovement(e, move, mtv);
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private prepareMovement(e: ecs.Entity, move: MoveToPathComp, mtv: VariableMoveToPathComponent, end: Vec3) {
|
|
|
let target = end.clone();
|
|
|
let start = move.ns == Node.NodeSpace.WORLD ? move.node.worldPosition : move.node.position;
|
|
|
move.velocity = Vec3Util.sub(target, start).normalize();
|
|
|
-
|
|
|
let distance = Vec3.distance(start, target);
|
|
|
move.onChange?.call(this);
|
|
|
|
|
|
if (distance <= 0) {
|
|
|
// this.exit(e);
|
|
|
+ mtv.isComplete = true
|
|
|
} else {
|
|
|
mtv.timer.step = distance / move.speed;
|
|
|
mtv.end = end.clone();
|
|
|
- mtv.target = move.velocity.clone().multiplyScalar(distance).add(start);
|
|
|
+ mtv.target = target;
|
|
|
+ mtv.start = start.clone()
|
|
|
+ mtv.distance = Vec3.distance(mtv.end, mtv.start);
|
|
|
}
|
|
|
}
|
|
|
|