181404010226 4 сар өмнө
parent
commit
91a7b953cb
36 өөрчлөгдсөн 3856 нэмэгдсэн , 139 устгасан
  1. 11 102
      assets/assets/Prefabs/Pellet.prefab
  2. 169 14
      assets/assets/Prefabs/PelletContainer.prefab
  3. 450 0
      assets/assets/Prefabs/PelletWithTrail.prefab
  4. 13 0
      assets/assets/Prefabs/PelletWithTrail.prefab.meta
  5. 12 0
      assets/cases.meta
  6. 12 0
      assets/cases/ui.meta
  7. 12 0
      assets/cases/ui/24.motion-streak.meta
  8. 64 0
      assets/cases/ui/24.motion-streak/motion-streak-ctrl.ts
  9. 13 0
      assets/cases/ui/24.motion-streak/motion-streak-ctrl.ts.meta
  10. 1713 0
      assets/cases/ui/24.motion-streak/motion-streak.scene
  11. 11 0
      assets/cases/ui/24.motion-streak/motion-streak.scene.meta
  12. 288 0
      assets/cases/ui/24.motion-streak/move_around.anim
  13. 13 0
      assets/cases/ui/24.motion-streak/move_around.anim.meta
  14. BIN
      assets/cases/ui/24.motion-streak/图层 2.png
  15. 43 0
      assets/cases/ui/24.motion-streak/图层 2.png.meta
  16. 149 6
      assets/resources/data/excel/config_manager.py
  17. 80 0
      assets/resources/data/excel/update_visual_config.py
  18. BIN
      assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx
  19. 23 15
      assets/resources/data/weapons.json
  20. 6 2
      assets/scripts/CombatSystem/BallController.ts
  21. 196 0
      assets/scripts/CombatSystem/BulletTrailController.ts
  22. 13 0
      assets/scripts/CombatSystem/BulletTrailController.ts.meta
  23. 48 0
      assets/scripts/CombatSystem/WeaponBullet.ts
  24. 12 0
      assets/shared-res.meta
  25. 12 0
      assets/shared-res/textures.meta
  26. 12 0
      assets/shared-res/textures/ui.meta
  27. BIN
      assets/shared-res/textures/ui/gold.png
  28. 142 0
      assets/shared-res/textures/ui/gold.png.meta
  29. BIN
      assets/shared-res/textures/ui/singleColor.png
  30. 142 0
      assets/shared-res/textures/ui/singleColor.png.meta
  31. BIN
      assets/shared-res/textures/ui/star.png
  32. 42 0
      assets/shared-res/textures/ui/star.png.meta
  33. 37 0
      check_visual_config_trail.py
  34. 79 0
      debug_visual_config.py
  35. 19 0
      test_trail_effect.py
  36. 20 0
      test_visual_config.py

+ 11 - 102
assets/assets/Prefabs/Pellet.prefab

@@ -17,28 +17,24 @@
     "_objFlags": 0,
     "__editorExtras__": {},
     "_parent": null,
-    "_children": [
-      {
-        "__id__": 2
-      }
-    ],
+    "_children": [],
     "_active": true,
     "_components": [
       {
-        "__id__": 6
+        "__id__": 2
       },
       {
-        "__id__": 8
+        "__id__": 4
       },
       {
-        "__id__": 10
+        "__id__": 6
       },
       {
-        "__id__": 12
+        "__id__": 8
       }
     ],
     "_prefab": {
-      "__id__": 14
+      "__id__": 10
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -69,92 +65,6 @@
     },
     "_id": ""
   },
-  {
-    "__type__": "cc.Node",
-    "_name": "ParticleSystem",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "_parent": {
-      "__id__": 1
-    },
-    "_children": [],
-    "_active": true,
-    "_components": [
-      {
-        "__id__": 3
-      }
-    ],
-    "_prefab": {
-      "__id__": 5
-    },
-    "_lpos": {
-      "__type__": "cc.Vec3",
-      "x": 0,
-      "y": 0,
-      "z": 0
-    },
-    "_lrot": {
-      "__type__": "cc.Quat",
-      "x": 0,
-      "y": 0,
-      "z": 0,
-      "w": 1
-    },
-    "_lscale": {
-      "__type__": "cc.Vec3",
-      "x": 1,
-      "y": 1,
-      "z": 1
-    },
-    "_mobility": 0,
-    "_layer": 33554432,
-    "_euler": {
-      "__type__": "cc.Vec3",
-      "x": 0,
-      "y": 0,
-      "z": 0
-    },
-    "_id": ""
-  },
-  {
-    "__type__": "cc.UITransform",
-    "_name": "",
-    "_objFlags": 0,
-    "__editorExtras__": {},
-    "node": {
-      "__id__": 2
-    },
-    "_enabled": true,
-    "__prefab": {
-      "__id__": 4
-    },
-    "_contentSize": {
-      "__type__": "cc.Size",
-      "width": 100,
-      "height": 100
-    },
-    "_anchorPoint": {
-      "__type__": "cc.Vec2",
-      "x": 0.5,
-      "y": 0.5
-    },
-    "_id": ""
-  },
-  {
-    "__type__": "cc.CompPrefabInfo",
-    "fileId": "0aN40gSsxAVbvdTd83wVdT"
-  },
-  {
-    "__type__": "cc.PrefabInfo",
-    "root": {
-      "__id__": 1
-    },
-    "asset": {
-      "__id__": 0
-    },
-    "fileId": "f1z+yQ8yNNY6MreVM/9LUs",
-    "nestedPrefabInstanceRoots": null
-  },
   {
     "__type__": "cc.UITransform",
     "_name": "",
@@ -165,7 +75,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 7
+      "__id__": 3
     },
     "_contentSize": {
       "__type__": "cc.Size",
@@ -193,7 +103,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 9
+      "__id__": 5
     },
     "_customMaterial": null,
     "_srcBlendFactor": 2,
@@ -235,7 +145,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 11
+      "__id__": 7
     },
     "enabledContactListener": true,
     "bullet": true,
@@ -269,7 +179,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 13
+      "__id__": 9
     },
     "tag": 3,
     "_group": 8,
@@ -302,7 +212,6 @@
       "__id__": 0
     },
     "fileId": "ecZuuI1ixD85bubQwhroh8",
-    "instance": null,
-    "targetOverrides": null
+    "instance": null
   }
 ]

+ 169 - 14
assets/assets/Prefabs/PelletContainer.prefab

@@ -23,22 +23,28 @@
       },
       {
         "__id__": 10
+      },
+      {
+        "__id__": 16
       }
     ],
     "_active": true,
     "_components": [
       {
-        "__id__": 16
+        "__id__": 22
       },
       {
-        "__id__": 18
+        "__id__": 24
       },
       {
-        "__id__": 20
+        "__id__": 26
+      },
+      {
+        "__id__": 28
       }
     ],
     "_prefab": {
-      "__id__": 22
+      "__id__": 30
     },
     "_lpos": {
       "__type__": "cc.Vec3",
@@ -55,8 +61,8 @@
     },
     "_lscale": {
       "__type__": "cc.Vec3",
-      "x": 0.6,
-      "y": 0.6,
+      "x": 1,
+      "y": 1,
       "z": 1
     },
     "_mobility": 0,
@@ -250,7 +256,7 @@
       "__id__": 1
     },
     "_children": [],
-    "_active": true,
+    "_active": false,
     "_components": [
       {
         "__id__": 11
@@ -262,6 +268,134 @@
     "_prefab": {
       "__id__": 15
     },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 12
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 100
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "TrailEffectUITransform001"
+  },
+  {
+    "__type__": "cc.MotionStreak",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 10
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 14
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_preview": false,
+    "_fadeTime": 0.5,
+    "_minSeg": 1,
+    "_stroke": 10,
+    "_texture": {
+      "__uuid__": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8@6c48a",
+      "__expectedType__": "cc.Texture2D"
+    },
+    "_fastMode": false,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "TrailEffectMotionStreak001"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "TrailEffectPrefabInfo001",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Spine",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 17
+      },
+      {
+        "__id__": 19
+      }
+    ],
+    "_prefab": {
+      "__id__": 21
+    },
     "_lpos": {
       "__type__": "cc.Vec3",
       "x": -92.176,
@@ -297,11 +431,11 @@
     "_objFlags": 0,
     "__editorExtras__": {},
     "node": {
-      "__id__": 10
+      "__id__": 16
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 12
+      "__id__": 18
     },
     "_contentSize": {
       "__type__": "cc.Size",
@@ -325,11 +459,11 @@
     "_objFlags": 0,
     "__editorExtras__": {},
     "node": {
-      "__id__": 10
+      "__id__": 16
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 14
+      "__id__": 20
     },
     "_customMaterial": null,
     "_srcBlendFactor": 2,
@@ -387,7 +521,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 17
+      "__id__": 23
     },
     "_contentSize": {
       "__type__": "cc.Size",
@@ -415,7 +549,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 19
+      "__id__": 25
     },
     "enabledContactListener": true,
     "bullet": true,
@@ -449,7 +583,7 @@
     },
     "_enabled": true,
     "__prefab": {
-      "__id__": 21
+      "__id__": 27
     },
     "tag": 3,
     "_group": 8,
@@ -473,6 +607,27 @@
     "__type__": "cc.CompPrefabInfo",
     "fileId": "f6qdCY1HlJnrlAGAQlEG80"
   },
