--- --- Generated by EmmyLua(https://github.com/EmmyLua) --- Created by PZM. --- DateTime: 2021/9/10 9:17 ---@class Misc ---@field currentUISelectedGameObject UnityEngine.GameObject ---@field isSelectInputField boolean Misc = class() local this = Misc this.spriteFrameDelta = Vector3(-22, 16, 0) this.spriteColor = Vector4(1, 1, 1, 1) this.scaleOne = Vector3.one this.rotationIdentity = Quaternion.identity this.tempDot = Dot2.zero this.tempDot2 = Dot2.zero this.tempRotation = Quaternion.identity this.tempVec3 = Vector3.zero ---@return function function this.Bind(self, callback, eventData) if not callback then return nil end return function(...) local callBackData = table.pack(...) return callback(self, eventData, callBackData) end end function this.GetSpriteLoader() if not this.spriteLoader then this.spriteLoader = CS.TCFramework.AssetLoader(nil) --CS.TCFramework.DisposeOnDestroy.Add(self.gameObject, self.spriteLoader) end return this.spriteLoader end function this.GetRawImage(path, cacheTime) if not this.spriteLoader then this.spriteLoader = CS.TCFramework.AssetLoader(nil) end this.spriteLoader:LoadRawImage(path, cacheTime or CS.TCFramework.ResourceManager.ASSET_CACHE_TIME_USE_DEFAULT) if this.spriteLoader.request then return this.spriteLoader.request.asset end end ---@alias LoadSpriteCallback fun(self: table, sprite: UnityEngine.Sprite,data:any):void ---@param callback LoadSpriteCallback ---@return void @非UI逻辑加载Res文件夹中的Sprite 同步加载 function this.LoadSprite(self, path, callback, data, cacheTime) this.GetSpriteLoader():Load(path, typeof(CS.UnityEngine.Sprite), cacheTime or CS.TCFramework.ResourceManager.ASSET_CACHE_TIME_USE_DEFAULT) if this.spriteLoader.request then callback(self, this.spriteLoader.request.asset, data) end end ---@param callback LoadSpriteCallback ---@return void @非UI逻辑加载Res文件夹中的Sprite 同步加载 function this.LoadSpriteAsync(self, path, callback, data, cacheTime) this.GetSpriteLoader():LoadAsync(path, typeof(CS.UnityEngine.Sprite), cacheTime or CS.TCFramework.ResourceManager.ASSET_CACHE_TIME_USE_DEFAULT) if this.spriteLoader.isLoading then this.spriteLoader.loadCallback = function(sprite) callback(self, sprite, data) end else callback(self, this.spriteLoader.request.asset, data) end end ---@param atlasName string @图集名称 ---@param IconName string @图片名称 ---@param arg function|UIControl @回调或者图片控件 function this.SetSprite(atlasName, iconName, arg) local atlasPath = string.format("Atlas/%s.spriteatlas", atlasName) this.GetSpriteLoader():Load(atlasPath, typeof(CS.UnityEngine.U2D.SpriteAtlas)) if this.spriteLoader.request then local spriteAtlas = this.spriteLoader.request.res local sprite = spriteAtlas:GetSprite(tostring(iconName)) if (sprite ~= nil and iconName ~= nil) then sprite.name = tostring(iconName) local typeArg = type(arg) if typeArg == "function" then ---@type function local callBack = arg callBack(sprite) elseif typeArg == "table" then if IsSubTypeOf(arg, UIControl) then ---@type UIControl local ui = arg ui:SetSprite(sprite) end end else logError(atlasName .. " 图集中没有发现 imageTable.IconName " .. iconName) end end end ---@return void @临时,后续需要整理 ---@param assetGroup TCFramework.AssetGroup function this.SetSpriteFromAtlas(assetGroup, atlasName, iconName, arg) local atlasPath = string.format("Atlas/%s.spriteatlas", atlasName) local spriteAtlas = assetGroup:LoadAsset(atlasPath, typeof(CS.UnityEngine.U2D.SpriteAtlas)) local sprite = spriteAtlas:GetSprite(tostring(iconName)) if (sprite ~= nil and iconName ~= nil) then sprite.name = tostring(iconName) local typeArg = type(arg) if typeArg == "function" then ---@type function local callBack = arg callBack(sprite) elseif typeArg == "table" then if IsSubTypeOf(arg, UIControl) then ---@type UIControl local ui = arg ui:SetSprite(sprite) end end return sprite else logError(atlasName .. " 图集中没有发现 imageTable.IconName " .. iconName) end end ---@param coord1 Dot2 ---@param coord2 Dot2 ---@return EDirection function this.GetDirectionByTarget(coord1, coord2) if coord1 == coord2 then return EDirection.None end this.tempDot:CopyFromSub(coord2, coord1) this.tempDot:SetNormalize() local max = -math.huge local dir = EDirection.None for k, v in pairs(EDirectionToDot2) do this.tempDot2:Copy(v) local dot = Dot2.Dot(this.tempDot2:SetNormalize(), this.tempDot) if dot > max then max = dot dir = k end end return dir end ---@return number @8方向或者16方向,16方向从0开始到15.顺时针依次增加 function this.GetEffectDirection(coord1, coord2, is16Dir) if not is16Dir then return this.GetDirectionByTarget(coord1, coord2) end if coord1 == coord2 then return EDirection.None end local stepAngle = is16Dir and 22.5 or 45 local up = Dot2(0, -1) local dot = coord2 - coord1 local upVec = Vector3(up.x, up.z, 0) local dotVec = Vector3(dot.x, dot.z, 0) local cross = Vector3.Cross(upVec, dotVec) local angle = Vector3.Angle(upVec, dotVec) if cross.z > 0 then angle = angle else angle = 360 - angle end local index = Mathf.Round(angle / stepAngle) return index end ---@param dir Dot2 ---@return EDirection function this.GetDirection(dir) for k, v in pairs(EDirectionToDot2) do if v == dir then return k end end return EDirection.None end ---@param dir EDirection ---@return Dot2 function this.GetDirectionDot2(dir) return EDirectionToDot2[dir] end function Misc.IsOnUI() if CS.TCFramework.DebugTool.hasInstance and not CS.TCFramework.DebugTool.instance.minimize then return true end if EventSystem.current == null then return false end if Main.isEditor then return EventSystem.current:IsPointerOverGameObject() end if Platform.name == 'Android' or Platform.name == 'iOS' then if Input.touchCount > 0 then return EventSystem.current:IsPointerOverGameObject(Input.GetTouch(0).fingerId) end return false else return EventSystem.current:IsPointerOverGameObject() end end ---@return boolean @不要在Update中一直调用 function this.IsFocusOnInputText() if ObjectEx.IsNull(EventSystem.current.currentSelectedGameObject) then this.isSelectInputField = false this.currentUISelectedGameObject = nil return this.isSelectInputField end if this.currentUISelectedGameObject == EventSystem.current.currentSelectedGameObject then return this.isSelectInputField end this.currentUISelectedGameObject = EventSystem.current.currentSelectedGameObject logError(EventSystem.current.currentSelectedGameObject.name) this.isSelectInputField = ObjectEx.IsNull(this.currentUISelectedGameObject.transform:GetComponent(typeof(CS.UnityEngine.UI.InputField))) == false return this.isSelectInputField end ---@param srcDot Dot2 ---@param pos Vector3 ---@return EDirection function this.GetDirectionByWorldPos(srcDot, pos) return this.GetDirectionByTarget(srcDot, Scene.WorldToTile(pos.x, pos.y, pos.z)) end ---@return Dot2 function Misc.GetDirectionDot2ByWorldPos(srcDot, pos) return this.GetDirectionDot2(this.GetDirectionByWorldPos(srcDot, pos)) end function this.GetEnumKey(enumTable, value) for k, v in pairs(enumTable) do if v == value then return k end end return nil end ---@param trans UnityEngine.Transform function this.SetSceneGoTrans(trans, pos, rotaion, scale) if not pos then pos = Vector3.zeroNonAlloc end if not rotaion then rotaion = EngineMgr.sceneGoRotaion end if not scale then scale = EngineMgr.modelScale end this.tempRotation:EulerNonAlloc(rotaion.x, rotaion.y, rotaion.z) local q = this.tempRotation trans:SetLocalPosAndLocalRotAndLocalScale(pos.x, pos.y, pos.z, q.x, q.y, q.z, q.w, scale.x, scale.y, scale.z) end ---@param trans UnityEngine.Transform function this.SetSceneEffectGoTrans(trans, pos) if EngineMgr.isEffect2D then if EngineMgr.engineType == EEngineType.Base then this.SetSceneGoTrans(trans, pos, RoleHeadCfg.headRotation, this.scaleOne) elseif EngineMgr.engineType == EEngineType.QJ then this.SetSceneGoTrans(trans, pos, RoleHeadCfg.headRotation, this.scaleOne) local f = -trans.forward * 50 + pos trans:SetLocalPosition(f.x, f.y, f.z) end else this.SetSceneGoTrans(trans, pos) end end --- 根据配置表id获取贴图路径 function this.GetSpritePath(cfgId) local tbl = ConfigManager.Get_cfg_item(cfgId) return tbl.looks end function this.GetSkillIconName(cfgId, level) local tbl = ConfigManager.Get_cfg_skill_info(cfgId, level) return tbl.icon ~= "" and tbl.icon or "0" end --- 转化标签文本 --- like | function this.TransSpecialText(srcString) if not string.contains(srcString, "') local retStrList = {} local retStr = "" --like {} for _, splitStr in pairs(strList) do retStr = "" if string.sub(splitStr, 1, 1) == "|" then retStr = retStr .. "\n" end -- like Text|x=25|y=20|color=250|size=18|text=施毒术使用必需品. splitStr_2 = string.gsub(splitStr, "[%<]", "") -- like {Text,x=25,y=20, color=250, size=18, text=施毒术使用必需品.} splitStr_3 = string.split(splitStr_2, "|") -- 先找到文本 for _, splitStr_4 in pairs(splitStr_3) do if string.contains(splitStr_4, "text") then -- resStr=施毒术使用必需品. retStr = retStr .. string.replace(splitStr_4, "text=", "") end end -- 在找其他 for _, splitStr_4 in pairs(splitStr_3) do if string.contains(splitStr_4, "color") then local rgbId = tonumber(string.replace(splitStr_4, "color=", "")) local a = ConfigManager.Get_cfg_color(tonumber(rgbId)) local rgbConfig = ConfigManager.Get_cfg_color(tonumber(rgbId)).color -- like 施毒术使用必需品 retStr = string.format("", rgbConfig) .. retStr retStr = retStr .. "" end end table.insert(retStrList, retStr) end return table.concat(retStrList, "") end ---@return number @获得图集播放帧率 ---@param frameInterval number @单位毫秒 function this:GetAtlasFPS(frameInterval) if frameInterval > 0 then return 1000 / frameInterval end return 10 end ---@return number @获得图集播放时间 ---@param frameInterval number @单位毫秒 ---@param frameCount number @图集的图片数量 function this:GetAtlasPlayTime(frameCount, frameInterval) return frameCount * frameInterval * 0.001 end function this.NewEventManager() return rrequire "Event/EventManagerBase" end ---@param event Event function this.DispatchValueChange(event, old, new) if not this.changeData then ---@type RoleChangeData this.changeData = {} end this.changeData.old = old this.changeData.new = new EventManager.Dispatch(event, this.changeData) end ---@param role Role function this.DispatchSelfValueChange(event, role, old, new) if role.RoleType == ERoleType.Me then if not this.changeData then ---@type RoleChangeData this.changeData = {} end this.changeData.old = old this.changeData.new = new EventManager.Dispatch(event, this.changeData) end end ---@param trans UnityEngine.Transform function this.PrintParent(trans, pre) local content = "" while trans do content = trans.name .. '=>' .. content trans = trans.parent end logError(pre .. ' ' .. content) end function this.GetTimeStamp() -- return (DateTime.ToUniversalTime() - DateTime(1970, 1, 1, 0, 0, 0, CS.System.DateTimeKind.Utc)).TotalMillisecond return UtilityLua.ToNowTimestamp() end -- 配置表中的#00ffff转成0x00ffffff function this.TransTableColorToUnityColor(color) return string.replace(color, "#", "0x")--.."ff" end -- 配置表中的#00ffff转成0x00ffffff function this.TransUnityColorToTableColor(color) return string.replace(color, "0x", "#")--.."ff" end this.leftTop = 0 this.leftButtom = 0 this.rightTop = 0 this.rightButtom = 0 this.top = 11 this.buttom = 9 ---@param coord Dot2 function this.IsRoleInView(coord) if not RoleManager.meData then return end if Dot2.DistancePow2(RoleManager.meData.OldCoord, coord) > 169 then return false end this.leftTop = (this.top) * (coord.z - (RoleManager.meData.OldCoord.z)) - (-this.buttom) * (coord.x - (RoleManager.meData.OldCoord.x - this.top)) this.leftButtom = (this.top) * (coord.z - (RoleManager.meData.OldCoord.z - this.buttom)) - (this.buttom) * (coord.x - RoleManager.meData.OldCoord.x) this.rightTop = (-this.top) * (coord.z - RoleManager.meData.OldCoord.z) - (this.top) * (coord.x - (RoleManager.meData.OldCoord.x + this.top)) this.rightButtom = (-this.top) * (coord.z - (RoleManager.meData.OldCoord.z + this.top)) - (-this.buttom) * (coord.x - (RoleManager.meData.OldCoord.x)) if ((this.leftTop > 0 and this.leftButtom > 0 and this.rightTop > 0 and this.rightButtom > 0) or (this.leftTop < 0 and this.leftButtom < 0 and this.rightTop < 0 and this.rightButtom < 0)) then return true end return false end function this:IsRoleEnterMapPointRange(x, z, range) return RoleManager.meData.NextCoord.z >= z - range and RoleManager.meData.NextCoord.z <= z + range and RoleManager.meData.NextCoord.x >= x - range and RoleManager.meData.NextCoord.x <= x + range end -- 根据颜色表中的cfgId和文本返回富文本 function this.ReturnRichTextByColorIdAndText(colorId, text) local colorCfg = ConfigManager.Get_cfg_color(colorId) local color = colorCfg.color return this.ReturnRichTextByColorAndText(color, text) end -- 根据rgb和文本返回富文本 function this.ReturnRichTextByColorAndText(color, text) return '' .. text .. "" end function this.foreachUserData(t, func) if not t or not func then return end local count = t.Length for i = 1, count do func(t[i - 1]) end end function this.GetMonsterAtlasName(path) local strs = string.split(path, '/') if strs ~= nil then return strs[#strs - 1], strs[#strs] end return nil, nil end --获取怪物血条状态 function this.GetBloodColorByStage(stage, specialBloodtab) local index = stage % (#specialBloodtab - 1) if index == 0 then index = #specialBloodtab else index = index + 1 end local hpColorId = specialBloodtab[index] local hpBgColorId if index == #specialBloodtab then hpBgColorId = specialBloodtab[2] else hpBgColorId = specialBloodtab[index + 1] end if ConfigManager.Exsit_cfg_color(hpColorId) and ConfigManager.Exsit_cfg_color(hpBgColorId) then return string.replace(ConfigManager.Get_cfg_color(hpColorId).color, '#', '0x'), string.replace(ConfigManager.Get_cfg_color(hpBgColorId).color, '#', '0x') -- return ColorUtil.TryParseHtmlStringToColor(ConfigManager.Get_cfg_color(hpColorId).color) ,ColorUtil.TryParseHtmlStringToColor(ConfigManager.Get_cfg_color(hpBgColorId).color) end return nil, nil end -- ◆如,经验大于10000,则显示为1.X万,经验大于100000000,则显示1.X亿 -- 显示2位小数 function this.GetFormatStringNumber(number) if number < 10000 then return number elseif number < 100000000 then return string.format('%.2f万', number / 10000) else return string.format('%.2f亿', number / 100000000) end end -- ◆如,经验大于10000,则显示为1.X万,经验大于100000000,则显示1.X亿 -- 显示2位小数 function this.GetFormatStringNumberWithoutPoint(number) if number < 10000 then return number elseif number < 100000000 then return string.format('%.0f万', number / 10000) else return string.format('%.0f亿', number / 100000000) end end function this.NumberToChinese(num) local chineseNum = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" } local chineseUnit = { "", "十", "百", "千", "万", "亿" } if num == 0 then return chineseNum[1] end local result = "" local unitPos = 1 local nonZero = false while num > 0 do local digit = num % 10 if digit > 0 then if unitPos == 2 then result = chineseUnit[unitPos] .. result else result = chineseNum[digit + 1] .. chineseUnit[unitPos] .. result end nonZero = true elseif (unitPos == 5 and result:sub(1, 1) ~= chineseNum[1]) or (unitPos ~= 5 and nonZero) then result = chineseNum[digit + 1] .. result nonZero = false end num = math.floor(num / 10) unitPos = unitPos + 1 end return result end local lastCollectFuncCallCountsTime = 0 local collectFuncCallCounts = {} ---@return boolean @ 用来查找死循环调用的 使用 在函数开头 if not Misc.IsCanFuncCallByLimitCount() then return end function this.IsCanFuncCallByLimitCount(tableName, funcName, limitCallTime) if Time.frameCount ~= lastCollectFuncCallCountsTime then table.clear(collectFuncCallCounts) end if not collectFuncCallCounts[tableName] then collectFuncCallCounts[tableName] = {} end if limitCallTime == nil then limitCallTime = 100 end collectFuncCallCounts[tableName][funcName] = collectFuncCallCounts[tableName][funcName] and collectFuncCallCounts[tableName][funcName] + 1 or 1 if collectFuncCallCounts[tableName][funcName] > limitCallTime then logError(tableName, funcName, ' call too much > ', limitCallTime) return false end return true end function this.GetSampleNumberString(numArg) local num = tonumber(numArg) if not num then return numArg end if num < 10000 then --5位 return num elseif num < 100000000 then --9位 return math.floor(num / 1000 + 0.5) / 10 .. "万" elseif num < 1000000000000 then --13位 return math.floor(num / 10000000 + 0.5) / 10 .. "亿" elseif num < 10000000000000000 then --17位 return math.floor(num / 100000000000 + 0.5) / 10 .. "兆" else return math.floor(num / 100000000000 + 0.5) / 10 .. "兆" end return "" end function this.GetSampleNumberString2(num) if num < 10000 then --5位 return num elseif num < 100000000 then --9位W return math.floor(num / 1000 + 0.5) / 10 .. "W" elseif num < 1000000000000 then --13位 return math.floor(num / 10000000 + 0.5) / 10 .. "Y" elseif num < 10000000000000000 then --17位 return math.floor(num / 100000000000 + 0.5) / 10 .. "Z" else return math.floor(num / 100000000000 + 0.5) / 10 .. "Z" end return "" end