@fps-games/vfx 0.3.2 → 0.3.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.
Files changed (234) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +5 -5
  3. package/dist/effects/treasure-attention/index.d.ts +1 -1
  4. package/package.json +6 -5
  5. package/tooling/vfx-cli.mjs +31 -22
  6. package/tooling/vfx-package-resolution.mjs +8 -8
  7. package/docs/AUTHORING_EFFECTS.md +0 -297
  8. package/docs/INTEGRATION.md +0 -194
  9. package/docs/VFX_LIBRARY_ARCHITECTURE_chatgpt.md +0 -1580
  10. package/docs/VFX_LIBRARY_EXECUTION_PLAN.md +0 -229
  11. package/docs/VFX_LIBRARY_PLAN.md +0 -546
  12. package/docs/hit-flash-red-method.md +0 -155
  13. package/docs/treasure_attention_fx_babylonjs_guide.md +0 -901
  14. package/docs/vfx-ab/RESULTS.md +0 -35
  15. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/after.png +0 -0
  16. package/docs/vfx-ab/lumber-order/vehicle-exhaust-smoke/before.png +0 -0
  17. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/after.png +0 -0
  18. package/docs/vfx-ab/lumber-truck/vehicle-exhaust-smoke/before.png +0 -0
  19. package/docs/vfx-integration_chatgpt.md +0 -462
  20. package/docs/vfx-placement-design.md +0 -164
  21. package/docs/weapon-trail-visualization.html +0 -241
  22. package/packages/EffectPackageService.ts +0 -346
  23. package/packages/SceneVfxService.ts +0 -96
  24. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/runtime/simpleMeshEffect.v1.js +0 -333
  25. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.frag.glsl +0 -25
  26. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/shaders/mesh-effect-preview.vert.glsl +0 -11
  27. package/packages/build.mesh.yellow_build_upgrade_indicator/assets/textures/effect_jianbian.png +0 -0
  28. package/packages/build.mesh.yellow_build_upgrade_indicator/effect.json +0 -927
  29. package/packages/build.mesh.yellow_build_upgrade_indicator/media/contact-sheet.png +0 -0
  30. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.gif +0 -0
  31. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.mp4 +0 -0
  32. package/packages/build.mesh.yellow_build_upgrade_indicator/media/preview.webm +0 -0
  33. package/packages/build.mesh.yellow_build_upgrade_indicator/media/thumbnail.png +0 -0
  34. package/packages/build.mesh.yellow_build_upgrade_indicator/metadata/description.json +0 -197
  35. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-effect.original.json +0 -895
  36. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/03-normalized-vfx-to-babylon-report.json +0 -241
  37. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-overrides.json +0 -542
  38. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/04-preview-tuning-report.json +0 -69
  39. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/asset-map.json +0 -125
  40. package/packages/build.mesh.yellow_build_upgrade_indicator/provenance/lineage.json +0 -44
  41. package/packages/build.particle.golden_upgrade_starburst/assets/runtime/particleEmitter.v1.js +0 -210
  42. package/packages/build.particle.golden_upgrade_starburst/assets/textures/effect_guangdian.png +0 -0
  43. package/packages/build.particle.golden_upgrade_starburst/effect.json +0 -880
  44. package/packages/build.particle.golden_upgrade_starburst/media/contact-sheet.png +0 -0
  45. package/packages/build.particle.golden_upgrade_starburst/media/preview.gif +0 -0
  46. package/packages/build.particle.golden_upgrade_starburst/media/preview.mp4 +0 -0
  47. package/packages/build.particle.golden_upgrade_starburst/media/preview.webm +0 -0
  48. package/packages/build.particle.golden_upgrade_starburst/media/thumbnail.png +0 -0
  49. package/packages/build.particle.golden_upgrade_starburst/metadata/description.json +0 -161
  50. package/packages/build.particle.golden_upgrade_starburst/provenance/03-effect.original.json +0 -762
  51. package/packages/build.particle.golden_upgrade_starburst/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  52. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-overrides.json +0 -436
  53. package/packages/build.particle.golden_upgrade_starburst/provenance/04-preview-tuning-report.json +0 -40
  54. package/packages/build.particle.golden_upgrade_starburst/provenance/asset-map.json +0 -115
  55. package/packages/build.particle.golden_upgrade_starburst/provenance/lineage.json +0 -40
  56. package/packages/build.particle.orange_upgrade_transform_sparks/assets/runtime/particleEmitter.v1.js +0 -210
  57. package/packages/build.particle.orange_upgrade_transform_sparks/assets/textures/b5b27ab1-e740-4398-b407-848fc2b2c897.png +0 -0
  58. package/packages/build.particle.orange_upgrade_transform_sparks/effect.json +0 -887
  59. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.gif +0 -0
  60. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.mp4 +0 -0
  61. package/packages/build.particle.orange_upgrade_transform_sparks/media/preview.webm +0 -0
  62. package/packages/build.particle.orange_upgrade_transform_sparks/media/thumbnail.png +0 -0
  63. package/packages/build.particle.orange_upgrade_transform_sparks/metadata/description.json +0 -179
  64. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-effect.original.json +0 -859
  65. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/03-normalized-vfx-to-babylon-report.json +0 -260
  66. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-overrides.json +0 -478
  67. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/04-preview-tuning-report.json +0 -40
  68. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/asset-map.json +0 -114
  69. package/packages/build.particle.orange_upgrade_transform_sparks/provenance/lineage.json +0 -41
  70. package/packages/build.particle.wood_chip_dust_burst/assets/runtime/particleEmitter.v1.js +0 -210
  71. package/packages/build.particle.wood_chip_dust_burst/assets/textures/effect_yanwu4.png +0 -0
  72. package/packages/build.particle.wood_chip_dust_burst/assets/textures/suipian3.png +0 -0
  73. package/packages/build.particle.wood_chip_dust_burst/effect.json +0 -1400
  74. package/packages/build.particle.wood_chip_dust_burst/media/contact-sheet.png +0 -0
  75. package/packages/build.particle.wood_chip_dust_burst/media/preview.gif +0 -0
  76. package/packages/build.particle.wood_chip_dust_burst/media/preview.mp4 +0 -0
  77. package/packages/build.particle.wood_chip_dust_burst/media/preview.webm +0 -0
  78. package/packages/build.particle.wood_chip_dust_burst/media/thumbnail.png +0 -0
  79. package/packages/build.particle.wood_chip_dust_burst/metadata/description.json +0 -173
  80. package/packages/build.particle.wood_chip_dust_burst/provenance/03-effect.original.json +0 -1277
  81. package/packages/build.particle.wood_chip_dust_burst/provenance/03-normalized-vfx-to-babylon-report.json +0 -329
  82. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-overrides.json +0 -749
  83. package/packages/build.particle.wood_chip_dust_burst/provenance/04-preview-tuning-report.json +0 -60
  84. package/packages/build.particle.wood_chip_dust_burst/provenance/asset-map.json +0 -146
  85. package/packages/build.particle.wood_chip_dust_burst/provenance/lineage.json +0 -69
  86. package/packages/effects/building-upgrade/effect.json +0 -6
  87. package/packages/effects/building-upgrade/index.ts +0 -387
  88. package/packages/effects/character-entrance/effect.json +0 -6
  89. package/packages/effects/character-entrance/index.ts +0 -308
  90. package/packages/effects/coin-burst/index.ts +0 -48
  91. package/packages/effects/comet-trail-flame/assets/textures/trail_5x4.webp +0 -0
  92. package/packages/effects/comet-trail-flame/index.ts +0 -107
  93. package/packages/effects/conveyor-upgrade/effect.json +0 -6
  94. package/packages/effects/conveyor-upgrade/index.ts +0 -401
  95. package/packages/effects/debris-smoke/assets/models/rock_debris.glb +0 -0
  96. package/packages/effects/debris-smoke/assets/textures/smoke22.webp +0 -0
  97. package/packages/effects/debris-smoke/index.ts +0 -102
  98. package/packages/effects/door_open_gold_flakes/assets/runtime/goldFlakes.v1.js +0 -397
  99. package/packages/effects/door_open_gold_flakes/door_open_gold_flakes.json +0 -498
  100. package/packages/effects/door_open_gold_flakes/index.ts +0 -11
  101. package/packages/effects/electric-arc/assets/textures/spark_4x4.webp +0 -0
  102. package/packages/effects/electric-arc/index.ts +0 -63
  103. package/packages/effects/energy-shield/effect.json +0 -7
  104. package/packages/effects/energy-shield/index.ts +0 -432
  105. package/packages/effects/explosion/assets/textures/baozha29.webp +0 -0
  106. package/packages/effects/explosion/assets/textures/glow01.webp +0 -0
  107. package/packages/effects/explosion/assets/textures/lizi01.webp +0 -0
  108. package/packages/effects/explosion/assets/textures/xulie_lizibaozha02_5x5.webp +0 -0
  109. package/packages/effects/explosion/index.ts +0 -115
  110. package/packages/effects/ground-tile-upgrade/effect.json +0 -6
  111. package/packages/effects/ground-tile-upgrade/index.ts +0 -410
  112. package/packages/effects/hit-flash/index.ts +0 -77
  113. package/packages/effects/laser-beam/assets/textures/laser_glow.webp +0 -0
  114. package/packages/effects/laser-beam/assets/textures/laser_noise.webp +0 -0
  115. package/packages/effects/laser-beam/index.ts +0 -6
  116. package/packages/effects/laser-beam-factory.ts +0 -146
  117. package/packages/effects/lumber-cart-suction/effect.json +0 -6
  118. package/packages/effects/lumber-cart-suction/index.ts +0 -399
  119. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb +0 -0
  120. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/.active +0 -1
  121. package/packages/effects/lumber-debris-scatter/assets/models/lumber_prop_model.glb.versions/1781589063890_upload.glb +0 -0
  122. package/packages/effects/lumber-debris-scatter/assets/runtime/solidParticleScatter.v1.js +0 -236
  123. package/packages/effects/lumber-debris-scatter/effect.json +0 -228
  124. package/packages/effects/lumber-debris-scatter/index.ts +0 -780
  125. package/packages/effects/lumber_vehicle_gear_spin/assets/runtime/gearSpin.v1.js +0 -202
  126. package/packages/effects/lumber_vehicle_gear_spin/index.ts +0 -11
  127. package/packages/effects/lumber_vehicle_gear_spin/lumber_vehicle_gear_spin.json +0 -338
  128. package/packages/effects/lumber_vehicle_upgrade_aura/assets/runtime/upgradeAura.v1.js +0 -353
  129. package/packages/effects/lumber_vehicle_upgrade_aura/index.ts +0 -13
  130. package/packages/effects/lumber_vehicle_upgrade_aura/lumber_vehicle_upgrade_aura.json +0 -365
  131. package/packages/effects/lumber_vehicle_wood_chips/assets/runtime/solidParticleScatter.v1.js +0 -310
  132. package/packages/effects/lumber_vehicle_wood_chips/index.ts +0 -11
  133. package/packages/effects/lumber_vehicle_wood_chips/lumber_vehicle_wood_chips.json +0 -335
  134. package/packages/effects/monster-hit/index.ts +0 -129
  135. package/packages/effects/player-upgrade/effect.json +0 -6
  136. package/packages/effects/player-upgrade/index.ts +0 -640
  137. package/packages/effects/pulse-laser-volley/assets/textures/bolt_guangshu.webp +0 -0
  138. package/packages/effects/pulse-laser-volley/index.ts +0 -215
  139. package/packages/effects/resource-collect-sparkles/effect.json +0 -6
  140. package/packages/effects/resource-collect-sparkles/index.ts +0 -254
  141. package/packages/effects/run-footstep-dust/assets/runtime/runFootstepDust.v1.js +0 -215
  142. package/packages/effects/run-footstep-dust/effect.json +0 -183
  143. package/packages/effects/run-footstep-dust/index.ts +0 -377
  144. package/packages/effects/space-shared.ts +0 -120
  145. package/packages/effects/thruster-flame/index.ts +0 -306
  146. package/packages/effects/treasure-attention/effect.json +0 -7
  147. package/packages/effects/treasure-attention/index.ts +0 -630
  148. package/packages/effects/tree-chop-dust/assets/textures/tree_chop_dust_atlas.png +0 -0
  149. package/packages/effects/tree-chop-dust/effect.json +0 -8
  150. package/packages/effects/tree-chop-dust/index.ts +0 -202
  151. package/packages/effects/tree-leaf-chop-burst/assets/runtime/particleEmitter.v1.js +0 -303
  152. package/packages/effects/tree-leaf-chop-burst/assets/textures/tree_leaf_chop_burst_leaf_atlas.png +0 -0
  153. package/packages/effects/tree-leaf-chop-burst/effect.json +0 -498
  154. package/packages/effects/tree-leaf-chop-burst/index.ts +0 -294
  155. package/packages/effects/tree_chop_dust_burst/assets/runtime/particleEmitter.v1.js +0 -318
  156. package/packages/effects/tree_chop_dust_burst/assets/textures/tree_chop_dust_burst_dust.png +0 -0
  157. package/packages/effects/tree_chop_dust_burst/index.ts +0 -13
  158. package/packages/effects/tree_chop_dust_burst/tree_chop_dust_burst.json +0 -412
  159. package/packages/effects/ufo-thread-flame/assets/textures/flame_flow.webp +0 -0
  160. package/packages/effects/ufo-thread-flame/assets/textures/flame_spike.webp +0 -0
  161. package/packages/effects/ufo-thread-flame/index.ts +0 -153
  162. package/packages/effects/vehicle-exhaust-smoke/assets/textures/vehicle_exhaust_smoke_atlas.png +0 -0
  163. package/packages/effects/vehicle-exhaust-smoke/effect.json +0 -8
  164. package/packages/effects/vehicle-exhaust-smoke/index.ts +0 -298
  165. package/packages/effects/vehicle-upgrade/effect.json +0 -6
  166. package/packages/effects/vehicle-upgrade/index.ts +0 -404
  167. package/packages/effects/weapon-trail/assets/textures/trail_wedge.png +0 -0
  168. package/packages/effects/weapon-trail/index.ts +0 -317
  169. package/packages/effects/wood-crusher-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  170. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  171. package/packages/effects/wood-crusher-sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  172. package/packages/effects/wood-crusher-sawdust/index.ts +0 -43
  173. package/packages/effects/wood-crusher-sawdust/wood_crusher_sawdust.json +0 -592
  174. package/packages/effects/wood-cutter-sawdust/assets/runtime/particleEmitter.v1.js +0 -312
  175. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  176. package/packages/effects/wood-cutter-sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  177. package/packages/effects/wood-cutter-sawdust/index.ts +0 -43
  178. package/packages/effects/wood-cutter-sawdust/wood_cutter_sawdust.json +0 -592
  179. package/packages/effects/wood-sawdust-effect-factory.ts +0 -194
  180. package/packages/effects/wood_crusher_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  181. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_dust.png +0 -0
  182. package/packages/effects/wood_crusher_sawdust/assets/textures/wood_crusher_sawdust_fiber.png +0 -0
  183. package/packages/effects/wood_crusher_sawdust/index.ts +0 -29
  184. package/packages/effects/wood_crusher_sawdust/wood_crusher_sawdust.json +0 -592
  185. package/packages/effects/wood_cutter_sawdust/assets/runtime/particleEmitter.v1.js +0 -318
  186. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_chip.png +0 -0
  187. package/packages/effects/wood_cutter_sawdust/assets/textures/wood_cutter_sawdust_dust.png +0 -0
  188. package/packages/effects/wood_cutter_sawdust/index.ts +0 -29
  189. package/packages/effects/wood_cutter_sawdust/wood_cutter_sawdust.json +0 -592
  190. package/packages/effects/wood_peel_material_test/assets/runtime/woodPeelMaterialTest.v1.js +0 -196
  191. package/packages/effects/wood_peel_material_test/index.ts +0 -11
  192. package/packages/effects/wood_peel_material_test/wood_peel_material_test.json +0 -136
  193. package/packages/env.particle.forest_edge_fog/assets/runtime/particleEmitter.v1.js +0 -210
  194. package/packages/env.particle.forest_edge_fog/assets/textures/f12a23c4-b924-4322-a260-3d982428f1e8.png +0 -0
  195. package/packages/env.particle.forest_edge_fog/assets/textures/yuan.png +0 -0
  196. package/packages/env.particle.forest_edge_fog/effect.json +0 -854
  197. package/packages/env.particle.forest_edge_fog/media/preview.gif +0 -0
  198. package/packages/env.particle.forest_edge_fog/media/preview.mp4 +0 -0
  199. package/packages/env.particle.forest_edge_fog/media/preview.webm +0 -0
  200. package/packages/env.particle.forest_edge_fog/media/thumbnail.png +0 -0
  201. package/packages/env.particle.forest_edge_fog/metadata/description.json +0 -148
  202. package/packages/env.particle.forest_edge_fog/provenance/03-effect.original.json +0 -827
  203. package/packages/env.particle.forest_edge_fog/provenance/03-normalized-vfx-to-babylon-report.json +0 -196
  204. package/packages/env.particle.forest_edge_fog/provenance/04-preview-overrides.json +0 -432
  205. package/packages/env.particle.forest_edge_fog/provenance/04-preview-tuning-report.json +0 -28
  206. package/packages/env.particle.forest_edge_fog/provenance/asset-map.json +0 -124
  207. package/packages/env.particle.forest_edge_fog/provenance/lineage.json +0 -41
  208. package/packages/generation.ts +0 -14
  209. package/packages/index.ts +0 -14
  210. package/packages/legacy-particle-runtime.ts +0 -113
  211. package/packages/manifestRuntimePackage.ts +0 -519
  212. package/packages/registry.ts +0 -85
  213. package/packages/rendering.ts +0 -13
  214. package/packages/resource.particle.viscous_oil_suction/assets/runtime/top_disk_suction/particleEmitter.v1.js +0 -424
  215. package/packages/resource.particle.viscous_oil_suction/assets/textures/Glow ad.png +0 -0
  216. package/packages/resource.particle.viscous_oil_suction/effect.json +0 -1254
  217. package/packages/resource.particle.viscous_oil_suction/media/preview.gif +0 -0
  218. package/packages/resource.particle.viscous_oil_suction/media/preview.mp4 +0 -0
  219. package/packages/resource.particle.viscous_oil_suction/media/preview.webm +0 -0
  220. package/packages/resource.particle.viscous_oil_suction/media/thumbnail.png +0 -0
  221. package/packages/resource.particle.viscous_oil_suction/metadata/description.json +0 -122
  222. package/packages/resource.particle.viscous_oil_suction/provenance/03-effect.original.json +0 -1051
  223. package/packages/resource.particle.viscous_oil_suction/provenance/03-normalized-vfx-to-babylon-report.json +0 -200
  224. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-overrides.json +0 -581
  225. package/packages/resource.particle.viscous_oil_suction/provenance/04-preview-tuning-report.json +0 -28
  226. package/packages/resource.particle.viscous_oil_suction/provenance/asset-map.json +0 -111
  227. package/packages/resource.particle.viscous_oil_suction/provenance/lineage.json +0 -45
  228. package/packages/types.ts +0 -195
  229. package/tooling/check-dist-runtime.mjs +0 -166
  230. package/tooling/generate-index.mjs +0 -55
  231. package/tooling/test-guardrails.mjs +0 -157
  232. package/tooling/validate-boundary.mjs +0 -92
  233. package/tooling/validate-effects.mjs +0 -304
  234. package/tooling/validate.mjs +0 -53