+  {
+    "__type__": "45e52RfjzZAfatmnUHw8J5a",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 29
+    },
+    "motionStreak": {
+      "__id__": 13
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "8ey0IBbt9BvZLCcxeeDHqf"
+  },
   {
     "__type__": "cc.PrefabInfo",
     "root": {

+ 450 - 0
assets/assets/Prefabs/PelletWithTrail.prefab

@@ -0,0 +1,450 @@
+[
+  {
+    "__type__": "cc.Prefab",
+    "_name": "PelletWithTrail",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_native": "",
+    "data": {
+      "__id__": 1
+    },
+    "optimizationPolicy": 0,
+    "persistent": false
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "PelletWithTrail",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": null,
+    "_children": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 6
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 10
+      },
+      {
+        "__id__": 12
+      },
+      {
+        "__id__": 14
+      },
+      {
+        "__id__": 16
+      },
+      {
+        "__id__": 18
+      }
+    ],
+    "_prefab": {
+      "__id__": 20
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 0.5,
+      "y": 0.5,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "ParticleSystem",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 3
+      }
+    ],
+    "_prefab": {
+      "__id__": 5
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 4
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 100
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "0aN40gSsxAVbvdTd83wVdT"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "f1z+yQ8yNNY6MreVM/9LUs",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "MotionStreak",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 7
+      }
+    ],
+    "_prefab": {
+      "__id__": 9
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 33554432,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.MotionStreak",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 6
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 8
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 252,
+      "g": 252,
+      "b": 248,
+      "a": 255
+    },
+    "_preview": false,
+    "_fadeTime": 1,
+    "_minSeg": 1,
+    "_stroke": 15,
+    "_texture": {
+      "__uuid__": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8@6c48a",
+      "__expectedType__": "cc.Texture2D"
+    },
+    "_fastMode": false,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "07Cs3nJK1HF5xU5vRbC8tF"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "a0rFq+f+lLYKv/Eg6V7VMi",
+    "instance": null,
+    "targetOverrides": null,
+    "nestedPrefabInstanceRoots": null
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 11
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 57,
+      "height": 57
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "01PFH40wdI/5w0W4w5nM/4"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 13
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": null,
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 1,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "a58czs9GZLJp7XWpINUriv"
+  },
+  {
+    "__type__": "cc.RigidBody2D",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 15
+    },
+    "enabledContactListener": true,
+    "bullet": true,
+    "awakeOnLoad": true,
+    "_group": 8,
+    "_type": 2,
+    "_allowSleep": false,
+    "_gravityScale": 0,
+    "_linearDamping": 0,
+    "_angularDamping": 0,
+    "_linearVelocity": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_angularVelocity": 0,
+    "_fixedRotation": false,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "35W4266NlITpxotlJ97Tir"
+  },
+  {
+    "__type__": "cc.BoxCollider2D",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 17
+    },
+    "tag": 3,
+    "_group": 8,
+    "_density": 1,
+    "_sensor": false,
+    "_friction": 0.2,
+    "_restitution": 0,
+    "_offset": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_size": {
+      "__type__": "cc.Size",
+      "width": 57,
+      "height": 57
+    },
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "9bb08vp9FMf4YvjtykcC6W"
+  },
+  {
+    "__type__": "cc.MotionStreak",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 1
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 19
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 248,
+      "g": 248,
+      "b": 248,
+      "a": 255
+    },
+    "_preview": false,
+    "_fadeTime": 0.5,
+    "_minSeg": 1,
+    "_stroke": 10,
+    "_texture": {
+      "__uuid__": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8@6c48a",
+      "__expectedType__": "cc.Texture2D"
+    },
+    "_fastMode": false,
+    "_id": ""
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "16MotionStreakComponent001"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": {
+      "__id__": 1
+    },
+    "asset": {
+      "__id__": 0
+    },
+    "fileId": "ecZuuI1ixD85bubQwhroh8",
+    "instance": null,
+    "targetOverrides": null
+  }
+]

+ 13 - 0
assets/assets/Prefabs/PelletWithTrail.prefab.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "1.1.50",
+  "importer": "prefab",
+  "imported": true,
+  "uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {
+    "syncNodeName": "PelletWithTrail"
+  }
+}

+ 12 - 0
assets/cases.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "700ba467-650f-4f33-bc5a-667423b2be7a",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "compressionType": {},
+    "isRemoteBundle": {}
+  }
+}

+ 12 - 0
assets/cases/ui.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "efeccf7d-8ba2-4b75-ba90-9197d404e568",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "compressionType": {},
+    "isRemoteBundle": {}
+  }
+}

+ 12 - 0
assets/cases/ui/24.motion-streak.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "fae49215-671d-4595-9669-93d73514da30",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "compressionType": {},
+    "isRemoteBundle": {}
+  }
+}

+ 64 - 0
assets/cases/ui/24.motion-streak/motion-streak-ctrl.ts

@@ -0,0 +1,64 @@
+
+import { _decorator, Component, Node, MotionStreak, Texture2D, Animation, Color } from 'cc';
+const { ccclass, type } = _decorator;
+
+@ccclass('MotionStreakCtrl')
+export class MotionStreakCtrl extends Component {
+    @type(MotionStreak)
+    motionStreak: MotionStreak | null = null;
+
+    @type(Texture2D)
+    newTexture: Texture2D | null = null;
+
+    @type(Animation)
+    animationCom: Animation | null = null;
+
+    private _changed: boolean = true;
+    private _oldTexture: Texture2D | null = null;
+
+    private _colorChanged: boolean = false;
+    private _newColor = Color.CYAN;
+    private _oldColor = Color.WHITE;
+
+    onLoad () {
+        this._changed = true;
+        this._oldTexture = this.motionStreak!.texture;
+        this._colorChanged = false;
+    }
+
+    onClick () {
+        if (this._changed) {
+            this.setMotionStreak(2, 3, 20, this.newTexture!);
+        }
+        else {
+            this.setMotionStreak(0.5, 1, 30, this._oldTexture!);
+        }
+        this._changed = !this._changed;
+    }
+
+    colorChange () {
+        this._colorChanged = !this._colorChanged;
+        if (this._colorChanged) {
+            this.motionStreak!.color = this._newColor;
+        } else {
+            this.motionStreak!.color = this._oldColor;
+        }
+    }
+
+    setMotionStreak (fadeTime: number, minSeg: number, stroke: number, texture: Texture2D) {
+        this.motionStreak!.fadeTime = fadeTime;
+        this.motionStreak!.minSeg = minSeg;
+        this.motionStreak!.stroke = stroke;
+        this.motionStreak!.texture = texture;
+    }
+
+    lateUpdate () {
+        if (!this.animationCom!.getState('move_around').isPlaying) {
+            this.animationCom!.play();
+        }
+    }
+
+    onDisable () {
+        this.animationCom!.stop();
+    }
+}

+ 13 - 0
assets/cases/ui/24.motion-streak/motion-streak-ctrl.ts.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "22ac104c-eecb-401b-8181-0e8d15c29eea",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "moduleId": "project:///assets/cases/ui/24.motion-streak/motion-streak-ctrl.js",
+    "importerSettings": 3,
+    "simulateGlobals": []
+  }
+}

+ 1713 - 0
assets/cases/ui/24.motion-streak/motion-streak.scene

