three-player-controller 0.3.8 → 0.4.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/README.md +4 -8
- package/dist/index.d.mts +15 -5
- package/dist/index.d.ts +15 -5
- package/dist/index.js +33 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1000,13 +1000,12 @@ var PlayerController = class {
|
|
|
1000
1000
|
}
|
|
1001
1001
|
const w = window.innerWidth;
|
|
1002
1002
|
const h = window.innerHeight;
|
|
1003
|
-
this.camera.setViewOffset(w, h,
|
|
1003
|
+
this.camera.setViewOffset(w, h, w * 0.15, 0, w, h);
|
|
1004
1004
|
}
|
|
1005
1005
|
// 初始化加载器
|
|
1006
1006
|
async initLoader() {
|
|
1007
1007
|
const dracoLoader = new DRACOLoader();
|
|
1008
|
-
dracoLoader.setDecoderPath("https://unpkg.com/three@0.
|
|
1009
|
-
dracoLoader.setDecoderConfig({ type: "js" });
|
|
1008
|
+
dracoLoader.setDecoderPath("https://unpkg.com/three@0.182.0/examples/jsm/libs/draco/gltf/");
|
|
1010
1009
|
this.loader.setDRACOLoader(dracoLoader);
|
|
1011
1010
|
}
|
|
1012
1011
|
// 初始化物理引擎
|
|
@@ -1079,12 +1078,12 @@ var PlayerController = class {
|
|
|
1079
1078
|
action.setEffectiveWeight(0);
|
|
1080
1079
|
this.personActions.set(actionName, action);
|
|
1081
1080
|
}
|
|
1082
|
-
this.personActions.get("idle")
|
|
1083
|
-
this.personActions.get("idle")
|
|
1081
|
+
this.personActions.get("idle")?.setEffectiveWeight(1);
|
|
1082
|
+
this.personActions.get("idle")?.play();
|
|
1084
1083
|
this.actionState = this.personActions.get("idle");
|
|
1085
|
-
this.
|
|
1084
|
+
this.personMixerFinishedCb = (ev) => {
|
|
1086
1085
|
const done = ev.action;
|
|
1087
|
-
if (done === this.personActions
|
|
1086
|
+
if (done === this.personActions?.get("jumping")) {
|
|
1088
1087
|
if (this.fwdPressed) {
|
|
1089
1088
|
this.playPersonAnimationByName(this.shiftPressed ? "running" : "walking");
|
|
1090
1089
|
return;
|
|
@@ -1100,7 +1099,8 @@ var PlayerController = class {
|
|
|
1100
1099
|
this.playPersonAnimationByName("idle");
|
|
1101
1100
|
}
|
|
1102
1101
|
if (done === this.personActions?.get("enterCar")) this.onEnterCarAnimFinished();
|
|
1103
|
-
}
|
|
1102
|
+
};
|
|
1103
|
+
this.personMixer.addEventListener("finished", this.personMixerFinishedCb);
|
|
1104
1104
|
this.personMixer.update(0);
|
|
1105
1105
|
this.person.updateMatrixWorld(true);
|
|
1106
1106
|
const { size } = this.getBbox(this.person);
|
|
@@ -1155,6 +1155,10 @@ var PlayerController = class {
|
|
|
1155
1155
|
this.personHead = null;
|
|
1156
1156
|
}
|
|
1157
1157
|
if (this.personMixer) {
|
|
1158
|
+
if (this.personMixerFinishedCb) {
|
|
1159
|
+
this.personMixer.removeEventListener("finished", this.personMixerFinishedCb);
|
|
1160
|
+
this.personMixerFinishedCb = void 0;
|
|
1161
|
+
}
|
|
1158
1162
|
this.personMixer.stopAllAction();
|
|
1159
1163
|
this.personMixer.uncacheRoot(this.personMixer.getRoot());
|
|
1160
1164
|
this.personMixer = void 0;
|
|
@@ -1405,15 +1409,13 @@ var PlayerController = class {
|
|
|
1405
1409
|
changeView() {
|
|
1406
1410
|
this.isFirstPerson = !this.isFirstPerson;
|
|
1407
1411
|
if (this.isFirstPerson) {
|
|
1408
|
-
const
|
|
1409
|
-
|
|
1410
|
-
const flatDir = new THREE4.Vector3(camWorldDir.x, 0, camWorldDir.z).normalize();
|
|
1412
|
+
const playerFwd = new THREE4.Vector3(0, 0, 1).applyQuaternion(this.player.quaternion);
|
|
1413
|
+
const flatDir = new THREE4.Vector3(playerFwd.x, 0, playerFwd.z).normalize();
|
|
1411
1414
|
if (flatDir.lengthSq() > 1e-3) {
|
|
1412
1415
|
const yAngle = Math.atan2(flatDir.x, flatDir.z);
|
|
1413
|
-
this.player.rotation.set(0, yAngle
|
|
1416
|
+
this.player.rotation.set(0, yAngle, 0);
|
|
1414
1417
|
}
|
|
1415
|
-
|
|
1416
|
-
this.setFirstPersonCamera(vertAngle);
|
|
1418
|
+
this.setFirstPersonCamera();
|
|
1417
1419
|
this.setOverShoulderView(false);
|
|
1418
1420
|
} else {
|
|
1419
1421
|
this.controls.enabled = true;
|
|
@@ -1611,7 +1613,7 @@ var PlayerController = class {
|
|
|
1611
1613
|
return;
|
|
1612
1614
|
}
|
|
1613
1615
|
merged.boundsTree = new MeshBVH(merged, { maxDepth: 100 });
|
|
1614
|
-
this.collider = new THREE4.Mesh(merged, new THREE4.MeshBasicMaterial({ opacity: 0.5, transparent: true, wireframe: true, depthTest: true }));
|
|
1616
|
+
this.collider = new THREE4.Mesh(merged, new THREE4.MeshBasicMaterial({ opacity: 0.5, transparent: true, wireframe: true, depthTest: true, side: THREE4.DoubleSide }));
|
|
1615
1617
|
if (this.displayCollider) this.scene.add(this.collider);
|
|
1616
1618
|
if (this.displayVisualizer) {
|
|
1617
1619
|
if (this.visualizer) this.scene.remove(this.visualizer);
|
|
@@ -1649,7 +1651,7 @@ var PlayerController = class {
|
|
|
1649
1651
|
return;
|
|
1650
1652
|
}
|
|
1651
1653
|
merged.boundsTree = new MeshBVH(merged);
|
|
1652
|
-
this.dynamicCollider = new THREE4.Mesh(merged, new THREE4.MeshBasicMaterial({ opacity: 0.5, transparent: true, wireframe: true, depthTest: true }));
|
|
1654
|
+
this.dynamicCollider = new THREE4.Mesh(merged, new THREE4.MeshBasicMaterial({ opacity: 0.5, transparent: true, wireframe: true, depthTest: true, side: THREE4.DoubleSide }));
|
|
1653
1655
|
if (this.displayCollider) this.scene.add(this.dynamicCollider);
|
|
1654
1656
|
}
|
|
1655
1657
|
// ==================== 控制器过渡 ====================
|
|
@@ -1884,16 +1886,17 @@ var PlayerController = class {
|
|
|
1884
1886
|
if (!this.spacePressed) {
|
|
1885
1887
|
this.playerVelocity.set(0, 0, 0);
|
|
1886
1888
|
this.playerIsOnGround = true;
|
|
1887
|
-
this.player.position.y = hits[0].point.y + h;
|
|
1889
|
+
this.player.position.y = THREE4.MathUtils.lerp(this.player.position.y, hits[0].point.y + h, Math.min(1, 15 * delta));
|
|
1888
1890
|
}
|
|
1889
1891
|
} else if (dist >= minH) {
|
|
1890
1892
|
this.playerVelocity.set(0, 0, 0);
|
|
1891
1893
|
this.playerIsOnGround = true;
|
|
1892
1894
|
this.player.position.y = hits[0].point.y + h;
|
|
1893
1895
|
} else {
|
|
1896
|
+
const targetY = hits[0].point.y + h;
|
|
1894
1897
|
this.playerVelocity.set(0, 0, 0);
|
|
1895
|
-
this.player.position.y = hits[0].point.y + h;
|
|
1896
1898
|
this.playerIsOnGround = true;
|
|
1899
|
+
this.player.position.y = THREE4.MathUtils.lerp(this.player.position.y, targetY, Math.min(1, 15 * delta));
|
|
1897
1900
|
}
|
|
1898
1901
|
}
|
|
1899
1902
|
this.player.updateMatrixWorld();
|
|
@@ -1914,7 +1917,14 @@ var PlayerController = class {
|
|
|
1914
1917
|
const distance = tri.closestPointToSegment(this.tempSegment, this.tempVector, this.tempVector2);
|
|
1915
1918
|
if (distance < capsuleInfo.radius) {
|
|
1916
1919
|
const normal = tri.getNormal(new THREE4.Vector3());
|
|
1917
|
-
if (normal.y > 0.5
|
|
1920
|
+
if (!this.isFlying && Math.abs(normal.y) > 0.5) return;
|
|
1921
|
+
if (!this.isFlying && Math.abs(normal.y) <= 0.5) {
|
|
1922
|
+
const e = this.collider.matrixWorld.elements;
|
|
1923
|
+
const contactWorldY = e[1] * this.tempVector.x + e[5] * this.tempVector.y + e[9] * this.tempVector.z + e[13];
|
|
1924
|
+
const s = this.playerModel.scale;
|
|
1925
|
+
const feetY = this.player.position.y - this.playerCapsuleHeight * s * 0.75;
|
|
1926
|
+
if (contactWorldY < feetY + this.playerCapsuleHeight * s * 0.25) return;
|
|
1927
|
+
}
|
|
1918
1928
|
const dir = this.tempVector2.sub(this.tempVector).normalize();
|
|
1919
1929
|
const depth = capsuleInfo.radius - distance;
|
|
1920
1930
|
this.tempSegment.start.addScaledVector(dir, depth);
|
|
@@ -2009,13 +2019,14 @@ var PlayerController = class {
|
|
|
2009
2019
|
}
|
|
2010
2020
|
// 屏幕中心射线
|
|
2011
2021
|
getCenterScreenRaycastHit() {
|
|
2022
|
+
if (!this.collider) return void 0;
|
|
2012
2023
|
this.camera.updateMatrixWorld();
|
|
2013
2024
|
this.centerRay.setFromCamera(this.centerMouse, this.camera);
|
|
2014
2025
|
return this.centerRay.intersectObject(this.collider, false)[0];
|
|
2015
2026
|
}
|
|
2016
2027
|
// 获取当前人物动画名称
|
|
2017
2028
|
getCurrentPersonAnimationName() {
|
|
2018
|
-
return this.actionState
|
|
2029
|
+
return this.actionState?.getClip()?.name ?? null;
|
|
2019
2030
|
}
|
|
2020
2031
|
// 更新动画混合器
|
|
2021
2032
|
updateMixers(delta) {
|
|
@@ -2182,6 +2193,7 @@ var PlayerController = class {
|
|
|
2182
2193
|
for (const v of this.vehicles) {
|
|
2183
2194
|
this.scene.remove(v.vehicleGroup);
|
|
2184
2195
|
v.pathPlanner?.dispose();
|
|
2196
|
+
v.vehicleController?.destroy?.();
|
|
2185
2197
|
}
|
|
2186
2198
|
this.vehicles = [];
|
|
2187
2199
|
this.activeVehicle = null;
|