Unity导弹转向玩家功能失效求助:Quaternion.RotateTowards无效
导弹无法转向的问题修复(Quaternion.RotateTowards使用错误)
问题根源分析
- RotateTowards未赋值:
Quaternion.RotateTowards是纯函数,只会返回计算后的新四元数,不会直接修改物体旋转,必须将结果赋值给transform.rotation才会生效。 - 除以0判断逻辑错误:原代码
if (direction !=0.5)完全无效,应该判断direction != 0来避免除以0的情况。 - 旋转值获取错误:
transform.rotation.z是四元数的分量值,并非欧拉角的Z轴旋转角度,正确的获取方式是transform.eulerAngles.z。 - 旋转速度未适配FixedUpdate:
turnQuaternionSpeed需要乘以Time.fixedDeltaTime保证帧率无关,且RotateTowards的第三个参数单位是弧度/帧,需要将角度速度转换为弧度。
修正后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class missileScript : MonoBehaviour { public Transform player; public float moveSpeed = 2f; public float turnSpeed = 30f; // 改为正角度,方向由后续逻辑控制 private float distanceToPlayer; private float moveX; private float moveY; public float turnQuaternionSpeed = 90f; // 单位:度/秒 void FixedUpdate() { distanceToPlayer = Vector3.Distance(player.position, transform.position); if (distanceToPlayer < 8.58f) { fire(); } } void fire() { float direction = player.position.y - transform.position.y; // 正确判断是否为0,避免除以0 if (direction != 0) { direction = direction / Mathf.Abs(direction); // 归一化为-1或1 Debug.Log(direction); // 正确获取当前Z轴欧拉角 float currentZRotation = transform.eulerAngles.z; float targetZRotation = currentZRotation + (direction * turnSpeed * Time.fixedDeltaTime); Quaternion targetRotation = Quaternion.Euler(0, 0, targetZRotation); // 将RotateTowards的结果赋值给transform.rotation,同时处理帧率适配 float step = turnQuaternionSpeed * Mathf.Deg2Rad * Time.fixedDeltaTime; transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, step); // 计算移动方向 float rotationInRadians = transform.eulerAngles.z * Mathf.Deg2Rad; moveY = Mathf.Sin(rotationInRadians); moveX = Mathf.Cos(rotationInRadians); Vector2 moveDirection = new Vector2(-moveX, -moveY).normalized * moveSpeed * Time.fixedDeltaTime; transform.Translate(moveDirection, Space.World); } } }
关于Lerp的使用说明
如果想用Quaternion.Lerp实现平滑旋转,替换RotateTowards的部分即可,注意Lerp需要基于时间的插值因子:
// 示例:用Lerp实现平滑转向 float t = turnQuaternionSpeed * Time.fixedDeltaTime / 180f; // 控制插值速度 transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, t);
注意:Lerp会以固定比例插值,当目标旋转变化时可能出现"滑动"感,而RotateTowards是匀速旋转到目标,更适合导弹追踪的场景。
内容的提问来源于stack exchange,提问作者edfawef waef
相关产品推荐
相关产品推荐

