diff --git a/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs b/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs index f06d128e6..2a462724b 100644 --- a/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs +++ b/Assets/MyGame/Scripts/Characters/Monster/MonsterContral.cs @@ -679,7 +679,9 @@ public class MonsterContral : MonoBehaviour bezierData.start, uirootRect, mainCamera); // 700:根据起点 y 值决定正方向;701:固定向上(dir=-1) - bool goUp = (_yzPrefix == "701") || (bezierData.start.y > 0); + // ⭐ 座位镜像:701 写死的"向上"随镜像取反(起点/朝向都已翻转,固定方向必须跟着翻); + // 700 按 start.y 判断——数据已翻转,自动适应无需处理 + bool goUp = (_yzPrefix == "701") ? !SeatMirror.IsMirrored : (bezierData.start.y > 0); _yzLineDir = goUp ? -1f : 1f; // ⭐ 分布角方向缓存:按 forwordXYZ 读根当前(=生成端刚设置的)前方向量,取XY平面投影。 @@ -738,7 +740,8 @@ public class MonsterContral : MonoBehaviour monsterData.moveLine.bezierCurveData.start, uirootRect, mainCamera); // 700:根据起点 y 值决定正方向;701:固定 - bool goUp = (_yzPrefix == "701") || (monsterData.moveLine.bezierCurveData.start.y > 0); + // ⭐ 座位镜像:701 写死的"向上"随镜像取反(与 CacheYzLineMoveData 同规则) + bool goUp = (_yzPrefix == "701") ? !SeatMirror.IsMirrored : (monsterData.moveLine.bezierCurveData.start.y > 0); float dir = goUp ? -1f : 1f; // ⭐ 同缓存分支:沿分布方向移动(缓存值优先,未初始化回退固定垂直),朝向不转 diff --git a/Assets/MyGame/Scripts/Characters/Monster/MonsterMoveLine.cs b/Assets/MyGame/Scripts/Characters/Monster/MonsterMoveLine.cs index 44be0af6d..3bd4914d2 100644 --- a/Assets/MyGame/Scripts/Characters/Monster/MonsterMoveLine.cs +++ b/Assets/MyGame/Scripts/Characters/Monster/MonsterMoveLine.cs @@ -70,6 +70,9 @@ public class MonsterMoveLine for (int i = 1; i < points.Count - 1; i++) curve.controlPoints.Add(points[i]); + // ⭐ 座位镜像:本端在上方座位时路线整条上下翻转(写入字典/建缓存前,只翻一次) + FlipCurveYForMirror(curve); + curves.Add(curve); dic_BezierCurveDatas.Add(curve.name, curve); // ⭐ 同步构建点数组缓存(单条加载路径) @@ -77,6 +80,28 @@ public class MonsterMoveLine } } + /// + /// ⭐ 座位镜像:路线整条上下翻转(所有点 y 关于画布中心取反,画布坐标以中心为原点)。 + /// B样条求值(de Boor)是逐点线性插值,对控制点 y 取反后求样条 ≡ 原样条求值后 y 取反, + /// 曲线形状严格镜像不形变。必须在写入 dic_BezierCurveDatas / BuildCurvePointsArray + /// 之前调用(curves 列表与字典引用同一实例,只翻一次)。 + /// 下游自动适应:取点/移动/朝向切线/鱼阵 700 起点/翻面/分布角全部基于翻转后数据; + /// 仅 701 环形阵写死的"固定向上"需在 MonsterContral 里随镜像取反。 + /// + private static void FlipCurveYForMirror(BezierCurveData curve) + { + if (!SeatMirror.IsMirrored) return; + + curve.start.y = -curve.start.y; + curve.end.y = -curve.end.y; + for (int i = 0; i < curve.controlPoints.Count; i++) + { + Vector2 p = curve.controlPoints[i]; + p.y = -p.y; + curve.controlPoints[i] = p; + } + } + /// /// ⭐ 将曲线的 [start, controlPoints..., end] 组装成 Vector2[] 并缓存。 /// 所有引用此曲线的鱼共享同一份数组,避免每帧每鱼 new List + ToArray 的 GC。 @@ -177,6 +202,9 @@ public class MonsterMoveLine for (int i = 1; i < points.Count - 1; i++) curve.controlPoints.Add(points[i]); + // ⭐ 座位镜像:本端在上方座位时路线整条上下翻转(写入字典/建缓存前,只翻一次) + FlipCurveYForMirror(curve); + curves.Add(curve); // ⭐ 同名直接覆盖(清场后理论上无重复,防御性覆盖确保永远用当前玩法数据) @@ -187,7 +215,10 @@ public class MonsterMoveLine } Addressables.Release(handles); - Debug.Log("曲线读取完成共" + dic_BezierCurveDatas.Count + "条"); + // ⭐ 座位镜像状态提示:镜像未初始化(-1)时按不镜像处理,排查进房时序问题用 + if (SeatMirror.LocalServerPos < 0) + Debug.LogWarning("[MonsterMoveLine] 加载路线时 SeatMirror 未初始化(未收到 RoomJoinNotice),本次按不镜像处理"); + Debug.Log($"曲线读取完成共{dic_BezierCurveDatas.Count}条 镜像={SeatMirror.IsMirrored}(本地服务端座位={SeatMirror.LocalServerPos})"); } public static async Task UnLoadBezierTxtAsync(string path)