当前位置: 首页 > news >正文

UE5 发射物目标追踪

UE5 发射物目标追踪

思路

求出需要旋转的角度,然后每帧旋转,再更新速度

实现:

求出发射物当前方向和目标方向的旋转后,插值求每帧的旋转。

//向目标旋转
float Speed = MovementComponent->Velocity.Length();
//获取发射物坐标到目标几何中心的方向向量
FVector Origin, BoxExtent;
TraceTarget->GetActorBounds(false, Origin, BoxExtent);
FVector TargetVector = Origin - GetActorLocation();
TargetVector.Normalize();
//获取发射物速度到目标几何中心的方向向量的旋转四元数
FQuat RotationQuat = FQuat::FindBetweenVectors(MovementComponent->Velocity, TargetVector);
FQuat TargetRotationQuat = FQuat::Slerp(FQuat::Identity, RotationQuat, RotateSpeed * DeltaTime);
//更新速度
MovementComponent->Velocity = TargetRotationQuat.RotateVector(MovementComponent->Velocity).GetSafeNormal() * Speed;

但是这样写有个致命的缺点:每帧旋转的角度与需要旋转的角度正相关,角度越小旋转越小,角度越大旋转越大,我们不能接受

直接旋转固定角度

计算出需要的角度,然后每帧旋转固定角度。

发射物旋转我们需要注意的地方就是,在发射物的速度和旋转角度都很大且达到某一个平衡时,如果离目标足够近就可能导致变成绕着目标旋转。

我们可以选择设定当需要旋转的角度大于90度(或者设定的角度)后,就不再旋转。或者避免发射速度和旋转角度达成那个关系。

//向目标旋转
float Speed = MovementComponent->Velocity.Length();
//获取发射物坐标到目标几何中心的方向向量
FVector Origin, BoxExtent;
TraceTarget->GetActorBounds(false, Origin, BoxExtent);
FVector TargetVector = Origin - GetActorLocation();
TargetVector.Normalize();
FQuat RotationQuat = FQuat::FindBetweenVectors(MovementComponent->Velocity, TargetVector);
float Angle = RotationQuat.GetAngle();
UE_LOG(LogTemp, Display, TEXT("Angle : %f, RotateAngle : %f"),FMath::RadiansToDegrees(Angle), FMath::RadiansToDegrees(RotateAngle));
if(Angle < FMath::DegreesToRadians(5))
{MovementComponent->Velocity = TargetVector.GetSafeNormal() * Speed;return;
} 
float RotationDirection = FMath::Sign(Angle);
//RotateAngle是类的成员
FQuat DeltaRotation = FQuat(RotationQuat.GetRotationAxis(), RotationDirection * RotateAngle * DeltaTime );
//更新速度
MovementComponent->Velocity = DeltaRotation.RotateVector(MovementComponent->Velocity).GetSafeNormal() * Speed;

相关文章:

  • CDN简介
  • freemarker 使用
  • Vue46-render函数
  • 收银系统源码-连锁店收银系统,支持二次开发
  • MYSQL(事务)
  • oracle发送邮件附件的步骤?怎么配置发信?
  • CUDA算子优化:矩阵乘GEMM优化(三)
  • Java 插入Mysql 报错:Column count doesn‘t match value count at row 1
  • 如何完美解决 Xshell 使用 SSH 连接 Linux 服务器报错:找不到匹配的 host key 算法
  • Linux下C程序的编写
  • 如何安全进行亚马逊、沃尔玛测评?
  • 【vue】终端 常用代码 和其他注意
  • 提高磁盘I/O速度的途径
  • 【C++】AVL树/红黑树实现及map与set的封装
  • 龙芯+RT-Thread+LVGL实战笔记(36)——密码锁完善
  • 分享的文章《人生如棋》
  • 【剑指offer】让抽象问题具体化
  • Apache Spark Streaming 使用实例
  • CentOS7简单部署NFS
  • Node项目之评分系统(二)- 数据库设计
  • NSTimer学习笔记
  • python3 使用 asyncio 代替线程
  • React的组件模式
  • Solarized Scheme
  • SQLServer之创建显式事务
  • Swoft 源码剖析 - 代码自动更新机制
  • windows下如何用phpstorm同步测试服务器
  • 前言-如何学习区块链
  • 微信支付JSAPI,实测!终极方案
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​马来语翻译中文去哪比较好?
  • # 计算机视觉入门
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #Linux(Source Insight安装及工程建立)
  • #vue3 实现前端下载excel文件模板功能
  • #宝哥教你#查看jquery绑定的事件函数
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (6) 深入探索Python-Pandas库的核心数据结构:DataFrame全面解析
  • (CPU/GPU)粒子继承贴图颜色发射
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (ZT)出版业改革:该死的死,该生的生
  • (二)pulsar安装在独立的docker中,python测试
  • (二)windows配置JDK环境
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (每日一问)计算机网络:浏览器输入一个地址到跳出网页这个过程中发生了哪些事情?(废话少说版)
  • (三)终结任务
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (转)【Hibernate总结系列】使用举例
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .class文件转换.java_从一个class文件深入理解Java字节码结构
  • .NET C# 使用 iText 生成PDF
  • .NET Core中如何集成RabbitMQ
  • .NET 材料检测系统崩溃分析