three-player-controller 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,7 +8,7 @@ npm install three-player-controller
8
8
 
9
9
  # 示例
10
10
 
11
- [Player Controller](https://hh-hang.github.io/three-player-controller/)
11
+ [glbScene](https://hh-hang.github.io/three-player-controller/index.html)
12
12
 
13
13
  ### 控制
14
14
 
package/dist/index.d.mts CHANGED
@@ -26,6 +26,7 @@ type PlayerControllerOptions = {
26
26
  minCamDistance?: number;
27
27
  maxCamDistance?: number;
28
28
  colliderMeshUrl?: string;
29
+ isShowMobileControls?: boolean;
29
30
  };
30
31
  declare function playerController(): {
31
32
  init: (opts: PlayerControllerOptions, callback?: () => void) => Promise<void>;
@@ -33,6 +34,7 @@ declare function playerController(): {
33
34
  reset: (pos?: THREE.Vector3) => void;
34
35
  update: (dt?: number) => Promise<void>;
35
36
  destroy: () => void;
37
+ setInput: (i: any) => void;
36
38
  };
37
39
  declare function onAllEvent(): void;
38
40
  declare function offAllEvent(): void;
package/dist/index.d.ts CHANGED
@@ -26,6 +26,7 @@ type PlayerControllerOptions = {
26
26
  minCamDistance?: number;
27
27
  maxCamDistance?: number;
28
28
  colliderMeshUrl?: string;
29
+ isShowMobileControls?: boolean;
29
30
  };
30
31
  declare function playerController(): {
31
32
  init: (opts: PlayerControllerOptions, callback?: () => void) => Promise<void>;
@@ -33,6 +34,7 @@ declare function playerController(): {
33
34
  reset: (pos?: THREE.Vector3) => void;
34
35
  update: (dt?: number) => Promise<void>;
35
36
  destroy: () => void;
37
+ setInput: (i: any) => void;
36
38
  };
37
39
  declare function onAllEvent(): void;
38
40
  declare function offAllEvent(): void;
package/dist/index.js CHANGED
@@ -42,6 +42,17 @@ var import_RoundedBoxGeometry = require("three/examples/jsm/geometries/RoundedBo
42
42
  var import_DRACOLoader = require("three/examples/jsm/loaders/DRACOLoader.js");
43
43
  var import_GLTFLoader = require("three/examples/jsm/loaders/GLTFLoader.js");
44
44
  var BufferGeometryUtils = __toESM(require("three/examples/jsm/utils/BufferGeometryUtils.js"));
45
+
46
+ // assets/imgs/fly.png
47
+ var fly_default = "data:image/png;base64,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";
48
+
49
+ // assets/imgs/jump.png
50
+ var jump_default = "data:image/png;base64,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";
51
+
52
+ // assets/imgs/view.png
53
+ var view_default = "data:image/png;base64,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";
54
+
55
+ // src/playerController.ts
45
56
  THREE.Mesh.prototype.raycast = import_three_mesh_bvh.acceleratedRaycast;
46
57
  var controllerInstance = null;
47
58
  var clock = new THREE.Clock();
@@ -57,15 +68,15 @@ var PlayerController = class {
57
68
  this.displayPlayer = false;
58
69
  this.displayCollider = false;
59
70
  this.displayVisualizer = false;
60
- // 场景对象
71
+ // 场景对象
61
72
  this.collider = null;
62
73
  this.visualizer = null;
63
74
  this.person = null;
64
- // 状态开关
75
+ // 状态开关
65
76
  this.playerIsOnGround = false;
66
77
  this.isupdate = true;
67
78
  this.isFlying = false;
68
- // 输入状态
79
+ // 输入状态
69
80
  this.fwdPressed = false;
70
81
  this.bkdPressed = false;
71
82
  this.lftPressed = false;
@@ -73,6 +84,19 @@ var PlayerController = class {
73
84
  this.spacePressed = false;
74
85
  this.ctPressed = false;
75
86
  this.shiftPressed = false;
87
+ // 移动端输入
88
+ this.prevJoyState = { dirX: 0, dirY: 0, shift: false };
89
+ // 移动控制相关
90
+ this.joystickManager = null;
91
+ this.joystickZoneEl = null;
92
+ this.lookAreaEl = null;
93
+ this.jumpBtnEl = null;
94
+ this.flyBtnEl = null;
95
+ this.viewBtnEl = null;
96
+ this.lookPointerId = null;
97
+ this.isLookDown = false;
98
+ this.lastTouchX = 0;
99
+ this.lastTouchY = 0;
76
100
  // 第三人称
77
101
  this._camCollisionLerp = 0.18;
78
102
  // 平滑系数
@@ -83,7 +107,7 @@ var PlayerController = class {
83
107
  this._maxCamDistance = 4.4;
84
108
  // 摄像机最大距离
85
109
  this.orginMaxCamDistance = 4.4;
86
- // 物理/运动
110
+ // 物理/运动
87
111
  this.playerVelocity = new THREE.Vector3();
88
112
  // 玩家速度向量
89
113
  this.upVector = new THREE.Vector3(0, 1, 0);
@@ -93,6 +117,8 @@ var PlayerController = class {
93
117
  this.tempBox = new THREE.Box3();
94
118
  this.tempMat = new THREE.Matrix4();
95
119
  this.tempSegment = new THREE.Line3();
120
+ // 检测动画定时
121
+ this.recheckAnimTimer = null;
96
122
  // 复用向量:用于相机朝向 / 移动
97
123
  this.camDir = new THREE.Vector3();
98
124
  this.moveDir = new THREE.Vector3();
@@ -143,6 +169,8 @@ var PlayerController = class {
143
169
  case "Space":
144
170
  this.spacePressed = true;
145
171
  if (!this.playerIsOnGround || this.isFlying) return;
172
+ const next = this.personActions?.get("jumping");
173
+ if (next && this.actionState === next) return;
146
174
  this.playPersonAnimationByName("jumping");
147
175
  this.playerVelocity.y = this.jumpHeight;
148
176
  this.playerIsOnGround = false;
@@ -156,6 +184,8 @@ var PlayerController = class {
156
184
  case "KeyF":
157
185
  this.isFlying = !this.isFlying;
158
186
  this.setAnimationByPressed();
187
+ if (!this.isFlying && !this.playerIsOnGround)
188
+ this.playPersonAnimationByName("jumping");
159
189
  break;
160
190
  }
161
191
  };
@@ -235,49 +265,51 @@ var PlayerController = class {
235
265
  this.playPersonAnimationByName("walking_backward");
236
266
  return;
237
267
  }
238
- } else {
239
- this.playPersonAnimationByName("jumping");
240
268
  }
269
+ if (this.recheckAnimTimer !== null) {
270
+ clearTimeout(this.recheckAnimTimer);
271
+ }
272
+ this.recheckAnimTimer = setTimeout(() => {
273
+ this.setAnimationByPressed();
274
+ this.recheckAnimTimer = null;
275
+ }, 200);
241
276
  };
242
277
  // 鼠标移动事件
243
278
  this._mouseMove = (e) => {
244
279
  if (document.pointerLockElement !== document.body) return;
245
- if (this.isFirstPerson) {
246
- const yaw = -e.movementX * 1e-4 * this.mouseSensity;
247
- const pitch = -e.movementY * 1e-4 * this.mouseSensity;
248
- this.player.rotateY(yaw);
249
- this.camera.rotation.x = THREE.MathUtils.clamp(
250
- this.camera.rotation.x + pitch,
251
- -1.3,
252
- 1.4
253
- );
254
- } else {
255
- const sensitivity = 1e-4 * this.mouseSensity;
256
- const deltaX = -e.movementX * sensitivity;
257
- const deltaY = -e.movementY * sensitivity;
258
- const target = this.player.position.clone();
259
- const distance = this.camera.position.distanceTo(target);
260
- const currentPosition = this.camera.position.clone().sub(target);
261
- let theta = Math.atan2(currentPosition.x, currentPosition.z);
262
- let phi = Math.acos(currentPosition.y / distance);
263
- theta += deltaX;
264
- phi += deltaY;
265
- phi = Math.max(0.1, Math.min(Math.PI - 0.1, phi));
266
- const newX = distance * Math.sin(phi) * Math.sin(theta);
267
- const newY = distance * Math.cos(phi);
268
- const newZ = distance * Math.sin(phi) * Math.cos(theta);
269
- this.camera.position.set(
270
- target.x + newX,
271
- target.y + newY,
272
- target.z + newZ
273
- );
274
- this.camera.lookAt(target);
275
- }
280
+ this.setToward(e.movementX, e.movementY, 1e-4);
276
281
  };
277
282
  this._mouseClick = (e) => {
278
283
  if (document.pointerLockElement !== document.body)
279
284
  document.body.requestPointerLock();
280
285
  };
286
+ this.onPointerDown = (e) => {
287
+ if (e.pointerType !== "touch") return;
288
+ this.isLookDown = true;
289
+ this.lookPointerId = e.pointerId;
290
+ this.lastTouchX = e.clientX;
291
+ this.lastTouchY = e.clientY;
292
+ this.lookAreaEl?.setPointerCapture && this.lookAreaEl.setPointerCapture(e.pointerId);
293
+ e.preventDefault();
294
+ };
295
+ this.onPointerMove = (e) => {
296
+ if (!this.isLookDown || e.pointerId !== this.lookPointerId) return;
297
+ const dx = e.clientX - this.lastTouchX;
298
+ const dy = e.clientY - this.lastTouchY;
299
+ this.lastTouchX = e.clientX;
300
+ this.lastTouchY = e.clientY;
301
+ this.setInput({
302
+ lookDeltaX: dx,
303
+ lookDeltaY: dy
304
+ });
305
+ e.preventDefault();
306
+ };
307
+ this.onPointerUp = (e) => {
308
+ if (e.pointerId !== this.lookPointerId) return;
309
+ this.isLookDown = false;
310
+ this.lookPointerId = null;
311
+ this.lookAreaEl?.releasePointerCapture && this.lookAreaEl.releasePointerCapture(e.pointerId);
312
+ };
281
313
  this._raycaster.firstHitOnly = true;
282
314
  this._raycasterPersonToCam.firstHitOnly = true;
283
315
  }
@@ -301,11 +333,18 @@ var PlayerController = class {
301
333
  this._minCamDistance = opts.minCamDistance ? opts.minCamDistance * s : 100 * s;
302
334
  this._maxCamDistance = opts.maxCamDistance ? opts.maxCamDistance * s : 440 * s;
303
335
  this.orginMaxCamDistance = this._maxCamDistance;
336
+ this.isShowMobileControls = opts.isShowMobileControls ?? true;
337
+ function isMobileDevice() {
338
+ return navigator.maxTouchPoints && navigator.maxTouchPoints > 0 || "ontouchstart" in window || /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
339
+ }
340
+ if (isMobileDevice() && this.isShowMobileControls) {
341
+ this.initMobileControls();
342
+ }
304
343
  await this.createBVH(opts.colliderMeshUrl);
305
344
  this.createPlayer();
306
345
  await this.loadPersonGLB();
307
- if (this.isFirstPerson && this.player) {
308
- this.player.add(this.camera);
346
+ if (this.isFirstPerson && this.person) {
347
+ this.person.add(this.camera);
309
348
  }
310
349
  this.onAllEvent();
311
350
  this.setCameraPos();
@@ -404,11 +443,7 @@ var PlayerController = class {
404
443
  this.person.traverse((child) => {
405
444
  if (child.isMesh) {
406
445
  child.castShadow = true;
407
- const mat = child.material;
408
- if (!mat) return;
409
- const mats = Array.isArray(mat) ? mat : [mat];
410
- mats.forEach((m) => {
411
- });
446
+ child.receiveShadow = true;
412
447
  }
413
448
  });
414
449
  this.player.add(this.person);
@@ -791,6 +826,7 @@ var PlayerController = class {
791
826
  this.scene.remove(this.collider);
792
827
  this.collider = null;
793
828
  }
829
+ this.destroyMobileControls();
794
830
  controllerInstance = null;
795
831
  }
796
832
  // 事件绑定
@@ -928,6 +964,305 @@ var PlayerController = class {
928
964
  }
929
965
  this.boundingBoxMinY = this.collider.geometry.boundingBox.min.y;
930
966
  }
967
+ // 设置朝向
968
+ setToward(dx, dy, speed) {
969
+ if (this.isFirstPerson) {
970
+ const yaw = -dx * speed * this.mouseSensity;
971
+ const pitch = -dy * speed * this.mouseSensity;
972
+ this.player.rotateY(yaw);
973
+ this.camera.rotation.x = THREE.MathUtils.clamp(
974
+ this.camera.rotation.x + pitch,
975
+ -1.1,
976
+ 1.4
977
+ );
978
+ } else {
979
+ const sensitivity = this.mouseSensity;
980
+ const deltaX = -dx * speed * sensitivity;
981
+ const deltaY = -dy * speed * sensitivity;
982
+ const target = this.player.position.clone();
983
+ const distance = this.camera.position.distanceTo(target);
984
+ const currentPosition = this.camera.position.clone().sub(target);
985
+ let theta = Math.atan2(currentPosition.x, currentPosition.z);
986
+ let phi = Math.acos(currentPosition.y / distance);
987
+ theta += deltaX;
988
+ phi += deltaY;
989
+ phi = Math.max(0.1, Math.min(Math.PI - 0.1, phi));
990
+ const newX = distance * Math.sin(phi) * Math.sin(theta);
991
+ const newY = distance * Math.cos(phi);
992
+ const newZ = distance * Math.sin(phi) * Math.cos(theta);
993
+ this.camera.position.set(
994
+ target.x + newX,
995
+ target.y + newY,
996
+ target.z + newZ
997
+ );
998
+ this.camera.lookAt(target);
999
+ }
1000
+ }
1001
+ // 设置输入
1002
+ setInput(input) {
1003
+ if (typeof input.moveX === "number") {
1004
+ this.lftPressed = input.moveX == -1;
1005
+ this.rgtPressed = input.moveX == 1;
1006
+ this.setAnimationByPressed();
1007
+ }
1008
+ if (typeof input.moveY === "number") {
1009
+ this.fwdPressed = input.moveY == 1;
1010
+ this.bkdPressed = input.moveY == -1;
1011
+ this.setAnimationByPressed();
1012
+ }
1013
+ if (typeof input.lookDeltaX === "number" && typeof input.lookDeltaY === "number") {
1014
+ this.setToward(input.lookDeltaX, input.lookDeltaY, 2e-3);
1015
+ }
1016
+ if (typeof input.jump === "boolean") {
1017
+ if (input.jump) {
1018
+ this.spacePressed = true;
1019
+ if (!this.playerIsOnGround || this.isFlying) return;
1020
+ this.playPersonAnimationByName("jumping");
1021
+ this.playerVelocity.y = this.jumpHeight;
1022
+ this.playerIsOnGround = false;
1023
+ } else {
1024
+ this.spacePressed = false;
1025
+ }
1026
+ }
1027
+ if (typeof input.shift === "boolean") {
1028
+ this.shiftPressed = input.shift;
1029
+ }
1030
+ if (input.toggleView) {
1031
+ this.changeView();
1032
+ }
1033
+ if (input.toggleFly) {
1034
+ this.isFlying = !this.isFlying;
1035
+ this.setAnimationByPressed();
1036
+ if (!this.isFlying && !this.playerIsOnGround)
1037
+ this.playPersonAnimationByName("jumping");
1038
+ }
1039
+ }
1040
+ // 初始化移动端摇杆控制
1041
+ async initMobileControls() {
1042
+ this.controls.maxPolarAngle = Math.PI * (300 / 360);
1043
+ this.controls.touches = { ONE: null, TWO: null };
1044
+ const mod = (await import("nipplejs")).default;
1045
+ const nipple = mod;
1046
+ const JOY_SIZE = 120;
1047
+ const container = document.body;
1048
+ this.joystickZoneEl = document.createElement("div");
1049
+ this.joystickZoneEl.id = "joy-zone";
1050
+ Object.assign(this.joystickZoneEl.style, {
1051
+ position: "absolute",
1052
+ left: "16px",
1053
+ bottom: "16px",
1054
+ width: `${JOY_SIZE + 40}px`,
1055
+ height: `${JOY_SIZE + 40}px`,
1056
+ touchAction: "none",
1057
+ zIndex: "999",
1058
+ pointerEvents: "auto",
1059
+ WebkitUserSelect: "none",
1060
+ userSelect: "none"
1061
+ });
1062
+ container.appendChild(this.joystickZoneEl);
1063
+ ["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
1064
+ (evtName) => {
1065
+ this.joystickZoneEl?.addEventListener(
1066
+ evtName,
1067
+ (e) => {
1068
+ e.preventDefault();
1069
+ },
1070
+ { passive: false }
1071
+ );
1072
+ }
1073
+ );
1074
+ this.joystickManager = nipple.create({
1075
+ zone: this.joystickZoneEl,
1076
+ mode: "static",
1077
+ position: {
1078
+ left: `${(JOY_SIZE + 40) / 2}px`,
1079
+ bottom: `${(JOY_SIZE + 40) / 2}px`
1080
+ },
1081
+ color: "#ffffff",
1082
+ size: JOY_SIZE,
1083
+ multitouch: true,
1084
+ maxNumberOfNipples: 1
1085
+ });
1086
+ this.joystickManager.on("move", (_evt, data) => {
1087
+ if (!data) return;
1088
+ const rawX = data.vector?.x ?? 0;
1089
+ const rawY = data.vector?.y ?? 0;
1090
+ const distance = data.distance ?? 0;
1091
+ const deadzone = 0.5;
1092
+ const dirX = rawX > deadzone ? 1 : rawX < -deadzone ? -1 : 0;
1093
+ const dirY = rawY > deadzone ? 1 : rawY < -deadzone ? -1 : 0;
1094
+ const sprintThreshold = JOY_SIZE / 2;
1095
+ const isSprinting = distance >= sprintThreshold;
1096
+ const prev = this.prevJoyState || { dirX: 0, dirY: 0, shift: false };
1097
+ if (dirX === prev.dirX && dirY === prev.dirY && isSprinting === prev.shift) {
1098
+ return;
1099
+ }
1100
+ this.prevJoyState = { dirX, dirY, shift: isSprinting };
1101
+ this.setInput({ moveX: dirX, moveY: dirY, shift: isSprinting });
1102
+ });
1103
+ this.joystickManager.on("end", () => {
1104
+ const prev = this.prevJoyState || { dirX: 0, dirY: 0, shift: false };
1105
+ if (prev.dirX !== 0 || prev.dirY !== 0 || prev.shift !== false) {
1106
+ this.prevJoyState = { dirX: 0, dirY: 0, shift: false };
1107
+ this.setInput({ moveX: 0, moveY: 0, shift: false });
1108
+ }
1109
+ });
1110
+ this.lookAreaEl = document.createElement("div");
1111
+ Object.assign(this.lookAreaEl.style, {
1112
+ position: "absolute",
1113
+ right: "0",
1114
+ bottom: "0",
1115
+ width: "50%",
1116
+ height: "100%",
1117
+ zIndex: "998",
1118
+ touchAction: "none",
1119
+ WebkitUserSelect: "none",
1120
+ userSelect: "none"
1121
+ });
1122
+ container.appendChild(this.lookAreaEl);
1123
+ ["touchstart", "touchmove", "touchend", "touchcancel"].forEach(
1124
+ (evtName) => {
1125
+ this.lookAreaEl?.addEventListener(
1126
+ evtName,
1127
+ (e) => {
1128
+ e.preventDefault();
1129
+ },
1130
+ { passive: false }
1131
+ );
1132
+ }
1133
+ );
1134
+ this.lookAreaEl.addEventListener("pointerdown", this.onPointerDown, {
1135
+ passive: false
1136
+ });
1137
+ this.lookAreaEl.addEventListener("pointermove", this.onPointerMove, {
1138
+ passive: false
1139
+ });
1140
+ this.lookAreaEl.addEventListener("pointerup", this.onPointerUp, {
1141
+ passive: false
1142
+ });
1143
+ this.lookAreaEl.addEventListener("pointercancel", this.onPointerUp, {
1144
+ passive: false
1145
+ });
1146
+ const createBtn = (rightPx, bottomPx, bgUrl) => {
1147
+ const btn = document.createElement("button");
1148
+ const styles = {
1149
+ position: "absolute",
1150
+ right: `${rightPx}px`,
1151
+ bottom: `${bottomPx}px`,
1152
+ width: "56px",
1153
+ height: "56px",
1154
+ zIndex: "1000",
1155
+ borderRadius: "50%",
1156
+ border: "2px solid black",
1157
+ background: "rgba(0,0,0)",
1158
+ padding: "20px",
1159
+ opacity: "0.95",
1160
+ touchAction: "none",
1161
+ fontSize: "14px",
1162
+ userSelect: "none",
1163
+ overflow: "hidden",
1164
+ boxSizing: "border-box",
1165
+ backgroundColor: "transparent",
1166
+ backgroundRepeat: "no-repeat, no-repeat",
1167
+ backgroundPosition: "center center, center center",
1168
+ backgroundSize: "100% 100%, 80% 80%"
1169
+ };
1170
+ if (bgUrl) {
1171
+ const overlayColor = "rgba(0,0,0,0.5)";
1172
+ styles.backgroundImage = `linear-gradient(${overlayColor}, ${overlayColor}), url("${bgUrl}")`;
1173
+ }
1174
+ Object.assign(btn.style, styles);
1175
+ container.appendChild(btn);
1176
+ ["touchstart", "touchend", "touchcancel"].forEach((evtName) => {
1177
+ btn.addEventListener(
1178
+ evtName,
1179
+ (e) => {
1180
+ e.preventDefault();
1181
+ },
1182
+ { passive: false }
1183
+ );
1184
+ });
1185
+ return btn;
1186
+ };
1187
+ this.jumpBtnEl = createBtn(14, 14, jump_default);
1188
+ this.jumpBtnEl.addEventListener(
1189
+ "touchstart",
1190
+ (e) => {
1191
+ e.preventDefault();
1192
+ this.setInput({ jump: true });
1193
+ },
1194
+ { passive: false }
1195
+ );
1196
+ this.jumpBtnEl.addEventListener(
1197
+ "touchend",
1198
+ (e) => {
1199
+ e.preventDefault();
1200
+ this.setInput({ jump: false });
1201
+ },
1202
+ { passive: false }
1203
+ );
1204
+ this.jumpBtnEl.addEventListener(
1205
+ "touchcancel",
1206
+ (e) => {
1207
+ e.preventDefault();
1208
+ this.setInput({ jump: false });
1209
+ },
1210
+ { passive: false }
1211
+ );
1212
+ this.flyBtnEl = createBtn(14, 14 + 80, fly_default);
1213
+ this.flyBtnEl.addEventListener(
1214
+ "touchstart",
1215
+ (e) => {
1216
+ e.preventDefault();
1217
+ this.setInput({ toggleFly: true });
1218
+ },
1219
+ { passive: false }
1220
+ );
1221
+ this.viewBtnEl = createBtn(14, 14 + 200, view_default);
1222
+ this.viewBtnEl.addEventListener(
1223
+ "touchstart",
1224
+ (e) => {
1225
+ e.preventDefault();
1226
+ this.setInput({ toggleView: true });
1227
+ },
1228
+ { passive: false }
1229
+ );
1230
+ }
1231
+ // 销毁移动端摇杆控制
1232
+ destroyMobileControls() {
1233
+ try {
1234
+ if (this.joystickManager && this.joystickManager.destroy) {
1235
+ this.joystickManager.destroy();
1236
+ this.joystickManager = null;
1237
+ }
1238
+ if (this.joystickZoneEl?.parentElement) {
1239
+ this.joystickZoneEl.parentElement.removeChild(this.joystickZoneEl);
1240
+ this.joystickZoneEl = null;
1241
+ }
1242
+ if (this.lookAreaEl?.parentElement) {
1243
+ this.lookAreaEl.parentElement.removeChild(this.lookAreaEl);
1244
+ this.lookAreaEl = null;
1245
+ }
1246
+ if (this.jumpBtnEl?.parentElement) {
1247
+ this.jumpBtnEl.parentElement.removeChild(this.jumpBtnEl);
1248
+ this.jumpBtnEl = null;
1249
+ }
1250
+ if (this.flyBtnEl?.parentElement) {
1251
+ this.flyBtnEl.parentElement.removeChild(this.flyBtnEl);
1252
+ this.flyBtnEl = null;
1253
+ }
1254
+ if (this.viewBtnEl?.parentElement) {
1255
+ this.viewBtnEl.parentElement.removeChild(this.viewBtnEl);
1256
+ this.viewBtnEl = null;
1257
+ }
1258
+ this.lookAreaEl?.removeEventListener("pointerdown", this.onPointerDown);
1259
+ this.lookAreaEl?.removeEventListener("pointermove", this.onPointerMove);
1260
+ this.lookAreaEl?.removeEventListener("pointerup", this.onPointerUp);
1261
+ this.lookAreaEl?.removeEventListener("pointercancel", this.onPointerUp);
1262
+ } catch (e) {
1263
+ console.warn("\u9500\u6BC1\u79FB\u52A8\u7AEF\u6447\u6746\u63A7\u5236\u65F6\u51FA\u9519\uFF1A", e);
1264
+ }
1265
+ }
931
1266
  };
932
1267
  function playerController() {
933
1268
  if (!controllerInstance) controllerInstance = new PlayerController();
@@ -937,7 +1272,8 @@ function playerController() {
937
1272
  changeView: () => c.changeView(),
938
1273
  reset: (pos) => c.reset(pos),
939
1274
  update: (dt) => c.update(dt),
940
- destroy: () => c.destroy()
1275
+ destroy: () => c.destroy(),
1276
+ setInput: (i) => c.setInput(i)
941
1277
  };
942
1278
  }
943
1279
  function onAllEvent() {