MoveTo.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { Node, Vec3 } from "cc";
  2. import { Timer } from "../../../../../../extensions/oops-plugin-framework/assets/core/common/timer/Timer";
  3. import { Vec3Util } from "../../../../../../extensions/oops-plugin-framework/assets/core/utils/Vec3Util";
  4. import { ecs } from "../../../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
  5. /** 向目标移动,移动过程中目标位置变化会自动修正移动目标点,直到未修正前移动到目标点停止 */
  6. @ecs.register('MoveTo')
  7. export class MoveToComp extends ecs.Comp {
  8. /** 移动节点 */
  9. node: Node = null!;
  10. /** 移动方向 */
  11. velocity: Vec3 = Vec3Util.zero;
  12. /** 移动速度(每秒移动的像素距离) */
  13. speed: number = 0;
  14. /** 目标实体ECS编号、目标位置 */
  15. target: Vec3 | Node | null = null;
  16. /** 坐标标(默认本地坐标) */
  17. ns: number = Node.NodeSpace.LOCAL;
  18. /** 偏移距离 */
  19. offset: number = 0;
  20. /** 偏移向量 */
  21. offsetVector: Vec3 | null = null;
  22. /** 移动完成回调 */
  23. onComplete: Function | null = null;
  24. /** 距离变化时 */
  25. onChange: Function | null = null;
  26. reset() {
  27. this.ns = Node.NodeSpace.LOCAL;
  28. this.offset = 0;
  29. this.target = null;
  30. this.offsetVector = null;
  31. this.onComplete = null;
  32. this.onChange = null;
  33. }
  34. }
  35. @ecs.register('VariableMoveTo')
  36. class VariableMoveToComponent extends ecs.Comp {
  37. /** 延时触发器 */
  38. timer: Timer = new Timer();
  39. /** 终点备份 */
  40. end: Vec3 | null = null;
  41. /** 目标位置 */
  42. target!: Vec3;
  43. reset() {
  44. this.end = null;
  45. this.timer.reset();
  46. }
  47. }
  48. /** 跟踪移动到目标位置 */
  49. export class MoveToSystem extends ecs.ComblockSystem<ecs.Entity> implements ecs.IEntityEnterSystem, ecs.IEntityRemoveSystem, ecs.ISystemUpdate {
  50. filter(): ecs.IMatcher {
  51. return ecs.allOf(MoveToComp);
  52. }
  53. entityEnter(e: ecs.Entity): void {
  54. e.add(VariableMoveToComponent);
  55. }
  56. entityRemove(e: ecs.Entity): void {
  57. e.remove(VariableMoveToComponent);
  58. }
  59. update(e: ecs.Entity) {
  60. let move = e.get(MoveToComp);
  61. let mtv = e.get(VariableMoveToComponent);
  62. let end: Vec3;
  63. console.assert(move.speed > 0, "移动速度必须要大于零");
  64. if (move.target instanceof Node) {
  65. end = move.ns == Node.NodeSpace.WORLD ? move.target.worldPosition : move.target.position;
  66. }
  67. else {
  68. end = move.target as Vec3;
  69. }
  70. // 目标移动后,重计算移动方向与移动到目标点的速度
  71. if (mtv.end == null || !mtv.end.strictEquals(end)) {
  72. let target = end.clone();
  73. if (move.offsetVector) {
  74. target = target.add(move.offsetVector); // 这里的问题
  75. }
  76. // 移动方向与移动数度
  77. let start = move.ns == Node.NodeSpace.WORLD ? move.node.worldPosition : move.node.position;
  78. move.velocity = Vec3Util.sub(target, start).normalize();
  79. // 移动时间与目标偏位置计算
  80. let distance = Vec3.distance(start, target) - move.offset;
  81. move.onChange?.call(this);
  82. if (distance - move.offset <= 0) {
  83. this.exit(e);
  84. }
  85. else {
  86. mtv.timer.step = distance / move.speed;
  87. mtv.end = end.clone();
  88. mtv.target = move.velocity.clone().multiplyScalar(distance).add(start);
  89. }
  90. }
  91. if (move.speed > 0) {
  92. let trans = Vec3Util.mul(move.velocity, move.speed * this.dt);
  93. move.node.translate(trans, Node.NodeSpace.LOCAL);
  94. }
  95. // 移动完成事件
  96. if (mtv.timer.update(this.dt)) {
  97. if (move.ns == Node.NodeSpace.WORLD)
  98. move.node.worldPosition = mtv.target;
  99. else
  100. move.node.position = mtv.target;
  101. this.exit(e);
  102. }
  103. }
  104. private exit(e: ecs.Entity) {
  105. let move = e.get(MoveToComp);
  106. move.onComplete?.call(this);
  107. e.remove(VariableMoveToComponent);
  108. e.remove(MoveToComp);
  109. }
  110. }