C# Unity 如何使用点积在内侧向量变化时保持外侧向量相对关系
内侧向量动态跟随的外侧向量计算实现
原有参考代码的核心问题
- 两个外侧舵向量的计算逻辑完全失效:当前写的计算式
RudderTop = (DirSteerIndicator - RudderBottom).normalized、RudderBottom = (DirSteerIndicator - RudderBottom).normalized,会让两个向量计算结果完全重叠,根本无法形成参考图里的三点夹角结构。 - 计算逻辑存在循环依赖:外侧向量的计算反向依赖RudderBottom的实时位置差值,中间向量动态变化时会出现数值震荡,无法保持固定相对角度。
- 代码中的
DirSteerTo = DirSteerTo * -1属于无意义方向反转,除非内侧向量的初始方向定义反向,否则会让两个外侧向量整体朝向和内侧相反。 - 向量计算流程中嵌入的
Debug.Log("release")属于冗余调试代码,正式运行时需要删除,避免造成不必要的性能消耗。
基于点积约束的正确实现逻辑
整个方案的核心目标:当内侧DirSteerIndicator动态变化时,两个外侧向量始终和内侧向量保持固定夹角,两个向量与内侧向量的点积值全程恒定,不会出现角度偏移。
点积的几何意义是两个单位向量夹角的余弦值,只要点积值恒定,两个向量的相对夹角就不会变化,完全不需要依赖端点坐标做差值计算。
固定参数初始化
- 提前标定参考图中外侧向量和内侧向量的固定夹角,记为
offsetAngle - 计算该夹角对应的点积基准值:
fixedDotValue = Mathf.Cos(offsetAngle * Mathf.Deg2Rad),这个值在运行全程保持不变,是约束相对位置的核心依据。 - 将内侧指向向量做单位化处理:
DirSteerTo = DirSteerIndicator.normalized;
动态生成外侧向量(两种等价实现方式)
方式一:基于垂直向量解算(纯向量计算,无旋转依赖)
先计算和内侧向量垂直的单位向量:
Vector3 perpendicular = new Vector3(-DirSteerTo.y, DirSteerTo.x, 0).normalized; // 上侧外侧向量 RudderTop = DirSteerTo * fixedDotValue + perpendicular * Mathf.Sin(offsetAngle * Mathf.Deg2Rad); // 下侧外侧向量 RudderBottom = DirSteerTo * fixedDotValue - perpendicular * Mathf.Sin(offsetAngle * Mathf.Deg2Rad);
这种方式自动满足点积约束:Vector3.Dot(RudderTop, DirSteerTo)、Vector3.Dot(RudderBottom, DirSteerTo)的计算结果永远等于fixedDotValue,也就是两个外侧向量和内侧向量的相对夹角完全固定。
方式二:基于固定角度旋转变换
平面内只需要绕平面法向量旋转固定角度,即可同步跟随内侧向量变化:
// 上侧:向内测方向的顺时针旋转固定偏移角 RudderTop = Quaternion.AngleAxis(offsetAngle, Vector3.forward) * DirSteerTo; // 下侧:向内测方向的逆时针旋转固定偏移角 RudderBottom = Quaternion.AngleAxis(-offsetAngle, Vector3.forward) * DirSteerTo;
调试校验方法
每帧打印两个外侧向量和内侧向量的点积值,如果和预先计算的fixedDotValue存在明显偏差,就说明旋转轴或者垂直向量的方向写反了,调整一下垂直分量的正负即可修正。
内容的提问来源于stack exchange,提问作者NewGuy
相关产品推荐
相关产品推荐

