提问
simulink 有一个和UE5协同的模块,叫做Simulation 3D Scence Configuration,还有一个发送来自simulink到UE5数据的模块叫做Simulation 3D Message。
现在遇到的问题是,这两个模块的优先级设置是正确的,且sample time都设置为0.02s,Simulation 3D Message用于发送被控Actor的位置坐标(例如x=100)。然而在UE5中,运行后发现被控的Actor得到的位置坐标中间会夹杂0,一开始运行时还好,到后面会稳定在2个正常的接收(x=100)中间夹杂3个x=0. ,这会导致被控的actor在画面中会出现残影。
现在请你分析一下原因,为什么会出现被控的Actor得到的位置坐标中间会夹杂0这种情况
这是目前的关卡蓝图
回答
看了你的关卡蓝图(Event Tick → 两个 Read Vector From Simulation 3D Message,直接把 Data 接到 SetActorLocationAndRotation),需要改。现在“Status/Found”没用到,未命中时 Data 会回退为 (0,0,0),你就把 0 写回去了,所以会闪回到原点。
就在你截图里。每个 Read Vector Float 节点右侧,黄色 Data
的下面那个红色引脚,标的就是 Status
——这就是我前面说的 Found/Valid 等价物。
怎么用(最小改动):
-
在关卡蓝图里先建缓存变量:
LastLocation
(Vector)、LastRotation
(Rotator)、bLocValid
、bRotValid
。 -
对“位置”的那个 Read Vector Float:
- 把
Status
→ Branch。 - True:
LastLocation = Data
,bLocValid = true
。 - False:不接
Data
(别把 0 写回)。
- 把
-
对“姿态”的那个 Read Vector Float 同样处理:
Status → Branch
。- True:
LastRotation = MakeRotator(BreakVector(Data))
,bRotValid = true
。
-
在两个分支之后,用 缓存 去驱动
SetActorLocationAndRotation
:New Location
接LastLocation
New Rotation
接LastRotation
- 不要再把两个
Data
直接连去SetActor…
。
如果你的节点 Status
不是 Bool 而是返回枚举/整型(个别版本会这样),就先做个判断:“Status == Success(0)
”→ 再喂给 Branch;逻辑一样。
继续追问
status的作用是什么
回答
你蓝图节点里的 Status
引脚,其实就是用来告诉你 这一次读取有没有成功拿到 Simulink 发来的数据。
具体来说:
- 成功(Found/Valid):说明这一帧里 UE5 真正收到了数据包,那么
Data
引脚里就是 Simulink 发送的数值(位置、姿态等)。 - 失败(Not Found/Invalid):说明这一帧 UE5 没有收到对应 Key 的消息。这时如果你直接用
Data
,它会给你一个默认值(通常是0
或(0,0,0)
)。这就是你看到“夹杂 0”残影的根源。
所以 Status
的作用就是一个 有效性标志位,等价于 “有没有数据 / 数据是否可靠”。
正确用法
- 把
Status
接到一个 Branch(条件分支)。 - True 分支:更新缓存(
LastLocation/LastRotation
= Data),再更新 Actor。 - False 分支:不要用 Data,而是直接沿用上一次缓存的值(或者什么都不做)。
这样,即使某一帧 Simulink 没有发数据(UE 读取未命中),你也不会把 0 写进 Actor 的位置。
继续追问
你说的Rotator是不是就是旋转体数据类型?还是向量数据类型?
回答
是 UE 的 Rotator 类型(旋转体),不是普通向量。
Rotator 在 UE 里表示欧拉角,三个分量是 Roll / Pitch / Yaw,单位是度。而 Vector
只是三维数值(位置、方向或任意三元组),没有“旋转”的语义。
你蓝图里的做法是:Read Vector Float
拿到一个三元组 → Break Vector
→ 用 Make Rotator(Roll= X, Pitch= Y, Yaw= Z)
组装成 Rotator → 喂给 SetActorLocationAndRotation
。这没问题,但要注意:
- 如果 Simulink 发来的是弧度,要先乘 180/π 变成度。
- 如果发来的顺序不是 (Roll, Pitch, Yaw),要在蓝图里重排对应到 Rotator 的 (Roll, Pitch, Yaw)。
- 只发 Yaw 时:
Make Rotator(Roll=0, Pitch=0, Yaw=YawDeg)
即可。 - 若你要缓存,变量就建成
LastRotation
(Rotator),比存 Vector 更直观。
(坐标系/旋转方向如果与 UE 不同,还需要做轴向和符号的映射;UE 默认 X 前、Y 右、Z 上,Rotator 按 Roll→X、Pitch→Y、Yaw→Z 解释,单位是度。)
继续追问
为什么我变量名叫做bLoc_Valid,但是搜索只能搜索到 Loc Valid的变量名?
回答
这是 UE 的“友好显示名(Friendly Name)”在作祟。
Blueprint 默认会把布尔变量名的前缀 b
去掉、把下划线变成空格、再按大小写加空格显示。所以
bLoc_Valid
在面板/搜索里会显示成 “Loc Valid”。搜索框默认也是按“显示名”匹配,不按内部名字匹配。
你有三种处理方式:
- 关掉友好显示名(显示原始变量名)
- 打开 Editor Preferences → Blueprint Editor(或 General → Blueprint)
- 取消勾选 Use Friendly Variable Names(或类似选项)
- 变量列表与搜索就会显示/匹配
bLoc_Valid
。
- 给变量自定义显示名
- 选中变量 → Details 面板 → 勾开 Advanced → Display Name
- 填你想要的名字(比如
bLoc_Valid
或“位置有效”)。搜索会按这个显示名匹配。
- 维持现状,按显示名搜索
- 直接搜 Loc Valid(或 Loc、Valid 关键词)。
这是正常行为;UE 遵循布尔用 b
前缀的命名规范,但在蓝图 UI 里默认把它“藏起来”,让名字更可读。
继续追问
是不是还要一个“New Location”变量?
回答
不需要单独再建一个叫 “New Location” 的变量。
SetActorLocationAndRotation
里写着 New Location 只是节点的输入引脚名,不是要求你有同名变量。直接把你的缓存变量接过去就行。
最小配置(够用了)
LastLocation : Vector
(缓存上一帧成功收到的位置)LastRotation : Rotator
(缓存上一帧成功收到的姿态)bLocValid : Bool
bRotValid : Bool
读消息 → Status
为真时更新 LastLocation/LastRotation
→ 最后把 LastLocation
接到 SetActorLocationAndRotation 的 New Location,把 LastRotation
接到 New Rotation。
什么时候“多一个变量”会更好(可选)
-
只收到 X,需要拼成向量
-
增加
LastX : Float
(可选) -
每次有效时:
Make Vector(LastX, LastLocation.Y, LastLocation.Z)
得到一个临时的 NewLocation,再:SetActorLocationAndRotation(NewLocation, LastRotation)
- 同时
LastLocation = NewLocation
(保持缓存同步)
-
这里的 NewLocation 只是临时拼装值,不必建成持久变量。
-
-
想做平滑/抗抖动
- 增加
TargetLocation : Vector
(收到新值就更新) - 增加
SmoothedLocation : Vector
(实际用于设置位置) - Tick/定时器里:
SmoothedLocation = VInterpTo(SmoothedLocation, TargetLocation, DeltaSeconds, Speed)
→ 接到 New Location。 - 这时
LastLocation
可当TargetLocation
用,也能省一个。
- 增加
-
直接收 Transform
- 用
LastTransform : Transform
即可 →SetActorTransform
的 New Transform 引脚,不需要 New Location 变量。
- 用
小结:默认不需要“New Location”这个变量名;除非你为了拼装/插值想把“当前要写入的位置”单独存一下,否则直接用
LastLocation
接到 New Location 就是最简洁、正确的做法。
结果
成功解决。