111 lines
4.4 KiB
Lua
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
|
||
|
|