@@ -0,0 +1,1713 @@
+[
+  {
+    "__type__": "cc.SceneAsset",
+    "_name": "motion-streak",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_native": "",
+    "scene": {
+      "__id__": 1
+    }
+  },
+  {
+    "__type__": "cc.Scene",
+    "_name": "motion-streak",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": null,
+    "_children": [
+      {
+        "__id__": 2
+      },
+      {
+        "__id__": 20
+      }
+    ],
+    "_active": true,
+    "_components": [],
+    "_prefab": {
+      "__id__": 51
+    },
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "autoReleaseAssets": false,
+    "_globals": {
+      "__id__": 52
+    },
+    "_id": "482eed84-f365-4a2f-b174-b67d38abbb6e"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Canvas",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [
+      {
+        "__id__": 3
+      },
+      {
+        "__id__": 7
+      },
+      {
+        "__id__": 32
+      },
+      {
+        "__id__": 23
+      },
+      {
+        "__id__": 46
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 48
+      },
+      {
+        "__id__": 49
+      },
+      {
+        "__id__": 50
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 360,
+      "y": 667,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "d4lnc4J49En7kj2v59gUfT"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "background",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 4
+      },
+      {
+        "__id__": 5
+      },
+      {
+        "__id__": 6
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "74AvgCHDJMpKbdx6qH8ln9"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 720,
+      "height": 1334
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "ffKONW/KxLg67ZRP7Xc2Lz"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 56,
+      "g": 59,
+      "b": 65,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": "c5SkVEX5RINZIX5qI/iaxd"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 3
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_alignFlags": 45,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 100,
+    "_originalHeight": 100,
+    "_alignMode": 1,
+    "_lockFlags": 0,
+    "_id": "1ceyRhFexBp4rH3fg4Py8Q"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Button",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [
+      {
+        "__id__": 8
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 13
+      },
+      {
+        "__id__": 15
+      },
+      {
+        "__id__": 17
+      },
+      {
+        "__id__": 31
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 239.226,
+      "y": -599.387,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "01j9cST4dDhIxWMSL3/Yf+"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Label",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 7
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 9
+      },
+      {
+        "__id__": 11
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "ecSTtXI0JLf6fL/n2Hgj7N"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 8
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 10
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 40
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "beByS5WRRGnJpTJfljLMTm"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "beByS5WRRGnJpTJfljLMTm"
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 8
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 12
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_string": "改变拖尾",
+    "_horizontalAlign": 1,
+    "_verticalAlign": 1,
+    "_actualFontSize": 20,
+    "_fontSize": 20,
+    "_fontFamily": "Arial",
+    "_lineHeight": 40,
+    "_overflow": 1,
+    "_enableWrapText": false,
+    "_font": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_isItalic": false,
+    "_isBold": false,
+    "_isUnderline": false,
+    "_underlineHeight": 0,
+    "_cacheMode": 0,
+    "_enableOutline": false,
+    "_outlineColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_outlineWidth": 2,
+    "_enableShadow": false,
+    "_shadowColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_shadowOffset": {
+      "__type__": "cc.Vec2",
+      "x": 2,
+      "y": 2
+    },
+    "_shadowBlur": 2,
+    "_id": "22x8JrPJlKN64O5kdLYYw3"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "22x8JrPJlKN64O5kdLYYw3"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 7
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 14
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 40
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "dcqjpWs5NG7J1Wsm5oplLm"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "dcqjpWs5NG7J1Wsm5oplLm"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 7
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 16
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 1,
+    "_fillType": 0,
+    "_sizeMode": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": "6blPVB4HdInIbd7J1+bAnD"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "6blPVB4HdInIbd7J1+bAnD"
+  },
+  {
+    "__type__": "cc.Button",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 7
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 18
+    },
+    "clickEvents": [
+      {
+        "__id__": 19
+      }
+    ],
+    "_interactable": true,
+    "_transition": 2,
+    "_normalColor": {
+      "__type__": "cc.Color",
+      "r": 214,
+      "g": 214,
+      "b": 214,
+      "a": 255
+    },
+    "_hoverColor": {
+      "__type__": "cc.Color",
+      "r": 211,
+      "g": 211,
+      "b": 211,
+      "a": 255
+    },
+    "_pressedColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_disabledColor": {
+      "__type__": "cc.Color",
+      "r": 124,
+      "g": 124,
+      "b": 124,
+      "a": 255
+    },
+    "_normalSprite": {
+      "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_hoverSprite": {
+      "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_pressedSprite": {
+      "__uuid__": "544e49d6-3f05-4fa8-9a9e-091f98fc2ce8@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_disabledSprite": {
+      "__uuid__": "951249e0-9f16-456d-8b85-a6ca954da16b@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_duration": 0.1,
+    "_zoomScale": 1.2,
+    "_target": {
+      "__id__": 7
+    },
+    "_id": "39WI/59jJE1aDdqLotwQRP"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "39WI/59jJE1aDdqLotwQRP"
+  },
+  {
+    "__type__": "cc.ClickEvent",
+    "target": {
+      "__id__": 20
+    },
+    "component": "",
+    "_componentId": "22ac1BM7stAG4GBDo0Vwp7q",
+    "handler": "onClick",
+    "customEventData": ""
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "motion-streak-ctrl",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 1
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 21
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 1073741824,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "9dVgsUlXBMIJbwUeUzesIu"
+  },
+  {
+    "__type__": "22ac1BM7stAG4GBDo0Vwp7q",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 20
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "motionStreak": {
+      "__id__": 22
+    },
+    "newTexture": {
+      "__uuid__": "b585a82a-6354-40a1-acc7-76f985d9a91c@6c48a",
+      "__expectedType__": "cc.Texture2D"
+    },
+    "animationCom": {
+      "__id__": 30
+    },
+    "_id": "71aQHjQnlLcJigoE/Wale8"
+  },
+  {
+    "__type__": "cc.MotionStreak",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 23
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_preview": false,
+    "_fadeTime": 0.2,
+    "_minSeg": 0.05,
+    "_stroke": 30,
+    "_texture": {
+      "__uuid__": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8@6c48a",
+      "__expectedType__": "cc.Texture2D"
+    },
+    "_fastMode": false,
+    "_id": "c5BHWVn5NCYKPQQ7JqjgYp"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "MotionStreak",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [
+      {
+        "__id__": 24
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 29
+      },
+      {
+        "__id__": 22
+      },
+      {
+        "__id__": 30
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": -399.484,
+      "y": 26.323,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "87ZAGTW/lHW66WiYXIQjJK"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "gold",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 23
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 25
+      },
+      {
+        "__id__": 27
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "03bWC+7KBHJYpHTOzuYqnV"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 24
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 26
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 40,
+      "height": 40
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "54FYP+/mlATLAZ7Gi2FDs3"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "54FYP+/mlATLAZ7Gi2FDs3"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 24
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 28
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "877e09bf-ded6-4b38-a1a5-eab3f11b099e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 0,
+    "_fillType": 0,
+    "_sizeMode": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": "55plxD+BpA+IxsydfwBI4i"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "55plxD+BpA+IxsydfwBI4i"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 23
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 40,
+      "height": 40
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "802VzqiHNNJbZ2ZPVlhs+9"
+  },
+  {
+    "__type__": "cc.Animation",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 23
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "playOnLoad": false,
+    "_clips": [
+      {
+        "__uuid__": "2656aaaf-e556-4fd5-b218-e392256dc399",
+        "__expectedType__": "cc.AnimationClip"
+      }
+    ],
+    "_defaultClip": {
+      "__uuid__": "2656aaaf-e556-4fd5-b218-e392256dc399",
+      "__expectedType__": "cc.AnimationClip"
+    },
+    "_id": "d3Y4dLCuNLBZFB/6hqcHeM"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 7
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_alignFlags": 36,
+    "_target": null,
+    "_left": 0,
+    "_right": 70.774,
+    "_top": 0,
+    "_bottom": 47.613,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": "5eqiglJYBD3K5p8YgtA4Ky"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Button-color",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [
+      {
+        "__id__": 33
+      }
+    ],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 38
+      },
+      {
+        "__id__": 40
+      },
+      {
+        "__id__": 42
+      },
+      {
+        "__id__": 45
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 239.226,
+      "y": -531.04,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "0c6KigMPtMz52Q2jWZFkba"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "Label",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 32
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 34
+      },
+      {
+        "__id__": 36
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "f9MgLjXOZIKpd55i6lwzFr"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 33
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 35
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 40
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "be/adtgfJBAYl5Tqbcdad9"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "beByS5WRRGnJpTJfljLMTm"
+  },
+  {
+    "__type__": "cc.Label",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 33
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 37
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_string": "改变颜色",
+    "_horizontalAlign": 1,
+    "_verticalAlign": 1,
+    "_actualFontSize": 20,
+    "_fontSize": 20,
+    "_fontFamily": "Arial",
+    "_lineHeight": 40,
+    "_overflow": 1,
+    "_enableWrapText": false,
+    "_font": null,
+    "_isSystemFontUsed": true,
+    "_spacingX": 0,
+    "_isItalic": false,
+    "_isBold": false,
+    "_isUnderline": false,
+    "_underlineHeight": 0,
+    "_cacheMode": 0,
+    "_enableOutline": false,
+    "_outlineColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_outlineWidth": 2,
+    "_enableShadow": false,
+    "_shadowColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 255
+    },
+    "_shadowOffset": {
+      "__type__": "cc.Vec2",
+      "x": 2,
+      "y": 2
+    },
+    "_shadowBlur": 2,
+    "_id": "39cm2n0B9Ix7YHwGQiFfJ3"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "22x8JrPJlKN64O5kdLYYw3"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 32
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 39
+    },
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 100,
+      "height": 40
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "8e5YP6bH1IE5D7rEOOVaLC"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "dcqjpWs5NG7J1Wsm5oplLm"
+  },
+  {
+    "__type__": "cc.Sprite",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 32
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 41
+    },
+    "_customMaterial": null,
+    "_srcBlendFactor": 2,
+    "_dstBlendFactor": 4,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_spriteFrame": {
+      "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_type": 1,
+    "_fillType": 0,
+    "_sizeMode": 0,
+    "_fillCenter": {
+      "__type__": "cc.Vec2",
+      "x": 0,
+      "y": 0
+    },
+    "_fillStart": 0,
+    "_fillRange": 0,
+    "_isTrimmedMode": true,
+    "_useGrayscale": false,
+    "_atlas": null,
+    "_id": "c4M9Wc94NAF6rZA6rOi9r+"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "6blPVB4HdInIbd7J1+bAnD"
+  },
+  {
+    "__type__": "cc.Button",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 32
+    },
+    "_enabled": true,
+    "__prefab": {
+      "__id__": 43
+    },
+    "clickEvents": [
+      {
+        "__id__": 44
+      }
+    ],
+    "_interactable": true,
+    "_transition": 2,
+    "_normalColor": {
+      "__type__": "cc.Color",
+      "r": 214,
+      "g": 214,
+      "b": 214,
+      "a": 255
+    },
+    "_hoverColor": {
+      "__type__": "cc.Color",
+      "r": 211,
+      "g": 211,
+      "b": 211,
+      "a": 255
+    },
+    "_pressedColor": {
+      "__type__": "cc.Color",
+      "r": 255,
+      "g": 255,
+      "b": 255,
+      "a": 255
+    },
+    "_disabledColor": {
+      "__type__": "cc.Color",
+      "r": 124,
+      "g": 124,
+      "b": 124,
+      "a": 255
+    },
+    "_normalSprite": {
+      "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_hoverSprite": {
+      "__uuid__": "20835ba4-6145-4fbc-a58a-051ce700aa3e@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_pressedSprite": {
+      "__uuid__": "544e49d6-3f05-4fa8-9a9e-091f98fc2ce8@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_disabledSprite": {
+      "__uuid__": "951249e0-9f16-456d-8b85-a6ca954da16b@f9941",
+      "__expectedType__": "cc.SpriteFrame"
+    },
+    "_duration": 0.1,
+    "_zoomScale": 1.2,
+    "_target": {
+      "__id__": 32
+    },
+    "_id": "b9jFNEQ+RN9qHHbqh+yxry"
+  },
+  {
+    "__type__": "cc.CompPrefabInfo",
+    "fileId": "39WI/59jJE1aDdqLotwQRP"
+  },
+  {
+    "__type__": "cc.ClickEvent",
+    "target": {
+      "__id__": 20
+    },
+    "component": "",
+    "_componentId": "22ac1BM7stAG4GBDo0Vwp7q",
+    "handler": "colorChange",
+    "customEventData": ""
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 32
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_alignFlags": 36,
+    "_target": null,
+    "_left": 0,
+    "_right": 70.774,
+    "_top": 0,
+    "_bottom": 115.96000000000001,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": "ed6fZNEj5ECJM/03oZs5NK"
+  },
+  {
+    "__type__": "cc.Node",
+    "_name": "UICamera_Canvas",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "_parent": {
+      "__id__": 2
+    },
+    "_children": [],
+    "_active": true,
+    "_components": [
+      {
+        "__id__": 47
+      }
+    ],
+    "_prefab": null,
+    "_lpos": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 1000
+    },
+    "_lrot": {
+      "__type__": "cc.Quat",
+      "x": 0,
+      "y": 0,
+      "z": 0,
+      "w": 1
+    },
+    "_lscale": {
+      "__type__": "cc.Vec3",
+      "x": 1,
+      "y": 1,
+      "z": 1
+    },
+    "_mobility": 0,
+    "_layer": 524288,
+    "_euler": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 0,
+      "z": 0
+    },
+    "_id": "69OknLXJlIL41X75idenvV"
+  },
+  {
+    "__type__": "cc.Camera",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 46
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_projection": 0,
+    "_priority": 1073741824,
+    "_fov": 45,
+    "_fovAxis": 0,
+    "_orthoHeight": 667,
+    "_near": 1,
+    "_far": 2000,
+    "_color": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 0
+    },
+    "_depth": 1,
+    "_stencil": 0,
+    "_clearFlags": 7,
+    "_rect": {
+      "__type__": "cc.Rect",
+      "x": 0,
+      "y": 0,
+      "width": 1,
+      "height": 1
+    },
+    "_aperture": 19,
+    "_shutter": 7,
+    "_iso": 0,
+    "_screenScale": 1,
+    "_visibility": 42467328,
+    "_targetTexture": null,
+    "_postProcess": null,
+    "_usePostProcess": false,
+    "_cameraType": -1,
+    "_trackingType": 0,
+    "_id": "996WeJ701JQo+J2MYdUBQA"
+  },
+  {
+    "__type__": "cc.UITransform",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_contentSize": {
+      "__type__": "cc.Size",
+      "width": 720,
+      "height": 1334
+    },
+    "_anchorPoint": {
+      "__type__": "cc.Vec2",
+      "x": 0.5,
+      "y": 0.5
+    },
+    "_id": "4eMcREl9BN4KhMcm8ULCuR"
+  },
+  {
+    "__type__": "cc.Canvas",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_cameraComponent": {
+      "__id__": 47
+    },
+    "_alignCanvasWithScreen": true,
+    "_id": "25iAoPo2tHFLAqK5TgKB/1"
+  },
+  {
+    "__type__": "cc.Widget",
+    "_name": "",
+    "_objFlags": 0,
+    "__editorExtras__": {},
+    "node": {
+      "__id__": 2
+    },
+    "_enabled": true,
+    "__prefab": null,
+    "_alignFlags": 45,
+    "_target": null,
+    "_left": 0,
+    "_right": 0,
+    "_top": 0,
+    "_bottom": 0,
+    "_horizontalCenter": 0,
+    "_verticalCenter": 0,
+    "_isAbsLeft": true,
+    "_isAbsRight": true,
+    "_isAbsTop": true,
+    "_isAbsBottom": true,
+    "_isAbsHorizontalCenter": true,
+    "_isAbsVerticalCenter": true,
+    "_originalWidth": 0,
+    "_originalHeight": 0,
+    "_alignMode": 2,
+    "_lockFlags": 0,
+    "_id": "06OWTcUDFCXrV/94f7sL1R"
+  },
+  {
+    "__type__": "cc.PrefabInfo",
+    "root": null,
+    "asset": null,
+    "fileId": "482eed84-f365-4a2f-b174-b67d38abbb6e",
+    "instance": null,
+    "targetOverrides": null
+  },
+  {
+    "__type__": "cc.SceneGlobals",
+    "ambient": {
+      "__id__": 53
+    },
+    "shadows": {
+      "__id__": 54
+    },
+    "_skybox": {
+      "__id__": 55
+    },
+    "fog": {
+      "__id__": 56
+    },
+    "octree": {
+      "__id__": 57
+    },
+    "skin": {
+      "__id__": 58
+    },
+    "lightProbeInfo": {
+      "__id__": 59
+    },
+    "postSettings": {
+      "__id__": 60
+    },
+    "bakedWithStationaryMainLight": false,
+    "bakedWithHighpLightmap": false
+  },
+  {
+    "__type__": "cc.AmbientInfo",
+    "_skyColorHDR": {
+      "__type__": "cc.Vec4",
+      "x": 0.2,
+      "y": 0.5019607843137255,
+      "z": 0.8,
+      "w": 0.520833125
+    },
+    "_skyColor": {
+      "__type__": "cc.Vec4",
+      "x": 0.2,
+      "y": 0.5019607843137255,
+      "z": 0.8,
+      "w": 0.520833125
+    },
+    "_skyIllumHDR": 20000,
+    "_skyIllum": 20000,
+    "_groundAlbedoHDR": {
+      "__type__": "cc.Vec4",
+      "x": 0.2,
+      "y": 0.2,
+      "z": 0.2,
+      "w": 1
+    },
+    "_groundAlbedo": {
+      "__type__": "cc.Vec4",
+      "x": 0.2,
+      "y": 0.2,
+      "z": 0.2,
+      "w": 1
+    },
+    "_skyColorLDR": {
+      "__type__": "cc.Vec4",
+      "x": 0.2,
+      "y": 0.5019607843137255,
+      "z": 0.8,
+      "w": 0.520833125
+    },
+    "_skyIllumLDR": 0.78125,
+    "_groundAlbedoLDR": {
+      "__type__": "cc.Vec4",
+      "x": 0.2,
+      "y": 0.2,
+      "z": 0.2,
+      "w": 1
+    }
+  },
+  {
+    "__type__": "cc.ShadowsInfo",
+    "_enabled": false,
+    "_type": 0,
+    "_normal": {
+      "__type__": "cc.Vec3",
+      "x": 0,
+      "y": 1,
+      "z": 0
+    },
+    "_distance": 0,
+    "_planeBias": 1,
+    "_shadowColor": {
+      "__type__": "cc.Color",
+      "r": 0,
+      "g": 0,
+      "b": 0,
+      "a": 76
+    },
+    "_maxReceived": 4,
+    "_size": {
+      "__type__": "cc.Vec2",
+      "x": 512,
+      "y": 512
+    }
+  },
+  {
+    "__type__": "cc.SkyboxInfo",
+    "_envLightingType": 0,
+    "_envmapHDR": null,
+    "_envmap": null,
+    "_envmapLDR": null,
+    "_diffuseMapHDR": null,
+    "_diffuseMapLDR": null,
+    "_enabled": false,
+    "_useHDR": true,
+    "_editableMaterial": null,
+    "_reflectionHDR": null,
+    "_reflectionLDR": null,
+    "_rotationAngle": 0
+  },
+  {
+    "__type__": "cc.FogInfo",
+    "_type": 0,
+    "_fogColor": {
+      "__type__": "cc.Color",
+      "r": 225,
+      "g": 225,
+      "b": 225,
+      "a": 255
+    },
+    "_enabled": false,
+    "_fogDensity": 0.3,
+    "_fogStart": 0.5,
+    "_fogEnd": 300,
+    "_fogAtten": 5,
+    "_fogTop": 1.5,
+    "_fogRange": 1.2,
+    "_accurate": false
+  },
+  {
+    "__type__": "cc.OctreeInfo",
+    "_enabled": false,
+    "_minPos": {
+      "__type__": "cc.Vec3",
+      "x": -1024,
+      "y": -1024,
+      "z": -1024
+    },
+    "_maxPos": {
+      "__type__": "cc.Vec3",
+      "x": 1024,
+      "y": 1024,
+      "z": 1024
+    },
+    "_depth": 8
+  },
+  {
+    "__type__": "cc.SkinInfo",
+    "_enabled": true,
+    "_blurRadius": 0.01,
+    "_sssIntensity": 3
+  },
+  {
+    "__type__": "cc.LightProbeInfo",
+    "_giScale": 1,
+    "_giSamples": 1024,
+    "_bounces": 2,
+    "_reduceRinging": 0,
+    "_showProbe": true,
+    "_showWireframe": true,
+    "_showConvex": false,
+    "_data": null,
+    "_lightProbeSphereVolume": 1
+  },
+  {
+    "__type__": "cc.PostSettingsInfo",
+    "_toneMappingType": 0
+  }
+]

+ 11 - 0
assets/cases/ui/24.motion-streak/motion-streak.scene.meta

@@ -0,0 +1,11 @@
+{
+  "ver": "1.1.50",
+  "importer": "scene",
+  "imported": true,
+  "uuid": "482eed84-f365-4a2f-b174-b67d38abbb6e",
+  "files": [
+    ".json"
+  ],
+  "subMetas": {},
+  "userData": {}
+}

+ 288 - 0
assets/cases/ui/24.motion-streak/move_around.anim

@@ -0,0 +1,288 @@
+[
+  {
+    "__type__": "cc.AnimationClip",
+    "_name": "move_around",
+    "_objFlags": 0,
+    "_native": "",
+    "sample": 60,
+    "speed": 1,
+    "wrapMode": 22,
+    "_duration": 2,
+    "_hash": 0,
+    "_tracks": [
+      {
+        "__id__": 1
+      }
+    ],
+    "_events": [],
+    "_exoticAnimation": null
+  },
+  {
+    "__type__": "cc.animation.VectorTrack",
+    "_binding": {
+      "__type__": "cc.animation.TrackBinding",
+      "path": {
+        "__id__": 2
+      }
+    },
+    "_channels": [
+      {
+        "__id__": 3
+      },
+      {
+        "__id__": 5
+      },
+      {
+        "__id__": 7
+      },
+      {
+        "__id__": 9
+      }
+    ],
+    "_nComponents": 3
+  },
+  {
+    "__type__": "cc.animation.TrackPath",
+    "_paths": [
+      "position"
+    ]
+  },
+  {
+    "__type__": "cc.animation.Channel",
+    "_curve": {
+      "__id__": 4
+    }
+  },
+  {
+    "__type__": "cc.RealCurve",
+    "_times": [
+      0.016666666666666666,
+      0.5,
+      1,
+      1.4833333333333334,
+      2
+    ],
+    "_values": [
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": -399.484,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 10.839,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 376.258,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 11.922,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": -399.484,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      }
+    ],
+    "preExtrapolation": 1,
+    "postExtrapolation": 1
+  },
+  {
+    "__type__": "cc.animation.Channel",
+    "_curve": {
+      "__id__": 6
+    }
+  },
+  {
+    "__type__": "cc.RealCurve",
+    "_times": [
+      0.016666666666666666,
+      0.5,
+      1,
+      1.4833333333333334,
+      2
+    ],
+    "_values": [
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 26.323,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 255.484,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 27.871,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": -236.851,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 26.323,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      }
+    ],
+    "preExtrapolation": 1,
+    "postExtrapolation": 1
+  },
+  {
+    "__type__": "cc.animation.Channel",
+    "_curve": {
+      "__id__": 8
+    }
+  },
+  {
+    "__type__": "cc.RealCurve",
+    "_times": [
+      0.016666666666666666,
+      0.5,
+      1,
+      1.4833333333333334,
+      2
+    ],
+    "_values": [
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 0,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 0,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 0,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 0,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      },
+      {
+        "__type__": "cc.RealKeyframeValue",
+        "interpolationMode": 0,
+        "tangentWeightMode": 0,
+        "value": 0,
+        "rightTangent": 0,
+        "rightTangentWeight": 0,
+        "leftTangent": 0,
+        "leftTangentWeight": 0,
+        "easingMethod": 0
+      }
+    ],
+    "preExtrapolation": 1,
+    "postExtrapolation": 1
+  },
+  {
+    "__type__": "cc.animation.Channel",
+    "_curve": {
+      "__id__": 10
+    }
+  },
+  {
+    "__type__": "cc.RealCurve",
+    "_times": [],
+    "_values": [],
+    "preExtrapolation": 1,
+    "postExtrapolation": 1
+  }
+]

