forked from endernon/PGRData
488 lines
No EOL
16 KiB
Lua
488 lines
No EOL
16 KiB
Lua
|
|
local CsVector3 = CS.UnityEngine.Vector3
|
|
local CsQuaternion = CS.UnityEngine.Quaternion
|
|
local NormalPivot = CS.UnityEngine.Vector2(0.5, 0.5)
|
|
|
|
---@class XUiPanelAreaWarMainBlockList3D
|
|
---@field NearCamera UnityEngine.Camera
|
|
---@field Line UnityEngine.RectTransform
|
|
---@field PanelLine UnityEngine.RectTransform
|
|
---@field PanelStage UnityEngine.RectTransform
|
|
---@field GridBlocks table<number,XUiGridAreaWarBlock>
|
|
---@field BlockScript table<number, XAreaWarBlockArea>
|
|
---@field GameObject UnityEngine.GameObject
|
|
local XUiPanelAreaWarMainBlockList3D = XClass(nil, "XUiPanelAreaWarMainBlockList3D")
|
|
local XUiGridAreaWarBlock = require("XUi/XUiAreaWar/XUiGridAreaWarBlock")
|
|
|
|
local PositionRatio = 10000
|
|
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:Ctor(ui, cameraData, blockAreas, clickCb, isNormaCameraCb)
|
|
XTool.InitUiObjectByUi(self, ui)
|
|
self.FirstRefresh = true
|
|
self.LinePivot = self.Line.pivot
|
|
self.GridBlocks = {}
|
|
self.GridLines = {}
|
|
self.LineSize = self.Line.sizeDelta
|
|
self.ClickCb = clickCb
|
|
self.ClickBlockCb = handler(self, self.OnClickBlock)
|
|
self.IsNormaCameraCb = isNormaCameraCb
|
|
--偏移一个格子的高度
|
|
self.Offset = nil
|
|
--用于计算的Vector3 避免重复创建对象
|
|
self.CalVec3 = CsVector3.zero
|
|
--相机引用
|
|
self.NearCamera = cameraData.NearCamera
|
|
self.FarCamera = cameraData.FarCamera
|
|
self.NormalVirtual = cameraData.NormalVirtual
|
|
self.DetailVirtual = cameraData.DetailVirtual
|
|
|
|
self.IsSmall = false
|
|
|
|
self:InitAngle()
|
|
self:InitPanel(blockAreas)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:StartTimer()
|
|
if self.Timer then
|
|
return
|
|
end
|
|
self.Timer = XScheduleManager.ScheduleForever(function()
|
|
self:Update()
|
|
end, 200)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:StopTimer()
|
|
if not self.Timer then
|
|
return
|
|
end
|
|
XScheduleManager.UnSchedule(self.Timer)
|
|
self.Timer = nil
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:OnDispose()
|
|
self:StopTimer()
|
|
XDataCenter.AreaWarManager.SaveLastCameraFollowPointPos(self.CameraFollowPoint.transform.position)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:Update()
|
|
if XTool.UObjIsNil(self.GameObject) then
|
|
return
|
|
end
|
|
|
|
if not self.GameObject.activeInHierarchy then
|
|
return
|
|
end
|
|
|
|
--if not self:CheckNeedUpdate() then
|
|
-- return
|
|
--end
|
|
|
|
for blockId, grid in pairs(self.GridBlocks) do
|
|
local visible
|
|
if self.IsNormaCameraCb() then
|
|
visible = CS.XUiHelper.IsInView(self.NearCamera, grid.Transform.position, -0.2, 1.2, -0.5, 1.2)
|
|
if visible then
|
|
if self.IsSmall then
|
|
grid:PlayMiniEnable()
|
|
else
|
|
grid:PlayMiniDisable()
|
|
end
|
|
end
|
|
else
|
|
visible = blockId == self.FocusDetailBlockId
|
|
end
|
|
grid:SetVisible(visible)
|
|
local blockArea = self.BlockScript[blockId]
|
|
if blockArea then
|
|
CS.XUiHelper.WorldPoint2CanvasPoint(self.FarCamera, self.NearCamera, grid.Transform, blockArea:GetCenterPoint(), self.Offset)
|
|
end
|
|
end
|
|
|
|
--隐藏时也同步位置,是为了连线时位置是准确的
|
|
--if XTool.UObjIsNil(grid.GameObject) or not grid.GameObject.activeInHierarchy then
|
|
-- return
|
|
--end
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:Refresh(isRepeatChallenge)
|
|
self.IsRepeatChallenge = isRepeatChallenge
|
|
--local checkMap = XDataCenter.AreaWarManager.GetNewUnlockBlockIdDic()
|
|
for _, chapterId in pairs(XAreaWarConfigs.GetChapterIds()) do
|
|
--章节开放
|
|
--if XDataCenter.AreaWarManager.IsChapterUnlock(chapterId) then
|
|
local blockIds = XAreaWarConfigs.GetBlockIdsByChapterId(chapterId)
|
|
for _ ,blockId in pairs(blockIds) do
|
|
if XDataCenter.AreaWarManager.IsBlockVisible(blockId) then
|
|
self:UpdateBlock(blockId)
|
|
end
|
|
end
|
|
--end
|
|
end
|
|
|
|
--首次刷新
|
|
if self.FirstRefresh then
|
|
--还原上次相机位置
|
|
local pos = XDataCenter.AreaWarManager.GetLastCameraFollowPointPos()
|
|
if not pos then
|
|
local allBockIds = XAreaWarConfigs.GetAllBlockIds()
|
|
pos = self:_GetGridParent(allBockIds[1]).transform.position
|
|
end
|
|
self.CameraFollowPoint.transform.position = pos
|
|
|
|
self.FirstRefresh = false
|
|
|
|
self:StartTimer()
|
|
end
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:RefreshNewUnlockBlocks()
|
|
local checkMap = XDataCenter.AreaWarManager.GetNewUnlockBlockIdDic()
|
|
for blockId in pairs(checkMap) do
|
|
self:UpdateBlock(blockId)
|
|
end
|
|
|
|
XDataCenter.AreaWarManager.SetNewUnlockBlockIdDicCookie(checkMap)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:UpdateBlock(blockId)
|
|
|
|
local grid = self.GridBlocks[blockId]
|
|
if not grid then
|
|
local block = self.BlockScript[blockId]
|
|
if not block then
|
|
XLog.Warning("创建事件区域失败! BlockId = " .. blockId)
|
|
return
|
|
end
|
|
if not self.Offset then
|
|
--只偏移高度,因为原点在模型底部中心
|
|
self.Offset = block:GetGridSize()
|
|
self.Offset.x = 0
|
|
self.Offset.z = 0
|
|
end
|
|
self:SetCalVec3(0, 0, block.RotateY)
|
|
grid = self:CreateBlockPanel(blockId, block, self.CalVec3)
|
|
local preBlockIds = XAreaWarConfigs.GetPreBlockIds(blockId)
|
|
--local isUnlock = XDataCenter.AreaWarManager.IsBlockUnlock(blockId)
|
|
for _, preBlockId in pairs(preBlockIds) do
|
|
--preBlockId 类型是string
|
|
local ids = string.Split(preBlockId, "|")
|
|
for _, id in pairs(ids) do
|
|
local numId = tonumber(id)
|
|
if XDataCenter.AreaWarManager.IsBlockVisible(numId) then
|
|
--if isUnlock and XDataCenter.AreaWarManager.IsBlockUnlock(numId) then
|
|
self:CreateArrowLine(numId, blockId)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
grid:Refresh(blockId, self.IsRepeatChallenge)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:FocusTargetBlock(blockId)
|
|
local grid = self:_GetGridParent(blockId)
|
|
if not grid then
|
|
XLog.Error(
|
|
"XUiPanelAreaWarMainBlockList3D:FocusTargetBlock error: grid not exist, blockId: ",
|
|
blockId
|
|
)
|
|
return
|
|
end
|
|
self.CameraFollowPoint.transform.position = grid.transform.position
|
|
|
|
for _, camera in pairs(self.NormalVirtual) do
|
|
camera.Follow = self.CameraFollowPoint.transform
|
|
end
|
|
|
|
for id, tempGrid in pairs(self.GridBlocks) do
|
|
tempGrid:SetVisible(true)
|
|
end
|
|
|
|
self:RefreshLineState(true)
|
|
self.FocusDetailBlockId = nil
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:FocusBlockDetail(blockId)
|
|
local grid = self.GridBlocks[blockId]
|
|
if not grid then
|
|
XLog.Error(
|
|
"XUiPanelAreaWarMainBlockList3D:FocusBlockDetail error: grid not exist, blockId: ",
|
|
blockId
|
|
)
|
|
return
|
|
end
|
|
|
|
for _, camera in pairs(self.DetailVirtual) do
|
|
camera.Follow = grid.Transform.parent
|
|
end
|
|
|
|
for id, tempGrid in pairs(self.GridBlocks) do
|
|
tempGrid:SetVisible(id == blockId)
|
|
end
|
|
|
|
self:RefreshLineState(false)
|
|
if self.IsSmall then
|
|
grid:PlayMiniDisable()
|
|
end
|
|
grid:PlayNearAnim()
|
|
self.FocusDetailBlockId = blockId
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:PlayGridFarAnim(blockId)
|
|
local grid = self.GridBlocks[blockId]
|
|
if not grid then
|
|
XLog.Error("XUiPanelAreaWarMainBlockList3D:PlayGridFarAnim error: grid not exist, blockId: ", blockId)
|
|
return
|
|
end
|
|
|
|
grid:PlayFarAnim()
|
|
|
|
if self.IsSmall then
|
|
grid:PlayMiniEnable()
|
|
end
|
|
end
|
|
|
|
--- 初始化面板
|
|
---@param blockAreas XAreaWarBlockArea[]
|
|
--------------------------
|
|
function XUiPanelAreaWarMainBlockList3D:InitPanel(blockAreas)
|
|
local blockMap = {}
|
|
for i = 0, blockAreas.Length - 1 do
|
|
local block = blockAreas[i]
|
|
blockMap[block.Id] = block
|
|
end
|
|
self.BlockScript = blockMap
|
|
end
|
|
|
|
--动态创建线
|
|
function XUiPanelAreaWarMainBlockList3D:CreateArrowLine(startBlockId, endBlockId)
|
|
if not XTool.IsNumberValid(startBlockId) or not XTool.IsNumberValid(endBlockId) then
|
|
return
|
|
end
|
|
|
|
local key = self:_GetLineKey(startBlockId, endBlockId)
|
|
if self.GridLines[key] then
|
|
return
|
|
end
|
|
|
|
local name = self:_GetLineName(startBlockId, endBlockId)
|
|
---@type UnityEngine.GameObject
|
|
local obj = self.PanelLine:FindTransform(name)
|
|
if obj then
|
|
self.GridLines[self:_GetLineKey(startBlockId, endBlockId)] = obj
|
|
return
|
|
end
|
|
---@type UnityEngine.GameObject
|
|
obj = XUiHelper.Instantiate(self.Line, self.PanelLine)
|
|
obj.name = name
|
|
|
|
self:SetLineTransform(obj, startBlockId, endBlockId)
|
|
obj.gameObject:SetActiveEx(true)
|
|
self.GridLines[key] = obj
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:ResetLinePosition()
|
|
for key, grid in pairs(self.GridLines) do
|
|
local startBlockId, endBlockId = self:_GetLineStartAndEndBlockId(key)
|
|
self:SetLineTransform(grid, startBlockId, endBlockId)
|
|
end
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:SetLineTransform(obj, startBlockId, endBlockId)
|
|
local position, angle, distance = self:CalculateLineWith3DUI(self:_GetGridLinePoint(startBlockId), self:_GetGridLinePoint(endBlockId), self.LinePivot)
|
|
obj.transform.localPosition = position
|
|
obj.transform.localRotation = angle
|
|
local size = self.LineSize
|
|
size.x = distance
|
|
obj.transform.sizeDelta = size
|
|
end
|
|
|
|
--- 动态创建关卡节点
|
|
---@param blockId number
|
|
---@param blockArea XAreaWarBlockArea
|
|
---@param rotation UnityEngine.Vector3
|
|
---@return XUiGridAreaWarBlock
|
|
--------------------------
|
|
function XUiPanelAreaWarMainBlockList3D:CreateBlockPanel(blockId, blockArea, rotation)
|
|
local name = string.format("Block_%d", blockId)
|
|
local block = XUiHelper.Instantiate(self.Stage, self.PanelStage)
|
|
block.name = name
|
|
block.gameObject:SetActiveEx(true)
|
|
|
|
local prefabPath = XAreaWarConfigs.GetBlockShowTypePrefab(blockId)
|
|
local go = block.transform:LoadPrefab(prefabPath)
|
|
local grid = XUiGridAreaWarBlock.New(go, self.ClickBlockCb)
|
|
CS.XUiHelper.WorldPoint2CanvasPoint(self.FarCamera, self.NearCamera, block.transform, blockArea:GetCenterPoint(), self.Offset)
|
|
grid:Rotate(CS.UnityEngine.Quaternion.Euler(rotation))
|
|
self.GridBlocks[blockId] = grid
|
|
|
|
return grid
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:CheckNeedUpdate()
|
|
local lastCameraX = self.LastCameraX or 0
|
|
local lastCameraY = self.LastCameraY or 0
|
|
local lastCameraZ = self.LastCameraZ or 0
|
|
|
|
local curCameraX = math.floor(self.NearCamera.transform.position.x * PositionRatio)
|
|
local curCameraY = math.floor(self.NearCamera.transform.position.y * PositionRatio)
|
|
local curCameraZ = math.floor(self.NearCamera.transform.position.z * PositionRatio)
|
|
if lastCameraX ~= curCameraX or lastCameraY ~= curCameraY or lastCameraZ ~= curCameraZ then
|
|
self.LastCameraX = curCameraX
|
|
self.LastCameraY = curCameraY
|
|
self.LastCameraZ = curCameraZ
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:PlayScaleAnim(isSmall)
|
|
if self.IsSmall == isSmall then
|
|
return
|
|
end
|
|
self.IsSmall = isSmall
|
|
for _, grid in pairs(self.GridBlocks) do
|
|
if self.IsSmall then
|
|
grid:PlayMiniEnable()
|
|
else
|
|
grid:PlayMiniDisable()
|
|
end
|
|
end
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:RefreshLineState(state)
|
|
self.PanelLine.gameObject:SetActiveEx(state)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:RefreshStageState(state)
|
|
self.PanelStage.gameObject:SetActiveEx(state)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:OnClickBlock(blockId)
|
|
if not XDataCenter.AreaWarManager.IsBlockUnlock(blockId) then
|
|
--优先提示区块解锁时间
|
|
if XDataCenter.AreaWarManager.GetBlockUnlockLeftTime(blockId) > 0 then
|
|
local openTime = XDataCenter.AreaWarManager.GetBlockUnlockTime(blockId)
|
|
local tipStr =
|
|
CsXTextManagerGetText(
|
|
"AreaWarBlockUnlockTime",
|
|
XTime.TimestampToGameDateTimeString(openTime, "MM/dd HH:mm")
|
|
)
|
|
XUiManager.TipMsg(tipStr)
|
|
return
|
|
end
|
|
|
|
--提示未解锁区块
|
|
local needTip, tipStr = XDataCenter.AreaWarManager.GetBlockUnlockTips(blockId)
|
|
XUiManager.TipMsg(tipStr)
|
|
return
|
|
end
|
|
if self.ClickCb then self.ClickCb(blockId) end
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:SetAsBlockChild(transform, blockId)
|
|
local grid = self:_GetGridParent(blockId)
|
|
if not grid then
|
|
XLog.Error("XUiPanelAreaWarMainBlockList3D:SetAsBlockChild error: grid not exist, blockId: ", blockId)
|
|
return
|
|
end
|
|
transform:SetParent(grid.transform, false)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:GetBlockWorldPoint(blockId)
|
|
local grid = self:_GetGridParent(blockId)
|
|
if not grid then
|
|
XLog.Error("XUiPanelAreaWarMainBlockList3D:GetBlockWorldPoint error: grid not exist, blockId: ", blockId)
|
|
return CsVector3.zero
|
|
end
|
|
return grid.transform.position
|
|
end
|
|
|
|
---@return UnityEngine.Vector3
|
|
function XUiPanelAreaWarMainBlockList3D:_GetGridLinePoint(blockId)
|
|
local grid = self.GridBlocks[blockId]
|
|
if not grid or XTool.UObjIsNil(grid.GameObject) then
|
|
return CsVector3.zero
|
|
end
|
|
return grid:GetLinePoint()
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:_GetLineKey(startBlockId, endBlockId)
|
|
return startBlockId * 1000 + endBlockId
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:_GetLineStartAndEndBlockId(key)
|
|
local endBlockId = key % 1000
|
|
local startBlockId = math.floor(key / 1000)
|
|
|
|
return startBlockId, endBlockId
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:_GetLineName(startBlockId, endBlockId)
|
|
return string.format("Line_%d_To_%d", startBlockId, endBlockId)
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:_GetGridParent(blockId)
|
|
local grid = self.GridBlocks[blockId]
|
|
if not grid then
|
|
return
|
|
end
|
|
return grid.Transform.parent
|
|
end
|
|
|
|
--- 根据起始点,结束点计算线的长度,位置,旋转信息
|
|
---@param startPoint UnityEngine.Vector3
|
|
---@param endPoint UnityEngine.Vector3
|
|
---@param pivot UnityEngine.Vector2
|
|
---@return UnityEngine.Vector3, UnityEngine.Quaternion, number
|
|
--------------------------
|
|
function XUiPanelAreaWarMainBlockList3D:CalculateLineWith3DUI(startPoint, endPoint, pivot)
|
|
pivot = pivot or NormalPivot
|
|
local offset = endPoint - startPoint
|
|
local width = offset.magnitude
|
|
--local height = endPoint.y - startPoint.y
|
|
local position = (startPoint + endPoint) / 2
|
|
position.x = position.x + (0.5 - pivot.x) * width
|
|
position.y = position.y + (0.5 - pivot.y)
|
|
|
|
self:SetCalVec3(offset.x, offset.y, 0)
|
|
local angleZ = CsVector3.Angle(CsVector3.right, self.CalVec3)
|
|
self:SetCalVec3(offset.x, 0, offset.z)
|
|
local angleY = CsVector3.Angle(CsVector3.left, self.CalVec3)
|
|
|
|
|
|
local xNum, yNum, zNum = offset.x >= 0 and 1 or 0, offset.y >= 0 and 1 or 0, offset.z >= 0 and 1 or 0
|
|
local key = xNum * 256 + yNum * 16 + zNum * 1
|
|
local fun = self.AngleFunc[key]
|
|
if not key then
|
|
XLog.Error("no transform function for " .. xNum, yNum, zNum)
|
|
self:SetCalVec3(0, angleY, angleZ)
|
|
return position, CsQuaternion.Euler(self.CalVec3), width
|
|
end
|
|
angleY, angleZ = fun(angleY, angleZ)
|
|
self:SetCalVec3(0, angleY, angleZ)
|
|
return position, CsQuaternion.Euler(self.CalVec3), width
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:SetCalVec3(x, y, z)
|
|
self.CalVec3.x = x
|
|
self.CalVec3.y = y
|
|
self.CalVec3.z = z
|
|
end
|
|
|
|
function XUiPanelAreaWarMainBlockList3D:InitAngle()
|
|
self.AngleFunc = {
|
|
[0x011] = function(x, y) return x, y end,
|
|
[0x110] = function(x, y) return -x, 180-y end,
|
|
[0x001] = function(x, y) return x, -y end,
|
|
[0x010] = function(x, y) return -x, y end,
|
|
[0x111] = function(x, y) return x, 180-y end,
|
|
[0x100] = function(x, y) return -x, y+180 end,
|
|
[0x101] = function(x, y) return x, y+180 end,
|
|
[0x000] = function(x, y) return -x, -y end,
|
|
}
|
|
end
|
|
|
|
return XUiPanelAreaWarMainBlockList3D |