2025-01-04 23:00:19 +08:00

111 lines
4.4 KiB
Lua

WidgetLibrary = WidgetLibrary or {}
--- 设置
---@param widget UUserWidget
---@param offset float
function WidgetLibrary.SetWidgetToRightBorder(widget, offset)
if not widget then return end
local slot = WidgetLayoutLibrary.SlotAsCanvasSlot(widget)
slot:SetAnchors({ Minimum = { X = 1, Y = 0 }, Maximum = { X = 1, Y = 0 } })
slot:SetAlignment({ X = 1, Y = 0 })
local offsets = slot:GetOffsets()
slot:SetOffsets({ Left = offset, Right = offsets.Right, Bottom = offsets.Bottom, Top = offsets.Top })
end
--- 为防止被清除做出的全局处理
function WidgetLibrary.BindButtonClicked(TargetButton, Func, Obj)
TargetButton.OnClicked:Add(Func, Obj)
end
--- 为防止被清除做出的全局处理
function WidgetLibrary.BindButtonPressed(TargetButton, Func, Obj)
TargetButton.OnPressed:Add(Func, Obj)
end
--- 为防止被清除做出的全局处理
function WidgetLibrary.BindButtonReleased(TargetButton, Func, Obj)
TargetButton.OnReleased:Add(Func, Obj)
end
--- 绑定UI文本
function WidgetLibrary.TextBlockBindingPropertyText(TargetTextBlock, Func, Obj)
TargetTextBlock:BindingProperty("Text", Func, Obj)
end
function WidgetLibrary.BindingPropertyChange(DelegationPropertyName, TargetWidgetItem, Func, Obj)
TargetWidgetItem:BindingProperty(DelegationPropertyName, Func, Obj)
end
--- 直接绑定按键点击打开WidgetManager的页面
function WidgetLibrary.ButtonOnClickShowPanel(TargetButton, UIType, bIsShow)
if bIsShow == nil then
bIsShow = true
end
TargetButton.OnClicked:Add(
function()
if bIsShow then
WidgetManager:ShowPanel(UIType, false)
else
WidgetManager:ClosePanel(UIType)
end
end
)
end
function WidgetLibrary.SliderOnValueChanged(Slider, Func, Obj)
Slider.OnValueChanged:Add(Func, Obj)
end
--- Widget对齐到世界坐标
---@ActorPos Vector
---@param CanvasSlot UCanvasPanelSlot
function WidgetLibrary.SetWidgetAlignToWorldPosition(ActorPos, CanvasSlot)
local IsOnScreen, WidgetPosition = WidgetLayoutLibrary.ProjectWorldLocationToWidgetPosition(UGCSystemLibrary.GetLocalPlayerController(), ActorPos, {X = 0, Y = 0});
-- 获取屏幕视口尺寸信息
local VPSize = WidgetLayoutLibrary.GetViewportSize(UGCSystemLibrary.GetLocalPlayerController())
local VPScale = WidgetLayoutLibrary.GetViewportScale(UGCSystemLibrary.GetLocalPlayerController())
local WidgetSize = VectorHelper.MulNumber2D(VPSize, 1 / VPScale)
-- 获取插槽尺寸信息
local CompSize = CanvasSlot:GetSize()
local MidCompSize = VectorHelper.MulNumber2D(CompSize, 0.5)
-- 获取移动位置范围
local TargetPosMin = MidCompSize
local TargetPosMax = VectorHelper.Sub2D(WidgetSize, MidCompSize)
local TargetDir = nil
-- Actor判断是否在视锥范围内
if not (IsOnScreen and VectorHelper.Vector2DInRange(WidgetPosition, TargetPosMin, TargetPosMax)) then
-- 获取目标位置到相机的向量映射到相机平面的向量
local LocalCamera = UGCSystemLibrary.GetLocalPlayerController().PlayerCameraManager
local CameraPos = LocalCamera:K2_GetActorLocation()
local CameraForward = LocalCamera:GetActorForwardVector()
local ActorToCameraVector = VectorHelper.Sub(ActorPos, CameraPos)
local PlaneVector = KismetMathLibrary.ProjectVectorOnToPlane(ActorToCameraVector, CameraForward)
-- 将平面向量旋转至原点
local RotatorPlaneVector = KismetMathLibrary.NegateRotator(KismetMathLibrary.Conv_VectorToRotator(CameraForward))
local NormalPlaneVector = KismetMathLibrary.GreaterGreater_VectorRotator(PlaneVector, RotatorPlaneVector)
-- 获取屏幕的方向向量
TargetDir = {X = NormalPlaneVector.Y, Y = -NormalPlaneVector.Z}
TargetDir = VectorHelper.MulNumber2D(TargetDir, 1 / VectorHelper.Length2D(TargetDir))
-- 判断屏幕及方向向量的斜率
if math.abs(TargetDir.Y / TargetDir.X) < WidgetSize.Y / WidgetSize.X then
WidgetPosition.X = ((TargetDir.X < 0) and TargetPosMin.X or TargetPosMax.X)
WidgetPosition.Y = ((WidgetSize.X / 2 - MidCompSize.X) / math.abs(TargetDir.X) * TargetDir.Y + WidgetSize.Y / 2)
else
WidgetPosition.Y = ((TargetDir.Y < 0) and TargetPosMin.Y or TargetPosMax.Y)
WidgetPosition.X = ((WidgetSize.Y - MidCompSize.Y) / 2 / math.abs(TargetDir.Y) * TargetDir.X + WidgetSize.X / 2)
end
end
return WidgetPosition, TargetDir
end