+ 13 - 0
assets/cases/ui/24.motion-streak/move_around.anim.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "2.0.3",
+  "importer": "animation-clip",
+  "imported": true,
+  "uuid": "2656aaaf-e556-4fd5-b218-e392256dc399",
+  "files": [
+    ".cconb"
+  ],
+  "subMetas": {},
+  "userData": {
+    "name": "move_around"
+  }
+}

BIN
assets/cases/ui/24.motion-streak/图层 2.png


+ 43 - 0
assets/cases/ui/24.motion-streak/图层 2.png.meta

@@ -0,0 +1,43 @@
+{
+  "ver": "1.0.27",
+  "importer": "image",
+  "imported": true,
+  "uuid": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8",
+  "files": [
+    ".json",
+    ".png"
+  ],
+  "subMetas": {
+    "6c48a": {
+      "importer": "texture",
+      "uuid": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8@6c48a",
+      "displayName": "图层 2",
+      "id": "6c48a",
+      "name": "texture",
+      "userData": {
+        "wrapModeS": "clamp-to-edge",
+        "wrapModeT": "clamp-to-edge",
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "anisotropy": 0,
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8",
+        "visible": false
+      },
+      "ver": "1.0.22",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {}
+    }
+  },
+  "userData": {
+    "type": "texture",
+    "hasAlpha": true,
+    "fixAlphaTransparencyArtifacts": false,
+    "redirect": "87ea3ba6-4cd5-4189-8d1d-9d069ea009a8@6c48a",
+    "flipVertical": true
+  }
+}

+ 149 - 6
assets/resources/data/excel/config_manager.py

