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

为UE5的Actor添加能够读写姿态的功能

提问

// Copyright 2019-2022 The MathWorks, Inc.
#include "SetGetActorLocation.h"// Sets default values
ASetGetActorLocation::ASetGetActorLocation():SignalReader(nullptr), SignalWriter(nullptr)
{
}void ASetGetActorLocation::Sim3dSetup()
{
Super::Sim3dSetup();if (Tags.Num() != 0) {unsigned int numElements = 3;FString tagName = Tags.Top().ToString();FString SignalReaderTag = tagName;SignalReaderTag.Append(TEXT("Set"));SignalReader = StartSimulation3DMessageReader(TCHAR_TO_ANSI(*SignalReaderTag), sizeof(float)*numElements);FString SignalWriterTag = tagName;SignalWriterTag.Append(TEXT("Get"));SignalWriter = StartSimulation3DMessageWriter(TCHAR_TO_ANSI(*SignalWriterTag), sizeof(float)*numElements);}
}void ASetGetActorLocation::Sim3dStep(float DeltaSeconds)
{unsigned int numElements = 3;float array[3];int statusR = ReadSimulation3DMessage(SignalReader, sizeof(float)*numElements, array);FVector NewLocation;NewLocation.X = array[0];NewLocation.Y = array[1];NewLocation.Z = array[2];SetActorLocation(NewLocation);float fvector[3] = { NewLocation.X, NewLocation.Y, NewLocation.Z };int statusW = WriteSimulation3DMessage(SignalWriter, sizeof(float)*numElements ,fvector);
}void ASetGetActorLocation::Sim3dRelease()
{Super::Sim3dRelease();if (SignalReader) {StopSimulation3DMessageReader(SignalReader);}SignalReader = nullptr;     if (SignalWriter) {StopSimulation3DMessageWriter(SignalWriter);}SignalWriter = nullptr;
}

这个代码块的核心功能应该是可以接收三维坐标的位置,同时也支持输出三维坐标的位置,是么?

回答

是的,你的理解完全正确。

这个 ASetGetActorLocation 类的核心功能就是:

接收 (Set)输出 (Get) 三维坐标位置(FVector)的功能。


📌 详细说明如下:

1. 输入位置:从外部系统接收位置坐标并设置Actor的位置
int statusR = ReadSimulation3DMessage(SignalReader, sizeof(float)*3, array);
FVector NewLocation;
NewLocation.X = array[0];
NewLocation.Y = array[1];
NewLocation.Z = array[2];
SetActorLocation(NewLocation);
  • SignalReader 中读取一个 float[3] 数组。
  • 把这个数组解析为 X, Y, Z 三个坐标。
  • 使用 SetActorLocation 设置这个 Actor 的新位置。
2. 输出位置:获取当前Actor的位置并输出
float fvector[3] = { NewLocation.X, NewLocation.Y, NewLocation.Z };
int statusW = WriteSimulation3DMessage(SignalWriter, sizeof(float)*3 ,fvector);
  • 把当前的坐标写入到 fvector 数组中。
  • SignalWriter 写出这组坐标,让外部系统获取当前的位置。

🧠 额外注意事项:

  • Tags.Top().ToString() 作为唯一标识名拼接 "Set""Get",作为信号通道名。
  • 这段代码是用于 Unreal Engine 与 Simulink 3D 信号交换的接口层(Simulink + Unreal plugin 常用的方式)。

结论:这段代码确实是双向处理Actor位置的:接收 → 设置位置,输出 → 获取位置。


a. 需要我帮你加上错误处理逻辑,比如检查 statusR / statusW 是否成功吗?
b. 想加入一个调试输出 GEngine->AddOnScreenDebugMessage 显示当前坐标吗?

继续提问:SetActorLocation 来自SetGetActorLocation.h是么?

回答

不是的,SetActorLocation 不是 来自你自定义的 SetGetActorLocation.h,而是:

✅ 来自 Unreal Engine 的基类 AActor


详细解释:

你的类定义是这样的:

class ASetGetActorLocation : public AActor

