提問
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 就是最簡潔、正確的做法。
結果
成功解決。