@@ -1771,6 +1771,134 @@ class ConfigManagerGUI:
                                 
                                 weapon['upgradeConfig'] = upgrade_config_struct
             
+            # 解析视觉配置工作表(新增支持)
+            visual_config_sheet = None
+            print(f"查找视觉配置工作表...")
+            for sheet_name in ['视觉配置', 'Visual Config', 'visual_config', '武器视觉配置']:
+                if sheet_name in all_sheets_data:
+                    visual_config_sheet = all_sheets_data[sheet_name]
+                    print(f"找到视觉配置工作表: {sheet_name}")
+                    break
+            
+            if visual_config_sheet is None:
+                print("未找到视觉配置工作表")
+            
+            if visual_config_sheet is not None:
+                # 直接处理视觉配置数据(横向表格格式)
+                print(f"开始处理视觉配置,工作表行数: {len(visual_config_sheet)}")
+                visual_config_data = []
+                
+                # 检查第一行是否为表头
+                first_row = visual_config_sheet.iloc[0] if len(visual_config_sheet) > 0 else None
+                is_header = False
+                if first_row is not None:
+                    first_cell = str(first_row.iloc[0]).strip() if len(first_row) > 0 else ""
+                    # 如果第一列是"武器ID"等表头文字,则认为是表头
+                    if first_cell in ['武器ID', 'ID', 'weapon_id', 'weaponId']:
+                        is_header = True
+                        print(f"检测到表头行,第一列内容: {first_cell}")
+                
+                for index, row in visual_config_sheet.iterrows():
+                    if is_header and index == 0:  # 只有确认是表头时才跳过第一行
+                        print(f"跳过表头行 {index}")
+                        continue
+                    
+                    # 支持多种武器ID字段名:武器ID、ID、weapon_id等
+                    weapon_id = None
+                    for id_field in ['武器ID', 'ID', 'weapon_id', 'weaponId']:
+                        if id_field in row and pd.notna(row[id_field]):
+                            weapon_id = row[id_field]
+                            break
+                    
+                    # 如果没有找到命名字段,则使用第一列
+                    if weapon_id is None:
+                        weapon_id = row.iloc[0] if len(row) > 0 else None
+                    
+                    print(f"处理行 {index}: weapon_id = {weapon_id}")
+                    if weapon_id and str(weapon_id).strip():  # 确保武器ID不为空
+                        visual_config = {}
+                        
+                        # 读取武器精灵配置
+                        weapon_sprites = {}
+                        sprite_fields = {
+                            'I': ['I形状精灵', 'I_sprite', 'I形状图片', 'I'],
+                            'H-I': ['H-I形状精灵', 'HI_sprite', 'H-I形状图片', 'H-I'],
+                            'L': ['L形状精灵', 'L_sprite', 'L形状图片', 'L'],
+                            'S': ['S形状精灵', 'S_sprite', 'S形状图片', 'S'],
+                            'D-T': ['D-T形状精灵', 'DT_sprite', 'D-T形状图片', 'D-T']
+                        }
+                        
+                        for shape, field_names in sprite_fields.items():
+                            for field_name in field_names:
+                                if field_name in row and pd.notna(row[field_name]):
+                                    sprite_path = str(row[field_name]).strip()
+                                    if sprite_path:
+                                        weapon_sprites[shape] = sprite_path
+                                        print(f"  {shape}形状精灵: {sprite_path}")
+                                        break
+                        
+                        if weapon_sprites:
+                            visual_config['weaponSprites'] = weapon_sprites
+                        
+                        # 读取开火音效
+                        fire_sound_fields = ['开火音效', 'fireSound', '射击音效', '音效']
+                        for field in fire_sound_fields:
+                            if field in row and pd.notna(row[field]):
+                                fire_sound = str(row[field]).strip()
+                                if fire_sound:
+                                    visual_config['fireSound'] = fire_sound
+                                    print(f"  开火音效: {fire_sound}")
+                                    break
+                        
+                        # 读取拖尾特效
+                        trail_effect_fields = ['拖尾特效', 'trailEffect', '尾迹特效', '特效']
+                        for field in trail_effect_fields:
+                            if field in row and pd.notna(row[field]):
+                                trail_effect = str(row[field]).strip()
+                                if trail_effect and trail_effect.lower() != 'null':
+                                    visual_config['trailEffect'] = trail_effect
+                                    print(f"  拖尾特效: {trail_effect}")
+                                    break
+                        
+                        if visual_config:  # 只有当有视觉配置数据时才添加
+                            visual_config_data.append({
+                                'weapon_id': str(weapon_id).strip(),
+                                'visualConfig': visual_config
+                            })
+                            print(f"为武器 {weapon_id} 添加了视觉配置")
+                        else:
+                            print(f"武器 {weapon_id} 没有有效的视觉配置数据")
+                
+                # 将视觉配置合并到原始武器数据中
+                print(f"总共解析到 {len(visual_config_data)} 个武器的视觉配置")
+                weapon_list = None
+                if 'items' in weapons_config:
+                    weapon_list = weapons_config['items']
+                    print(f"使用items字段,开始合并视觉配置到 {len(weapon_list)} 个武器")
+                elif 'weapons' in weapons_config:
+                    weapon_list = weapons_config['weapons']
+                    print(f"使用weapons字段,开始合并视觉配置到 {len(weapon_list)} 个武器")
+                else:
+                    print("weapons_config中没有items或weapons字段")
+                
+                if weapon_list:
+                    for weapon in weapon_list:
+                        # 支持两种字段名格式:ID(原始数据)和id(转换后数据)
+                        weapon_id = weapon.get('ID', '') or weapon.get('id', '')
+                        if weapon_id:
+                            # 查找对应的视觉配置
+                            matching_visual = None
+                            for visual_data in visual_config_data:
+                                if visual_data['weapon_id'] == weapon_id:
+                                    matching_visual = visual_data
+                                    break
+                            
+                            if matching_visual:
+                                weapon['visualConfig'] = matching_visual['visualConfig']
+                                print(f"✓ 为武器 {weapon_id} 添加了视觉配置: {matching_visual['visualConfig']}")
+                            else:
+                                print(f"✗ 武器 {weapon_id} 未找到匹配的视觉配置")
+            
             # 解析游戏内成本配置工作表(新增支持)
             cost_config_sheet = None
             print(f"查找游戏内成本配置工作表...")
@@ -2835,8 +2963,8 @@ class ConfigManagerGUI:
                     'range': weapon_range,
                     'bulletSpeed': min(bullet_speed, 50)  # 限制子弹速度
                 },
-                'bulletConfig': self._generate_bullet_config(weapon_id, weapon_type, damage, weapon_range),
-                'visualConfig': self._generate_visual_config(weapon_id, weapon_name)
+                'bulletConfig': self._generate_bullet_config(weapon_id, weapon_type, damage, weapon_range, item),
+                'visualConfig': self._generate_visual_config(weapon_id, weapon_name, item)
             }
             
             # 如果原始数据中有upgradeConfig,则添加到结果中
@@ -2868,15 +2996,21 @@ class ConfigManagerGUI:
             print(f"转换武器数据失败: {e} - 数据: {item}")
             return None
     
-    def _generate_bullet_config(self, weapon_id, weapon_type, damage, weapon_range):
+    def _generate_bullet_config(self, weapon_id, weapon_type, damage, weapon_range, item=None):
         """生成子弹配置"""
+        # 从item中获取trailEffect,如果没有则使用默认值
+        trail_effect = None
+        if item and 'visualConfig' in item and 'trailEffect' in item['visualConfig']:
+            trail_effect = item['visualConfig']['trailEffect']
+            print(f"为武器 {weapon_id} 在bulletConfig.visual中使用Excel中的拖尾特效: {trail_effect}")
+        
         # 基础配置模板
         base_config = {
             'count': {'type': 'single', 'amount': 1, 'spreadAngle': 0, 'burstCount': 1, 'burstDelay': 0},
             'trajectory': {'type': 'straight', 'speed': 200, 'gravity': 0, 'arcHeight': 0, 'homingStrength': 0, 'homingDelay': 0},
             'hitEffects': [{'type': 'normal_damage', 'priority': 1, 'params': {'damage': damage}}],
             'lifecycle': {'type': 'hit_destroy', 'maxLifetime': 5.0, 'penetration': 1, 'ricochetCount': 0, 'returnToOrigin': False},
-            'visual': {'bulletPrefab': f'bullets/{weapon_id.title()}Bullet', 'hitEffect': 'Animation/WeaponTx/tx0002/tx0002', 'trailEffect': None, 'muzzleFlash': 'Animation/WeaponTx/tx0002/tx0002'}
+            'visual': {'bulletPrefab': f'bullets/{weapon_id.title()}Bullet', 'hitEffect': 'Animation/WeaponTx/tx0002/tx0002', 'trailEffect': trail_effect, 'muzzleFlash': 'Animation/WeaponTx/tx0002/tx0002'}
         }
         
         # 根据武器类型调整配置
@@ -3025,7 +3159,7 @@ class ConfigManagerGUI:
             print(f"加载游戏内成本配置失败: {e}")
             return None
     