这说明 ASetGetActorLocation 是从 AActor 继承的。而 SetActorLocationAActor 提供的公共成员函数:

🔧 SetActorLocation 定义:

bool AActor::SetActorLocation(FVector NewLocation, bool bSweep = false, FHitResult* OutSweepHitResult = nullptr, ETeleportType Teleport = ETeleportType::None);

所以结论:

  • SetActorLocation 是 Unreal Engine 4/5 自带的。
  • 它在你头文件 SetGetActorLocation.h 中没有定义,而是通过继承 AActor 获得的。

a. 想看下完整的 SetGetActorLocation.h 文件结构,确认有哪些成员和继承关系?
b. 是否需要我帮你补全一个带注释的 .h 文件来配合这个 .cpp 文件使用?

继续提问

现在我想仿照上面的代码,做一个实时获取三个方向旋转的代码。可以分别叫做SetGetActorRotation.h和SetGetActorLocation.cpp。 现在要求你为我提供这两个代码。我相信也很方便,可能需要用到类似于SetActorLocation (只不过是旋转版本)的函数(应该也是继承自AActor)

回答

好的,下面是你要的两个完整文件:


SetGetActorRotation.h

// Copyright 2019-2025 The MathWorks, Inc.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SetGetActorRotation.generated.h"UCLASS()
class ASetGetActorRotation : public AActor
{GENERATED_BODY()public:ASetGetActorRotation();virtual void Sim3dSetup();virtual void Sim3dStep(float DeltaSeconds);virtual void Sim3dRelease();private:void* SignalReader;void* SignalWriter;
};

SetGetActorRotation.cpp

// Copyright 2019-2025 The MathWorks, Inc.#include "SetGetActorRotation.h"// Sets default values
ASetGetActorRotation::ASetGetActorRotation() : SignalReader(nullptr), SignalWriter(nullptr)
{
}void ASetGetActorRotation::Sim3dSetup()
{Super::Sim3dSetup();if (Tags.Num() != 0) {unsigned int numElements = 3;FString tagName = Tags.Top().ToString();FString SignalReaderTag = tagName + TEXT("SetRot");SignalReader = StartSimulation3DMessageReader(TCHAR_TO_ANSI(*SignalReaderTag), sizeof(float) * numElements);FString SignalWriterTag = tagName + TEXT("GetRot");SignalWriter = StartSimulation3DMessageWriter(TCHAR_TO_ANSI(*SignalWriterTag), sizeof(float) * numElements);}
}void ASetGetActorRotation::Sim3dStep(float DeltaSeconds)
{unsigned int numElements = 3;float array[3];int statusR = ReadSimulation3DMessage(SignalReader, sizeof(float) * numElements, array);FRotator NewRotation;NewRotation.Roll = array[0];NewRotation.Pitch = array[1];NewRotation.Yaw = array[2];SetActorRotation(NewRotation);float frotator[3] = { NewRotation.Roll, NewRotation.Pitch, NewRotation.Yaw };int statusW = WriteSimulation3DMessage(SignalWriter, sizeof(float) * numElements, frotator);
}void ASetGetActorRotation::Sim3dRelease()
{Super::Sim3dRelease();if (SignalReader) {StopSimulation3DMessageReader(SignalReader);}SignalReader = nullptr;if (SignalWriter) {StopSimulation3DMessageWriter(SignalWriter);}SignalWriter = nullptr;
}

📌 说明

  • 使用了 FRotator 来处理三维旋转角度(Roll, Pitch, Yaw),与 Unreal Engine 的坐标系统一致。
  • SetActorRotationAActor 提供的函数,类似于 SetActorLocation,用于设置 Actor 的旋转。
  • 信号名后缀改为 SetRot / GetRot,以便和位置的信号区分。

a. 需要我同时给你添加 OnScreenDebugMessage 输出当前角度调试信息吗?
b. 想加入角度范围的验证或归一化(如限制在 [-180°, 180°])吗?

继续提问

