如何获取四元数在任意轴上的带符号旋转角度(飞机控制器开发场景)
解决方案
你当前遇到的无符号角度问题是因为Quaternion.Angle接口仅返回0~180°的绝对夹角,无法区分旋转方向。针对你需要和roll成正比计算转向力的需求,不需要做任意平面的泛化适配,直接用Unity自带的Vector3.SignedAngle接口计算绕指定轴的带符号夹角即可。
修改后代码
private void FixedUpdate() { float desiredYaw = _yaw * _rotationSpeed * Time.fixedDeltaTime; float desiredPitch = -_pitch * _rotationSpeed * Time.fixedDeltaTime; // 补充roll轴输入对应的旋转量,可根据实际输入映射调整 float desiredRoll = _roll * _rotationSpeed * Time.fixedDeltaTime; float rotationStepSize = _throttle * Time.fixedDeltaTime; // Euler角参数按pitch、yaw、roll顺序填入,补充roll轴旋转 Quaternion toRotate = Quaternion.Euler(desiredPitch, desiredYaw, desiredRoll); Quaternion straighRotation = Quaternion.LookRotation(_transform.forward, Vector3.up ); _rotation = _transform.rotation * toRotate; // 替换原有无符号角度计算,获取带符号的roll值,范围-180°~180° float signedRoll = Vector3.SignedAngle(Vector3.right, _transform.right, _transform.forward); float turningForce = signedRoll; _rigidbody.MoveRotation( _rotation ); // 带符号的转向力会自动调整扭矩方向,实现左滚左拐、右滚右拐的效果 _rigidbody.AddTorque( turningForce * _rotationForce * rotationStepSize * Vector3.up ); _rigidbody.AddRelativeForce( _speed * rotationStepSize * Vector3.forward ); }
实现说明
Vector3.SignedAngle接收三个参数:起始向量、目标向量、旋转参考轴,返回值范围为-180°~180°,正负值代表相对于参考轴的顺时针/逆时针旋转方向- 这里选择飞机自身的前向轴
transform.forward作为参考轴,计算世界右向量到飞机自身右向量的夹角,得到的就是飞机当前的带符号滚转角,完全匹配转向力和roll成正比的需求 - 如果后续需要其他轴的带符号夹角,只要更换对应的参考轴和起止向量即可,不需要处理复杂的四元数符号判断逻辑
内容的提问来源于stack exchange,提问作者BananaSupreme
相关产品推荐
相关产品推荐