-    def _generate_visual_config(self, weapon_id, weapon_name):
+    def _generate_visual_config(self, weapon_id, weapon_name, item=None):
         """生成视觉配置"""
         # 根据武器ID生成图片编号
         weapon_sprite_map = {
@@ -3042,7 +3176,7 @@ class ConfigManagerGUI:
         
         sprite_id = weapon_sprite_map.get(weapon_id, '001')
         
-        return {
+        visual_config = {
             'weaponSprites': {
                 'I': f'images/PlantsSprite/{sprite_id}',
                 'H-I': f'images/PlantsSprite/{sprite_id}',
@@ -3052,6 +3186,15 @@ class ConfigManagerGUI:
             },
             'fireSound': f'audio/{weapon_id}_shot'
         }
+        
+        # 从item中获取trailEffect,如果有的话添加到visualConfig中
+        if item and 'visualConfig' in item and 'trailEffect' in item['visualConfig']:
+            trail_effect = item['visualConfig']['trailEffect']
+            if trail_effect and trail_effect != 'NaN' and str(trail_effect).strip():
+                visual_config['trailEffect'] = trail_effect
+                print(f"为武器 {weapon_id} 在visualConfig中添加拖尾特效: {trail_effect}")
+        
+        return visual_config
     
     def _convert_skill_data(self, item):
         """转换技能数据格式"""

+ 80 - 0
assets/resources/data/excel/update_visual_config.py

@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""
+更新视觉配置工作表,添加缺失的trailEffect字段
+"""
+
+import pandas as pd
+import os
+from pathlib import Path
+
+def update_visual_config_sheet():
+    """更新视觉配置工作表,添加trailEffect字段"""
+    
+    # 获取Excel文件路径
+    excel_file = Path(__file__).parent / '方块武器配置' / '方块武器配置表.xlsx'
+    
+    print(f"正在更新Excel文件: {excel_file}")
+    
+    try:
+        # 读取现有的视觉配置工作表
+        visual_config = pd.read_excel(excel_file, sheet_name='视觉配置')
+        print(f"当前视觉配置表列名: {list(visual_config.columns)}")
+        
+        # 检查是否已有trailEffect字段
+        if 'trailEffect' not in visual_config.columns and '拖尾特效' not in visual_config.columns:
+            # 在开火音效列之前插入trailEffect列
+            insert_pos = visual_config.columns.get_loc('开火音效')
+            
+            # 创建trailEffect数据 - 根据weapons.json中的配置
+            trail_effects = {
+                'pea_shooter': None,
+                'sharp_carrot': 'Animation/WeaponTx/tx0001/tx0001',
+                'saw_grass': 'Animation/WeaponTx/tx0001/tx0001',
+                'watermelon_bomb': None,
+                'boomerang_plant': 'Animation/WeaponTx/tx0001/tx0001',
+                'hot_pepper': 'Animation/WeaponTx/tx0001/tx0001',
+                'cactus_shotgun': None,
+                'okra_missile': None,
+                'mace_club': None
+            }
+            
+            # 为每个武器添加trailEffect值
+            trail_effect_values = []
+            for _, row in visual_config.iterrows():
+                weapon_id = row['武器ID']
+                trail_effect = trail_effects.get(weapon_id, None)
+                trail_effect_values.append(trail_effect)
+            
+            # 插入新列
+            visual_config.insert(insert_pos, '拖尾特效', trail_effect_values)
+            
+            print(f"添加了拖尾特效列,新的列名: {list(visual_config.columns)}")
+            
+            # 读取所有现有工作表
+            all_sheets = pd.read_excel(excel_file, sheet_name=None)
+            
+            # 更新视觉配置工作表
+            all_sheets['视觉配置'] = visual_config
+            
+            # 重新写入Excel文件
+            with pd.ExcelWriter(excel_file, engine='openpyxl') as writer:
+                for sheet_name, sheet_data in all_sheets.items():
+                    sheet_data.to_excel(writer, sheet_name=sheet_name, index=False)
+            
+            print("✓ 成功更新视觉配置工作表,添加了拖尾特效字段")
+            return True
+        else:
+            print("视觉配置表已包含拖尾特效字段,无需更新")
+            return True
+            
+    except Exception as e:
+        print(f"更新视觉配置表失败: {e}")
+        return False
+
+if __name__ == '__main__':
+    success = update_visual_config_sheet()
+    if success:
+        print("\n视觉配置工作表更新完成!")
+    else:
+        print("\n视觉配置工作表更新失败!")

BIN
assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx


+ 23 - 15
assets/resources/data/weapons.json

@@ -47,7 +47,7 @@
         "visual": {
           "bulletPrefab": "bullets/Pea_ShooterBullet",
           "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -59,7 +59,8 @@
           "S": "images/PlantsSprite/001-1",
           "D-T": "images/PlantsSprite/001-1"
         },
-        "fireSound": "audio/pea_shooter_shot"
+        "fireSound": "audio/pea_shooter_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -178,7 +179,8 @@
           "S": "images/PlantsSprite/002",
           "D-T": "images/PlantsSprite/002"
         },
-        "fireSound": "audio/sharp_carrot_shot"
+        "fireSound": "audio/sharp_carrot_shot",
+        "trailEffect": "Animation/WeaponTx/tx0001/tx0001"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -293,7 +295,7 @@
         "visual": {
           "bulletPrefab": "bullets/Saw_GrassBullet",
           "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -305,7 +307,8 @@
           "S": "images/PlantsSprite/003",
           "D-T": "images/PlantsSprite/003"
         },
-        "fireSound": "audio/saw_grass_shot"
+        "fireSound": "audio/saw_grass_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -412,7 +415,7 @@
         "visual": {
           "bulletPrefab": "bullets/Watermelon_BombBullet",
           "hitEffect": "Animation/WeaponTx/tx0007/tx0007",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -424,7 +427,8 @@
           "S": "images/PlantsSprite/007",
           "D-T": "images/PlantsSprite/007"
         },
-        "fireSound": "audio/watermelon_bomb_shot"
+        "fireSound": "audio/watermelon_bomb_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -530,7 +534,7 @@
         "visual": {
           "bulletPrefab": "bullets/Boomerang_PlantBullet",
           "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -542,7 +546,8 @@
           "S": "images/PlantsSprite/004",
           "D-T": "images/PlantsSprite/004"
         },
-        "fireSound": "audio/boomerang_plant_shot"
+        "fireSound": "audio/boomerang_plant_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -647,7 +652,7 @@
         "visual": {
           "bulletPrefab": "bullets/Hot_PepperBullet",
           "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -659,7 +664,8 @@
           "S": "images/PlantsSprite/005",
           "D-T": "images/PlantsSprite/005"
         },
-        "fireSound": "audio/hot_pepper_shot"
+        "fireSound": "audio/hot_pepper_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -765,7 +771,7 @@
         "visual": {
           "bulletPrefab": "bullets/Cactus_ShotgunBullet",
           "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -777,7 +783,8 @@
           "S": "images/PlantsSprite/008",
           "D-T": "images/PlantsSprite/008"
         },
-        "fireSound": "audio/cactus_shotgun_shot"
+        "fireSound": "audio/cactus_shotgun_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,
@@ -884,7 +891,7 @@
         "visual": {
           "bulletPrefab": "bullets/Okra_MissileBullet",
           "hitEffect": "Animation/WeaponTx/tx0002/tx0002",
-          "trailEffect": null,
+          "trailEffect": "True",
           "muzzleFlash": "Animation/WeaponTx/tx0002/tx0002"
         }
       },
@@ -896,7 +903,8 @@
           "S": "images/PlantsSprite/006",
           "D-T": "images/PlantsSprite/006"
         },
-        "fireSound": "audio/okra_missile_shot"
+        "fireSound": "audio/okra_missile_shot",
+        "trailEffect": "True"
       },
       "upgradeConfig": {
         "maxLevel": 10,

+ 6 - 2
assets/scripts/CombatSystem/BallController.ts

@@ -1182,8 +1182,12 @@ export class BallController extends Component {
             }
 
             // === 根据武器配置选择合适的预制体 ===
-            const needsTrail = !!(finalConfig.bulletConfig?.visual?.trailEffect);
-            const prefabToUse: Prefab = (needsTrail && this.bulletContainerPrefab) ? this.bulletContainerPrefab : this.bulletPrefab;
+            const trailEffect = finalConfig.bulletConfig?.visual?.trailEffect;
+            // 尖胡萝卜特殊处理:使用PelletContainer预制体但激活Spine节点
+            const isSharpCarrot = finalConfig.id === 'sharp_carrot';
+            // 当trailEffect为true或者是尖胡萝卜时都使用容器预制体
+            const needsContainerPrefab = Boolean(trailEffect) || isSharpCarrot;
+            const prefabToUse: Prefab = (needsContainerPrefab && this.bulletContainerPrefab) ? this.bulletContainerPrefab : this.bulletPrefab;
             if (!prefabToUse) {
                 return; // 如果没有可用的预制体则直接退出
             }

+ 196 - 0
assets/scripts/CombatSystem/BulletTrailController.ts

@@ -0,0 +1,196 @@
+import { _decorator, Component, Node, MotionStreak, Color, Texture2D } from 'cc';
+const { ccclass, property } = _decorator;
+
+/**
+ * 子弹拖尾控制器
+ * 负责管理子弹的拖尾效果
+ */
+@ccclass('BulletTrailController')
+export class BulletTrailController extends Component {
+    
+    @property({
+        type: MotionStreak,
+        tooltip: '拖尾组件引用'
+    })
+    public motionStreak: MotionStreak | null = null;
+    
+    // 拖尾配置
+    private trailConfig = {
+        fadeTime: 0.5,      // 拖尾消失时间
+        minSeg: 1,          // 最小分段
+        stroke: 10,         // 拖尾宽度
+        fastMode: false     // 快速模式
+    };
+    
+    // 预设颜色
+    private trailColors = {
+        default: new Color(255, 255, 0, 255),    // 黄色
+        white: new Color(255, 255, 255, 255),    // 白色
+        fire: new Color(255, 100, 0, 255),       // 橙红色
+        ice: new Color(0, 200, 255, 255),        // 冰蓝色
+        poison: new Color(100, 255, 0, 255),     // 毒绿色
+        electric: new Color(200, 0, 255, 255)    // 紫色
+    };
+    
+    onLoad() {
+        this.initializeTrail();
+    }
+    
+    /**
+     * 初始化拖尾效果
+     */
+    private initializeTrail() {
+        if (!this.motionStreak) {
+            // 尝试从子节点中查找MotionStreak组件
+            this.motionStreak = this.getComponentInChildren(MotionStreak);
+            
+            if (!this.motionStreak) {
+                // 尝试从当前节点获取
+                this.motionStreak = this.getComponent(MotionStreak);
+            }
+        }
+        
+        if (this.motionStreak) {
+            this.applyTrailConfig();
+        }
+    }
+    
+    /**
+     * 应用拖尾配置
+     */
+    private applyTrailConfig() {
+        if (!this.motionStreak) return;
+        
+        this.motionStreak.fadeTime = this.trailConfig.fadeTime;
+        this.motionStreak.minSeg = this.trailConfig.minSeg;
+        this.motionStreak.stroke = this.trailConfig.stroke;
+        this.motionStreak.fastMode = this.trailConfig.fastMode;
+        this.motionStreak.color = this.trailColors.white;
+    }
+    
+    /**
+     * 设置拖尾颜色
+     * @param colorType 颜色类型
+     */
+    public setTrailColor(colorType: 'default' | 'white' | 'fire' | 'ice' | 'poison' | 'electric') {
+        if (!this.motionStreak) return;
+        
+        const color = this.trailColors[colorType];
+        if (color) {
+            this.motionStreak.color = color;
+        }
+    }
+    
+    /**
+     * 设置自定义拖尾颜色
+     * @param color 颜色
+     */
+    public setCustomTrailColor(color: Color) {
+        if (!this.motionStreak) return;
+        
+        this.motionStreak.color = color;
+    }
+    
+    /**
+     * 设置拖尾宽度
+     * @param width 宽度
+     */
+    public setTrailWidth(width: number) {
+        if (!this.motionStreak) return;
+        
+        this.trailConfig.stroke = width;
+        this.motionStreak.stroke = width;
+    }
+    
+    /**
+     * 设置拖尾消失时间
+     * @param fadeTime 消失时间
+     */
+    public setTrailFadeTime(fadeTime: number) {
+        if (!this.motionStreak) return;
+        
+        this.trailConfig.fadeTime = fadeTime;
+        this.motionStreak.fadeTime = fadeTime;
+    }
+    
+    /**
+     * 设置拖尾纹理
+     * @param texture 纹理
+     */
+    public setTrailTexture(texture: Texture2D) {
+        if (!this.motionStreak) return;
+        
+        this.motionStreak.texture = texture;
+    }
+    
+    /**
+     * 启用拖尾效果
+     */
+    public enableTrail() {
+        if (this.motionStreak) {
+            this.motionStreak.enabled = true;
+        }
+    }
+    
+    /**
+     * 禁用拖尾效果
+     */
+    public disableTrail() {
+        if (this.motionStreak) {
+            this.motionStreak.enabled = false;
+        }
+    }
+    
+    /**
+     * 重置拖尾效果
+     */
+    public resetTrail() {
+        if (this.motionStreak) {
+            this.motionStreak.reset();
+        }
+    }
+    
+    /**
+     * 根据武器类型配置拖尾效果
+     * @param weaponType 武器类型
+     */
+    public configureTrailByWeaponType(weaponType: string) {
+        switch (weaponType) {
+            case 'pea_shooter':
+                this.setTrailColor('white');
+                this.setTrailWidth(8);
+                this.setTrailFadeTime(0.3);
+                break;
+            case 'fire_shooter':
+                this.setTrailColor('fire');
+                this.setTrailWidth(12);
+                this.setTrailFadeTime(0.5);
+                break;
+            case 'ice_shooter':
+                this.setTrailColor('ice');
+                this.setTrailWidth(10);
+                this.setTrailFadeTime(0.4);
+                break;
+            case 'poison_shooter':
+                this.setTrailColor('poison');
+                this.setTrailWidth(9);
+                this.setTrailFadeTime(0.6);
+                break;
+            case 'electric_shooter':
+                this.setTrailColor('electric');
+                this.setTrailWidth(11);
+                this.setTrailFadeTime(0.2);
+                break;
+            default:
+                this.setTrailColor('white');
+                this.setTrailWidth(10);
+                this.setTrailFadeTime(0.5);
+                break;
+        }
+    }
+    
+    onDestroy() {
+        // 清理资源
+        this.motionStreak = null;
+    }
+}

+ 13 - 0
assets/scripts/CombatSystem/BulletTrailController.ts.meta

@@ -0,0 +1,13 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "45e5245f-8f36-407d-ab66-9d41f0f09e5a",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "moduleId": "project:///assets/scripts/CombatSystem/BulletTrailController.js",
+    "importerSettings": 3,
+    "simulateGlobals": []
+  }
+}

+ 48 - 0
assets/scripts/CombatSystem/WeaponBullet.ts

@@ -3,6 +3,7 @@ import { BulletCount, BulletSpawnInfo } from './BulletEffects/BulletCount';
 import { BulletTrajectory } from './BulletEffects/BulletTrajectory';
 import { BulletHitEffect, HitResult } from './BulletEffects/BulletHitEffect';
 import { BulletLifecycle } from './BulletEffects/BulletLifecycle';
+import { BulletTrailController } from './BulletTrailController';
 import { ConfigManager, WeaponConfig, BulletCountConfig, BulletTrajectoryConfig, HitEffectConfig, BulletLifecycleConfig } from '../Core/ConfigManager';
 import  EventBus,{ GameEvents } from '../Core/EventBus';
 import { PersistentSkillManager } from '../FourUI/SkillSystem/PersistentSkillManager';
@@ -42,6 +43,7 @@ export class WeaponBullet extends Component {
     private bulletTrajectory: BulletTrajectory = null;
     private bulletHitEffect: BulletHitEffect = null;
     private bulletLifecycle: BulletLifecycle = null;
+    private bulletTrailController: BulletTrailController = null;
     
     // 武器配置和状态
     private weaponConfig: WeaponConfig = null;
@@ -226,6 +228,9 @@ export class WeaponBullet extends Component {
         // 设置子弹外观
         this.setupBulletSprite();
         
+        // 设置子弹效果节点激活状态
+        this.setupBulletEffectNodes();
+        
         // 设置碰撞监听
         this.setupCollisionListener();
         
@@ -304,6 +309,15 @@ export class WeaponBullet extends Component {
         this.bulletLifecycle = this.getComponent(BulletLifecycle) || this.addComponent(BulletLifecycle);
         this.bulletLifecycle.init(config.lifecycle, initData.firePosition);
         
+        // 初始化拖尾控制器(只有当trailEffect为true时才使用我们实现的拖尾效果)
+        if (config.visual?.trailEffect) {
+            this.bulletTrailController = this.getComponent(BulletTrailController) || this.addComponent(BulletTrailController);
+            if (this.bulletTrailController) {
+                // 根据武器类型配置拖尾效果
+                this.bulletTrailController.configureTrailByWeaponType(this.weaponId);
+            }
+        }
+        
         // 设置碰撞监听
         this.setupCollisionListener();
         
@@ -529,6 +543,12 @@ export class WeaponBullet extends Component {
         if (collider) {
             collider.off(Contact2DType.BEGIN_CONTACT, this.onHit, this);
         }
+        
+        // 清理拖尾控制器
+        if (this.bulletTrailController) {
+            this.bulletTrailController.resetTrail();
+            this.bulletTrailController = null;
+        }
     }
     
     /**
@@ -585,6 +605,34 @@ export class WeaponBullet extends Component {
     );
     }
     
+    /**
+     * 设置子弹效果节点激活状态
+     */
+    private setupBulletEffectNodes() {
+        // 尖胡萝卜特殊处理:使用Spine动画而不是拖尾效果
+        const isSharpCarrot = this.weaponId === 'sharp_carrot';
+        
+        // 查找Spine节点
+        const spineNode = this.node.getChildByName('Spine');
+        if (spineNode) {
+            spineNode.active = isSharpCarrot;
+        }
+        
+        // 查找TrailEffect节点
+        const trailEffectNode = this.node.getChildByName('TrailEffect');
+        if (trailEffectNode) {
+            trailEffectNode.active = !isSharpCarrot;
+            
+            // 为拖尾效果设置白色颜色
+            if (!isSharpCarrot) {
+                const trailController = trailEffectNode.getComponent(BulletTrailController);
+                if (trailController) {
+                    trailController.setTrailColor('white');
+                }
+            }
+        }
+    }
+    
     /**
      * 静态:根据给定世界坐标,寻找最近的敌人节点
      */

+ 12 - 0
assets/shared-res.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "185d44e9-04dd-41b6-b04b-57ac78a5c013",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "compressionType": {},
+    "isRemoteBundle": {}
+  }
+}

+ 12 - 0
assets/shared-res/textures.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "4ac47f63-f66f-44cf-b6ba-1437690c67fb",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "compressionType": {},
+    "isRemoteBundle": {}
+  }
+}

+ 12 - 0
assets/shared-res/textures/ui.meta

@@ -0,0 +1,12 @@
+{
+  "ver": "1.2.0",
+  "importer": "directory",
+  "imported": true,
+  "uuid": "ea159efe-0553-4335-a4de-d1d21eeb70c9",
+  "files": [],
+  "subMetas": {},
+  "userData": {
+    "compressionType": {},
+    "isRemoteBundle": {}
+  }
+}

BIN
assets/shared-res/textures/ui/gold.png


+ 142 - 0
assets/shared-res/textures/ui/gold.png.meta

@@ -0,0 +1,142 @@
+{
+  "ver": "1.0.27",
+  "importer": "image",
+  "imported": true,
+  "uuid": "877e09bf-ded6-4b38-a1a5-eab3f11b099e",
+  "files": [
+    ".json",
+    ".png"
+  ],
+  "subMetas": {
+    "6c48a": {
+      "importer": "texture",
+      "uuid": "877e09bf-ded6-4b38-a1a5-eab3f11b099e@6c48a",
+      "displayName": "gold",
+      "id": "6c48a",
+      "name": "texture",
+      "ver": "1.0.22",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {},
+      "userData": {
+        "wrapModeS": "clamp-to-edge",
+        "wrapModeT": "clamp-to-edge",
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "premultiplyAlpha": false,
+        "anisotropy": 0,
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "877e09bf-ded6-4b38-a1a5-eab3f11b099e",
+        "visible": false
+      }
+    },
+    "f9941": {
+      "ver": "1.0.12",
+      "importer": "sprite-frame",
+      "uuid": "877e09bf-ded6-4b38-a1a5-eab3f11b099e@f9941",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {},
+      "userData": {
+        "wrapModeS": "repeat",
+        "wrapModeT": "repeat",
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "premultiplyAlpha": false,
+        "anisotropy": 1,
+        "trimType": "auto",
+        "trimThreshold": 1,
+        "rotated": false,
+        "offsetX": 0,
+        "offsetY": 0,
+        "trimX": 0,
+        "trimY": 0,
+        "width": 80,
+        "height": 80,
+        "rawWidth": 80,
+        "rawHeight": 80,
+        "borderTop": 0,
+        "borderBottom": 0,
+        "borderLeft": 0,
+        "borderRight": 0,
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "877e09bf-ded6-4b38-a1a5-eab3f11b099e@6c48a",
+        "atlasUuid": "",
+        "packable": true,
+        "pixelsToUnit": 100,
+        "pivotX": 0.5,
+        "pivotY": 0.5,
+        "meshType": 0,
+        "vertices": {
+          "rawPosition": [
+            -40,
+            -40,
+            0,
+            40,
+            -40,
+            0,
+            -40,
+            40,
+            0,
+            40,
+            40,
+            0
+          ],
+          "indexes": [
+            0,
+            1,
+            2,
+            2,
+            1,
+            3
+          ],
+          "uv": [
+            0,
+            80,
+            80,
+            80,
+            0,
+            0,
+            80,
+            0
+          ],
+          "nuv": [
+            0,
+            0,
+            1,
+            0,
+            0,
+            1,
+            1,
+            1
+          ],
+          "minPos": [
+            -40,
+            -40,
+            0
+          ],
+          "maxPos": [
+            40,
+            40,
+            0
+          ]
+        }
+      },
+      "displayName": "gold",
+      "id": "f9941",
+      "name": "spriteFrame"
+    }
+  },
+  "userData": {
+    "type": "sprite-frame",
+    "redirect": "877e09bf-ded6-4b38-a1a5-eab3f11b099e@6c48a",
+    "hasAlpha": true,
+    "fixAlphaTransparencyArtifacts": false
+  }
+}

BIN
assets/shared-res/textures/ui/singleColor.png


+ 142 - 0
assets/shared-res/textures/ui/singleColor.png.meta

@@ -0,0 +1,142 @@
+{
+  "ver": "1.0.27",
+  "importer": "image",
+  "imported": true,
+  "uuid": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf",
+  "files": [
+    ".json",
+    ".png"
+  ],
+  "subMetas": {
+    "6c48a": {
+      "importer": "texture",
+      "uuid": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf@6c48a",
+      "displayName": "singleColor",
+      "id": "6c48a",
+      "name": "texture",
+      "ver": "1.0.22",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {},
+      "userData": {
+        "wrapModeS": "clamp-to-edge",
+        "wrapModeT": "clamp-to-edge",
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "premultiplyAlpha": false,
+        "anisotropy": 0,
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf",
+        "visible": false
+      }
+    },
+    "f9941": {
+      "ver": "1.0.12",
+      "importer": "sprite-frame",
+      "uuid": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf@f9941",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {},
+      "userData": {
+        "wrapModeS": "repeat",
+        "wrapModeT": "repeat",
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "premultiplyAlpha": false,
+        "anisotropy": 1,
+        "trimType": "auto",
+        "trimThreshold": 1,
+        "rotated": false,
+        "offsetX": 0,
+        "offsetY": 0,
+        "trimX": 0,
+        "trimY": 0,
+        "width": 2,
+        "height": 2,
+        "rawWidth": 2,
+        "rawHeight": 2,
+        "borderTop": 0,
+        "borderBottom": 0,
+        "borderLeft": 0,
+        "borderRight": 0,
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf@6c48a",
+        "atlasUuid": "",
+        "packable": true,
+        "pixelsToUnit": 100,
+        "pivotX": 0.5,
+        "pivotY": 0.5,
+        "meshType": 0,
+        "vertices": {
+          "rawPosition": [
+            -1,
+            -1,
+            0,
+            1,
+            -1,
+            0,
+            -1,
+            1,
+            0,
+            1,
+            1,
+            0
+          ],
+          "indexes": [
+            0,
+            1,
+            2,
+            2,
+            1,
+            3
+          ],
+          "uv": [
+            0,
+            2,
+            2,
+            2,
+            0,
+            0,
+            2,
+            0
+          ],
+          "nuv": [
+            0,
+            0,
+            1,
+            0,
+            0,
+            1,
+            1,
+            1
+          ],
+          "minPos": [
+            -1,
+            -1,
+            0
+          ],
+          "maxPos": [
+            1,
+            1,
+            0
+          ]
+        }
+      },
+      "displayName": "singleColor",
+      "id": "f9941",
+      "name": "spriteFrame"
+    }
+  },
+  "userData": {
+    "type": "sprite-frame",
+    "redirect": "093b45c8-80d9-49a8-ac5c-bcdbaed2c6bf@6c48a",
+    "hasAlpha": false,
+    "fixAlphaTransparencyArtifacts": false
+  }
+}

BIN
assets/shared-res/textures/ui/star.png


+ 42 - 0
assets/shared-res/textures/ui/star.png.meta

@@ -0,0 +1,42 @@
+{
+  "ver": "1.0.27",
+  "importer": "image",
+  "imported": true,
+  "uuid": "b585a82a-6354-40a1-acc7-76f985d9a91c",
+  "files": [
+    ".json",
+    ".png"
+  ],
+  "subMetas": {
+    "6c48a": {
+      "importer": "texture",
+      "uuid": "b585a82a-6354-40a1-acc7-76f985d9a91c@6c48a",
+      "displayName": "star",
+      "id": "6c48a",
+      "name": "texture",
+      "userData": {
+        "wrapModeS": "repeat",
+        "wrapModeT": "repeat",
+        "minfilter": "linear",
+        "magfilter": "linear",
+        "mipfilter": "none",
+        "anisotropy": 0,
+        "isUuid": true,
+        "imageUuidOrDatabaseUri": "b585a82a-6354-40a1-acc7-76f985d9a91c",
+        "visible": false
+      },
+      "ver": "1.0.22",
+      "imported": true,
+      "files": [
+        ".json"
+      ],
+      "subMetas": {}
+    }
+  },
+  "userData": {
+    "hasAlpha": true,
+    "type": "texture",
+    "redirect": "b585a82a-6354-40a1-acc7-76f985d9a91c@6c48a",
+    "fixAlphaTransparencyArtifacts": false
+  }
+}

+ 37 - 0
check_visual_config_trail.py

@@ -0,0 +1,37 @@
+import json
+
+# 读取weapons.json文件
+with open('d:/CocosGame/Pong/assets/resources/data/weapons.json', 'r', encoding='utf-8') as f:
+    weapons_data = json.load(f)
+
+print("检查weapons.json中的visualConfig是否包含trailEffect字段:")
+print("="*60)
+
+for weapon in weapons_data['weapons']:
+    weapon_id = weapon['id']
+    print(f"\n武器ID: {weapon_id}")
+    
+    # 检查visualConfig
+    if 'visualConfig' in weapon:
+        visual_config = weapon['visualConfig']
+        print(f"  visualConfig字段: {list(visual_config.keys())}")
+        
+        if 'trailEffect' in visual_config:
+            print(f"  ✓ visualConfig包含trailEffect: {visual_config['trailEffect']}")
+        else:
+            print(f"  ✗ visualConfig不包含trailEffect")
+    else:
+        print(f"  ✗ 没有visualConfig字段")
+    
+    # 检查bulletConfig.visual中的trailEffect
+    if 'bulletConfig' in weapon and 'visual' in weapon['bulletConfig']:
+        bullet_visual = weapon['bulletConfig']['visual']
+        if 'trailEffect' in bullet_visual:
+            print(f"  bulletConfig.visual.trailEffect: {bullet_visual['trailEffect']}")
+        else:
+            print(f"  bulletConfig.visual没有trailEffect")
+    else:
+        print(f"  没有bulletConfig.visual")
+
+print("\n总结:")
+print("trailEffect字段目前在bulletConfig.visual部分,但用户期望它也在visualConfig部分。")

+ 79 - 0
debug_visual_config.py

@@ -0,0 +1,79 @@
+import pandas as pd
+
+# 模拟config_manager.py中的视觉配置解析逻辑
+def test_visual_config_parsing():
+    # 读取Excel文件中的视觉配置
+    df = pd.read_excel('d:/CocosGame/Pong/assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx', sheet_name='视觉配置')
+    
+    print("开始解析视觉配置...")
+    
+    for index, row in df.iterrows():
+        if index == 0:  # 跳过表头
+            print(f"跳过表头行 {index}")
+            continue
+            
+        # 获取武器ID
+        weapon_id = None
+        for id_field in ['武器ID', 'ID', 'weapon_id', 'weaponId']:
+            if id_field in row and pd.notna(row[id_field]):
+                weapon_id = row[id_field]
+                break
+        
+        if weapon_id is None:
+            weapon_id = row.iloc[0] if len(row) > 0 else None
+            
+        print(f"\n处理行 {index}: weapon_id = {weapon_id}")
+        
+        if weapon_id and str(weapon_id).strip():
+            visual_config = {}
+            
+            # 读取武器精灵配置
+            weapon_sprites = {}
+            sprite_fields = {
+                'I': ['I形状精灵', 'I_sprite', 'I形状图片', 'I'],
+                'H-I': ['H-I形状精灵', 'HI_sprite', 'H-I形状图片', 'H-I'],
+                'L': ['L形状精灵', 'L_sprite', 'L形状图片', 'L'],
+                'S': ['S形状精灵', 'S_sprite', 'S形状图片', 'S'],
+                'D-T': ['D-T形状精灵', 'DT_sprite', 'D-T形状图片', 'D-T']
+            }
+            
+            for shape, field_names in sprite_fields.items():
+                for field_name in field_names:
+                    if field_name in row and pd.notna(row[field_name]):
+                        sprite_path = str(row[field_name]).strip()
+                        if sprite_path:
+                            weapon_sprites[shape] = sprite_path
+                            print(f"  {shape}形状精灵: {sprite_path}")
+                            break
+            
+            if weapon_sprites:
+                visual_config['weaponSprites'] = weapon_sprites
+            
+            # 读取开火音效
+            fire_sound_fields = ['开火音效', 'fireSound', '射击音效', '音效']
+            for field in fire_sound_fields:
+                if field in row and pd.notna(row[field]):
+                    fire_sound = str(row[field]).strip()
+                    if fire_sound:
+                        visual_config['fireSound'] = fire_sound
+                        print(f"  开火音效: {fire_sound}")
+                        break
+            
+            # 读取拖尾特效
+            trail_effect_fields = ['拖尾特效', 'trailEffect', '尾迹特效', '特效']
+            for field in trail_effect_fields:
+                if field in row and pd.notna(row[field]):
+                    trail_effect = str(row[field]).strip()
+                    if trail_effect and trail_effect.lower() != 'null':
+                        visual_config['trailEffect'] = trail_effect
+                        print(f"  拖尾特效: {trail_effect}")
+                        break
+            
+            print(f"  最终visual_config: {visual_config}")
+            
+            # 只处理前3个武器作为测试
+            if index >= 3:
+                break
+
+if __name__ == "__main__":
+    test_visual_config_parsing()

+ 19 - 0
test_trail_effect.py

@@ -0,0 +1,19 @@
+import pandas as pd
+
+# 读取Excel文件中的视觉配置
+df = pd.read_excel('d:/CocosGame/Pong/assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx', sheet_name='视觉配置')
+
+# 检查sharp_carrot行数据
+row = df.iloc[1]  # sharp_carrot是第二行
+print('sharp_carrot行数据:')
+print(row)
+
+print('\n拖尾特效字段检查:')
+for field in ['拖尾特效', 'trailEffect', '尾迹特效', '特效']:
+    has_field = field in row
+    value = row.get(field, '不存在') if has_field else '不存在'
+    print(f'{field}: 存在={has_field}, 值={value}')
+
+# 检查pandas是否正确读取了数据
+print('\n拖尾特效列的所有值:')
+print(df['拖尾特效'])

+ 20 - 0
test_visual_config.py

@@ -0,0 +1,20 @@
+import pandas as pd
+import json
+
+# 读取Excel文件中的视觉配置
+df = pd.read_excel('d:/CocosGame/Pong/assets/resources/data/excel/方块武器配置/方块武器配置表.xlsx', sheet_name='视觉配置')
+print("Excel视觉配置数据:")
+print(df[['武器ID', '拖尾特效']].head())
+
+# 读取当前的weapons.json文件
+with open('d:/CocosGame/Pong/assets/resources/data/weapons.json', 'r', encoding='utf-8') as f:
+    weapons_data = json.load(f)
+
+print("\nweapons.json中的visualConfig示例:")
+for weapon in weapons_data['weapons'][:3]:
+    print(f"武器ID: {weapon['id']}")
+    if 'visualConfig' in weapon:
+        print(f"  visualConfig: {weapon['visualConfig']}")
+    else:
+        print("  没有visualConfig字段")
+    print()