我能不能直接在现有的cpp:SetActorLocation.cpp上进行添加呀?然后重新命名为SetActorLocation_Rotation.cpp,使其同时具有读写三维坐标信息和三维朝向信息,因为我需要一个C++类的实例化实体本身具有同时具有读写三维坐标信息和三维朝向信息,并为这个实例赋予静态网格体,而不是说拆成两个实例。

回答

是的 ✅,你完全可以位置 + 旋转 的功能合并在一个类中,并将 .cpp 文件重命名为 SetActorLocation_Rotation.cpp。这符合 Unreal Engine 的编程范式,也更适合你说的目标:

需要一个 C++ 类的实体同时具有:

  • 读写三维位置(Location)
  • 读写三维朝向(Rotation)
  • 并挂载一个静态网格体组件(Static Mesh Component)

✅ 合并设计方案

类名建议:

ASetGetActorLocationRotation

✅ 功能包含:

1. Setup(创建两个通道:位置 Set/Get + 旋转 Set/Get)

2. Step(读取并设置位置和旋转;写出当前的位置和旋转)

3. Release(释放所有通道资源)

4. 添加静态网格体组件(通过 UStaticMeshComponent


✅ 下一步我将为你生成一个完整的版本:

  • .h 文件:SetGetActorLocationRotation.h
  • .cpp 文件:SetGetActorLocation_Rotation.cpp

是否需要我现在就为你生成完整的合并版本代码?是否你已经有绑定好的 mesh 名字,还是我用默认 placeholder?
你也可以告诉我使用哪个 .uasset 路径,我可以写到 ConstructorHelpers::FObjectFinder 里。


a. 是否希望我加入 UStaticMeshComponent 并自动绑定一个默认立方体?
b. 是否你想我把信号命名规范统一为 "SetPos"/"GetPos""SetRot"/"GetRot"

http://www.lryc.cn/news/2402936.html

相关文章:

  • 机器学习:支持向量机(SVM)原理解析及垃圾邮件过滤实战
  • LLM Agent 如何颠覆股价预测的传统范式
  • App/uni-app 离线本地存储方案有哪些?最推荐的是哪种方案?
  • 【案例分享】如何借助JS UI组件库DHTMLX Suite构建高效物联网IIoT平台
  • Skia如何绘制几何图形
  • spring:实例化类过程中方法执行顺序。
  • 设置应用程序图标
  • 「基于连续小波变换(CWT)和卷积神经网络(CNN)的心律失常分类算法——ECG信号处理-第十五课」2025年6月6日
  • 用go从零构建写一个RPC(4)--gonet网络框架重构+聚集发包
  • OpenBayes 一周速览|TransPixeler 实现透明化文本到视频生成;统一图像定制框架 DreamO 上线,一键处理多种图像生成任务
  • 视频的分片上传,断点上传
  • CSS 性能优化
  • 华为×小鹏战略合作:破局智能驾驶深水区的商业逻辑深度解析
  • 4D毫米波雷达产品推荐
  • yolo 训练 中间可视化
  • Rust 学习笔记:关于 Cargo 的练习题
  • 光伏功率预测 | BiLSTM多变量单步光伏功率预测(Matlab完整源码和数据)
  • 20250606-C#知识:委托和事件
  • AI数字人技术革新进行时:井云数字人如何重塑人机交互未来?
  • ruoyi-plus-could 负载均衡 通过 Gateway模块配置负载均衡
  • 江科大读写内部flash到hal库实现
  • Matlab回归预测大合集又更新啦!新增2种高斯过程回归预测模型,已更新41个模型!性价比拉满!
  • 主流 AI IDE 之一的 Cursor 介绍
  • 0x-1 记一次SGA PGA设置失败,重新开库
  • 【科研绘图系列】R语言绘制和弦图(Chord diagram plot)
  • PPT转图片拼贴工具 v3.0
  • 关于安科瑞APD局部放电监测装置解决方案的应用分析
  • 设计模式-2 结构型模式
  • 大量企业系统超龄服役!R²AIN SUITE 一体化企业提效解决方案重构零售数智化基因
  • Cesium使用glb模型、图片标记来实现实时轨迹