Puerts 在 UE 開發中提供了一定的便利性,可以用程式碼的方式寫藍圖,但是官方是不推薦這麼做的
原話如下
那麼這個效能問題究竟有多大呢
這裡先用 C++ 寫一個測試程式碼
#include "TestWidget.h" #include "Blueprint/WidgetBlueprintLibrary.h" #include "Blueprint/WidgetLayoutLibrary.h" int32 UTestWidget::NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { FPaintContext Context(AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); FVector2D ViewportSize = UWidgetLayoutLibrary::GetViewportSize(const_cast<UTestWidget*>(this)); FVector2D LeftTopPoint = FVector2D(ViewportSize.X * 0.2, ViewportSize.Y * 0.2); FVector2D RightTopPoint = FVector2D(ViewportSize.X * 0.8, ViewportSize.Y * 0.2); FVector2D LeftBottomPoint = FVector2D(ViewportSize.X * 0.2, ViewportSize.Y * 0.8); FVector2D RightBottomPoint = FVector2D(ViewportSize.X * 0.8, ViewportSize.Y * 0.8); UWidgetBlueprintLibrary::DrawLine(Context, LeftTopPoint, RightTopPoint); UWidgetBlueprintLibrary::DrawLine(Context, RightTopPoint, RightBottomPoint); UWidgetBlueprintLibrary::DrawLine(Context, RightBottomPoint, LeftBottomPoint); UWidgetBlueprintLibrary::DrawLine(Context, LeftBottomPoint, LeftTopPoint); return Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); }
然後用 Unreal Insight 看一下效能資料
只看 Paint 的資料,作為對照組
然後在 TypeScript 實現一樣的程式碼
import { $Ref } from "puerts" import * as UE from "ue" class TS_TestWidget extends UE.PuertsWidget { OnPaint(Context: $Ref<UE.PaintContext>): void { let ViewportSize = UE.WidgetLayoutLibrary.GetViewportSize(this); let LeftTopPoint = new UE.Vector2D(ViewportSize.X * 0.2, ViewportSize.Y * 0.2); let RightTopPoint = new UE.Vector2D(ViewportSize.X * 0.8, ViewportSize.Y * 0.2); let LeftBottomPoint = new UE.Vector2D(ViewportSize.X * 0.2, ViewportSize.Y * 0.8); let RightBottomPoint = new UE.Vector2D(ViewportSize.X * 0.8, ViewportSize.Y * 0.8); UE.WidgetBlueprintLibrary.DrawLine(Context, LeftTopPoint, RightTopPoint); UE.WidgetBlueprintLibrary.DrawLine(Context, RightTopPoint, RightBottomPoint); UE.WidgetBlueprintLibrary.DrawLine(Context, RightBottomPoint, LeftBottomPoint); UE.WidgetBlueprintLibrary.DrawLine(Context, LeftBottomPoint, LeftTopPoint); } } export default TS_TestWidget
跟 C++ 對比,在最慢的時候可以可以達到幾十倍的差距,假如有幾十個這樣的 Widget 同時執行(例如血條),那麼肯定是會出現遊戲頓卡或者遊戲幀數低的情況
所以在 Puerts 中儘量不寫每幀都會執行的邏輯,避免因為跨語言呼叫而造成的效能問題