do----------基础框架第一部分:纯Lua环境---------- --luajit changes xpcall from lua5.1 (which does not support arguments), but luajit can't run Unity5 on OSX if UNITY_EDITOR == 'OSX' or UNITY_STANDALONE == 'OSX' then local function xpcall_handler(errFunc, ret, ...) if ret then return ret, ... else local msg = ... return ret, errFunc(msg) end end local pcall = pcall xpcall = function(func, errFunc, ...) return xpcall_handler(errFunc, pcall(func, ...)) end --math.random(a,b)函数在a>b时在mac平台下会报错, --在windows里不会报错,测了下有奇怪的结果,当a-b<=1时就返回a,a-b>1时就返回(a,b)中的随机数,两边是开集 --这里简单处理成反过来,即math.random(b,a).只影响mac editor local mr = math.random math.random = function(...) local a, b = ... if a and b and b < a then return mr(b, a) end return mr(...) end end --设置gc参数,setpause 99表示一个gc循环跑完之后立即跑下一个, setstepmul 200表示以内存分配的2倍速跑gc循环 collectgarbage("setpause", 99) collectgarbage("setstepmul", 200) --设置随机数种子,使用反转来改善当种子数值变化不大时,产生的随机序列数值也相近的问题 math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,6))) --显式定义全局变量的辅助方法 function def_G(key, val) rawset(_G, key, val) end end do----------基础框架第二部分:日志和面向对象---------- --日志系统 def_G("logging", require('Main/Logging')) --日志等级 if UNITY_EDITOR then logging.setLevel(logging.LL_LOG) logging.setTraceLevel(logging.LL_LOG) else if TAI_DEVELOPMENT_BUILD then logging.setLevel(logging.LL_LOG) else logging.setLevel(logging.LL_WARN) end logging.setTraceLevel(logging.LL_ERROR) end --日志标记 def_G("LTAG", require("Main/LogTags")) --面向对象 def_G('class', require('Infrast/Class')) end do----------基础框架第三部分:解析符号定义---------- local DEF = {} rawset(_G, 'DEF', DEF) --[[ 处理预定义符号 解析以分号分隔的标记字符串,可用于代码运行时的一些特性进行控制 例如:'OPEN_XXX;ENABLE_XXX = false;IP= 192.168.0.1;VAL_XXX = -123.456;INFO_V2 =path/dir/file_name.data' 解析后结果如下: boolean DEF.OPEN_XXX = true string DEF.ENABLE_XXX = 'false' string DEF.IP = '192.168.0.1' number DEF.VAL_XXX = -123.456 string DEF.INFO_V2 = 'path/dir/file_name.data' --]] local symbolStr = AuxUtil.ReadStreamingAssetText('symbols.txt') if symbolStr and #symbolStr > 0 then for token in string.gmatch(symbolStr..';', '%s*([^;]+)%s*;') do local key, val = string.match(token, '([%w_]+)%s*=%s*([%w_%.-/]+)') if key and val then DEF[key] = tonumber(val) or val else DEF[token] = true end end end --[[ 处理命令行参数 程序启动时的命令行参数会由CommandLineArgs表传入Lua环境(仅UnityEditor和UnityStandalone模式下支持) -DEF:USE_XXX=abc -DEF:VAL_XXX=1.5 -DEF:KEY_XXX='100' 解析后结果如下: string DEF.USE_XXX = abc number DEF.VAL_XXX = 1.5 string DEF.KEY_XXX = 100 --]] if CommandLineArgs then for _, token in ipairs(CommandLineArgs) do local key, quot, val = string.match(token, "-DEF:([%w_]+)=('*)([%w_%.-/]+)('*)") if key and #key > 0 and val and #val > 0 then if quot and #quot > 0 then DEF[key] = val else DEF[key] = tonumber(val) or val end end end end --打包都会有值,Editor下是没值的 if not DEF.Package_PostType then -- DEF.Package_PostType = "mirror" DEF.Package_PostType = "dev" end if DEF.Package_PostType=="mirror" then if LuaExt.FileExists("IsSwitchMirror") then DEF.Package_PostType="mirror1" end end end do----------基础框架第四部分:设置AppInfo---------- --根据配置文件设置环境变量 if DEF.APPINFO_USE_PROD_ID then AppInfo.productId = DEF.APPINFO_USE_PROD_ID end if DEF.APPINFO_USE_PKG_VER then AppInfo.marketVersion = DEF.APPINFO_USE_PKG_VER end if DEF.APPINFO_USE_PKG_TYPE then AppInfo.packageType = DEF.APPINFO_USE_PKG_TYPE end --[[ 这个值是表示超过1024字节 以压缩方式发送协议给服务器 并且这个值会发给服务器 但是服务器不使用 可以删掉但是不能热更 先放着 服务器也写死1024这个值 服务器发送的协议超过这个值也会压缩发给客户端 --]] AppInfo.gzipSize = 1024 end def_G("GameAppInfo", require("Main/GameAppInfo")) GameAppInfo.InitGameInfo(false) local GameApp = require("Main/GameApp") GameApp.Startup() def_G("ConstAssetPathConfig", require("Common/ConstAssetPathConfig")) if GameAppInfo.IsVersionGreaterThan16000() then local opCode = 10 --部分GameSystem改为在游戏中按需启用,为编辑器等非游戏环境提供支持 --其余的GameSystem的初始化时机仍然保持在LuaEnv创建之前 AuxUtil.OperateGameSystem("ApplicationSystem", opCode) AuxUtil.OperateGameSystem("ChatSystem", opCode) if GameAppInfo.IsPCPackage() or GameAppInfo.EditorOpenGME() then AuxUtil.OperateGameSystem("GMEPCSDKSystem", opCode) end if GameAppInfo.IsVersionGreaterThan19000() then AuxUtil.OperateGameSystem("RenderEntityAppendSystem", opCode) end end ----------设置运行环境---------- --数据持久化 def_G("PersistentData", require('Tools/PersistentData')) --事件系统 local EventSystem = require('Event/EventSystem') --更新函数 local LuaUpdater = require('Main/LuaUpdater') LuaUpdater.Startup() --尝试执行一下编辑器中的辅助代码 if UNITY_EDITOR then pcall(require, 'Editor/Startup') end ----------编辑器辅助代码---------- --这个库依赖module函数和全局表直接赋值 local protobuf = require("protobuf/protobuf") --开启全局表写入限制(理想情况下,此步应该尽可能提前) if not (UNITY_EDITOR == 'OSX' or UNITY_STANDALONE == 'OSX') then --Mac平台的module函数实现似乎与其它平台不同,造成运行时报错,暂时关闭全局检查 setmetatable(_G, { __newindex = function(t, key, val) error(string.format("__newindex on _G for key %s", key), 2) end }) end --事件枚举 def_G("EventID", require("Common/EventID")) --辅助方法 require("Common/Utils") --本地化 def_G("Localization", require("Localization/Localization")) local processorType = SystemInfo.processorType local isPCProcessor = string.find(processorType, "NEON", 1, true) ~= nil or string.find(processorType, "VFPv3", 1, true) ~= nil or string.find(processorType, "x86", 1, true) ~= nil or string.find(processorType, "SSE", 1, true) ~= nil or string.find(processorType, "AVX", 1, true) ~= nil or string.find(processorType, "Intel", 1, true) ~= nil or string.find(processorType, "VMH", 1, true) ~= nil local gpu = SystemInfo.graphicsDeviceName local isPCGPU = string.find(gpu, "Mesa", 1, true) ~= nil or string.find(gpu, "AMD", 1, true) ~= nil or string.find(gpu, "Intel", 1, true) ~= nil or string.find(gpu, "NVIDIA", 1, true) ~= nil or string.find(gpu, "GeForce", 1, true) ~= nil or string.find(gpu, "Radeon", 1, true) ~= nil local isEmulatorLocal = isPCProcessor or isPCGPU if UNITY_STANDALONE == "WIN" then isEmulatorLocal = false end def_G("IsEmulator", isEmulatorLocal) AppInfo.IsEmulator = IsEmulator --大数据 def_G("BIManager", require("BI/BIManager")) --c#端的launch,游戏启动初始化一次 if LoginProxy.IsFirstLaunch then --为保证依赖资源加载之后的某些方法,不重复执行,这里增加个标识,该标识只在第一次Launch或者有资源热更重载ab的时候会重置 --某些苹果设备(iphone11)在ios16版本多次调用WarmUpShaders,会调用时间过长,甚至卡死的现象,用该标识来保证只调用一次 PersistentData.DeviceData:Set("ExecuteIfLoadedAB", false, true) if GameAppInfo.IsVersionGreaterThan119000() then AuxUtil.SetAppDataExtName("AppDataExt") end GameApp.SetIsShowSplash(true) --版本检测,覆盖安装 local VersionCodeChange = require('Main/VersionCodeChange') VersionCodeChange.OnBaseHotfixCodeChange() --初始化Bugly if not UNITY_EDITOR and GameAppInfo.IsOfficalPackage() then local baseHotfixCode = DEF.LOCAL_HOTFIX_CODE or "" local buglyAppVersion = AppInfo.marketVersion .. "_" .. baseHotfixCode if UNITY_ANDROID then local buglyAppIdAndroid if GameAppInfo.IsChinesePackage() then buglyAppIdAndroid = "fa25ceb71b" elseif GameAppInfo.IsJapanesePackage() then buglyAppIdAndroid = "f7f37eb52c" elseif GameAppInfo.IsVietnamPackage() then buglyAppIdAndroid = "37f4df680a" else buglyAppIdAndroid = "76caca58f2" end -- level字段 Android端无意义 AuxUtil.BuglyAgentInit(buglyAppIdAndroid, GameAppInfo.Global_ProductId, buglyAppVersion, false, 2) elseif UNITY_IOS then local buglyAppIdiOS if GameAppInfo.IsChinesePackage() then buglyAppIdiOS = "60aad6a3e5" elseif GameAppInfo.IsJapanesePackage() then buglyAppIdiOS = "b7e24379b2" elseif GameAppInfo.IsVietnamPackage() then buglyAppIdiOS = "63475508c6" else buglyAppIdiOS = "8de837d14a" end -- level字段 iOS端为自定义日志上报级别 Silent=0,Error=1,Warn=2,Info=3,Debug=4,Verbose = 5 AuxUtil.BuglyAgentInit(buglyAppIdiOS, GameAppInfo.Global_ProductId, buglyAppVersion, false, 2); AuxUtil.EnableBlockMonitor(true) AuxUtil.EnableUnexpectedTerminatingDetection(true) end AuxUtil.BuglyAgentSetDeviceModel(SystemInfo.deviceName.."("..SystemInfo.deviceModel..")") AuxUtil.BuglyAgentSetDeviceId(SystemInfo.deviceUniqueIdentifier) AuxUtil.BuglyAgentSetScene(-9999) AuxUtil.BuglyAgentAddSceneData("DeviceId", SystemInfo.deviceUniqueIdentifier) AuxUtil.BuglyAgentAddSceneData("CurrentHotfixCode", LoginProxy.Get_HotfixVer()) -- level Unity上报的Log等级 Debug = 1, Info = 2, Warning = 3, Assert = 4, Error = 5, Exception = 6 AuxUtil.BuglyAgentOpenUnityReport(5, false) end --初始化易盾 if DEF.USE_YIDUN_PROTECT then if UNITY_ANDROID then if GameAppInfo.Global_PackageType == "hmt" and GameAppInfo.IsVersionGreaterThan113400() then --新版本易盾修复卡死问题 AuxUtil.InitNetSecProtect("A008069280", "ac448b267d0db2e25e3b958e0518a2e3", 2) elseif GameAppInfo.Global_PackageType == "cn" then AuxUtil.InitNetSecProtect("A003910409", "25c559acc40f3ababc103b4f829e51f1", 1) elseif GameAppInfo.Global_PackageType == "jp" then -- 日本先不分版本关闭易盾功能 -- AuxUtil.InitNetSecProtect("A009786405","b546e28079653a1d45029d3802619ac7", 2); elseif GameAppInfo.Global_PackageType == "vn" then AuxUtil.InitNetSecProtect("A000471199","9b4a4c4151e593a973598cba7e68d738", 2); end elseif UNITY_IOS then if GameAppInfo.Global_PackageType == "hmt" then AuxUtil.InitNetSecProtect("I004551288", "I004551288", 2) elseif GameAppInfo.Global_PackageType == "cn" then AuxUtil.InitNetSecProtect("I009692975", "I009692975", 1) elseif GameAppInfo.Global_PackageType == "jp" then AuxUtil.InitNetSecProtect("I005080630", "I005080630", 2) elseif GameAppInfo.Global_PackageType == "vn" then AuxUtil.InitNetSecProtect("I007840892", "I007840892", 2) end end end --初始化资源池 require("Main/SetupAssetPool") --初始化游戏配置 require("Common/CommonConfig") --游戏启动初始化 LoginProxy.LaunchGame() BIManager.Init() local baseHotfixCode = DEF.LOCAL_HOTFIX_CODE or "" local versionInfo = AppInfo.marketVersion .. "_" .. baseHotfixCode.."_"..LoginProxy.Get_HotfixVer() BIManager.DispatchBIClientEvent(BIManager.EventName.GameLaunch, "version", versionInfo, "processorType", tostring(SystemInfo.processorType)) if GameAppInfo.IsVersionGreaterThan16000() then if UNITY_STANDALONE ~= "WIN" and AuxUtil.IsUnknownDeviceLOD then BIManager.DispatchBIClientEvent(BIManager.EventName.UnknownDeviceLOD) end end if UNITY_ANDROID or not string.isNilOrEmpty(SDKUtil.BDCServerBean) then BIManager.DispatchBIClientEvent(BIManager.EventName.BDC_GameLaunch) BIManager.DispatchBIClientEvent(BIManager.EventName.BDC_GameFirstPage) end LoginProxy.IsFirstLaunch = false else BIManager.Init() end --通用的模块 require("Common/CommonDefine") local VersionCodeChange = require('Main/VersionCodeChange') VersionCodeChange.TempFixOldVersionAB() --预处理包内资源,然后启动游戏逻辑 if GameAppInfo.IsVersionGreaterThan119000() then AuxUtil.TryUncompressInternal() else GameApp.OnUncompressInternalFinish() end