在 Unreal Engine 的 UMG(Unreal Motion Graphics)中,“绝对坐标”和“局部空间”是两个常见的概念,主要用于描述 UI 元素的位置和大小。
概念与区别
- 绝对坐标(Absolute Coordinates):这是指相对于屏幕的坐标系。无论 UI 元素属于哪个父级,它的绝对坐标都是相对于整个屏幕的。
- 局部空间(Local Space):这是指相对于 UI 元素的父级的坐标系。一个 UI 元素的局部坐标是基于它的父级的坐标系来定义的。
函数
在 UMG 中,Unreal Engine 提供了一些函数来进行坐标转换:
-
绝对坐标转局部空间:
FVector2D UWidgetLayoutLibrary::AbsoluteToLocal(UObject* WorldContextObject, const FGeometry& Geometry, const FVector2D& AbsoluteCoordinate);
-
局部空间转绝对坐标:
FVector2D UWidgetLayoutLibrary::LocalToAbsolute(UObject* WorldContextObject, const FGeometry& Geometry, const FVector2D& LocalCoordinate);
示例
例子 1:绝对坐标转局部空间
假设你有一个 UWidget
,你想将一个绝对坐标转换为这个 UWidget
的局部坐标。
UWidget* MyWidget = ...; // 获取你的Widget
FGeometry WidgetGeometry = MyWidget->GetCachedGeometry();
FVector2D AbsolutePosition = FVector2D(500, 300); // 绝对坐标FVector2D LocalPosition = UWidgetLayoutLibrary::AbsoluteToLocal(nullptr, WidgetGeometry, AbsolutePosition);// 输出局部坐标
UE_LOG(LogTemp, Log, TEXT("Local Position: %s"), *LocalPosition.ToString());
例子 2:局部空间转绝对坐标
假设你有一个 UWidget
,你想将一个局部坐标转换为绝对坐标。
UWidget* MyWidget = ...; // 获取你的Widget
FGeometry WidgetGeometry = MyWidget->GetCachedGeometry();
FVector2D LocalPosition = FVector2D(50, 30); // 局部坐标FVector2D AbsolutePosition = UWidgetLayoutLibrary::LocalToAbsolute(nullptr, WidgetGeometry, LocalPosition);// 输出绝对坐标
UE_LOG(LogTemp, Log, TEXT("Absolute Position: %s"), *AbsolutePosition.ToString());
与屏幕位置的转换
屏幕位置 是指鼠标或触摸点在屏幕上的位置,通常用于处理输入事件。
屏幕位置转绝对坐标
屏幕位置在 Unreal Engine 中通常是绝对坐标,因为它们是相对于整个屏幕的。你可以直接使用屏幕位置作为绝对坐标。
绝对坐标转屏幕位置
绝对坐标和屏幕位置之间没有转换,因为它们实际上是相同的概念,都是相对于整个屏幕的坐标。
局部空间转屏幕位置
首先,将局部空间转换为绝对坐标,然后绝对坐标即为屏幕位置。
UWidget* MyWidget = ...; // 获取你的Widget
FGeometry WidgetGeometry = MyWidget->GetCachedGeometry();
FVector2D LocalPosition = FVector2D(50, 30); // 局部坐标// 先转换为绝对坐标
FVector2D AbsolutePosition = UWidgetLayoutLibrary::LocalToAbsolute(nullptr, WidgetGeometry, LocalPosition);// AbsolutePosition 即为屏幕位置
UE_LOG(LogTemp, Log, TEXT("Screen Position: %s"), *AbsolutePosition.ToString());
屏幕位置转局部空间
将屏幕位置(绝对坐标)转换为局部空间坐标。
UWidget* MyWidget = ...; // 获取你的Widget
FGeometry WidgetGeometry = MyWidget->GetCachedGeometry();
FVector2D ScreenPosition = FVector2D(500, 300); // 屏幕位置(绝对坐标)// 转换为局部坐标
FVector2D LocalPosition = UWidgetLayoutLibrary::AbsoluteToLocal(nullptr, WidgetGeometry, ScreenPosition);UE_LOG(LogTemp, Log, TEXT("Local Position: %s"), *LocalPosition.ToString());
总结
- 绝对坐标 是相对于屏幕的全局坐标。
- 局部空间 是相对于父 UI 元素的坐
接口归纳
SlateBlueprintLibrary.h C++ 文件中有一些绝对坐标与局部空间相互转换的函数
//SlateBlueprintLibrary.h C++ 文件中有一些绝对坐标与局部空间相互转换的函数
class USlateBlueprintLibrary : public UBlueprintFunctionLibrary
{GENERATED_UCLASS_BODY()public://如果以绝对坐标提供的位置在此几何图形的边界内,则返回true。static UMG_API bool IsUnderLocation(const FGeometry& Geometry, const FVector2D& AbsoluteCoordinate);//将绝对坐标转换为该几何的局部空间。//绝对坐标可以是桌面空间,也可以是窗口空间,这取决于小部件层次结构的根所在的空间。static UMG_API FVector2D AbsoluteToLocal(const FGeometry& Geometry, FVector2D AbsoluteCoordinate);//将局部坐标转换为绝对坐标//绝对坐标可以是桌面空间,也可以是窗口空间,这取决于小部件层次结构的根所在的空间。static UMG_API FVector2D LocalToAbsolute(const FGeometry& Geometry, FVector2D LocalCoordinate);//返回局部空间中几何体的局部顶部/左侧。static UMG_API FVector2D GetLocalTopLeft(const FGeometry& Geometry);//返回几何体在局部空间中的大小。static UMG_API FVector2D GetLocalSize(const FGeometry& Geometry);//返回几何图形在绝对空间中的大小static UMG_API FVector2D GetAbsoluteSize(const FGeometry& Geometry);static UMG_API float TransformScalarAbsoluteToLocal(const FGeometry& Geometry, float AbsoluteScalar);static UMG_API float TransformScalarLocalToAbsolute(const FGeometry& Geometry, float LocalScalar);static UMG_API FVector2D TransformVectorAbsoluteToLocal(const FGeometry& Geometry, FVector2D AbsoluteVector);static UMG_API FVector2D TransformVectorLocalToAbsolute(const FGeometry& Geometry, FVector2D LocalVector);//返回画笔A和B是否相同。static UMG_API bool EqualEqual_SlateBrush(const FSlateBrush& A, const FSlateBrush& B);//将提供的几何体的局部坐标转换为局部视口坐标。static UMG_API void LocalToViewport(UObject* WorldContextObject, const FGeometry& Geometry, FVector2D LocalCoordinate, FVector2D& PixelPosition, FVector2D& ViewportPosition);//将提供的几何图形在桌面空间中的绝对坐标转换为本地视口坐标。static UMG_API void AbsoluteToViewport(UObject* WorldContextObject, FVector2D AbsoluteDesktopCoordinate, FVector2D& PixelPosition, FVector2D& ViewportPosition);//将屏幕位置(以像素为单位)转换为具有给定几何形状的小部件的局部空间。//如果bIncludeWindowPosition为true,那么这个方法也会移除游戏窗口的位置(在窗口模式下很有用)。static UMG_API void ScreenToWidgetLocal(UObject* WorldContextObject, const FGeometry& Geometry, FVector2D ScreenPosition, FVector2D& LocalCoordinate, bool bIncludeWindowPosition = false);//将屏幕位置(以像素为单位)转换为绝对应用程序坐标。//如果bIncludeWindowPosition为true,那么这个方法也会移除游戏窗口的位置(在窗口模式下很有用)。static UMG_API void ScreenToWidgetAbsolute(UObject* WorldContextObject, FVector2D ScreenPosition, FVector2D& AbsoluteCoordinate, bool bIncludeWindowPosition = false);//将屏幕位置(以像素为单位)转换为视窗小部件的本地空间。static UMG_API void ScreenToViewport(UObject* WorldContextObject, FVector2D ScreenPosition, FVector2D& ViewportPosition);
}