@fps-games/vfx 0.1.1 → 0.3.2
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/CHANGELOG.md +107 -0
- package/README.md +41 -0
- package/dist/effects/coin-burst/index.js +6 -2
- package/dist/effects/comet-trail-flame/index.js +3 -1
- package/dist/effects/debris-smoke/index.js +1 -0
- package/dist/effects/electric-arc/index.js +1 -0
- package/dist/effects/energy-shield/index.js +1 -0
- package/dist/effects/explosion/index.js +3 -2
- package/dist/effects/hit-flash/index.js +12 -4
- package/dist/effects/laser-beam/index.js +14 -2
- package/dist/effects/lumber_vehicle_upgrade_aura/index.js +1 -0
- package/dist/effects/monster-hit/index.js +2 -1
- package/dist/effects/player-upgrade/index.js +5 -3
- package/dist/effects/pulse-laser-volley/index.js +14 -4
- package/dist/effects/thruster-flame/index.js +3 -1
- package/dist/effects/treasure-attention/index.d.ts +54 -0
- package/dist/effects/treasure-attention/index.js +535 -0
- package/dist/effects/ufo-thread-flame/index.js +1 -0
- package/dist/effects/vehicle-upgrade/index.js +4 -1
- package/dist/effects/weapon-trail/index.js +8 -3
- package/dist/effects/wood_crusher_sawdust/index.d.ts +4 -0
- package/dist/effects/wood_cutter_sawdust/index.d.ts +4 -0
- package/dist/index.js +85 -17
- package/dist/types.d.ts +80 -0
- package/docs/INTEGRATION.md +194 -0
- package/docs/hit-flash-red-method.md +155 -0
- package/docs/treasure_attention_fx_babylonjs_guide.md +901 -0
- package/docs/vfx-placement-design.md +164 -0
- package/index.json +19 -1
- package/package.json +5 -1
- package/packages/EffectPackageService.ts +123 -17
- package/packages/effects/coin-burst/index.ts +7 -2
- package/packages/effects/comet-trail-flame/index.ts +3 -2
- package/packages/effects/debris-smoke/index.ts +1 -0
- package/packages/effects/electric-arc/index.ts +1 -0
- package/packages/effects/energy-shield/index.ts +1 -0
- package/packages/effects/explosion/index.ts +3 -2
- package/packages/effects/hit-flash/index.ts +11 -3
- package/packages/effects/laser-beam-factory.ts +14 -3
- package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +2 -0
- package/packages/effects/monster-hit/index.ts +2 -1
- package/packages/effects/player-upgrade/index.ts +8 -3
- package/packages/effects/pulse-laser-volley/index.ts +15 -4
- package/packages/effects/thruster-flame/index.ts +3 -2
- package/packages/effects/treasure-attention/effect.json +7 -0
- package/packages/effects/treasure-attention/index.ts +630 -0
- package/packages/effects/treasure-attention/vfx-params.json +49 -0
- package/packages/effects/ufo-thread-flame/index.ts +1 -0
- package/packages/effects/vehicle-upgrade/index.ts +4 -1
- package/packages/effects/weapon-trail/index.ts +7 -3
- package/packages/types.ts +88 -0
|
@@ -80,8 +80,11 @@ const DEFAULT_PARAMS: PlayerUpgradeParams = {
|
|
|
80
80
|
export const playerUpgradeEffectPackage: VfxEffectPackage<PlayerUpgradeParams> = {
|
|
81
81
|
id: 'player-upgrade',
|
|
82
82
|
nameZh: '人物&NPC升级',
|
|
83
|
+
placement: 'socket',
|
|
83
84
|
manifest,
|
|
84
85
|
defaultParams: DEFAULT_PARAMS,
|
|
86
|
+
// initialHeight 走 service 存活的 Y 偏移通道(不写 root.position,避免被 applySpawnToRoot 覆盖)(G6/M13)。
|
|
87
|
+
spawnParams: { offsetY: 'initialHeight' },
|
|
85
88
|
debugAnchor: 'player',
|
|
86
89
|
debugParams: [
|
|
87
90
|
{ key: 'lifetime', label: '生命周期', kind: 'lifetime', min: 0.2, max: 6, step: 0.01 },
|
|
@@ -105,9 +108,8 @@ export const playerUpgradeEffectPackage: VfxEffectPackage<PlayerUpgradeParams> =
|
|
|
105
108
|
{ key: 'glowWidth', label: '光柱宽度', kind: 'number', min: 0.1, max: 4, step: 0.01 },
|
|
106
109
|
],
|
|
107
110
|
create({ scene, root, position, params }) {
|
|
108
|
-
const effectScale = Math.max(0.05, params.scale);
|
|
109
111
|
markVfxRoot(root);
|
|
110
|
-
root.position.copyFrom(position)
|
|
112
|
+
root.position.copyFrom(position); // 高度偏移由 service 经 spawnParams.offsetY 施加(存活)
|
|
111
113
|
const strands = createStrandSystem(scene, root, params);
|
|
112
114
|
const strandMeshes = createStrandMeshes(scene, root, params);
|
|
113
115
|
const rings = createExpandingRings(scene, root, params);
|
|
@@ -129,7 +131,10 @@ export const playerUpgradeEffectPackage: VfxEffectPackage<PlayerUpgradeParams> =
|
|
|
129
131
|
disposed = true;
|
|
130
132
|
window.clearTimeout(disposeTimer);
|
|
131
133
|
strands.stop();
|
|
132
|
-
|
|
134
|
+
// dispose(false):金丝粒子贴图是按 scene 缓存的共享 DynamicTexture(strandTextureByScene),
|
|
135
|
+
// ParticleSystem.dispose() 默认 disposeTexture=true 会销毁它,WeakMap 却仍持失效引用 →
|
|
136
|
+
// 二次升级金丝空白。纹理生命周期绑 scene、跨播放复用,故不随实例销毁。
|
|
137
|
+
strands.dispose(false);
|
|
133
138
|
strandMeshes.dispose();
|
|
134
139
|
rings.dispose();
|
|
135
140
|
glowAura.dispose();
|
|
@@ -9,6 +9,8 @@ import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
|
|
|
9
9
|
import { Effect } from '@babylonjs/core/Materials/effect';
|
|
10
10
|
import { Texture } from '@babylonjs/core/Materials/Textures/texture';
|
|
11
11
|
import { Color3 } from '@babylonjs/core/Maths/math.color';
|
|
12
|
+
import { Vector3 } from '@babylonjs/core/Maths/math.vector';
|
|
13
|
+
import { Space } from '@babylonjs/core/Maths/math.axis';
|
|
12
14
|
import { Constants } from '@babylonjs/core/Engines/constants';
|
|
13
15
|
import type { Mesh } from '@babylonjs/core/Meshes/mesh';
|
|
14
16
|
import type { Scene } from '@babylonjs/core/scene';
|
|
@@ -88,6 +90,8 @@ interface Bolt { mesh: Mesh; left: number; }
|
|
|
88
90
|
export const pulseLaserVolleyEffectPackage: VfxEffectPackage<PulseLaserParams> = {
|
|
89
91
|
id: 'pulse-laser-volley',
|
|
90
92
|
nameZh: '脉冲激光',
|
|
93
|
+
placement: 'socket',
|
|
94
|
+
optionalInputs: ['aim'],
|
|
91
95
|
defaultParams: DEFAULT_PARAMS,
|
|
92
96
|
debugAnchor: 'playerRight',
|
|
93
97
|
debugParams: [
|
|
@@ -104,10 +108,17 @@ export const pulseLaserVolleyEffectPackage: VfxEffectPackage<PulseLaserParams> =
|
|
|
104
108
|
{ key: 'boltBright', label: '光弹亮度', kind: 'number', min: 0.2, max: 3, step: 0.05 },
|
|
105
109
|
],
|
|
106
110
|
|
|
107
|
-
create({ scene, root, position, rotationY, params }) {
|
|
111
|
+
create({ scene, root, position, rotationY, params, inputs }) {
|
|
108
112
|
root.position.copyFrom(position);
|
|
109
113
|
root.rotation.y = rotationY;
|
|
110
114
|
registerShaders();
|
|
115
|
+
// 有 inputs.aim:每帧朝目标(Space.WORLD,root 挂在炮口)+ 齐射射程=到目标距离;无 aim 回退挂点朝向 + params.targetDistance。
|
|
116
|
+
const effectiveDist = (): number => {
|
|
117
|
+
if (!inputs?.aim) return params.targetDistance;
|
|
118
|
+
const tgt = inputs.aim();
|
|
119
|
+
root.lookAt(tgt, 0, 0, 0, Space.WORLD);
|
|
120
|
+
return Vector3.Distance(root.getAbsolutePosition(), tgt);
|
|
121
|
+
};
|
|
111
122
|
|
|
112
123
|
const boltTex = new Texture(boltTextureUrl, scene);
|
|
113
124
|
boltTex.hasAlpha = true;
|
|
@@ -151,9 +162,8 @@ export const pulseLaserVolleyEffectPackage: VfxEffectPackage<PulseLaserParams> =
|
|
|
151
162
|
muzzle.position.set(0, 0, 0);
|
|
152
163
|
let muzzleFlash = 0;
|
|
153
164
|
|
|
154
|
-
function fireVolley(): void {
|
|
165
|
+
function fireVolley(dist: number): void {
|
|
155
166
|
const n = Math.max(1, Math.round(params.boltsPerVolley));
|
|
156
|
-
const dist = params.targetDistance;
|
|
157
167
|
let fired = 0;
|
|
158
168
|
for (const b of pool) {
|
|
159
169
|
if (fired >= n) break;
|
|
@@ -171,8 +181,9 @@ export const pulseLaserVolleyEffectPackage: VfxEffectPackage<PulseLaserParams> =
|
|
|
171
181
|
let volleyTimer = 0;
|
|
172
182
|
const observer = scene.onBeforeRenderObservable.add(() => {
|
|
173
183
|
const dt = Math.min(scene.getEngine().getDeltaTime() / 1000, 0.05);
|
|
184
|
+
const dist = effectiveDist(); // 每帧:有 aim 则朝目标 + 取到目标距离
|
|
174
185
|
volleyTimer += dt;
|
|
175
|
-
if (volleyTimer >= params.volleyInterval) { volleyTimer = 0; fireVolley(); }
|
|
186
|
+
if (volleyTimer >= params.volleyInterval) { volleyTimer = 0; fireVolley(dist); }
|
|
176
187
|
|
|
177
188
|
muzzleFlash = Math.max(0, muzzleFlash - dt * 6);
|
|
178
189
|
const s = 1 + muzzleFlash * 0.6;
|
|
@@ -221,6 +221,7 @@ function excludeFromGlow(scene: Scene, mesh: AbstractMesh): void {
|
|
|
221
221
|
export const thrusterFlameEffectPackage: VfxEffectPackage<ThrusterFlameParams> = {
|
|
222
222
|
id: 'thruster-flame',
|
|
223
223
|
nameZh: '战机尾焰',
|
|
224
|
+
placement: 'socket',
|
|
224
225
|
defaultParams: DEFAULT_PARAMS,
|
|
225
226
|
debugAnchor: 'playerRight',
|
|
226
227
|
debugParams: [
|
|
@@ -236,7 +237,7 @@ export const thrusterFlameEffectPackage: VfxEffectPackage<ThrusterFlameParams> =
|
|
|
236
237
|
{ key: 'coreColor', label: '内核色', kind: 'color' },
|
|
237
238
|
],
|
|
238
239
|
|
|
239
|
-
create({ scene, root, position, params }) {
|
|
240
|
+
create({ scene, root, position, params, renderingGroupId }) {
|
|
240
241
|
root.position.copyFrom(position);
|
|
241
242
|
registerShaders();
|
|
242
243
|
const preset = PRESETS[(params.mode as EngineMode)] ?? PRESETS.ion;
|
|
@@ -245,7 +246,7 @@ export const thrusterFlameEffectPackage: VfxEffectPackage<ThrusterFlameParams> =
|
|
|
245
246
|
const outer = buildFlameMesh('vfx_thruster_outer', scene, FLAME_LEN, FLAME_R, 30, 24);
|
|
246
247
|
const core = buildFlameMesh('vfx_thruster_core', scene, FLAME_LEN * 0.68, FLAME_R * 0.5, 24, 18);
|
|
247
248
|
const swirl = buildFlameMesh('vfx_thruster_swirl', scene, FLAME_LEN * 0.42, FLAME_R * 1.3, 14, 24);
|
|
248
|
-
for (const m of [outer, core, swirl]) { m.parent = root; excludeFromGlow(scene, m); }
|
|
249
|
+
for (const m of [outer, core, swirl]) { m.parent = root; m.renderingGroupId = renderingGroupId ?? 0; excludeFromGlow(scene, m); }
|
|
249
250
|
|
|
250
251
|
const outerMat = makeFXMaterial('vfx_thruster_outerMat', scene, 'vfxThrusterFlame', noiseTex);
|
|
251
252
|
const coreMat = makeFXMaterial('vfx_thruster_coreMat', scene, 'vfxThrusterFlame', noiseTex);
|