unity2D以最小的角度旋转到目标方向(y方向为角色的主方向)
一.使用向量原理转换到目标方向
为了让角色的自身y转向目标方向,并且以最小角度旋转,要点是获得当前方向与目标方向的叉值,从而判断应该旋转的方向
float rotateSpeed;
//相对目标位置运动
void trackPosition02(Vector3 tarPosition)
{
Vector3 targetDir = tarPosition - transform.position;
Vector3 up = transform.up;
float angle = Vector3.Angle(targetDir, up);
if (angle <= Time.fixedDeltaTime * rotateSpeed) return;//判断角度是否小于临界值,如果小于,那么不需要旋转,此处用于避免旋转抖动
Vector3 cross = Vector3.Cross(up, targetDir);
if (cross.z > 0) transform.Rotate(new Vector3(0, 0, rotateSpeed0* Time.deltaTime)); else transform.Rotate(new Vector3(0, 0, -rotateSpeed0* Time.deltaTime));
}
可能unity提供了更简单的判定方式,知道的老兄留个评论
二.利用角度符号判断转到目标方向
这里原理和一相同,只是判断角度的方式是使用判断两者的角度差,而不是向量的叉值
float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward);
transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime));
三.有角度限制的转到目标方向
这里角度限制是指在局部坐标系内的角度限制,比如某个TD坦克,它的炮塔只能在正方向的-30度到正30度之间旋转,
但是除了计算局部旋转,还要加上父物体的旋转角度
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotateTest : MonoBehaviour { // The target marker. public Transform target; // Angular speed in radians per sec. public float speed; //Vector3.up方向为0角度方向 //局部坐标系内的最小角度和最大角度 public float minAngle; public float maxAngle; //局部坐标系内的最小角度和最大角度转换到直接坐标系的值 public float minAngleInWorld; public float maxAngleInWorld; void Update() { //父亲物体的当前角度 float offsetAngle = Vector3.SignedAngle(Vector3.up, transform.parent.transform.up,Vector3.forward); minAngleInWorld = minAngle + offsetAngle; maxAngleInWorld = maxAngle + offsetAngle; //当前的目标方向相对世界坐标Up方向的角度,用于判断是否在设定的范围内 float angle = Vector3.SignedAngle(Vector3.up, target.position - transform.position, Vector3.forward); //当前自身与目标的角度方向差,用于决定旋转方向 float signAngle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward); if (angle > minAngleInWorld && angle < maxAngleInWorld) transform.Rotate(new Vector3(0, 0, Mathf.Sign(signAngle)*speed * Time.deltaTime)); /* float angle = Vector3.SignedAngle(transform.up, target.position - transform.position, Vector3.forward); transform.Rotate(new Vector3(0, 0, Mathf.Sign(angle) * speed * Time.deltaTime)); */ } }
四.利用unity的接口旋转
//数学意义的转到目标方向 protected void RotateToDir(Vector3 dir) { float angle = Vector3.SignedAngle(Vector3.up, dir, Vector3.forward); Quaternion rotation00 = Quaternion.Euler(0, 0, angle); transform.rotation = Quaternion.RotateTowards(transform.rotation, rotation00, Time.fixedDeltaTime * computeRotateSpeed); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用