@@ -1,155 +0,0 @@
1
- # 方法:物体受击闪红(Hit Flash)
2
-
3
- > 给「**被击中的那个物体**」加一个受击瞬间染红 / 保持 / 淡回的反馈。供 coding agent 直接套用。
4
- > 移植自 axe_and_bear 的 `HitFlashService`(熊被斧子打到时整只变红)。
5
-
6
- ## 它和普通特效的本质区别 —— 先读这段
7
-
8
- - 普通 VFX(爆炸、拖尾、命中爆闪)是 **在某个位置 spawn 一团东西**(粒子/网格),和被打的物体无关。
9
- - 受击闪红是 **修改被打物体自己的材质颜色**(`emissiveColor`)。它没有"自己的网格",寄生在目标身上。
10
-
11
- 所以它**不是 `@fps/vfx` 的 `VfxEffectPackage`**(那个契约是 `create({position}) → 在该点生成`)。
12
- 不要试图 `vfx add hit-flash`。正确做法是把下面这个工具类放进**宿主工程**,在你能拿到目标 mesh 的地方用它。
13
-
14
- ## 原理(一句话)
15
-
16
- 每个目标 mesh:**克隆一份材质**(防止污染共享材质)→ 存下原始 `emissiveColor` → 受击时把 emissive 插值到红色,`holdTime` 秒保持全红,`fadeTime` 秒线性淡回原色。
17
-
18
- ```
19
- play() ┌─ holdTime ─┐┌──── fadeTime ────┐
20
- 红度 1.0 ████████████░░░░░░░░░░░░░░░░░░░░ → 回到原 emissive
21
- 命中 结束
22
- ```
23
- 红度 `t` → `emissive = Lerp(原色, Lerp(原色, 红, flashStrength), t)`
24
-
25
- ## 完整实现(复制即用)
26
-
27
- ```ts
28
- // hit-flash.ts —— 放进宿主工程(不是 @fps/vfx)
29
- import { Color3 } from '@babylonjs/core/Maths/math.color';
30
- import type { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
31
- import type { Material } from '@babylonjs/core/Materials/material';
32
- import type { Scene } from '@babylonjs/core/scene';
33
- import type { Observer } from '@babylonjs/core/Misc/observable';
34
-
35
- export interface HitFlashOptions {
36
- flashColor?: Color3; // 闪光色,默认红 (1,0,0)
37
- flashStrength?: number; // 0..1,红色混入强度(1=完全替换),默认 1
38
- holdTime?: number; // 全红保持秒,默认 0.2
39
- fadeTime?: number; // 淡回原色秒,默认 0.1
40
- emissiveBoost?: number; // HDR 倍率:有 bloom/tonemapping 时调大(默认 3.4);无后处理用 1
41
- }
42
-
43
- interface FlashEntry { mat: Material & { emissiveColor?: Color3 }; original: Color3; }
44
-
45
- export class HitFlash {
46
- private entries: FlashEntry[] = [];
47
- private readonly flashColor: Color3;
48
- private readonly flashStrength: number;
49
- private readonly holdTime: number;
50
- private readonly fadeTime: number;
51
- private elapsed = 0;
52
- private total = 0;
53
- private observer: Observer<Scene> | null = null;
54
-
55
- /** meshes:目标物体的所有可见 mesh(通常 root.getChildMeshes())。一个目标建一次,反复 play()。 */
56
- constructor(meshes: AbstractMesh[], private readonly scene: Scene, opts: HitFlashOptions = {}) {
57
- this.flashColor = (opts.flashColor ?? new Color3(1, 0, 0)).scale(opts.emissiveBoost ?? 3.4);
58
- this.flashStrength = opts.flashStrength ?? 1;
59
- this.holdTime = opts.holdTime ?? 0.2;
60
- this.fadeTime = opts.fadeTime ?? 0.1;
61
- for (const mesh of meshes) {
62
- const src = mesh.material;
63
- if (!src || !('emissiveColor' in src)) continue;
64
- // 关键:克隆材质,否则会染红所有共用此材质的物体
65
- const cloned = (src.clone(`${src.name}_hitflash`) ?? src) as FlashEntry['mat'];
66
- mesh.material = cloned;
67
- this.entries.push({ mat: cloned, original: (cloned.emissiveColor ?? Color3.Black()).clone() });
68
- }
69
- }
70
-
71
- /** 每次受击调用。连续受击会刷新到峰值(不叠加爆掉)。 */
72
- play(): void {
73
- this.elapsed = 0;
74
- this.total = this.holdTime + this.fadeTime;
75
- if (!this.observer) {
76
- this.observer = this.scene.onBeforeRenderObservable.add(() => this.update());
77
- }
78
- this.apply(1);
79
- }
80
-
81
- private update(): void {
82
- this.elapsed += this.scene.getEngine().getDeltaTime() / 1000;
83
- if (this.elapsed <= this.holdTime) {
84
- this.apply(1);
85
- } else if (this.elapsed < this.total) {
86
- this.apply(Math.max(0, 1 - (this.elapsed - this.holdTime) / this.fadeTime));
87
- } else {
88
- this.apply(0);
89
- this.detach();
90
- }
91
- }
92
-
93
- private apply(t: number): void {
94
- for (const e of this.entries) {
95
- const target = Color3.Lerp(e.original, this.flashColor, this.flashStrength);
96
- e.mat.emissiveColor = Color3.Lerp(e.original, target, t);
97
- }
98
- }
99
-
100
- private detach(): void {
101
- if (this.observer) { this.scene.onBeforeRenderObservable.remove(this.observer); this.observer = null; }
102
- }
103
-
104
- /** 目标销毁前调用:恢复原始 emissive + 移除 observer。 */
105
- dispose(): void {
106
- this.detach();
107
- for (const e of this.entries) e.mat.emissiveColor = e.original;
108
- }
109
- }
110
- ```
111
-
112
- ## 用法
113
-
114
- ```ts
115
- // 1) 目标出生时建一次(传它所有可见 mesh)
116
- const flash = new HitFlash(bear.getChildMeshes(), scene, {
117
- flashColor: new Color3(1, 0, 0), // 红
118
- holdTime: 0.2, fadeTime: 0.1,
119
- });
120
-
121
- // 2) 每次被打调用
122
- function onBearHit() {
123
- bear.subHp(dmg);
124
- flash.play(); // ← 闪红
125
- }
126
-
127
- // 3) 目标死亡/移除前
128
- flash.dispose();
129
- ```
130
-
131
- ## 参数怎么调影响什么
132
-
133
- | 参数 | 影响 |
134
- |---|---|
135
- | `flashColor` | 闪光颜色。红=受伤;白=普通受击;绿=治疗/buff |
136
- | `flashStrength` | 红色混入比例。1=峰值完全红;0.5=半红(保留原色感) |
137
- | `holdTime` | 全红保持时长。越大越"顿挫"/越重 |
138
- | `fadeTime` | 淡回时长。越大余韵越长越软 |
139
- | `emissiveBoost` | HDR 倍率。有 bloom/tonemapping 时调大让红更亮更艳(线性空间);无后处理设 1 |
140
-
141
- ## 必须注意的坑(coding agent 重点看)
142
-
143
- 1. **一定要克隆材质**。直接改 `mesh.material.emissiveColor` 会染红**所有共用这份材质的物体**(整片同模型一起变红)。上面构造里已 `clone()`。
144
- 2. **用 `emissiveColor` 不是 `diffuseColor`/`albedoColor`**。自发光不受光照影响、像"发光"般醒目,且能吃 bloom;`StandardMaterial` 和 `PBRMaterial` 都有 `emissiveColor`。
145
- 3. **存原色 + dispose 恢复**。目标原本可能就有 emissive(发光怪),必须存原值并在 dispose 时还原,否则残留。
146
- 4. **重复受击**。`play()` 重置计时到峰值 → 连击是"刷新红光"而非叠加,不会爆白。
147
- 5. **observer 生命周期**。淡出结束自动 `detach()`;目标销毁前务必 `dispose()` 移除残留 observer,避免泄漏与"对着已销毁材质写值"。
148
- 6. **PBR + emissiveTexture**:若目标材质带自发光贴图,纯色 emissive 会与贴图相加;受击闪红一般可接受,介意的话可在 play 时临时把 `emissiveTexture` 置 null、dispose 时还原。
149
- 7. **蒙皮/多子网格**:用 `root.getChildMeshes()` 把所有子网格都纳入,漏掉的部位不会变红。
150
-
151
- ## 可选增强
152
-
153
- - **配合受击粒子**:闪红是"染目标",再在命中点叠一个 `@fps/vfx` 的 `monster-hit`(闪光+血)burst,就是完整受击反馈——两者正交,各管一层。
154
- - **击退/缩放抖动**:`play()` 时顺带给 root 一个轻微 scale punch(1.1→1.0)或位移,手感更冲。
155
- - **死亡白闪**:把 `flashColor` 设白、`holdTime/fadeTime` 拉长,即死亡瞬间的泛白。