diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_1.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_1.prefab index 28ba592a5..1e01e5ef7 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_1.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_1.prefab @@ -284,6 +284,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_101.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_101.prefab index f2a4ea088..621080c41 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_101.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_101.prefab @@ -5202,8 +5202,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_103.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_103.prefab index 706472ae6..75a6d8aa6 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_103.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_103.prefab @@ -92,8 +92,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_104.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_104.prefab index c7b9f3903..b32933db6 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_104.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_104.prefab @@ -216,8 +216,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_105.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_105.prefab index 8a7d70988..18939bcef 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_105.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_105.prefab @@ -320,8 +320,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_106.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_106.prefab index 5fb51c3c9..d3285b657 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_106.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_106.prefab @@ -281,8 +281,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_107.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_107.prefab index d304a926e..edc0c5a96 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_107.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_107.prefab @@ -92,8 +92,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_108.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_108.prefab index ffc26d4d8..771385fb7 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_108.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_108.prefab @@ -92,8 +92,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_109.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_109.prefab index 15b073187..e7cf29251 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_109.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_109.prefab @@ -126,8 +126,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_110.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_110.prefab index 95ed5c6ca..e0de93e88 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_110.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_110.prefab @@ -4865,8 +4865,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_111.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_111.prefab index aa3e927f6..391ffd9ae 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_111.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_111.prefab @@ -2553,8 +2553,9 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_2.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_2.prefab index 8f8eee1b0..c7c1cbba7 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_2.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_2.prefab @@ -199,6 +199,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_3.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_3.prefab index f50169f37..87e977572 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_3.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_3.prefab @@ -94,6 +94,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_31.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_31.prefab index 24abdc246..a8fe918a7 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_31.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_31.prefab @@ -5037,6 +5037,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_32.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_32.prefab index cb1321df4..0499ce74d 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_32.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_32.prefab @@ -2452,6 +2452,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_4.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_4.prefab index 39b609ec9..47277ba63 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_4.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_4.prefab @@ -199,6 +199,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_5.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_5.prefab index 6dbedb871..27699b32e 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_5.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_5.prefab @@ -199,6 +199,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_6.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_6.prefab index 41616a046..df624fee9 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_6.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_6.prefab @@ -179,6 +179,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_7.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_7.prefab index db654cce3..35e15d9d2 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_7.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_7.prefab @@ -94,6 +94,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_8.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_8.prefab index 229642217..624d228aa 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_8.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_8.prefab @@ -284,6 +284,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_9.prefab b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_9.prefab index d5e574ec1..3d619faba 100644 --- a/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_9.prefab +++ b/Assets/Art/XJMH/pw/pw_prefab/game/enemy/XJMHEnemy/PW_Enemy_9.prefab @@ -2597,6 +2597,7 @@ MonoBehaviour: createVideoClip: {fileID: 0} rotationPY: 0 useMirrorCompensate: 1 + useRollSignFlip: 1 useRouteFlipX: 0 baseMmove: 0 isRotate: 1 diff --git a/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs b/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs index 051c54d0b..6130662f1 100644 --- a/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs +++ b/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs @@ -207,13 +207,6 @@ public class MonsterContral : MonoBehaviour /// 缓存的子物体(朝向控制用),避免每帧 transform.GetChild(0) private Transform _cachedChild; - /// - /// 左右半边状态(带±0.05滞回):false=朝右半边,true=朝左半边。 - /// 用于Z/NegZ单轴转向的反面补偿开关——越过中线明显后才切换, - /// 防止垂直游动时 dirNorm.x 微抖导致补偿来回跳(闪)。 - /// - private bool _defaultMirror = false; - // ---------------------------------------------------------------- // ⭐ 鱼阵 700/701 直线移动缓存 // 同一鱼阵起点相同,Init 时一次性算好世界坐标 + 方向系数, @@ -223,6 +216,8 @@ public class MonsterContral : MonoBehaviour private Vector3 _yzStartWorld; // 直线阵起点世界坐标 private float _yzLineDir; // 直线阵方向系数 (-1 向上 / +1 向下) private bool _yzLineInited; // 直线阵缓存是否已初始化 + /// 扇形(700)/圈(701)分布角方向:Init时按轴读生成姿态前方的XY投影,每条鱼各自不同 + private Vector2 _yzMoveDir = Vector2.zero; /// /// yzID 前3字符前缀缓存(Init 时 Substring 一次)。 @@ -384,9 +379,6 @@ public class MonsterContral : MonoBehaviour // (金龙/雷龙/玉龙等不走路径,直到爆奖结束销毁) // - 冰冻中重新激活的鱼,末尾会覆盖为 false,安全 isMove = baseMmove; - // ⭐ 重置左右半边状态:池复用残留会在出场瞬间带错误反面补偿, - // 第一帧滞回按实际移动方向修正后同帧生效 - _defaultMirror = false; // ⭐ 重置可锁定状态:needLockEvent=true 的鱼每次重新生成都需等 NotifyLockable() // needLockEvent=false 的鱼一直可锁定 isLockable = !needLockEvent; @@ -505,24 +497,10 @@ public class MonsterContral : MonoBehaviour // ⭐ 缓存 yzID 前3字符前缀,避免 UpdateYZMovement 每帧每鱼 Substring 产生 GC SetYzPrefix(yzID); - // ⭐ 700系扇形阵按起点y值翻转朝向:绕Z轴+180°旋转 - // (原为 scale.y 镜像翻转,负缩放有法线翻转/特效异常等副作用; - // rotation 由 Pool.Get 每次重置为本次生成角度,天然无池复用残留) - bool flipY700 = isyuzhen && _yzPrefix == "700" && bezierData.start.y < 0; - if (flipY700) - { - transform.Rotate(Vector3.forward, 180f, Space.Self); - } - // ⭐ 预计算 700/701 直线阵的世界起点 + 方向系数 // 原逻辑每帧每鱼 CanvasToWorld(start) + 判断 goUp,现 Init 一次性算好 CacheYzLineMoveData(bezierData); - // ⭐ 翻转(Z+180°)后 transform.up 反向,700 直线阵移动方向同步取反, - // 保持实际游向与翻转前一致(否则起点y<0的700阵鱼会反向游) - if (flipY700) - _yzLineDir = -_yzLineDir; - fishenum = (FishTypeEnum)monsterData.fishTypeConfig.fishType; // isMove=false 的鱼不需要移动路线,直接归位到 (0,0,0) @@ -692,6 +670,26 @@ public class MonsterContral : MonoBehaviour bool goUp = (_yzPrefix == "701") || (bezierData.start.y > 0); _yzLineDir = goUp ? -1f : 1f; + // ⭐ 分布角方向缓存:按 forwordXYZ 读根当前(=生成端刚设置的)前方向量,取XY平面投影。 + // 扇形(700)/圈(701)阵型靠生成端分布角实现:每条鱼朝各自方向辐射展开, + // 移动必须沿各自分布方向;此处姿态尚未被任何朝向逻辑修改,读到的就是分布方向。 + // 投影过短(如配X的鱼被生成端Y=-90摆平转出屏幕平面)时回退固定垂直方向(0,±1) + Vector3 fwd; + switch (_facingAxis) + { + case FacingAxis.X: fwd = transform.right; break; + case FacingAxis.NegX: fwd = -transform.right; break; + case FacingAxis.Y: fwd = transform.up; break; + case FacingAxis.NegY: fwd = -transform.up; break; + case FacingAxis.Z: fwd = transform.forward; break; + case FacingAxis.NegZ: fwd = -transform.forward; break; + default: fwd = transform.up; break; + } + Vector2 dir2 = new Vector2(fwd.x, fwd.y); + _yzMoveDir = dir2.sqrMagnitude > 0.25f + ? dir2.normalized + : new Vector2(0f, _yzLineDir); + _isYzLineMove = true; _yzLineInited = true; } @@ -699,20 +697,17 @@ public class MonsterContral : MonoBehaviour /// 鱼阵移动:按 yzID 前缀选择运动方程。 private void UpdateYZMovement() { - // ⭐ 700/701 直线阵:使用预计算缓存,零 CanvasToWorld 调用 + // ⭐ 700/701 直线阵(扇形/圈):使用预计算缓存,零 CanvasToWorld 调用 if (_isYzLineMove && _yzLineInited) { - // ⭐ 移动方向改用固定世界向量 (0,±1),不再用 transform.up: - // 加轴朝向(forwordXYZ)后鱼会被旋转,transform.up 随之改变, - // 原公式会把鱼带斜飞(隐含"鱼永不旋转"前提,现已不成立) - Vector2 lineDir = new Vector2(0f, _yzLineDir); + // ⭐ 沿各自生成分布角方向辐射移动(Init时缓存,每条鱼各自不同): + // 扇形/圈的阵型靠生成端分布角实现,移动方向必须与之一致; + // _yzMoveDir 在 CacheYzLineMoveData 里按轴读生成姿态前方,投影过短回退(0,±1) + Vector2 lineDir = _yzMoveDir; Vector2 pos = (Vector2)_yzStartWorld + lineDir * moveTime * monsterData.moveLine.moveTime; - // ⭐ 直线阵朝向:沿移动方向取前方一点,复用 ApplyFacingDirection 的轴逻辑 - // (原直线阵从不调朝向,设置 forwordXYZ 无效——鱼保持预制体朝向平移) - if (fishenum != FishTypeEnum.Boss鱼) - ApplyFacingDirection(pos + lineDir); - + // ⭐ 朝向保持生成姿态(分布角)不转——不调 ApplyFacingDirection: + // 它会覆盖根的分布角,把扇形/圈抹成一列竖队 // ⭐ 保留根节点当前 z(2D 小鱼 z 一直为 0,行为不变) transform.position = new Vector3(pos.x, pos.y, transform.position.z); return; @@ -723,24 +718,21 @@ public class MonsterContral : MonoBehaviour switch (_yzPrefix) { - // 700 / 701:直线向前移动—— 兜底分支,正常走缓存路径 + // 700 / 701:沿各自分布方向辐射移动—— 兜底分支,正常走缓存路径 case "700": case "701": { var startWorld = CoordinateTransformation.CanvasToWorld( monsterData.moveLine.bezierCurveData.start, uirootRect, mainCamera); - // 700:根据起点 y 值决定正方向;701:固定向上 + // 700:根据起点 y 值决定正方向;701:固定 bool goUp = (_yzPrefix == "701") || (monsterData.moveLine.bezierCurveData.start.y > 0); float dir = goUp ? -1f : 1f; - // ⭐ 同缓存分支:方向用固定世界向量,与朝向旋转解耦 - Vector2 lineDir = new Vector2(0f, dir); + // ⭐ 同缓存分支:沿分布方向移动(缓存值优先,未初始化回退固定垂直),朝向不转 + Vector2 lineDir = _yzMoveDir != Vector2.zero ? _yzMoveDir : new Vector2(0f, dir); Vector2 pos = (Vector2)startWorld + lineDir * moveTime * monsterData.moveLine.moveTime; - if (fishenum != FishTypeEnum.Boss鱼) - ApplyFacingDirection(pos + lineDir); - // ⭐ 保留根节点当前 z(2D 小鱼 z 一直为 0,行为不变) transform.position = new Vector3(pos.x, pos.y, transform.position.z); break; @@ -806,19 +798,14 @@ public class MonsterContral : MonoBehaviour _cachedChild = child; } - // ⭐ 700/701直线阵(扇形/圈):保留child本地偏移——阵型靠"生成时的根旋转角度+本地偏移" - // 实现均匀分布,归零会把分布抹成一点(所有鱼缩到根中心);其余鱼x/y归零摆正模型 - if (_yzPrefix != "700" && _yzPrefix != "701") - { - Vector3 localPos = child.localPosition; - // ⭐ x/y 归零摆正模型;z 深度只在显式配置 depthOffset(≠0)时才覆盖, - // 否则保留预制体上设置的 3D 深度(3D Boss 用,之前被强制归零导致深度无效) - localPos.x = 0f; - localPos.y = 0f; - if (depthOffset != 0) - localPos.z = depthOffset; - child.localPosition = localPos; - } + Vector3 localPos = child.localPosition; + // ⭐ x/y 归零摆正模型;z 深度只在显式配置 depthOffset(≠0)时才覆盖, + // 否则保留预制体上设置的 3D 深度(3D Boss 用,之前被强制归零导致深度无效) + localPos.x = 0f; + localPos.y = 0f; + if (depthOffset != 0) + localPos.z = depthOffset; + child.localPosition = localPos; if (!isRotate) return; Vector2 toNext = nextPos - (Vector2)transform.position; @@ -827,7 +814,7 @@ public class MonsterContral : MonoBehaviour Vector2 dirNorm = toNext.normalized; // ⭐ 缓存归一化向量,避免分支内重复计算 // ⭐ 路线左右方向懒缓存:终点在起点右边=左→右(+1)/左边=右→左(-1)/相同=纯垂直(0) - // 由起终点一次判定,路线终身不变——侧倾符号判断不再受曲线中段波动影响 + // 由起终点一次判定,路线终身不变——镜像/侧倾符号判断不再受曲线中段波动影响 if (!_routeDirXCached) { _routeDirXCached = true; @@ -837,10 +824,6 @@ public class MonsterContral : MonoBehaviour else _routeDirX = 0; } - // ⭐ 左右半边滞回:越过中线±0.05才切换(反面补偿的开关,防垂直游抖动闪跳) - if (!_defaultMirror && dirNorm.x < -0.05f) _defaultMirror = true; - else if (_defaultMirror && dirNorm.x > 0.05f) _defaultMirror = false; - // ⭐ 用预解析的枚举 switch,避免每帧每鱼 string 比较 // 处理未指定朝向轴的情况(默认行为) if (_facingAxis == FacingAxis.None) @@ -850,6 +833,12 @@ public class MonsterContral : MonoBehaviour // 配置了正方向的Boss走下方轴对齐逻辑,保持原有机制不变 if (IsRouteFlipBoss) return; + // ⭐ 镜像由路线方向一次判定(_routeDirX)+useMirrorCompensate开关(与轴分支统一): + // 横向向左路线才镜像;环形路线起终点相同(_routeDirX==0)天然不镜像—— + // 原每帧dirNorm.x滞回(_defaultMirror)在环形/绕圈路线上每圈跨中线两次, + // 镜像来回翻转导致模型闪(±90姿态跳,XJMH飞机类高发) + bool mirrorLeft = useMirrorCompensate && _routeDirX < 0; + if (!is3D) { float angle = Mathf.Atan2(toNext.y, toNext.x) * Mathf.Rad2Deg; @@ -859,7 +848,7 @@ public class MonsterContral : MonoBehaviour // 贴图头朝上的鱼纯旋转对齐时,往左游=整体转180°=肚皮朝上(反)。 // 往左时叠加X轴镜像:旋转角不变(镜像不改变鱼头方向), // 只翻回背腹朝向,左右游姿态一致。以预制体基准绝对赋值,池复用不叠加 - float mirrorX = _defaultMirror ? -_prefabScaleX : _prefabScaleX; + float mirrorX = mirrorLeft ? -_prefabScaleX : _prefabScaleX; var s = transform.localScale; if (!Mathf.Approximately(s.x, mirrorX)) { @@ -877,7 +866,7 @@ public class MonsterContral : MonoBehaviour * Quaternion.AngleAxis(90f, Vector3.up); // ⭐ 往左时绕头尾轴再转180°:3D鱼左右近似对称,等效镜像, // 背始终朝上(与往右一致),避免负缩放的法线翻转副作用 - if (_defaultMirror) + if (mirrorLeft) rot *= Quaternion.AngleAxis(180f, Vector3.forward); transform.rotation = rot; } diff --git a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs index 42f144bbf..166a45ac8 100644 --- a/Assets/MyGame/Scripts/Manager/CreateFishManager.cs +++ b/Assets/MyGame/Scripts/Manager/CreateFishManager.cs @@ -1170,12 +1170,23 @@ public class CreateFishManager : MonoSingleton { var cfg = spawnDic[createFishData.fishNumber]; + // ⭐ 上下基准角(与原始方向判断相反取正):起点 y>0→+90°/y<0→-90° + // (与MonsterContral.Init同key规则"鱼阵"+pathId查曲线) + float baseAngle = -90f; + if (MonsterMoveLine.dic_BezierCurveDatas.TryGetValue("鱼阵" + pathId, out var bd700)) + baseAngle = bd700.start.y > 0f ? 90f : -90f; + for (int i = 1; i <= 17; i++) { - // 交替正负角度,形成扇形分布 + // 交替正负角度,形成扇形分布(从基准角向两侧±5°~±85°展开) float angle = i * 5f * (i % 2 == 0 ? -1f : 1f); - var rotation = Quaternion.Euler( - prefab.transform.eulerAngles + Vector3.forward * angle); + // ⭐ 方向判断与原始flipY700一致:路线起点start.y<0的阵绕鱼头轴翻面180° + // (鱼头方向不变,肚背朝向翻转);原始写法为 transform.Rotate(Z,180,Space.Self) + float flipZ = (bd700 != null && bd700.start.y < 0f) ? 180f : 0f; + // ⭐ 分布角度=基准角+偏移,绕世界Z轴左乘叠加(屏幕平面内展开); + // Y=-90固定摆平,Z是朝前的轴(翻面阵+180) + var rotation = Quaternion.AngleAxis(baseAngle + angle, Vector3.forward) + * Quaternion.Euler(prefab.transform.eulerAngles.x, -90f, prefab.transform.eulerAngles.z + flipZ); //var fish = Instantiate(prefab, pos, rotation, fishRoot); var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, rotation, fishRoot); @@ -1210,7 +1221,10 @@ public class CreateFishManager : MonoSingleton for (int i = 0; i < count; i++) { float angle = (360f / count) * i; - var rotation = Quaternion.Euler(prefab.transform.eulerAngles + Vector3.forward * angle); + // ⭐ 分布角度=基准90°+偏移(上下的鱼阵,中间点从90°起算,沿圈360°均分); + // 绕世界Z轴左乘叠加(屏幕平面内展开);Y=-90固定摆平,Z是朝前的轴不动 + var rotation = Quaternion.AngleAxis(90f + angle, Vector3.forward) + * Quaternion.Euler(prefab.transform.eulerAngles.x, -90f, prefab.transform.eulerAngles.z); //var fish = Instantiate(prefab, pos, rotation, fishRoot); var fish = Pool.Instance.Get(int.Parse(yz.fishNumber), pos, rotation, fishRoot); diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab index 48d64b2a2..01befe67b 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2008 Variant.prefab @@ -629,7 +629,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab index 5e788b0e4..61e1dca07 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2009 Variant.prefab @@ -668,7 +668,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab index 6fba293ed..f4e5a7d95 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2011 Variant.prefab @@ -686,7 +686,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab index cdfe6d3e4..d916c1d9a 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2012 Variant.prefab @@ -690,7 +690,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 80 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab index 5439af808..4bc8fe5d7 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2013 Variant.prefab @@ -386,7 +386,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab index ab252c906..0c56652dd 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_2014 Variant.prefab @@ -418,7 +418,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab index b50fe33b5..f0c399bc5 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/Fish_3002 Variant.prefab @@ -900,7 +900,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab index 422b0d5f7..6f2557172 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1017 Variant.prefab @@ -203,7 +203,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab index b125acf10..d0204e29d 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1018 Variant.prefab @@ -203,7 +203,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab index c2dbf818c..a1179956c 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1019 Variant.prefab @@ -209,7 +209,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab index 77ef15960..4fd32d04e 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1020 Variant.prefab @@ -363,7 +363,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab index b3d533af0..731969a23 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1025 Variant.prefab @@ -209,7 +209,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 1 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab index a55ced2e0..0230e71be 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1026 Variant.prefab @@ -281,7 +281,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 30 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab index 821cd028f..6f3b8bbe3 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1027 Variant.prefab @@ -203,7 +203,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab index f2e685752..7a933445f 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_1028 Variant.prefab @@ -203,7 +203,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: -90 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab index 434fc6739..05108ee21 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_2010 Variant.prefab @@ -342,7 +342,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab index 2b397c7b3..1af7b5849 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3001 Variant.prefab @@ -498,7 +498,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab index 534db3fc0..bb02c79ad 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3003 Variant.prefab @@ -724,7 +724,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab index 38b7a2009..f9782902e 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3004 Variant.prefab @@ -1075,7 +1075,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 60 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1 diff --git a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab index 981f0d95f..9e9f038dd 100644 --- a/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab +++ b/Assets/MyGame/aa/Game/HHWK/Fish/fish_3005 Variant.prefab @@ -456,7 +456,7 @@ MonoBehaviour: - {fileID: 0} needLockEvent: 0 createVideoClip: {fileID: 0} - rotationPY: 30 + rotationPY: 90 useMirrorCompensate: 1 useRollSignFlip: 0 useRouteFlipX: 1