| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- import { Node, Vec3 } from "cc";
- import { Timer } from "../../../../../../extensions/oops-plugin-framework/assets/core/common/timer/Timer";
- import { Vec3Util } from "../../../../../../extensions/oops-plugin-framework/assets/core/utils/Vec3Util";
- import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
- /** 向目标移动,移动过程中目标位置变化会自动修正移动目标点,直到未修正前移动到目标点停止 */
- @ecs.register('MoveToPath')
- export class MoveToPathComp extends ecs.Comp {
- /** 移动节点 */
- node: Node = null!;
- /** 移动速度(每秒移动的像素距离) */
- speed: number = 0;
- /** 移动方向 */
- velocity: Vec3 = Vec3Util.zero;
- /** 路径数组 */
- paths: Vec3[] | null = null;
- /** 坐标标(默认本地坐标) */
- ns: number = Node.NodeSpace.LOCAL;
- /** 移动完成回调 */
- onComplete: Function | null = null;
- /** 距离变化时 */
- onChange: Function | null = null;
- reset() {
- this.ns = Node.NodeSpace.LOCAL;
- this.onComplete = null;
- this.onChange = null;
- }
- }
- @ecs.register('VariableMoveToPath')
- 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();
- }
- }
- /** 按照路径移动 */
- export class MoveToPathSystem extends ecs.ComblockSystem<ecs.Entity> implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem, ecs.ISystemUpdate {
- filter(): ecs.IMatcher {
- return ecs.allOf(MoveToPathComp);
- }
- entityEnter(e: ecs.Entity): void {
- e.add(VariableMoveToPathComponent);
- }
- entityRemove(e: ecs.Entity): void {
- e.remove(VariableMoveToPathComponent);
- }
- update(e: ecs.Entity) {
- let move = e.get(MoveToPathComp);
- let mtv = e.get(VariableMoveToPathComponent);
- // console.assert(move.speed > 0, "移动速度必须要大于零");
- // 如果没有路径点或者已经完成当前路径点的移动,则获取下一个路径点
- if ((move.paths && move.paths.length > 0)) {
- if ((mtv.end == null || mtv.isComplete)) {
- mtv.reset()
- let end = move.paths.shift();
- this.prepareMovement(e, move, mtv, end);
- }
- } else if (mtv.end == null || mtv.isComplete) {
- this.exit(e)
- }
- // 执行移动
- if (move.speed > 0 && mtv.end != null && !mtv.isComplete) {
- let trans = Vec3Util.mul(move.velocity, move.speed * this.dt);
- 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||mtv.timer.update(this.dt)) {
- this.finishMovement(e, move, mtv);
- mtv.isComplete = true
- } else {
- move.node.translate(trans, move.ns);
- move.node.forward = trans
- }
- }
- }
- 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 = target;
- mtv.start = start.clone()
- mtv.distance = Vec3.distance(mtv.end, mtv.start);
- }
- }
- private finishMovement(e: ecs.Entity, move: MoveToPathComp, mtv: VariableMoveToPathComponent) {
- if (move.ns == Node.NodeSpace.WORLD)
- move.node.worldPosition = mtv.target;
- else
- move.node.position = mtv.target;
- // this.exit(e);
- }
- private exit(e: ecs.Entity) {
- let move = e.get(MoveToPathComp);
- move.onComplete?.call(this);
- e.remove(VariableMoveToPathComponent);
- e.remove(MoveToPathComp);
- }
- }
|