three-player-controller 0.1.9 → 0.2.0
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/dist/index.js +151 -42
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +152 -43
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -42,6 +42,7 @@ 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
|
+
THREE.Mesh.prototype.raycast = import_three_mesh_bvh.acceleratedRaycast;
|
|
45
46
|
var controllerInstance = null;
|
|
46
47
|
var clock = new THREE.Clock();
|
|
47
48
|
var PlayerController = class {
|
|
@@ -105,8 +106,14 @@ var PlayerController = class {
|
|
|
105
106
|
this.DIR_UP = new THREE.Vector3(0, 1, 0);
|
|
106
107
|
this._personToCam = new THREE.Vector3();
|
|
107
108
|
this._originTmp = new THREE.Vector3();
|
|
108
|
-
this._raycaster = new THREE.Raycaster(
|
|
109
|
-
|
|
109
|
+
this._raycaster = new THREE.Raycaster(
|
|
110
|
+
new THREE.Vector3(),
|
|
111
|
+
new THREE.Vector3(0, -1, 0)
|
|
112
|
+
);
|
|
113
|
+
this._raycasterPersonToCam = new THREE.Raycaster(
|
|
114
|
+
new THREE.Vector3(),
|
|
115
|
+
new THREE.Vector3()
|
|
116
|
+
);
|
|
110
117
|
// 键盘按下事件
|
|
111
118
|
this._boundOnKeydown = async (e) => {
|
|
112
119
|
if (e.ctrlKey && (e.code === "KeyW" || e.code === "KeyA" || e.code === "KeyS" || e.code === "KeyD")) {
|
|
@@ -148,12 +155,7 @@ var PlayerController = class {
|
|
|
148
155
|
break;
|
|
149
156
|
case "KeyF":
|
|
150
157
|
this.isFlying = !this.isFlying;
|
|
151
|
-
this.
|
|
152
|
-
if (!this.isFlying && !this.playerIsOnGround) {
|
|
153
|
-
this.playPersonAnimationByName("jumping");
|
|
154
|
-
} else {
|
|
155
|
-
this.setAnimationByPressed();
|
|
156
|
-
}
|
|
158
|
+
this.setAnimationByPressed();
|
|
157
159
|
break;
|
|
158
160
|
}
|
|
159
161
|
};
|
|
@@ -233,6 +235,8 @@ var PlayerController = class {
|
|
|
233
235
|
this.playPersonAnimationByName("walking_backward");
|
|
234
236
|
return;
|
|
235
237
|
}
|
|
238
|
+
} else {
|
|
239
|
+
this.playPersonAnimationByName("jumping");
|
|
236
240
|
}
|
|
237
241
|
};
|
|
238
242
|
// 鼠标移动事件
|
|
@@ -242,7 +246,11 @@ var PlayerController = class {
|
|
|
242
246
|
const yaw = -e.movementX * 1e-4 * this.mouseSensity;
|
|
243
247
|
const pitch = -e.movementY * 1e-4 * this.mouseSensity;
|
|
244
248
|
this.player.rotateY(yaw);
|
|
245
|
-
this.camera.rotation.x = THREE.MathUtils.clamp(
|
|
249
|
+
this.camera.rotation.x = THREE.MathUtils.clamp(
|
|
250
|
+
this.camera.rotation.x + pitch,
|
|
251
|
+
-1.3,
|
|
252
|
+
1.4
|
|
253
|
+
);
|
|
246
254
|
} else {
|
|
247
255
|
const sensitivity = 1e-4 * this.mouseSensity;
|
|
248
256
|
const deltaX = -e.movementX * sensitivity;
|
|
@@ -258,12 +266,17 @@ var PlayerController = class {
|
|
|
258
266
|
const newX = distance * Math.sin(phi) * Math.sin(theta);
|
|
259
267
|
const newY = distance * Math.cos(phi);
|
|
260
268
|
const newZ = distance * Math.sin(phi) * Math.cos(theta);
|
|
261
|
-
this.camera.position.set(
|
|
269
|
+
this.camera.position.set(
|
|
270
|
+
target.x + newX,
|
|
271
|
+
target.y + newY,
|
|
272
|
+
target.z + newZ
|
|
273
|
+
);
|
|
262
274
|
this.camera.lookAt(target);
|
|
263
275
|
}
|
|
264
276
|
};
|
|
265
277
|
this._mouseClick = (e) => {
|
|
266
|
-
if (document.pointerLockElement !== document.body)
|
|
278
|
+
if (document.pointerLockElement !== document.body)
|
|
279
|
+
document.body.requestPointerLock();
|
|
267
280
|
};
|
|
268
281
|
this._raycaster.firstHitOnly = true;
|
|
269
282
|
this._raycasterPersonToCam.firstHitOnly = true;
|
|
@@ -302,15 +315,25 @@ var PlayerController = class {
|
|
|
302
315
|
this.isFirstPerson = !this.isFirstPerson;
|
|
303
316
|
if (this.isFirstPerson) {
|
|
304
317
|
this.player.attach(this.camera);
|
|
305
|
-
this.camera.position.set(
|
|
318
|
+
this.camera.position.set(
|
|
319
|
+
0,
|
|
320
|
+
40 * this.playerModel.scale,
|
|
321
|
+
30 * this.playerModel.scale
|
|
322
|
+
);
|
|
306
323
|
this.camera.rotation.set(0, Math.PI, 0);
|
|
307
324
|
document.body.requestPointerLock();
|
|
308
325
|
} else {
|
|
309
326
|
this.scene.attach(this.camera);
|
|
310
327
|
const worldPos = this.player.position.clone();
|
|
311
|
-
const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
|
|
328
|
+
const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
|
|
329
|
+
this.player.quaternion
|
|
330
|
+
);
|
|
312
331
|
const angle = Math.atan2(dir.z, dir.x);
|
|
313
|
-
const offset = new THREE.Vector3(
|
|
332
|
+
const offset = new THREE.Vector3(
|
|
333
|
+
Math.cos(angle) * 400 * this.playerModel.scale,
|
|
334
|
+
200 * this.playerModel.scale,
|
|
335
|
+
Math.sin(angle) * 400 * this.playerModel.scale
|
|
336
|
+
);
|
|
314
337
|
this.camera.position.copy(worldPos).add(offset);
|
|
315
338
|
this.controls.target.copy(worldPos);
|
|
316
339
|
document.body.requestPointerLock();
|
|
@@ -319,12 +342,22 @@ var PlayerController = class {
|
|
|
319
342
|
// 摄像机/控制器设置
|
|
320
343
|
setCameraPos() {
|
|
321
344
|
if (this.isFirstPerson) {
|
|
322
|
-
this.camera.position.set(
|
|
345
|
+
this.camera.position.set(
|
|
346
|
+
0,
|
|
347
|
+
40 * this.playerModel.scale,
|
|
348
|
+
30 * this.playerModel.scale
|
|
349
|
+
);
|
|
323
350
|
} else {
|
|
324
351
|
const worldPos = this.player.position.clone();
|
|
325
|
-
const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
|
|
352
|
+
const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
|
|
353
|
+
this.player.quaternion
|
|
354
|
+
);
|
|
326
355
|
const angle = Math.atan2(dir.z, dir.x);
|
|
327
|
-
const offset = new THREE.Vector3(
|
|
356
|
+
const offset = new THREE.Vector3(
|
|
357
|
+
Math.cos(angle) * 400 * this.playerModel.scale,
|
|
358
|
+
200 * this.playerModel.scale,
|
|
359
|
+
Math.sin(angle) * 400 * this.playerModel.scale
|
|
360
|
+
);
|
|
328
361
|
this.camera.position.copy(worldPos).add(offset);
|
|
329
362
|
}
|
|
330
363
|
this.camera.updateProjectionMatrix();
|
|
@@ -351,7 +384,9 @@ var PlayerController = class {
|
|
|
351
384
|
// 初始化加载器
|
|
352
385
|
async initLoader() {
|
|
353
386
|
const dracoLoader = new import_DRACOLoader.DRACOLoader();
|
|
354
|
-
dracoLoader.setDecoderPath(
|
|
387
|
+
dracoLoader.setDecoderPath(
|
|
388
|
+
"https://unpkg.com/three@0.180.0/examples/jsm/libs/draco/gltf/"
|
|
389
|
+
);
|
|
355
390
|
dracoLoader.setDecoderConfig({ type: "js" });
|
|
356
391
|
this.loader.setDRACOLoader(dracoLoader);
|
|
357
392
|
}
|
|
@@ -367,7 +402,11 @@ var PlayerController = class {
|
|
|
367
402
|
this.person.traverse((child) => {
|
|
368
403
|
if (child.isMesh) {
|
|
369
404
|
child.castShadow = true;
|
|
370
|
-
|
|
405
|
+
const mat = child.material;
|
|
406
|
+
if (!mat) return;
|
|
407
|
+
const mats = Array.isArray(mat) ? mat : [mat];
|
|
408
|
+
mats.forEach((m) => {
|
|
409
|
+
});
|
|
371
410
|
}
|
|
372
411
|
});
|
|
373
412
|
this.player.add(this.person);
|
|
@@ -379,9 +418,18 @@ var PlayerController = class {
|
|
|
379
418
|
const regs = [
|
|
380
419
|
[this.playerModel.idleAnim, "idle"],
|
|
381
420
|
[this.playerModel.walkAnim, "walking"],
|
|
382
|
-
[
|
|
383
|
-
|
|
384
|
-
|
|
421
|
+
[
|
|
422
|
+
this.playerModel.leftWalkAnim || this.playerModel.walkAnim,
|
|
423
|
+
"left_walking"
|
|
424
|
+
],
|
|
425
|
+
[
|
|
426
|
+
this.playerModel.rightWalkAnim || this.playerModel.walkAnim,
|
|
427
|
+
"right_walking"
|
|
428
|
+
],
|
|
429
|
+
[
|
|
430
|
+
this.playerModel.backwardAnim || this.playerModel.walkAnim,
|
|
431
|
+
"walking_backward"
|
|
432
|
+
],
|
|
385
433
|
[this.playerModel.jumpAnim, "jumping"],
|
|
386
434
|
[this.playerModel.runAnim, "running"],
|
|
387
435
|
[this.playerModel.flyIdleAnim || this.playerModel.idleAnim, "flyidle"],
|
|
@@ -470,11 +518,17 @@ var PlayerController = class {
|
|
|
470
518
|
material.depthWrite = false;
|
|
471
519
|
const r = this.playerRadius * this.playerModel.scale;
|
|
472
520
|
const h = this.playerHeight * this.playerModel.scale;
|
|
473
|
-
this.player = new THREE.Mesh(
|
|
521
|
+
this.player = new THREE.Mesh(
|
|
522
|
+
new import_RoundedBoxGeometry.RoundedBoxGeometry(r * 2, h, r * 2, 1, 75),
|
|
523
|
+
material
|
|
524
|
+
);
|
|
474
525
|
this.player.geometry.translate(0, -h * 0.25, 0);
|
|
475
526
|
this.player.capsuleInfo = {
|
|
476
527
|
radius: r,
|
|
477
|
-
segment: new THREE.Line3(
|
|
528
|
+
segment: new THREE.Line3(
|
|
529
|
+
new THREE.Vector3(),
|
|
530
|
+
new THREE.Vector3(0, -h * 0.5, 0)
|
|
531
|
+
)
|
|
478
532
|
};
|
|
479
533
|
this.player.name = "capsule";
|
|
480
534
|
this.scene.add(this.player);
|
|
@@ -484,7 +538,9 @@ var PlayerController = class {
|
|
|
484
538
|
getAngleWithYAxis(normal) {
|
|
485
539
|
const yAxis = { x: 0, y: 1, z: 0 };
|
|
486
540
|
const dotProduct = normal.x * yAxis.x + normal.y * yAxis.y + normal.z * yAxis.z;
|
|
487
|
-
const normalMagnitude = Math.sqrt(
|
|
541
|
+
const normalMagnitude = Math.sqrt(
|
|
542
|
+
normal.x * normal.x + normal.y * normal.y + normal.z * normal.z
|
|
543
|
+
);
|
|
488
544
|
const yAxisMagnitude = 1;
|
|
489
545
|
const cosTheta = dotProduct / (normalMagnitude * yAxisMagnitude);
|
|
490
546
|
return Math.acos(cosTheta);
|
|
@@ -493,7 +549,8 @@ var PlayerController = class {
|
|
|
493
549
|
async update(delta = clock.getDelta()) {
|
|
494
550
|
if (!this.isupdate || !this.player || !this.collider) return;
|
|
495
551
|
delta = Math.min(delta, 1 / 30);
|
|
496
|
-
if (!this.isFlying)
|
|
552
|
+
if (!this.isFlying)
|
|
553
|
+
this.player.position.addScaledVector(this.playerVelocity, delta);
|
|
497
554
|
this.updateMixers(delta);
|
|
498
555
|
this.camera.getWorldDirection(this.camDir);
|
|
499
556
|
let angle = Math.atan2(this.camDir.z, this.camDir.x) + Math.PI / 2;
|
|
@@ -519,11 +576,21 @@ var PlayerController = class {
|
|
|
519
576
|
this.playerSpeed = this.shiftPressed ? 900 * this.playerModel.scale : 400 * this.playerModel.scale;
|
|
520
577
|
}
|
|
521
578
|
this.moveDir.normalize().applyAxisAngle(this.upVector, angle);
|
|
522
|
-
this.player.position.addScaledVector(
|
|
579
|
+
this.player.position.addScaledVector(
|
|
580
|
+
this.moveDir,
|
|
581
|
+
this.playerSpeed * delta
|
|
582
|
+
);
|
|
523
583
|
let playerDistanceFromGround = Infinity;
|
|
524
|
-
this._originTmp.set(
|
|
584
|
+
this._originTmp.set(
|
|
585
|
+
this.player.position.x,
|
|
586
|
+
this.player.position.y,
|
|
587
|
+
this.player.position.z
|
|
588
|
+
);
|
|
525
589
|
this._raycaster.ray.origin.copy(this._originTmp);
|
|
526
|
-
const intersects = this._raycaster.intersectObject(
|
|
590
|
+
const intersects = this._raycaster.intersectObject(
|
|
591
|
+
this.collider,
|
|
592
|
+
false
|
|
593
|
+
);
|
|
527
594
|
if (intersects.length > 0) {
|
|
528
595
|
playerDistanceFromGround = this.player.position.y - intersects[0].point.y;
|
|
529
596
|
const normal = intersects[0].normal;
|
|
@@ -531,7 +598,6 @@ var PlayerController = class {
|
|
|
531
598
|
const maxH = this.playerHeight * this.playerModel.scale * 0.9;
|
|
532
599
|
const h = this.playerHeight * this.playerModel.scale * 0.75;
|
|
533
600
|
const minH = this.playerHeight * this.playerModel.scale * 0.7;
|
|
534
|
-
console.log(angle2, playerDistanceFromGround, maxH, h, minH);
|
|
535
601
|
if (this.isFlying) {
|
|
536
602
|
} else {
|
|
537
603
|
if (playerDistanceFromGround > maxH) {
|
|
@@ -552,7 +618,11 @@ var PlayerController = class {
|
|
|
552
618
|
this.playerIsOnGround = true;
|
|
553
619
|
} else if (playerDistanceFromGround < minH) {
|
|
554
620
|
this.playerVelocity.set(0, 0, 0);
|
|
555
|
-
this.player.position.set(
|
|
621
|
+
this.player.position.set(
|
|
622
|
+
this.player.position.x,
|
|
623
|
+
intersects[0].point.y + h,
|
|
624
|
+
this.player.position.z
|
|
625
|
+
);
|
|
556
626
|
this.playerIsOnGround = true;
|
|
557
627
|
}
|
|
558
628
|
}
|
|
@@ -575,7 +645,11 @@ var PlayerController = class {
|
|
|
575
645
|
intersectsTriangle: (tri) => {
|
|
576
646
|
const triPoint = this.tempVector;
|
|
577
647
|
const capsulePoint = this.tempVector2;
|
|
578
|
-
const distance = tri.closestPointToSegment(
|
|
648
|
+
const distance = tri.closestPointToSegment(
|
|
649
|
+
this.tempSegment,
|
|
650
|
+
triPoint,
|
|
651
|
+
capsulePoint
|
|
652
|
+
);
|
|
579
653
|
if (distance < capsuleInfo.radius) {
|
|
580
654
|
const depth = capsuleInfo.radius - distance;
|
|
581
655
|
const direction = capsulePoint.sub(triPoint).normalize();
|
|
@@ -585,7 +659,10 @@ var PlayerController = class {
|
|
|
585
659
|
}
|
|
586
660
|
});
|
|
587
661
|
const newPosition = this.tempVector.copy(this.tempSegment.start).applyMatrix4(this.collider.matrixWorld);
|
|
588
|
-
const deltaVector = this.tempVector2.subVectors(
|
|
662
|
+
const deltaVector = this.tempVector2.subVectors(
|
|
663
|
+
newPosition,
|
|
664
|
+
this.player.position
|
|
665
|
+
);
|
|
589
666
|
const offset = Math.max(0, deltaVector.length() - 1e-5);
|
|
590
667
|
deltaVector.normalize().multiplyScalar(offset);
|
|
591
668
|
this.player.position.add(deltaVector);
|
|
@@ -626,15 +703,24 @@ var PlayerController = class {
|
|
|
626
703
|
const desiredDist = this._personToCam.length();
|
|
627
704
|
this._raycasterPersonToCam.set(origin, direction);
|
|
628
705
|
this._raycasterPersonToCam.far = desiredDist;
|
|
629
|
-
const intersects2 = this._raycasterPersonToCam.intersectObject(
|
|
706
|
+
const intersects2 = this._raycasterPersonToCam.intersectObject(
|
|
707
|
+
this.collider,
|
|
708
|
+
false
|
|
709
|
+
);
|
|
630
710
|
if (intersects2.length > 0) {
|
|
631
711
|
const hit = intersects2[0];
|
|
632
|
-
const safeDist = Math.max(
|
|
712
|
+
const safeDist = Math.max(
|
|
713
|
+
hit.distance - this._camEpsilon,
|
|
714
|
+
this._minCamDistance
|
|
715
|
+
);
|
|
633
716
|
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
634
717
|
this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
|
|
635
718
|
} else {
|
|
636
719
|
this._raycasterPersonToCam.far = this._maxCamDistance;
|
|
637
|
-
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
|
|
720
|
+
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
|
|
721
|
+
this.collider,
|
|
722
|
+
false
|
|
723
|
+
);
|
|
638
724
|
let safeDist = this._maxCamDistance;
|
|
639
725
|
if (intersectsMaxDis.length) {
|
|
640
726
|
const hitMax = intersectsMaxDis[0];
|
|
@@ -645,15 +731,34 @@ var PlayerController = class {
|
|
|
645
731
|
}
|
|
646
732
|
}
|
|
647
733
|
if (this.player.position.y < this.boundingBoxMinY - 1) {
|
|
648
|
-
this._originTmp.set(
|
|
734
|
+
this._originTmp.set(
|
|
735
|
+
this.player.position.x,
|
|
736
|
+
1e4,
|
|
737
|
+
this.player.position.z
|
|
738
|
+
);
|
|
649
739
|
this._raycaster.ray.origin.copy(this._originTmp);
|
|
650
|
-
const intersects2 = this._raycaster.intersectObject(
|
|
740
|
+
const intersects2 = this._raycaster.intersectObject(
|
|
741
|
+
this.collider,
|
|
742
|
+
false
|
|
743
|
+
);
|
|
651
744
|
if (intersects2.length > 0) {
|
|
652
745
|
console.log("\u73A9\u5BB6\u4E3Abug\u610F\u5916\u6389\u843D");
|
|
653
|
-
this.reset(
|
|
746
|
+
this.reset(
|
|
747
|
+
new THREE.Vector3(
|
|
748
|
+
this.player.position.x,
|
|
749
|
+
intersects2[0].point.y + 5,
|
|
750
|
+
this.player.position.z
|
|
751
|
+
)
|
|
752
|
+
);
|
|
654
753
|
} else {
|
|
655
754
|
console.log("\u73A9\u5BB6\u6B63\u5E38\u6389\u843D");
|
|
656
|
-
this.reset(
|
|
755
|
+
this.reset(
|
|
756
|
+
new THREE.Vector3(
|
|
757
|
+
this.player.position.x,
|
|
758
|
+
this.player.position.y + 15,
|
|
759
|
+
this.player.position.z
|
|
760
|
+
)
|
|
761
|
+
);
|
|
657
762
|
}
|
|
658
763
|
}
|
|
659
764
|
}
|
|
@@ -757,7 +862,8 @@ var PlayerController = class {
|
|
|
757
862
|
attrMap.set(name, { itemSize, arrayCtor: ctor, examples: 1 });
|
|
758
863
|
} else {
|
|
759
864
|
const m = attrMap.get(name);
|
|
760
|
-
if (m.itemSize !== itemSize || m.arrayCtor !== ctor)
|
|
865
|
+
if (m.itemSize !== itemSize || m.arrayCtor !== ctor)
|
|
866
|
+
attrConflict.add(name);
|
|
761
867
|
else m.examples++;
|
|
762
868
|
}
|
|
763
869
|
}
|
|
@@ -778,7 +884,10 @@ var PlayerController = class {
|
|
|
778
884
|
const meta = attrMap.get(name);
|
|
779
885
|
const len = count * meta.itemSize;
|
|
780
886
|
const array = new meta.arrayCtor(len);
|
|
781
|
-
g.setAttribute(
|
|
887
|
+
g.setAttribute(
|
|
888
|
+
name,
|
|
889
|
+
new THREE.BufferAttribute(array, meta.itemSize)
|
|
890
|
+
);
|
|
782
891
|
}
|
|
783
892
|
}
|
|
784
893
|
}
|