整理代码

This commit is contained in:
xiekaidong 2023-04-03 10:59:13 +08:00
parent 9513c33cf6
commit e30ad1dbd0
1135 changed files with 1138892 additions and 0 deletions

8
lua/app.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bee5b0159cd785f40a74d5a225e5fc9e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
lua/app/bf.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aeccc7afe321ee046a0d31067d07f097
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
lua/app/bf/common.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2e378a528486f1d4381e29cd9aa82a27
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,583 @@
--[[
Copyright (c) 2014-2017 Chukong Technologies Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
]]
function checknumber(value, base)
return tonumber(value, base) or 0
end
function checkint(value)
return math.round(checknumber(value))
end
function checkbool(value)
return (value ~= nil and value ~= false)
end
function checktable(value)
if type(value) ~= "table" then value = {} end
return value
end
function clone(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local newObject = {}
lookup_table[object] = newObject
for key, value in pairs(object) do
newObject[_copy(key)] = _copy(value)
end
return setmetatable(newObject, getmetatable(object))
end
return _copy(object)
end
local function emptyFunction()
end
function class(classname, super)
local cls = {__cname = classname}
if super then
local superType = type(super)
assert(superType == "table",
string.format("class() - create class \"%s\" with invalid super class type \"%s\"",
classname, superType))
cls.super = super
setmetatable(cls, {__index = super})
end
cls.ctor = emptyFunction
cls.new = function(_, ...)
local instance = {}
setmetatable(instance, {__index = cls})
instance.class = cls
if instance.super then
local _constructor
_constructor = function(c, ...)
if c.super then
_constructor(c.super, ...)
end
c.ctor(instance, ...)
end
_constructor(instance.super, ...)
end
instance:ctor(...)
return instance
end
cls.create = cls.new
return cls
end
function iskindof(obj, classname)
local t = type(obj)
if t ~= "table" then return false end
local mt = getmetatable(obj)
if mt then
local __index = rawget(mt, "__index")
if type(__index) == "table" and rawget(__index, "__cname") == classname then return true end
end
if rawget(obj, "__cname") == classname then return true end
local super = obj.super
while super do
if rawget(super, "__cname") == classname then return true end
super = super.super
end
return false
end
function handler(obj, method)
return function(...)
return method(obj, ...)
end
end
function math.newrandomseed()
local ok, socket = pcall(function()
return require("socket")
end)
if ok then
math.randomseed(socket.gettime() * 1000)
else
math.randomseed(os.time())
end
math.random()
math.random()
math.random()
math.random()
end
function math.round(value)
value = checknumber(value)
return math.floor(value + 0.5)
end
function math.clamp(value, min, max)
if value < min then
return min
end
if value > max then
return max
end
return value
end
local pi_div_180 = math.pi / 180
function math.angle2radian(angle)
return angle * pi_div_180
end
function math.radian2angle(radian)
return radian * 180 / math.pi
end
function io.exists(path)
local file = io.open(path, "r")
if file then
io.close(file)
return true
end
return false
end
function io.readfile(path)
local file = io.open(path, "r")
if file then
local content = file:read("*a")
io.close(file)
return content
end
return nil
end
function io.writefile(path, content, mode)
mode = mode or "w+b"
local file = io.open(path, mode)
if file then
if file:write(content) == nil then return false end
io.close(file)
return true
else
return false
end
end
function io.pathinfo(path)
local pos = string.len(path)
local extpos = pos + 1
while pos > 0 do
local b = string.byte(path, pos)
if b == 46 then -- 46 = char "."
extpos = pos
elseif b == 47 then -- 47 = char "/"
break
end
pos = pos - 1
end
local dirname = string.sub(path, 1, pos)
local filename = string.sub(path, pos + 1)
extpos = extpos - pos
local basename = string.sub(filename, 1, extpos - 1)
local extname = string.sub(filename, extpos)
return {
dirname = dirname,
filename = filename,
basename = basename,
extname = extname
}
end
function io.filesize(path)
local size = false
local file = io.open(path, "r")
if file then
local current = file:seek()
size = file:seek("end")
file:seek("set", current)
io.close(file)
end
return size
end
function table.nums(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
function table.keys(hashtable)
local keys = {}
for k, v in pairs(hashtable) do
keys[#keys + 1] = k
end
return keys
end
function table.values(hashtable)
local values = {}
for k, v in pairs(hashtable) do
values[#values + 1] = v
end
return values
end
function table.merge(dest, src)
for k, v in pairs(src) do
dest[k] = v
end
end
function table.insertto(dest, src, begin)
begin = checkint(begin)
if begin <= 0 then
begin = #dest + 1
end
local len = #src
for i = 0, len - 1 do
dest[i + begin] = src[i + 1]
end
end
function table.indexof(array, value, begin)
for i = begin or 1, #array do
if array[i] == value then return i end
end
return false
end
function table.keyof(hashtable, value)
for k, v in pairs(hashtable) do
if v == value then return k end
end
return nil
end
function table.removebyvalue(array, value, removeall)
local c, i, max = 0, 1, #array
while i <= max do
if array[i] == value then
table.remove(array, i)
c = c + 1
i = i - 1
max = max - 1
if not removeall then break end
end
i = i + 1
end
return c
end
function table.map(t, fn)
for k, v in pairs(t) do
t[k] = fn(v, k)
end
end
function table.walk(t, fn)
for k,v in pairs(t) do
fn(v, k)
end
end
function table.filter(t, fn)
for k, v in pairs(t) do
if not fn(v, k) then t[k] = nil end
end
end
function table.unique(t, bArray)
local check = {}
local n = {}
local idx = 1
for k, v in pairs(t) do
if not check[v] then
if bArray then
n[idx] = v
idx = idx + 1
else
n[k] = v
end
check[v] = true
end
end
return n
end
function table.containValue(t, value)
for k, v in pairs(t) do
if v == value then
return true
end
end
return false
end
function table.shuffle(t)
if type(t)~="table" then
return
end
local tab = {}
local index = 1
while #t ~= 0 do
local n = math.random(1, #t)
if t[n] ~= nil then
tab[index] = t[n]
table.remove(t,n)
index = index + 1
end
end
return tab
end
---查找一个满足条件的元素
---@param t table
---@param predict fun(item):boolean
function table.find(t, predict)
for k, v in pairs(t) do
if predict(v) then
return v, k
end
end
end
---浅拷贝
---@param t table
---@return table
function table.refCopy(t)
if not t then return nil end
local copy = {}
for i,v in pairs(t) do
copy[i] = v
end
return copy
end
---将array'from' insert到to
function table.addArray(to, from)
if not to or not from then return end
for _, v in ipairs(from) do
table.insert(to, v)
end
return to
end
---将array'from' insert到to
function table.addDic(to, from)
if not to or not from then return end
for _, v in pairs(from) do
to[_] = v
end
return to
end
--tbl需要删除对象的表 func用于判断是否是需要删除的对象的函数
--func返回两个参数1、是否remove 2、是否继续
---该函数会copy一次table
function table.removeEx(tbl, func)
if tbl == nil or func == nil then
return tbl
end
local newTbl = {}
for k, v in pairs(tbl) do
local needRemove, continue = func(k, v)
if not needRemove and v then
newTbl[#newTbl + 1] = v
end
if not continue then
break
end
end
return newTbl
end
--- 反转阵列
function table.revert(tableArray)
local length = #tableArray
local half = length / 2
local temp
for i = 1, half do
temp = tableArray[i]
tableArray[i] = tableArray[length - i + 1]
tableArray[length - i + 1] = temp
end
return tableArray
end
---满足任意条件
function table.any(tbl, func)
for _, v in pairs(tbl) do
if func(v) then
return true
end
end
return false
end
--- 遍历
function table.foreach(tbl, func)
for k, v in pairs(tbl) do
func(k, v)
end
end
--- 计算每一个val的满足条件的count
function table.count(tbl, func)
local result = 0
for _, v in pairs(tbl) do
result = result + func(v)
end
return result
end
string._htmlspecialchars_set = {}
string._htmlspecialchars_set["&"] = "&amp;"
string._htmlspecialchars_set["\""] = "&quot;"
string._htmlspecialchars_set["'"] = "&#039;"
string._htmlspecialchars_set["<"] = "&lt;"
string._htmlspecialchars_set[">"] = "&gt;"
function string.htmlspecialchars(input)
for k, v in pairs(string._htmlspecialchars_set) do
input = string.gsub(input, k, v)
end
return input
end
function string.restorehtmlspecialchars(input)
for k, v in pairs(string._htmlspecialchars_set) do
input = string.gsub(input, v, k)
end
return input
end
function string.nl2br(input)
return string.gsub(input, "\n", "<br />")
end
function string.text2html(input)
input = string.gsub(input, "\t", " ")
input = string.htmlspecialchars(input)
input = string.gsub(input, " ", "&nbsp;")
input = string.nl2br(input)
return input
end
function string.split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if (delimiter=='') then return false end
local pos,arr = 0, {}
-- for each divider found
for st,sp in function() return string.find(input, delimiter, pos, true) end do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end
function string.ltrim(input)
return string.gsub(input, "^[ \t\n\r]+", "")
end
function string.rtrim(input)
return string.gsub(input, "[ \t\n\r]+$", "")
end
function string.trim(input)
input = string.gsub(input, "^[ \t\n\r]+", "")
return string.gsub(input, "[ \t\n\r]+$", "")
end
function string.ucfirst(input)
return string.upper(string.sub(input, 1, 1)) .. string.sub(input, 2)
end
local function urlencodechar(char)
return "%" .. string.format("%02X", string.byte(char))
end
function string.urlencode(input)
-- convert line endings
input = string.gsub(tostring(input), "\n", "\r\n")
-- escape all characters but alphanumeric, '.' and '-'
input = string.gsub(input, "([^%w%.%- ])", urlencodechar)
-- convert spaces to "+" symbols
return string.gsub(input, " ", "+")
end
function string.urldecode(input)
input = string.gsub (input, "+", " ")
input = string.gsub (input, "%%(%x%x)", function(h) return string.char(checknumber(h,16)) end)
input = string.gsub (input, "\r\n", "\n")
return input
end
function string.utf8len(input)
local len = string.len(input)
local left = len
local cnt = 0
local arr = {0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}
while left ~= 0 do
local tmp = string.byte(input, -left)
local i = #arr
while arr[i] do
if tmp >= arr[i] then
left = left - i
break
end
i = i - 1
end
cnt = cnt + 1
end
return cnt
end
function string.formatnumberthousands(num)
local formatted = tostring(checknumber(num))
local k
while true do
formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
if k == 0 then break end
end
return formatted
end
function string.isEmptyOrNil(str)
return not str or #str == 0
end

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 36aceca3a16f9474a9e5541202a761a6
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 84f8ba1d4c11fd341823cbc068b8a1e6
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,85 @@
---@class LuaComponent
local Component = class("Component")
function Component:ctor()
end
function Component:init()
end
function Component:getBaseObject()
return self.baseObject
end
function Component:getGameObject()
return self.baseObject:getGameObject()
end
function Component:getUIMap()
return self.baseObject:genAllChildren()
end
function Component:bind(data, fieldName, bindFunc, immediately)
self:_addOnDestroyCallback()
if not self._baseBindData then
self._baseBindData = {}
end
if not self._baseBindData[data] then
self._baseBindData[data] = {}
end
data:bind(fieldName, self, bindFunc, immediately)
table.insert(self._baseBindData[data], fieldName)
end
function Component:unBind(data, fieldName)
if self._baseBindData and self._baseBindData[data] then
for i, field in ipairs(self._baseBindData[data]) do
if field == fieldName then
data:unBind(field, self)
table.remove(self._baseBindData[data], i)
break
end
end
end
end
function Component:unBindAll()
if not self._baseBindData then
return
end
for data, fields in pairs(self._baseBindData) do
for _, field in ipairs(fields) do
data:unBind(field, self)
end
end
self._baseBindData = nil
end
function Component:isDestroyed()
return self.baseObject:isDestroyed()
end
function Component:onDestroy()
end
function Component:_init(baseObject)
self.baseObject = baseObject
if self.onDestroy ~= Component.onDestroy then -- 说明重写了onDestroy
self:_addOnDestroyCallback()
end
self:init()
end
function Component:_addOnDestroyCallback()
if self._addOnDestroyFlag then
return
end
self._addOnDestroyFlag = true
self.baseObject:addOnDestroyCallback(function()
self:unBindAll()
self:onDestroy()
end)
end
return Component

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 23d302132daaaaa40a2b7fec60cb1ad7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

29
lua/app/bf/init.lua Normal file
View File

@ -0,0 +1,29 @@
--禁用默认全局变量
-- export global variable
local __g = _G
BF = BF or {}
BF.exports = BF.exports or {}
setmetatable(BF.exports, {
__newindex = function(_, name, value)
rawset(__g, name, value)
end,
__index = function(_, name)
return rawget(__g, name)
end
})
-- disable create unexpected global variable
local function disableGlobal()
setmetatable(__g, {
__newindex = function(_, name, value)
print("new index, name is :", name)
error(string.format("USE \" BF.exports.%s = value \" INSTEAD OF SET GLOBAL VARIABLE", name), 0)
end
})
end
BF.disableGlobal = disableGlobal
disableGlobal()

7
lua/app/bf/init.lua.meta Normal file
View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 832f162f9b7af294a9ee5439141ff67b
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: aab46fb223e2b23458d2061ab393b68a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,15 @@
local StateInterface = class("StateInterface")
function StateInterface:enter(params)
end
function StateInterface:tick()
end
function StateInterface:exit()
end
function StateInterface:clear()
end
return StateInterface

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7c2a24b56b316e2459d21803b1121945
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,109 @@
local StateMachine = class("StateMachine")
function StateMachine:ctor()
self.stateMap = {}
self.active = false
self.curStateKey = nil
self.curState = nil
end
---- 获取是否active
function StateMachine:getIsActive()
return self.active
end
---- 获取当前state StateInterface
function StateMachine:getCurState()
return self.curState
end
---- 获取当前state对应的key
function StateMachine:getCurStateKey()
return self.curStateKey
end
---- 获取state
function StateMachine:getStateByKey(key)
return self.stateMap[key]
end
---- 注册一个state
function StateMachine:registerState(stateKey, state)
if self.stateMap[stateKey] then
Logger.logWarning("StateMachine registerState: state machine already have state %s", stateKey)
return
end
self.stateMap[stateKey] = state
end
---- 改变状态
function StateMachine:changeState(stateKey, params)
if not self.active then
Logger.logWarning("StateMachine changeState: state machine not active")
return
end
local newState = self.stateMap[stateKey]
if newState then
self.curState:exit()
self.curState = newState
self.curStateKey = stateKey
self.curState:enter(params)
else
Logger.logWarning("StateMachine changeState: state machine no such state %s", stateKey)
end
end
---- start状态机
function StateMachine:start(stateKey, params)
if self.active then
return
end
local newState = self.stateMap[stateKey]
if newState then
self.curState = newState
self.curState:enter(params)
self.curStateKey = stateKey
self.active = true
else
Logger.logWarning("StateMachine start: state machine no such state %s", stateKey)
end
end
---- 重新开始状态机
function StateMachine:restart(stateKey, params)
local newState = self.stateMap[stateKey]
if newState then
if self.active then
self.curState:exit()
end
self.curState = newState
self.curStateKey = stateKey
self.curState:enter(params)
self.active = true
else
Logger.logWarning("StateMachine restart: state machine no such state %s", stateKey)
end
end
---- 停止状态机
function StateMachine:stop()
if not self.active then
return
end
self.curState:exit()
self.curState = nil
self.curStateKey = nil
self.active = false
for _, state in pairs(self.stateMap) do
state:clear()
end
end
---- 每帧tick当前状态
function StateMachine:tick()
if self.active then
self.curState:tick()
end
end
return StateMachine

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b074e5dabbe91294fa6ea868939eb0b5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
lua/app/bf/unity.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b4af23ba746bfe84f81559ac6e2a628c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,574 @@
---@class BaseObject
local BaseObject = class("GameObject")
local Vector2 = BF.Vector2(0, 0)
local Vector3 = BF.Vector3(0, 0, 0)
function BaseObject:ctor()
self.components = {}
self.childList = {}
end
function BaseObject:initWithPrefab(assetPath, prefab)
self.assetPath = assetPath
self.gameObject = prefab
end
function BaseObject:initWithGameObject(gameObject)
self.gameObject = gameObject
end
function BaseObject:getAssetPath()
return self.assetPath
end
function BaseObject:setCustomData(name, value)
if self.customData == nil then
self.customData = {}
end
self.customData[name] = value
end
function BaseObject:getCustomData(name)
if self.customData == nil then
return nil
end
return self.customData[name]
end
function BaseObject:dontDestroyOnLoad()
CS.UnityEngine.GameObject.DontDestroyOnLoad(self:getGameObject())
end
function BaseObject:getGameObject()
return self.gameObject
end
function BaseObject:getTransform()
if self.transform == nil then
local gameObject = self:getGameObject()
if gameObject then
self.transform = gameObject.transform
end
end
return self.transform
end
function BaseObject:getInstanceID()
local gameObject = self:getGameObject()
if gameObject then
return gameObject:GetInstanceID()
end
return 0
end
function BaseObject:addLuaComponent(componentType, params)
local comp = self.components[componentType]
if comp == nil then
comp = require(componentType):create(params)
comp:_init(self)
self.components[componentType] = comp
end
return comp
end
function BaseObject:removeLuaComponent(componentType)
self.components[componentType] = nil
end
function BaseObject:getLuaComponent(componentType)
if self.components[componentType] == nil then
local comp = require(componentType):create()
comp:_init(self)
self.components[componentType] = comp
end
return self.components[componentType]
end
function BaseObject:addComponent(componentType)
if self.components[componentType] == nil then
local gameObject = self:getGameObject()
if gameObject then
self.components[componentType] = gameObject:AddComponent(componentType)
end
end
return self.components[componentType]
end
function BaseObject:getComponent(componentType)
if self.components[componentType] == nil then
local gameObject = self:getGameObject()
if gameObject then
local com = gameObject:BFGetComponent(componentType)
self.components[componentType] = com
end
end
return self.components[componentType]
end
function BaseObject:getAllComponents()
return self.components
end
function BaseObject:getActiveSelf()
local gameObject = self:getGameObject()
return gameObject.activeSelf
end
function BaseObject:setActive(active)
local gameObject = self:getGameObject()
if gameObject then
gameObject:SetActive(active)
end
end
function BaseObject:setName(name)
self.name = name
end
function BaseObject:getName()
return self.name or ""
end
function BaseObject:setScrollRectCellName(nameIndex)
local gameObject = self:getGameObject()
if gameObject then
gameObject.name = tostring(nameIndex)
end
end
function BaseObject:setTag(tag)
self.tag = tag
end
function BaseObject:getTag()
return self.tag
end
function BaseObject:setLayer(layer)
local trans = self:getTransform():GetComponentsInChildren(GConst.TYPEOF_UNITY_CLASS.TRANSFORM, true)
if trans then
local len = trans.Length
for i = 0, len - 1 do
trans[i].gameObject.layer = layer
end
end
end
function BaseObject:getAnchoredPosition()
local transform = self:getTransform()
return transform.anchoredPosition
end
function BaseObject:getAnchoredPositionX()
local transform = self:getTransform()
return transform.anchoredPosition.x
end
function BaseObject:getAnchoredPositionY()
local transform = self:getTransform()
return transform.anchoredPosition.y
end
function BaseObject:setAnchoredPositionX(x)
local transform = self:getTransform()
Vector2.x = x
Vector2.y = transform.anchoredPosition.y
transform.anchoredPosition = Vector2
end
function BaseObject:setAnchoredPositionY(y)
local transform = self:getTransform()
Vector2.x = transform.anchoredPosition.x
Vector2.y = y
transform.anchoredPosition = Vector2
end
function BaseObject:setAnchoredPosition(x, y)
local transform = self:getTransform()
Vector2.x = x
Vector2.y = y
transform.anchoredPosition = Vector2
end
function BaseObject:addAnchoredPosition(x, y)
local transform = self:getTransform()
local anchoredPosition = transform.anchoredPosition
Vector2.x = x + anchoredPosition.x
Vector2.y = y + anchoredPosition.y
transform.anchoredPosition = Vector2
end
function BaseObject:getRectSize()
local transform = self:getTransform()
return transform.rect
end
function BaseObject:getSizeDeltaY()
local transform = self:getTransform()
return transform.sizeDelta.y
end
function BaseObject:getSizeDeltaX()
local transform = self:getTransform()
return transform.sizeDelta.x
end
function BaseObject:setSizeDeltaX(x)
local transform = self:getTransform()
Vector2.x = x
Vector2.y = transform.sizeDelta.y
transform.sizeDelta = Vector2
end
function BaseObject:setSizeDeltaY(y)
local transform = self:getTransform()
Vector2.x = transform.sizeDelta.x
Vector2.y = y
transform.sizeDelta = Vector2
end
function BaseObject:setSizeDelta(x, y)
local transform = self:getTransform()
Vector2.x = x
Vector2.y = y
transform.sizeDelta = Vector2
end
function BaseObject:addSizeDelta(x, y)
local transform = self:getTransform()
local sizeDelta = transform.sizeDelta
Vector2.x = x + sizeDelta.x
Vector2.y = y + sizeDelta.y
transform.sizeDelta = Vector2
end
function BaseObject:setPosition(x, y, z)
local transform = self:getTransform()
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.position = Vector3
end
function BaseObject:addPosition(x, y, z)
local transform = self:getTransform()
local position = transform.position
Vector3.x = x + position.x
Vector3.y = y + position.y
Vector3.z = z + position.z
transform.position = Vector3
end
function BaseObject:getLocalPosition()
local transform = self:getTransform()
return transform.localPosition
end
function BaseObject:setLocalPosition(x, y, z)
local transform = self:getTransform()
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localPosition = Vector3
end
function BaseObject:setLocalPositionX(x)
local transform = self:getTransform()
local localPosition = transform.localPosition
Vector3.x = x
Vector3.y = localPosition.y
Vector3.z = localPosition.z
transform.localPosition = Vector3
end
function BaseObject:setLocalPositionY(y)
local transform = self:getTransform()
local localPosition = transform.localPosition
Vector3.x = localPosition.x
Vector3.y = y
Vector3.z = localPosition.z
transform.localPosition = Vector3
end
function BaseObject:setLocalPositionZ(z)
local transform = self:getTransform()
local localPosition = transform.localPosition
Vector3.x = localPosition.x
Vector3.y = localPosition.y
Vector3.z = z
transform.localPosition = Vector3
end
function BaseObject:addLocalPosition(x, y, z)
local transform = self:getTransform()
local localPosition = transform.localPosition
Vector3.x = x + localPosition.x
Vector3.y = y + localPosition.y
Vector3.z = z + localPosition.z
transform.localPosition = Vector3
end
function BaseObject:setVisible(visible, scale)
local transform = self:getTransform()
if visible then
Vector3.x = scale or 1
Vector3.y = scale or 1
Vector3.z = scale or 1
else
Vector3.x = 0
Vector3.y = 0
Vector3.z = 0
end
transform.localScale = Vector3
end
function BaseObject:setLocalScale(x, y, z)
local transform = self:getTransform()
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localScale = Vector3
end
function BaseObject:setLocalScaleX(x)
local transform = self:getTransform()
local currScale = transform.localScale
Vector3.x = x
Vector3.y = currScale.y
Vector3.z = currScale.z
transform.localScale = Vector3
end
function BaseObject:addLocalScale(x, y, z)
local transform = self:getTransform()
local localScale = transform.localScale
Vector3.x = x + localScale.x
Vector3.y = y + localScale.y
Vector3.z = z + localScale.z
transform.localScale = Vector3
end
function BaseObject:setLocalRotation(x, y, z)
local transform = self:getTransform()
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localRotation = Vector3
end
function BaseObject:setEulerAngles(x, y, z)
local transform = self:getTransform()
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.eulerAngles = Vector3
end
function BaseObject:addEulerAngles(x, y, z)
local transform = self:getTransform()
local eulerAngles = transform.eulerAngles
Vector3.x = x + eulerAngles.x
Vector3.y = y + eulerAngles.y
Vector3.z = z + eulerAngles.z
transform.eulerAngles = Vector3
end
function BaseObject:setLocalEulerAngles(x, y, z)
local transform = self:getTransform()
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localEulerAngles = Vector3
end
function BaseObject:addLocalEulerAngles(x, y, z)
local transform = self:getTransform()
local localEulerAngles = transform.localEulerAngles
Vector3.x = x + localEulerAngles.x
Vector3.y = y + localEulerAngles.y
Vector3.z = z + localEulerAngles.z
transform.localEulerAngles = Vector3
end
function BaseObject:getAdmin()
return self.admin
end
-- admin可能是parent也可能不是
function BaseObject:setAdmin(admin)
self.admin = admin
end
function BaseObject:removeAllChildren()
if self.childList then
local count = #self.childList
for i = 1, count do
local child = table.remove(self.childList)
child:setAdmin(nil)
child:destroy()
end
end
end
function BaseObject:removeChild(child)
if self.childList then
for k, v in ipairs(self.childList) do
if v == child then
table.remove(self.childList, k)
break
end
end
end
end
function BaseObject:getChildList()
return self.childList
end
function BaseObject:getFirstChild()
return self.childList[1]
end
function BaseObject:setParent(parent, worldPositionStays)
if self.admin then
self.admin:removeChild(self)
end
local transform = self:getTransform()
local parentTransform = parent and parent:getTransform() or nil
transform:SetParent(parentTransform, worldPositionStays)
if parent then
parent:addChildList(self)
else
self.admin = nil
end
end
function BaseObject:removeFromParent(isNeedCleanUp)
if isNeedCleanUp then
self:destroy()
else
if self.admin then
self.admin:removeChild(self)
self.admin = nil
end
self:getTransform():SetParent(nil, false)
end
end
function BaseObject:addChildList(child)
child:setAdmin(self)
table.insert(self.childList, child)
end
function BaseObject:addPrefab(prefab, worldPositionStays)
prefab.transform:SetParent(self:getTransform(), worldPositionStays)
end
function BaseObject:scheduleGlobal(func, inter)
local sid = SchedulerManager:scheduleGlobal(func, inter)
if self._schedulerIds == nil then
self._schedulerIds = {}
end
table.insert(self._schedulerIds, sid)
return sid
end
function BaseObject:performWithDelayGlobal(func, delay)
local sid = SchedulerManager:performWithDelayGlobal(func, delay)
if self._schedulerIds == nil then
self._schedulerIds = {}
end
table.insert(self._schedulerIds, sid)
return sid
end
function BaseObject:unscheduleGlobal(sid)
if self._schedulerIds == nil then
return
end
for k, v in ipairs(self._schedulerIds) do
if v == sid then
table.remove(self._schedulerIds, k)
break
end
end
SchedulerManager:unscheduleGlobal(sid)
end
function BaseObject:createBindTweenSequence()
local sequence = DOTweenManager:createSeqWithGameObject(self:getGameObject())
return sequence
end
function BaseObject:doScale(endValue, duration, onComplete)
DOTweenManager:doScale(self:getTransform(),endValue,duration,onComplete)
end
function BaseObject:addUnloadCallback(callback)
self._unloadCallback = callback
end
function BaseObject:addOnDestroyCallback(callback)
if not self._onDestroyCallbacks then
self._onDestroyCallbacks = {}
end
table.insert(self._onDestroyCallbacks, callback)
end
function BaseObject:clearOnDestroyCallback()
self._onDestroyCallbacks = nil
end
function BaseObject:isDestroyed()
return self._destroy
end
function BaseObject:onDestroy()
if self._destroy then
return
end
self._destroy = true
for k, child in ipairs(self.childList) do
child:onDestroy()
end
if self._schedulerIds then
for k, v in ipairs(self._schedulerIds) do
SchedulerManager:unscheduleGlobal(v)
end
self._schedulerIds = nil
end
if self._unloadCallback then
self._unloadCallback(self)
self._unloadCallback = nil
end
if self._onDestroyCallbacks then
for _, callback in ipairs(self._onDestroyCallbacks) do
callback(self)
end
self._onDestroyCallbacks = nil
end
self.childList = nil
for k, v in pairs(self.components) do
self.components[k] = nil
end
self.admin = nil
self.gameObject = nil
self.transform = nil
end
function BaseObject:destroy()
if self._destroy then
return
end
if self.admin then
self.admin:removeChild(self)
end
local gameObject = self.gameObject
if gameObject and not CS.BF.Utils.IsNull(gameObject) then
ResourceManager:destroyPrefab(gameObject)
end
self:onDestroy()
end
return BaseObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c999a15d1097bf142a16255bc00cf2b2
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,498 @@
local CharacterFSMManager = require "app/module/character_fsm/character_fsm_manager"
local BaseObject = require "app/bf/unity/base_object"
local CharacterObject = class("CharacterObject", BaseObject)
local BF_CHARACTER_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_CHARACTER_HELPER
local ANIMATOR = GConst.TYPEOF_UNITY_CLASS.ANIMATOR
local ANIMATION_FRAME_PER_SECOND = 30
local SUPPORT_SHADER = {
["BF/Models/Character Battle"] = true,
}
local hash = GFunc.hash
local HashName = {}
local function getHashName(str)
local intName = HashName[str]
if intName == nil then
intName = hash(str)
HashName[str] = intName
end
return intName
end
local CHILDMAP_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local v = rawget(t, hash(k))
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
local Vector3 = BF.Vector3(0, 0, 0)
local abs = math.abs
function CharacterObject:ctor()
self.timeScale = 1
end
function CharacterObject:initWithPrefab(assetPath, prefab, modelId)
BaseObject.initWithPrefab(self, assetPath, prefab)
self.characterHelper = self:getComponent(BF_CHARACTER_HELPER)
if self.characterHelper == nil then
self.characterHelper = self:addComponent(BF_CHARACTER_HELPER)
end
self.mainModel = self.characterHelper:GetModelObject()
self.objectIndex = -1
self.modelId = modelId
self:_genAllBones()
end
function CharacterObject:initWithCharacterHelper(characterHelper, index, gameObject, name, admin)
self.characterHelper = characterHelper
self.objectIndex = index
self.gameObject = gameObject
self.name = name
self.admin = admin
end
function CharacterObject:_genAllBones()
local childMap = {}
if self.characterHelper then
local childNum = self.characterHelper:GetListCount()
for i = 0, childNum do
local gameObject = self.characterHelper:GetGameObjectByIndex(i)
local hashName = self.characterHelper:GetHashNameByIndex(i)
local child = CharacterObject:create()
child:initWithCharacterHelper(self.characterHelper, i, gameObject, hashName, self)
if childMap[hashName] == nil then
childMap[hashName] = child
end
table.insert(self.childList, child)
end
end
setmetatable(childMap, CHILDMAP_METATABLE)
self.childMap = childMap
end
function CharacterObject:getBoneByName(name)
return self.childMap[name]
end
function CharacterObject:fastGetPosition()
if self.characterHelper then
self.characterHelper:CachePosition(self.objectIndex)
return self.characterHelper.PositionX, self.characterHelper.PositionY, self.characterHelper.PositionZ
else
local position = self:getTransform().position
return position.x, position.y, position.z
end
end
function CharacterObject:getBonePositionByName(name)
return self.childMap[name]:fastGetPosition()
end
function CharacterObject:getHashCode()
local code = -1
if self.characterHelper then
code = self.characterHelper:GetModelHashCode()
end
return code
end
function CharacterObject:play(name, layer, normalizedTime)
layer = layer or -1
normalizedTime = normalizedTime or 0
if self.weaponObj and not self.weaponObj:isDestroyed() then
if self.weaponAniName then
-- local weaponAniName = self:getWeaponSpecialAni(name, self.weaponAniName, true)
-- if self.weaponObj:getStateTime(weaponAniName) > 0 then
-- self.weaponObj:play(weaponAniName, layer, normalizedTime)
-- end
local newName = self:getWeaponSpecialAni(name, self.weaponAniName) or name
if self:getStateTime(newName) > 0 then
name = newName
end
end
else
self:setWeaponInfo()
end
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:Play(name, layer, normalizedTime)
end
else
self.mainAnimator:Play(name, layer, normalizedTime)
end
end
function CharacterObject:playHashName(hashName, layer, normalizedTime)
layer = layer or -1
normalizedTime = normalizedTime or 0
if self.weaponObj and not self.weaponObj:isDestroyed() then
if self.weaponAniName then
-- local weaponHashName = self:getWeaponSpecialAniHash(hashName, self.weaponAniName, true)
-- if self.weaponObj:getStateTimeHash(weaponHashName) > 0 then
-- self.weaponObj:playHashName(weaponHashName, layer, normalizedTime)
-- end
local newHashName = self:getWeaponSpecialAniHash(hashName, self.weaponAniName, true) or hashName
if self:getStateTimeHash(newHashName) > 0 then
hashName = newHashName
end
end
else
self:setWeaponInfo()
end
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:Play(hashName, layer, normalizedTime)
end
else
self.mainAnimator:Play(hashName, layer, normalizedTime)
end
end
function CharacterObject:getWeaponSpecialAni(name, specialAniName, isWeapon)
if not self.weaponSpecialAniMap then
self.weaponSpecialAniMap = {}
end
if not self.weaponSpecialAniMap[name] then
self.weaponSpecialAniMap[name] = {}
end
if not self.weaponSpecialAniMap[name][specialAniName] then
self.weaponSpecialAniMap[name][specialAniName] = {}
end
if not isWeapon then
if not self.weaponSpecialAniMap[name][specialAniName].heroAniName then
self.weaponSpecialAniMap[name][specialAniName].heroAniName = name .. "_" .. specialAniName
end
return self.weaponSpecialAniMap[name][specialAniName].heroAniName
else
if not self.weaponSpecialAniMap[name][specialAniName].weaponAniName and self.modelId then
self.weaponSpecialAniMap[name][specialAniName].weaponAniName = self.modelId .. "_" .. name .. "_" .. specialAniName
end
return self.weaponSpecialAniMap[name][specialAniName].weaponAniName
end
end
function CharacterObject:getWeaponSpecialAniHash(hashName, specialAniName, isWeapon)
if not self.weaponSpecialAniHashMap then
self.weaponSpecialAniHashMap = {}
end
if not self.weaponSpecialAniHashMap[hashName] then
self.weaponSpecialAniHashMap[hashName] = {}
end
if not self.weaponSpecialAniHashMap[hashName][specialAniName] then
self.weaponSpecialAniHashMap[hashName][specialAniName] = {}
end
if not isWeapon then
if not self.weaponSpecialAniHashMap[hashName][specialAniName].heroAniName then
local name = GConst.HeroConst.HERO_ANI_HASH_MAP[hashName]
if name then
self.weaponSpecialAniHashMap[hashName][specialAniName].heroAniName = CS.UnityEngine.Animator.StringToHash(name .. "_" .. specialAniName)
end
end
return self.weaponSpecialAniHashMap[hashName][specialAniName].heroAniName
else
if not self.weaponSpecialAniHashMap[hashName][specialAniName].weaponAniName and self.modelId then
local name = GConst.HeroConst.HERO_ANI_HASH_MAP[hashName]
if name then
self.weaponSpecialAniHashMap[hashName][specialAniName].weaponAniName = CS.UnityEngine.Animator.StringToHash(self.modelId .. "_" .. name .. "_" .. specialAniName)
end
end
return self.weaponSpecialAniHashMap[hashName][specialAniName].weaponAniName
end
end
function CharacterObject:setWeaponInfo(weaponAniName, weaponObj)
if not weaponObj then
self.weaponAniName = nil
self.weaponObj = nil
end
self.weaponAniName = weaponAniName
self.weaponObj = weaponObj
end
function CharacterObject:setAnimatorBool(key, value)
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:SetBool(key, value)
end
else
self.mainAnimator:SetBool(key, value)
end
end
function CharacterObject:getMainAnimator()
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
end
end
return self.mainAnimator
end
function CharacterObject:getMainModelTransform()
if self.mainModelTransform == nil then
self.mainModelTransform = self.mainModel and self.mainModel.transform or nil
end
return self.mainModelTransform
end
function CharacterObject:getMainModel()
return self.mainModel
end
function CharacterObject:getCurrentAnimationHash()
return CS.BF.Utils.GetCurrentAnimationHash(self:getMainAnimator())
end
function CharacterObject:setMainModelLocalScale(x, y, z)
local transform = self:getMainModelTransform()
if transform then
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localScale = Vector3
end
end
function CharacterObject:setMainModelLocalPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetMainModelLocalPosition(x, y, z)
else
local transform = self:getMainModelTransform()
if transform then
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localPosition = Vector3
end
end
end
function CharacterObject:getStateTime(name)
local hashName = getHashName(name)
return self.characterHelper:GetStateTime(hashName)
end
function CharacterObject:getStateTimeHash(hashName)
return self.characterHelper:GetStateTime(hashName)
end
function CharacterObject:getStateKeyTime(name, index)
local hashName = getHashName(name)
local keyTime = self.characterHelper:GetStateKeyFrame(hashName, index) or 0
return keyTime/ANIMATION_FRAME_PER_SECOND
end
function CharacterObject:containsState(name)
return self:getStateTime(name) > 0.00001
end
function CharacterObject:setTimeScale(timeScale)
if abs(self.timeScale - timeScale) < 0.00001 then
return
end
self.timeScale = timeScale
local mainAnimator = self:getMainAnimator()
mainAnimator.speed = timeScale*(self.timeScaleAddition or 1)
end
function CharacterObject:setTimeScaleAddition(addition)
self.timeScaleAddition = addition
local timeScale = self.timeScale*addition
local mainAnimator = self:getMainAnimator()
mainAnimator.speed = timeScale
end
function CharacterObject:setCullingMode(cullingMode)
local mainAnimator = self:getMainAnimator()
if mainAnimator then
mainAnimator.cullingMode = cullingMode
end
end
function CharacterObject:getCharacterMaterials()
if not self.characterMaterials then
self.characterMaterials = {}
for k, prefabObj in pairs(self.childMap) do
local render = prefabObj:getComponent(GConst.TYPEOF_UNITY_CLASS.SKINNED_MESH_RENDERER)
if not CS.BF.Utils.IsNull(render) and not CS.BF.Utils.IsNull(render.material) and SUPPORT_SHADER[render.material.shader.name] then
table.insert(self.characterMaterials, render.material)
end
end
end
return self.characterMaterials
end
function CharacterObject:getCharacterMeshRenderer()
if not self.characterMeshRenders then
self.characterMeshRenders = {}
for k, prefabObj in pairs(self.childMap) do
local render = prefabObj:getComponent(GConst.TYPEOF_UNITY_CLASS.SKINNED_MESH_RENDERER)
if not CS.BF.Utils.IsNull(render) and not CS.BF.Utils.IsNull(render.material) and SUPPORT_SHADER[render.material.shader.name] then
table.insert(self.characterMeshRenders, render)
end
end
end
return self.characterMeshRenders
end
function CharacterObject:getMaterialPropertyBlock()
if not self.mpb then
self.mpb = CS.UnityEngine.MaterialPropertyBlock()
end
return self.mpb
end
function CharacterObject:setCustomShadowEnable(enabled)
local materials = self:getCharacterMaterials()
for _, material in ipairs(materials) do
material:SetShaderPassEnabled("Always", enabled)
end
end
function CharacterObject:setCharacterFSM(fsm)
self.fsm = fsm
end
---- 默认
function CharacterObject:setDefault()
if self.fsm:getCurStateKey() == CharacterFSMManager.STATE_TYPE.DEFAULT then
return
end
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.DEFAULT)
end
---- 石化
function CharacterObject:setStone(callback)
if self.fsm:getCurStateKey() == CharacterFSMManager.STATE_TYPE.STONE then
return
end
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.STONE, {callback = callback})
end
---- 石化效果2
function CharacterObject:setStone2(callback)
if self.fsm:getCurStateKey() == CharacterFSMManager.STATE_TYPE.STONE_2 then
return
end
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.STONE_2, {callback = callback})
end
---- 冰化
function CharacterObject:setIce()
if self.fsm:getCurStateKey() == CharacterFSMManager.STATE_TYPE.ICE then
return
end
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.ICE)
end
---- 闪红
function CharacterObject:setGlow(time, callback)
local state = self.fsm:getCurStateKey()
if state == CharacterFSMManager.STATE_TYPE.DISSOLVE or state == CharacterFSMManager.STATE_TYPE.GLOW then
return
end
if state == CharacterFSMManager.STATE_TYPE.ICE then
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.DEFAULT)
end
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.GLOW, {time = time or 0.7, callback = function()
if callback then
callback()
end
self.fsm:changeState(state)
end})
end
---- 消融
function CharacterObject:setDissolve(time, callback, needCallback)
self.fsm:changeState(CharacterFSMManager.STATE_TYPE.DISSOLVE, {time = time,
callback = callback,
needCallback = needCallback})
end
function CharacterObject:setShadowColor(color)
local renderers = self:getCharacterMeshRenderer()
local mpBlock = self:getMaterialPropertyBlock()
for i, renderer in ipairs(renderers) do
renderer:GetPropertyBlock(mpBlock)
mpBlock:SetColor("_shadow_color", color)
renderer:SetPropertyBlock(mpBlock)
end
end
function CharacterObject:setLocalEulerAngles(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function CharacterObject:setLocalPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalPosition(self.objectIndex, x, y, z)
else
BaseObject.setLocalPosition(self, x, y, z)
end
end
function CharacterObject:setPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetPosition(self.objectIndex, x, y, z)
else
BaseObject.setPosition(self, x, y, z)
end
end
function CharacterObject:setLocalScale(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalScale(self.objectIndex, x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function CharacterObject:onDestroy()
if self.fsm then
CharacterFSMManager:stopFSM(self.fsm)
self.fsm = nil
end
BaseObject.onDestroy(self)
self.characterHelper = nil
self.mainModel = nil
self.mainAnimator = nil
self.childMap = nil
self.characterMaterials = nil
self.characterMeshRenders = nil
self.mpb = nil
end
return CharacterObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ca211280dfcb404458954cb27e84cfd8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,232 @@
local BaseObject = require "app/bf/unity/base_object"
local CharacterSpineObject = class("CharacterSpineObject", BaseObject)
local BF_CHARACTER_SPINE_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_CHARACTER_SPINE_HELPER
local hash = GFunc.hash
local CHILDMAP_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local v = rawget(t, hash(k))
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
function CharacterSpineObject:ctor()
end
function CharacterSpineObject:getCharacterSpineHelper()
return self.characterSpineHelper
end
function CharacterSpineObject:initWithPrefab(assetPath, prefab)
BaseObject.initWithPrefab(self, assetPath, prefab)
self.characterSpineHelper = self:getComponent(BF_CHARACTER_SPINE_HELPER)
if self.characterSpineHelper == nil then
self.characterSpineHelper = self:addComponent(BF_CHARACTER_SPINE_HELPER)
end
self.mainSpine = self.characterSpineHelper:GetSpineObject()
self.objectIndex = -1
self:_genAllChildren()
end
function CharacterSpineObject:initWithCharacterHelper(characterSpineHelper, index, gameObject, name, admin)
self.characterSpineHelper = characterSpineHelper
self.objectIndex = index
self.gameObject = gameObject
self.name = name
self.admin = admin
end
function CharacterSpineObject:refreshSkeletonDataAsset(dataAsset)
local skeletonAnimation = self:getSkeletonAnimation()
skeletonAnimation.skeletonDataAsset = dataAsset
skeletonAnimation:Initialize(true)
self.characterSpineHelper:Reload()
end
function CharacterSpineObject:_genAllChildren()
local childMap = {}
if self.characterSpineHelper then
local childNum = self.characterSpineHelper:GetListCount()
for i = 0, childNum do
local gameObject = self.characterSpineHelper:GetGameObjectByIndex(i)
local hashName = self.characterSpineHelper:GetHashNameByIndex(i)
local child = CharacterSpineObject:create()
child:initWithCharacterHelper(self.characterSpineHelper, i, gameObject, hashName, self)
if childMap[hashName] == nil then
childMap[hashName] = child
end
table.insert(self.childList, child)
end
end
setmetatable(childMap, CHILDMAP_METATABLE)
self.childMap = childMap
end
function CharacterSpineObject:getChildByName(name)
return self.childMap[name]
end
function CharacterSpineObject:getMainSpine()
return self.mainSpine
end
function CharacterSpineObject:fastGetBonePosition(name)
if self.characterSpineHelper then
self.characterSpineHelper:CacheBonePosition(name)
return self.characterSpineHelper.PositionX, self.characterSpineHelper.PositionY, self.characterSpineHelper.PositionZ
end
end
function CharacterSpineObject:fastGetPosition()
if self.characterSpineHelper then
self.characterSpineHelper:CachePosition(self.objectIndex)
return self.characterSpineHelper.PositionX, self.characterSpineHelper.PositionY, self.characterSpineHelper.PositionZ
else
local position = self:getTransform().position
return position.x, position.y, position.z
end
end
function CharacterSpineObject:setPosition(x, y, z)
if self.characterSpineHelper then
self.characterSpineHelper:SetPosition(self.objectIndex, x, y, z)
else
BaseObject.SetPosition(self, x, y, z)
end
end
function CharacterSpineObject:setEulerAngles(x, y, z)
if self.characterSpineHelper then
self.characterSpineHelper:SetEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setEulerAngles(self, x, y, z)
end
end
function CharacterSpineObject:setLocalEulerAngles(x, y, z)
if self.characterSpineHelper then
self.characterSpineHelper:SetLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function CharacterSpineObject:setLocalScale(x, y, z)
if self.characterSpineHelper then
self.characterSpineHelper:SetLocalScale(self.objectIndex, x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function CharacterSpineObject:setLocalScaleX(x)
if self.characterSpineHelper then
self.characterSpineHelper:SetLocalScaleX(self.objectIndex, x)
else
BaseObject.setLocalScaleX(self, x)
end
end
function CharacterSpineObject:playAnimation(animName, loop, forceRefresh)
if self.characterSpineHelper then
self.characterSpineHelper:PlayAnimation(animName, loop, forceRefresh)
end
end
-- 战斗里面粒子特效和spine特效混用统一调用的stop接口这里先放一个空方法
function CharacterSpineObject:stop()
end
function CharacterSpineObject:setTimeScale(timeScale)
self.timeScale = timeScale
if self.characterSpineHelper then
if self.localTimeScale then
self.characterSpineHelper:SetAnimationSpeed(self.timeScale*self.localTimeScale)
else
self.characterSpineHelper:SetAnimationSpeed(self.timeScale)
end
end
end
function CharacterSpineObject:setLocalTimeScale(localTimeScale)
self.localTimeScale = localTimeScale
self:setTimeScale(self.timeScale or 1)
end
function CharacterSpineObject:setLoop(isLoop)
if self.characterSpineHelper then
self.characterSpineHelper:SetLoop(isLoop)
end
end
function CharacterSpineObject:getAnimationDuration(animationName)
if self.characterSpineHelper then
return self.characterSpineHelper:GetAnimationDuration(animationName)
end
return 0
end
function CharacterSpineObject:addAnimationCompleteCallback(callback)
if self._animationStateCompleteCallback then
return
end
self._animationStateCompleteCallback = function(entry)
callback(entry.Animation.Name)
end
local state = self:getAnimationState()
state:Complete("+", self._animationStateCompleteCallback)
end
function CharacterSpineObject:removeAnimationCompleteCallback()
if self._animationStateCompleteCallback then
local state = self:getAnimationState()
state:Complete("-", self._animationStateCompleteCallback)
self._animationStateCompleteCallback = nil
end
end
function CharacterSpineObject:getSkeletonAnimation()
if self.skeletonAnimation == nil then
self.skeletonAnimation = self.characterSpineHelper:GetSkeletonAnimation()
end
return self.skeletonAnimation
end
function CharacterSpineObject:setSortingOrder(order)
if self.mainSpineMeshRenderer == nil then
self.mainSpineMeshRenderer = self.mainSpine:BFGetComponent(GConst.TYPEOF_UNITY_CLASS.MESH_RENDERER)
end
self.mainSpineMeshRenderer.sortingOrder = order
end
function CharacterSpineObject:getInstanceID()
if self.characterSpineHelper then
return self.characterSpineHelper:GetInstanceID(self.objectIndex)
end
return BaseObject.getInstanceID(self)
end
function CharacterSpineObject:setBattleScheduleId(id)
self.battleScheduleId = id
end
function CharacterSpineObject:getBattleScheduleId()
return self.battleScheduleId
end
function CharacterSpineObject:onDestroy()
self:removeAnimationCompleteCallback()
BaseObject.onDestroy(self)
self.skeletonAnimation = nil
self.animationState = nil
end
return CharacterSpineObject

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: bf2cec33a8ee9894880903595af32a39
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

View File

@ -0,0 +1,224 @@
local BaseObject = require "app/bf/unity/base_object"
local EffectObject = class("EffectObject", BaseObject)
local BF_EFFECT_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_EFFECT_HELPER
local abs = math.abs
local DEFAULT_DELAY_TIME = 1
function EffectObject:ctor()
self.timeScale = 1
end
function EffectObject:initWithPrefab(assetPath, prefab)
BaseObject.initWithPrefab(self, assetPath, prefab)
self.effectHelper = self:getComponent(BF_EFFECT_HELPER)
if self.effectHelper == nil then
self.effectHelper = self:addComponent(BF_EFFECT_HELPER)
end
local animatorCount = self.effectHelper.AnimatorCount or 0
if animatorCount > 0 then
self.animators = {}
local animators = prefab:GetComponentsInChildren(GConst.TYPEOF_UNITY_CLASS.ANIMATOR, true)
if animators then
local len = animators.Length
for i = 0, len - 1 do
table.insert(self.animators, animators[i])
end
end
end
end
function EffectObject:play()
self.effectHelper:Play()
end
-- 延迟播放
function EffectObject:playDelay(delayTime, hideBeforePlay)
if delayTime <= 0 then
self:play()
return
end
if self._effectPlayScheduleId then
self:unscheduleGlobal(self._effectPlayScheduleId)
end
if hideBeforePlay then
self:setActive(false)
end
self._effectPlayScheduleId = self:performWithDelayGlobal(function()
self._effectPlayScheduleId = nil
if hideBeforePlay then
self:setActive(true)
end
self:play()
end, delayTime)
return self._effectPlayScheduleId
end
function EffectObject:clear()
if self._effectPlayScheduleId then
self:unscheduleGlobal(self._effectPlayScheduleId)
self._effectPlayScheduleId = nil
end
self.effectHelper:Clear()
end
function EffectObject:stop()
if self._effectPlayScheduleId then
self:unscheduleGlobal(self._effectPlayScheduleId)
self._effectPlayScheduleId = nil
end
self.effectHelper:Stop()
end
function EffectObject:stopAndClear()
if self._effectPlayScheduleId then
self:unscheduleGlobal(self._effectPlayScheduleId)
self._effectPlayScheduleId = nil
end
self.effectHelper:StopAndClear()
end
function EffectObject:pause()
if self._effectPlayScheduleId then
self:unscheduleGlobal(self._effectPlayScheduleId)
self._effectPlayScheduleId = nil
end
self.effectHelper:Pause()
end
function EffectObject:setUIOrder(uiOrder)
self.effectHelper:SetUIOrder(uiOrder)
end
function EffectObject:setSortingOrder(uiOrder, order)
self.effectHelper:SetSortingOrder(uiOrder, order)
end
function EffectObject:changeSortingOrderToFudge(order, coefficient)
self.effectHelper:ChangeSortingOrderToFudge(order, coefficient)
end
function EffectObject:initParticleSystemRendererList()
self.effectHelper:InitParticleSystemRendererList()
end
function EffectObject:getDuration()
return self.effectHelper.EffectDuration
end
function EffectObject:setTimeScale(timeScale)
if abs(self.timeScale - timeScale) < 0.00001 then
return
end
self.timeScale = timeScale
self.effectHelper:SetTimeScale(timeScale)
if self.animators then
for k, v in ipairs(self.animators) do
v.speed = timeScale
end
end
end
function EffectObject:setIsLoop(isLoop)
self.isLoop = isLoop
end
function EffectObject:getIsLoop()
return self.isLoop
end
function EffectObject:performDurationDelay(callback, diffDuration)
if self.scheduleId then
self:unscheduleGlobal(self.scheduleId)
end
local duration = self.effectHelper.EffectDuration
if duration <= 0 then
duration = DEFAULT_DELAY_TIME
end
duration = duration + (diffDuration or 0)
duration = math.max(duration, 0)
self.scheduleId = self:performWithDelayGlobal(function()
self.scheduleId = nil
callback()
end, duration)
return self.scheduleId
end
function EffectObject:setEulerAngles(x, y, z)
if self.effectHelper then
self.effectHelper:SetEulerAngles(x, y, z)
else
BaseObject.setEulerAngles(self, x, y, z)
end
end
function EffectObject:setLocalEulerAngles(x, y, z)
if self.effectHelper then
self.effectHelper:SetLocalEulerAngles(x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function EffectObject:setLocalPosition(x, y, z)
if self.effectHelper then
self.effectHelper:SetLocalPosition(x, y, z)
else
BaseObject.setLocalPosition(self, x, y, z)
end
end
function EffectObject:setPosition(x, y, z)
if self.effectHelper then
self.effectHelper:SetPosition(x, y, z)
else
BaseObject.setPosition(self, x, y, z)
end
end
function EffectObject:setLocalScale(x, y, z)
if self.effectHelper then
self.effectHelper:SetLocalScale(x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function EffectObject:getIsEulerAnglesFlip()
if self.effectHelper then
return self.effectHelper.EulerAnglesFlip
end
return false
end
function EffectObject:setBattleScheduleId(id)
self.battleScheduleId = id
end
function EffectObject:getBattleScheduleId()
return self.battleScheduleId
end
function EffectObject:onDestroy()
if self.scheduleId then
self:unscheduleGlobal(self.scheduleId)
self.scheduleId = nil
end
if self._effectPlayScheduleId then
self:unscheduleGlobal(self._effectPlayScheduleId)
self._effectPlayScheduleId = nil
end
BaseObject.onDestroy(self)
self.effectHelper = nil
self.animators = nil
end
return EffectObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d83384436f7b68045a7cfd3ce6aec70a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,77 @@
local BaseObject = require "app/bf/unity/base_object"
local MeshSpineObject = class("SpineObject", BaseObject)
function MeshSpineObject:ctor()
end
function MeshSpineObject:initSkeletonDataAsset(dataAsset)
local skeletonAnimation = self:getSkeletonAnimation()
skeletonAnimation.skeletonDataAsset = dataAsset
skeletonAnimation:Initialize(false)
end
function MeshSpineObject:getSkeletonAnimation()
if not self.skeletonAnimation then
self.skeletonAnimation = self:getComponent(GConst.TYPEOF_UNITY_CLASS.SKELETON_ANIMATION)
end
return self.skeletonAnimation
end
function MeshSpineObject:getAnimationState()
self:getSkeletonAnimation()
if not self.animationState then
self.animationState = self.skeletonAnimation.AnimationState
end
return self.animationState
end
function MeshSpineObject:playAnim(animName, loop, forceRefresh)
self:getAnimationState()
if self.animationState then
local trackEntry = self.animationState:SetAnimation(0, animName, loop)
if forceRefresh then
self.skeletonAnimation:Update(0)
end
return trackEntry
end
end
function MeshSpineObject:setTimeScale(timeScale)
if self.skeletonAnimation then
self.skeletonAnimation.timeScale = timeScale
end
end
function MeshSpineObject:setIsLoop(isLoop)
if self.skeletonAnimation then
self.skeletonAnimation.loop = isLoop
end
end
function MeshSpineObject:addAnimationCompleteCallback(callback)
if self._animationStateCompleteCallback then
return
end
self._animationStateCompleteCallback = function(entry)
callback(entry.Animation.Name)
end
local state = self:getAnimationState()
state:Complete("+", self._animationStateCompleteCallback)
end
function MeshSpineObject:removeAnimationCompleteCallback()
if self._animationStateCompleteCallback then
local state = self:getAnimationState()
state:Complete("-", self._animationStateCompleteCallback)
self._animationStateCompleteCallback = nil
end
end
function MeshSpineObject:onDestroy()
self:removeAnimationCompleteCallback()
BaseObject.onDestroy(self)
self.skeletonAnimation = nil
self.animationState = nil
end
return MeshSpineObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 55e4917dee9f5d34582e422d8b28267d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,157 @@
local CharacterObject = require "app/bf/unity/character_object"
local EffectObject = require "app/bf/unity/effect_object"
local BaseObject = require "app/bf/unity/base_object"
local ModelObject = class("ModelObject", BaseObject)
local BF_NODE_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_NODE_HELPER
local hash = GFunc.hash
local CHILDMAP_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local v = rawget(t, hash(k))
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
local function _createModelChildObject(self, index, gameObject)
local child = ModelObject:create()
child:initWithModelHelper(self.modelHelper, index, gameObject)
return child
end
local function _createCharacterChildObject(self, index, gameObject)
local child = CharacterObject:create()
child:initWithPrefab(nil, gameObject)
return child
end
local function _createEffectChildObject(self, index, gameObject)
local child = EffectObject:create()
child:initWithPrefab(nil, gameObject)
return child
end
ModelObject.createChildObject = {
[GConst.GAME_OBJECT_TYPE.CHARACTER_OBJECT] = _createCharacterChildObject,
[GConst.GAME_OBJECT_TYPE.EFFECT_OBJECT] = _createEffectChildObject,
}
function ModelObject:initWithPrefab(assetPath, prefab)
BaseObject.initWithPrefab(self, assetPath, prefab)
self.modelHelper = self:getComponent(BF_NODE_HELPER)
if self.modelHelper == nil then
self.modelHelper = self:addComponent(BF_NODE_HELPER)
end
self.objectIndex = -1
self:_genAllChildren()
end
function ModelObject:initWithModelHelper(modelHelper, index, gameObject, name, admin)
self.modelHelper = modelHelper
self.objectIndex = index
self.gameObject = gameObject
self.name = name
self.admin = admin
end
function ModelObject:_genAllChildren()
local childMap = {}
if self.modelHelper then
local childNum = self.modelHelper:GetListCount()
for i = 0, childNum do
local gameObject = self.modelHelper:GetGameObjectByIndex(i)
local hashName = self.modelHelper:GetHashNameByIndex(i)
local objectType = self.modelHelper:GetObjectTypeByIndex(i)
local func = self.createChildObject[objectType] or _createModelChildObject
local child = func(self, i, gameObject)
child:setName(hashName)
child:setAdmin(self)
if childMap[hashName] == nil then
childMap[hashName] = child
end
table.insert(self.childList, child)
end
end
setmetatable(childMap, CHILDMAP_METATABLE)
self.childMap = childMap
end
function ModelObject:getChildByName(name)
return self.childMap[name]
end
function ModelObject:setLocalEulerAngles(x, y, z)
if self.modelHelper then
self.modelHelper:SetLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function ModelObject:fastGetLocalEulerAngles()
if self.modelHelper then
self.modelHelper:CacheLocalEulerAngles(self.objectIndex)
return self.modelHelper.PositionX, self.modelHelper.PositionY, self.modelHelper.PositionZ
else
local localEulerAngles = self:getTransform().localEulerAngles
return localEulerAngles.x, localEulerAngles.y, localEulerAngles.z
end
end
function ModelObject:setLocalPosition(x, y, z)
if self.modelHelper then
self.modelHelper:SetLocalPosition(self.objectIndex, x, y, z)
else
BaseObject.setLocalPosition(self, x, y, z)
end
end
function ModelObject:fastGetPosition()
if self.modelHelper then
self.modelHelper:CachePosition(self.objectIndex)
return self.modelHelper.PositionX, self.modelHelper.PositionY, self.modelHelper.PositionZ
else
local position = self:getTransform().position
return position.x, position.y, position.z
end
end
function ModelObject:setPosition(x, y, z)
if self.modelHelper then
self.modelHelper:SetPosition(self.objectIndex, x, y, z)
else
BaseObject.setPosition(self, x, y, z)
end
end
function ModelObject:setLocalScale(x, y, z)
if self.modelHelper then
self.modelHelper:SetLocalScale(self.objectIndex, x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function ModelObject:onDestroy()
BaseObject.onDestroy(self)
self.modelHelper = nil
self.childMap = nil
end
function ModelObject:setSpriteRenderRect(x, y)
if not self.spriteRender then
self.spriteRender = self:getComponent(GConst.TYPEOF_UNITY_CLASS.SPRITE_RENDERER)
end
if self.spriteRender then
self.spriteRender.size = BF.Vector2(x, y)
end
end
return ModelObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 72f36c38a103f8c4aa3b1d909acb4a2a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,251 @@
local BaseObject = require "app/bf/unity/base_object"
---@class UISpineObject : BaseObject
local UISpineObject = class("SpineObject", BaseObject)
local BF_UI_TOUCH_EVENT = GConst.TYPEOF_UNITY_CLASS.BF_UI_TOUCH_EVENT
local TYPE_OF_SPINE_ASSET = GConst.TYPEOF_UNITY_CLASS.SKELETON_DATA_ASSET
local SPINE_ASSET_PATH = "assets/arts/spines/ui/%s/%s_skeletondata.asset"
function UISpineObject:ctor()
end
function UISpineObject:initSkeletonDataAsset(dataAsset)
local skeletonGraphic = self:getSkeletonGraphic()
skeletonGraphic.skeletonDataAsset = dataAsset
skeletonGraphic:Initialize(false)
skeletonGraphic.raycastTarget = false
end
function UISpineObject:refreshAssets(dataAsset)
local skeletonGraphic = self:getSkeletonGraphic()
skeletonGraphic.skeletonDataAsset = dataAsset
skeletonGraphic:Initialize(true)
end
function UISpineObject:getSkeletonGraphic()
if not self.skeletonGraphic then
self.skeletonGraphic = self:getComponent(GConst.TYPEOF_UNITY_CLASS.SKELETON_GRAPHIC)
end
if not self.skeletonGraphic then
Logger.logFatal("UISpineObject missing component CS.Spine.Unity.SkeletonGraphic!")
end
return self.skeletonGraphic
end
function UISpineObject:getAnimationState(forceRefresh)
self:getSkeletonGraphic()
if (not self.animationState and self.skeletonGraphic) or forceRefresh then
self.animationState = self.skeletonGraphic.AnimationState
end
return self.animationState
end
function UISpineObject:playAnim(animName, loop, forceRefresh, forceGetSG)
self:getAnimationState(forceGetSG)
if self.animationState then
local trackEntry = self.animationState:SetAnimation(0, animName, loop)
if forceRefresh then
self.skeletonGraphic:Update(0)
end
return trackEntry
end
end
--未验证TODO
function UISpineObject:rePlayAnim(animName, loop, forceRefresh)
self:getAnimationState()
if self.animationState then
self.animationState:SetEmptyAnimation(0, 1)
local trackEntry = self.animationState:SetAnimation(0, animName, loop)
if forceRefresh then
self.skeletonGraphic:Update(0)
end
return trackEntry
end
end
function UISpineObject:playAnimComplete(animName, loop, forceRefresh, complete)
local spineAnim = self:getAnimation(self:playAnim(animName, loop, forceRefresh))
local duration = spineAnim.Duration
local sequence = self:createBindTweenSequence()
sequence:AppendInterval(duration)
sequence:OnComplete(complete)
return duration
end
function UISpineObject:findAnim(animName)
self:getAnimationState()
if self.animationState then
return self.animationState.Data.SkeletonData:FindAnimation(animName)
end
end
function UISpineObject:hasAnim(animName)
return nil ~= self:findAnim(animName)
end
function UISpineObject:getAnimation(trackEntry)
return trackEntry and trackEntry.Animation
end
function UISpineObject:getAnimSpeed()
if self.skeletonGraphic then
return self.skeletonGraphic.timeScale
end
end
function UISpineObject:setTimeScale(timeScale)
if self.skeletonGraphic then
self.skeletonGraphic.timeScale = timeScale
end
end
function UISpineObject:setIsFreeze(value)
if self.skeletonGraphic then
self.skeletonGraphic.freeze = value
end
end
function UISpineObject:setIsUnScaledTime(value)
if self.skeletonGraphic then
self.skeletonGraphic.unscaledTime = value
end
end
function UISpineObject:clearTrack()
if self.animationState then
self.animationState:ClearTrack(0)
end
end
function UISpineObject:addClickListener(func)
self._addTouchFlag = true
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener == nil then
eventListener = self:addComponent(BF_UI_TOUCH_EVENT)
end
self._touchEventCallback = func
eventListener:AddTouchEventListener(function(eventType, x, y)
self:_onClickEvent(eventType, x, y)
end)
end
function UISpineObject:_onClickEvent(eventType, x, y)
if self._touchEventCallback and eventType == GConst.TOUCH_EVENT.UP_INSIDE then
self._touchEventCallback(eventType, x, y)
end
end
function UISpineObject:setTouchEnable(enable)
local graphic = self:getSkeletonGraphic()
graphic.raycastTarget = enable
end
function UISpineObject:getWidth()
local graphic = self:getSkeletonGraphic()
return graphic.SkeletonData.Width
end
function UISpineObject:getHeight()
local graphic = self:getSkeletonGraphic()
return graphic.SkeletonData.Height
end
function UISpineObject:setGrey(isGrey)
local component = self:getSkeletonGraphic()
GFunc.setGrey(component, isGrey)
end
function UISpineObject:loadAssetSync(assetName)
local path = string.format(SPINE_ASSET_PATH, assetName, assetName)
if self.curAssetPath == path then
return
end
self:onLoadAsset()
self.curAssetPath = path
local spineAsset = ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET)
local skeletonGraphic = self:getSkeletonGraphic()
skeletonGraphic.skeletonDataAsset = spineAsset
skeletonGraphic:Initialize(true)
end
function UISpineObject:loadAssetAsync(assetName, callback)
local path = string.format(SPINE_ASSET_PATH, assetName, assetName)
if self.curAssetPath == path and not self.loadingAsset then
return callback and callback()
end
self:onLoadAsset()
self.curAssetPath = path
self.loadingAsset = true
ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset)
self.loadingAsset = false
if self:isDestroyed() then
ResourceManager:unload(spineAssetPath)
return
end
if self.curAssetPath ~= spineAssetPath then
ResourceManager:unload(spineAssetPath)
return
end
local skeletonGraphic = self:getSkeletonGraphic()
skeletonGraphic.skeletonDataAsset = spineAsset
skeletonGraphic:Initialize(true)
if callback then
callback()
end
end)
end
function UISpineObject:onLoadAsset()
if self.curAssetPath then
ResourceManager:unload(self.curAssetPath)
self.curAssetPath = nil
end
self:addUnloadCallback(function()
if self.curAssetPath then
ResourceManager:unload(self.curAssetPath)
self.curAssetPath = nil
end
end)
end
function UISpineObject:addAnimationCompleteCallback(callback)
if self._animationStateCompleteCallback then
return
end
self._animationStateCompleteCallback = function(entry)
callback(entry.Animation.Name)
end
local state = self:getAnimationState()
if state then
state:Complete("+", self._animationStateCompleteCallback)
end
end
function UISpineObject:removeAnimationCompleteCallback()
if self._animationStateCompleteCallback then
local state = self:getAnimationState()
if state then
state:Complete("-", self._animationStateCompleteCallback)
end
self._animationStateCompleteCallback = nil
end
end
function UISpineObject:setTimeScale(timeScale)
if self.skeletonGraphic then
self.skeletonGraphic.timeScale = timeScale
end
end
function UISpineObject:onDestroy()
self:removeAnimationCompleteCallback()
if self._addTouchFlag then
self._touchEventCallback = nil
end
BaseObject.onDestroy(self)
self.skeletonGraphic = nil
self.animationState = nil
end
return UISpineObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ead73859b84f6ed4a905ffa01dc33efc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,843 @@
---@type BaseObject
local BaseObject = require "app/bf/unity/base_object"
local EffectObject = require "app/bf/unity/effect_object"
local CharacterObject = require "app/bf/unity/character_object"
local UISpineObject = require "app/bf/unity/ui_spine_object"
local MeshSpineObject = require "app/bf/unity/mesh_spine_object"
---@class UIPrefabObject : BaseObject
local UIPrefabObject = class("UIPrefabObject", BaseObject)
local BF_PREFAB_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_PREFAB_HELPER
local BF_UI_TOUCH_EVENT = GConst.TYPEOF_UNITY_CLASS.BF_UI_TOUCH_EVENT
local BF_UI_DRAG_EVENT = GConst.TYPEOF_UNITY_CLASS.BF_UI_DRAG_EVENT
local BF_UI_CELL_DRAG_EVNET = GConst.TYPEOF_UNITY_CLASS.BF_UI_CELL_DRAG_EVENT
local UI_MASKABLE_GRAPHIC = GConst.TYPEOF_UNITY_CLASS.UI_MASKABLE_GRAPHIC
local LANGUAGE_ATLAS_PATH = "assets/arts/language/%s/sprites/%s/%s.asset"
local LANGUAGE_SPRITE_PATH = "assets/arts/language/%s/sprites/%s/%s.png"
local DELAULT_LONG_PRESS_TIME = 0.5
local Vector2 = BF.Vector2(0, 0)
local Color4 = BF.Color(0, 0, 0, 0)
local hash = GFunc.hash
local CHILDMAP_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local v = rawget(t, hash(k))
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
local function _createDefaultChildObject(self, index, gameObject)
local child = UIPrefabObject:create()
child:initWithPrefabHelper(self.prefabHelper, index, gameObject)
return child
end
local function _createUIChildObject(self, index, gameObject)
local child = UIPrefabObject:create()
child:initWithPrefab(nil, gameObject)
child:initPrefabHelper()
return child
end
local function _createEffectChildObject(self, index, gameObject)
local child = EffectObject:create()
child:initWithPrefab(nil, gameObject)
return child
end
local function _createSpineUIChildObject(self, index, gameObject)
local child = UISpineObject:create()
child:initWithPrefab(nil, gameObject)
child:getAnimationState()
local skeletonGraphic = child:getSkeletonGraphic()
skeletonGraphic:Initialize(false)
skeletonGraphic.raycastTarget = false
return child
end
local function _createSpineMeshChildObject(self, index, gameObject)
local child = MeshSpineObject:create()
child:initWithPrefab(nil, gameObject)
child:getAnimationState()
local skeletonAnimation = child:getSkeletonAnimation()
skeletonAnimation:Initialize(false)
return child
end
local function _createCharacterChildObject(self, index, gameObject)
local child = CharacterObject:create()
child:initWithPrefab(nil, gameObject)
return child
end
UIPrefabObject.createChildObject = {
[GConst.GAME_OBJECT_TYPE.DEFAULT] = _createDefaultChildObject,
[GConst.GAME_OBJECT_TYPE.UI_OBJECT] = _createUIChildObject,
[GConst.GAME_OBJECT_TYPE.EFFECT_OBJECT] = _createEffectChildObject,
[GConst.GAME_OBJECT_TYPE.MODEL_OBJECT] = _createDefaultChildObject,
[GConst.GAME_OBJECT_TYPE.CHARACTER_OBJECT] = _createCharacterChildObject,
[GConst.GAME_OBJECT_TYPE.TIMELINE_OBJECT] = _createDefaultChildObject,
[GConst.GAME_OBJECT_TYPE.SPINE_UI_OBJECT] = _createSpineUIChildObject,
[GConst.GAME_OBJECT_TYPE.SPINE_MESH_OBJECT] = _createSpineMeshChildObject,
}
function UIPrefabObject:initWithPrefabHelper(prefabHelper, index, gameObject)
if self.prefabHelper == nil then
self.prefabHelper = prefabHelper
self.objectIndex = index
self.gameObject = gameObject
end
end
function UIPrefabObject:initPrefabHelper()
if self.gameObject == nil then
return
end
self.prefabHelper = self.gameObject:GetComponent(BF_PREFAB_HELPER)
if self.prefabHelper then
self.objectIndex = self.prefabHelper:GetRootPrefabIndex()
end
end
function UIPrefabObject:getPrefabHelper()
return self.prefabHelper
end
function UIPrefabObject:genAllChildren(isRegenerate)
local childMap
if self.isGenChildren then
if isRegenerate then
childMap = {}
for k, child in ipairs(self.childList) do
local name = child:getName()
if name ~= "" and childMap[name] == nil then
childMap[name] = child
end
end
else
return self.childMap
end
else
self.isGenChildren = true
childMap = {}
if self.prefabHelper then
local childNum = self.prefabHelper:GetListCount()
for i = 0, childNum do
if i ~= self.objectIndex then
local gameObject = self.prefabHelper:GetGameObjectByIndex(i)
local objectType = self.prefabHelper:GetObjectTypeByIndex(i)
local hashName = self.prefabHelper:GetHashNameByIndex(i)
local func = self.createChildObject[objectType] or _createDefaultChildObject
local child = func(self, i, gameObject)
child:setName(hashName)
child:setAdmin(self)
if childMap[hashName] == nil then
childMap[hashName] = child
end
table.insert(self.childList, child)
end
end
end
end
setmetatable(childMap, CHILDMAP_METATABLE)
self.childMap = childMap
return childMap
end
function UIPrefabObject:getChildrenMap()
return self.childMap
end
function UIPrefabObject:getGameObject()
if self.gameObject == nil and self.objectIndex then
self.gameObject = self.prefabHelper:GetGameObjectByIndex(self.objectIndex)
end
return self.gameObject
end
function UIPrefabObject:setAnchoredPositionX(x)
if self.prefabHelper then
self.prefabHelper:SetAnchoredPositionX(self.objectIndex, x)
else
BaseObject.setAnchoredPositionX(self, x)
end
end
function UIPrefabObject:setAnchoredPositionY(y)
if self.prefabHelper then
self.prefabHelper:SetAnchoredPositionY(self.objectIndex, y)
else
BaseObject.setAnchoredPositionY(self, y)
end
end
function UIPrefabObject:setAnchoredPosition(x, y)
if self.prefabHelper then
self.prefabHelper:SetAnchoredPosition(self.objectIndex, x, y)
else
BaseObject.setAnchoredPosition(self, x, y)
end
end
function UIPrefabObject:fastGetAnchoredPosition()
if self.prefabHelper then
self.prefabHelper:CacheAnchoredPosition(self.objectIndex)
return self.prefabHelper.PositionX, self.prefabHelper.PositionY
else
local anchoredPosition = self:getTransform().anchoredPosition
return anchoredPosition.x, anchoredPosition.y
end
end
function UIPrefabObject:getAnchoredPosition()
if self.prefabHelper then
return self.prefabHelper:GetAnchoredPosition(self.objectIndex)
else
return BaseObject.getAnchoredPosition(self)
end
end
function UIPrefabObject:addAnchoredPosition(x, y)
if self.prefabHelper then
self.prefabHelper:AddAnchoredPosition(self.objectIndex, x, y)
else
BaseObject.addAnchoredPosition(self, x, y)
end
end
function UIPrefabObject:setAnchorMin(x, y)
if self.prefabHelper then
self.prefabHelper:SetAnchorMin(self.objectIndex, x, y)
end
end
function UIPrefabObject:setAnchorMax(x, y)
if self.prefabHelper then
self.prefabHelper:SetAnchorMax(self.objectIndex, x, y)
end
end
function UIPrefabObject:setSizeDelta(x, y)
if self.prefabHelper then
self.prefabHelper:SetSizeDelta(self.objectIndex, x, y)
else
BaseObject.setSizeDelta(self, x, y)
end
end
function UIPrefabObject:setSizeDeltaX(x)
if self.prefabHelper then
self.prefabHelper:SetSizeDeltaX(self.objectIndex, x)
else
BaseObject.setSizeDeltaX(self, x)
end
end
function UIPrefabObject:setSizeDeltaY(y)
if self.prefabHelper then
self.prefabHelper:SetSizeDeltaY(self.objectIndex, y)
else
BaseObject.setSizeDeltaY(self, y)
end
end
function UIPrefabObject:addSizeDelta(x, y)
if self.prefabHelper then
self.prefabHelper:AddSizeDelta(self.objectIndex, x, y)
else
BaseObject.addSizeDelta(self, x, y)
end
end
function UIPrefabObject:getSizeDelta()
if self.prefabHelper then
return self.prefabHelper:GetSizeDelta(self.objectIndex)
else
return BaseObject.getSizeDelta(self)
end
end
function UIPrefabObject:fastGetSizeDelta()
if self.prefabHelper then
self.prefabHelper:CacheSizeDelt(self.objectIndex)
return self.prefabHelper.PositionX, self.prefabHelper.PositionY
else
local sizeDelta = self:getSizeDelta()
return sizeDelta.x, sizeDelta.y
end
end
function UIPrefabObject:setPosition(x, y, z)
if self.prefabHelper then
self.prefabHelper:SetPosition(self.objectIndex, x, y, z)
else
BaseObject.setPosition(self, x, y, z)
end
end
function UIPrefabObject:addPosition(x, y, z)
if self.prefabHelper then
self.prefabHelper:AddPosition(self.objectIndex, x, y, z)
else
BaseObject.addPosition(self, x, y, z)
end
end
function UIPrefabObject:setLocalPosition(x, y, z)
if self.prefabHelper then
self.prefabHelper:SetLocalPosition(self.objectIndex, x, y, z)
else
BaseObject.setLocalPosition(self, x, y, z)
end
end
function UIPrefabObject:setLocalPositionX(x)
if self.prefabHelper then
self.prefabHelper:SetLocalPositionX(self.objectIndex, x)
else
BaseObject.setLocalPositionX(self, x)
end
end
function UIPrefabObject:setLocalPositionY(y)
if self.prefabHelper then
self.prefabHelper:SetLocalPositionY(self.objectIndex, y)
else
BaseObject.setLocalPositionY(self, y)
end
end
function UIPrefabObject:addLocalPosition(x, y, z)
if self.prefabHelper then
self.prefabHelper:AddLocalPosition(self.objectIndex, x, y, z)
else
BaseObject.addLocalPosition(self, x, y, z)
end
end
function UIPrefabObject:fastGetLocalPosition()
if self.prefabHelper then
self.prefabHelper:CacheLocalPosition(self.objectIndex)
return self.prefabHelper.PositionX, self.prefabHelper.PositionY, self.prefabHelper.PositionZ
else
local position = self:getTransform().localPosition
return position.x, position.y, position.z
end
end
function UIPrefabObject:getlocalRotationZ()
if self.prefabHelper then
return self.prefabHelper:GetlocalRotationZ(self.objectIndex)
else
return 0
end
end
function UIPrefabObject:setOffsetMin(x, y)
if self.prefabHelper then
self.prefabHelper:SetOffsetMin(self.objectIndex, x, y)
else
local transform = self:getTransform()
Vector2.x = x
Vector2.y = y
transform.offsetMin = Vector2
end
end
function UIPrefabObject:setOffsetMax(x, y)
if self.prefabHelper then
self.prefabHelper:SetOffsetMax(self.objectIndex, x, y)
else
local transform = self:getTransform()
Vector2.x = x
Vector2.y = y
transform.offsetMax = Vector2
end
end
function UIPrefabObject:setVisible(visible, scale)
if visible then
scale = scale or 1
self:setLocalScale(scale, scale, scale)
else
self:setLocalScale(0, 0, 0)
end
end
function UIPrefabObject:setLocalScale(x, y, z)
if self.prefabHelper then
self.prefabHelper:SetLocalScale(self.objectIndex, x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function UIPrefabObject:fastGetLocalScale()
if self.prefabHelper then
self.prefabHelper:CacheLocalScale(self.objectIndex)
return self.prefabHelper.PositionX, self.prefabHelper.PositionY, self.prefabHelper.PositionZ
else
local localScale = self:getTransform().localScale
return localScale.x, localScale.y, localScale.z
end
end
function UIPrefabObject:addLocalScale(x, y, z)
if self.prefabHelper then
self.prefabHelper:AddLocalScale(self.objectIndex, x, y, z)
else
BaseObject.addLocalScale(self, x, y, z)
end
end
function UIPrefabObject:setEulerAngles(x, y, z)
if self.prefabHelper then
self.prefabHelper:SetEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setEulerAngles(self, x, y, z)
end
end
function UIPrefabObject:addEulerAngles(x, y, z)
if self.prefabHelper then
self.prefabHelper:AddEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.addEulerAngles(self, x, y, z)
end
end
function UIPrefabObject:setLocalEulerAngles(x, y, z)
if self.prefabHelper then
self.prefabHelper:SetLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function UIPrefabObject:addLocalEulerAngles(x, y, z)
if self.prefabHelper then
self.prefabHelper:AddLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.addLocalEulerAngles(self, x, y, z)
end
end
--cell配合scrollrect使用监听滑动方向
function UIPrefabObject:addCellDragListener(func, bindSlideType)
self._addTouchFlag = true
local eventListener = self:getComponent(BF_UI_CELL_DRAG_EVNET)
if eventListener == nil then
eventListener = self:addComponent(BF_UI_CELL_DRAG_EVNET)
end
self._touchEventCallback = func
eventListener:AddTouchEventListener(function(eventType, x, y)
self:_onCellDragEvent(eventType, x, y)
end, bindSlideType)
end
function UIPrefabObject:_onCellDragEvent(eventType, x, y)
if self._touchEventCallback then
self._touchEventCallback(eventType, x, y)
end
self:_handleLongPressEvent(eventType, x, y)
end
function UIPrefabObject:addDragListener(func)
self._addTouchFlag = true
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener == nil then
eventListener = self:addComponent(BF_UI_DRAG_EVENT)
end
self._touchEventCallback = func
eventListener:AddTouchEventListener(function(eventType, x, y)
self:_onDragEvent(eventType, x, y)
end)
end
function UIPrefabObject:_onDragEvent(eventType, x, y)
if self._touchEventCallback then
self._touchEventCallback(eventType, x, y)
end
self:_handleLongPressEvent(eventType, x, y)
end
function UIPrefabObject:addTouchListener(func)
self._addTouchFlag = true
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener == nil then
eventListener = self:addComponent(BF_UI_TOUCH_EVENT)
end
self._touchEventCallback = func
eventListener:AddTouchEventListener(function(eventType, x, y)
self:_onTouchEvent(eventType, x, y)
end)
end
function UIPrefabObject:_onTouchEvent(eventType, x, y)
if self._touchEventCallback then
self._touchEventCallback(eventType, x, y)
end
self:_handleLongPressEvent(eventType, x, y)
end
function UIPrefabObject:addClickListener(func, clickSound)
self._addTouchFlag = true
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener == nil then
eventListener = self:addComponent(BF_UI_TOUCH_EVENT)
end
self._touchEventCallback = func
eventListener:AddTouchEventListener(function(eventType, x, y)
self:_onClickEvent(eventType, x, y, clickSound)
end)
end
function UIPrefabObject:_onClickEvent(eventType, x, y, clickSound)
if self._touchEventCallback and eventType == GConst.TOUCH_EVENT.UP_INSIDE then
if self.isShowClickAnimation == nil then
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener then
self.isShowClickAnimation = eventListener:GetShowClickAnimation()
end
end
if self.isShowClickAnimation then
clickSound = clickSound or GConst.CLICK_SOUND.NORMAL
local audioPath = AudioManager.CLICK_ID[clickSound]
if audioPath then
AudioManager:playEffect(audioPath)
end
end
self._touchEventCallback(eventType, x, y)
end
self:_handleLongPressEvent(eventType, x, y)
end
function UIPrefabObject:addLongPressListener(func, time)
self._addTouchFlag = true
self._longPressTime = time or DELAULT_LONG_PRESS_TIME
self._longPressCallback = func
if self._touchEventCallback == nil then
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener == nil then
eventListener = self:addComponent(BF_UI_TOUCH_EVENT)
end
eventListener:AddTouchEventListener(function(eventType, x, y)
self:_onTouchEvent(eventType, x, y)
end)
end
end
function UIPrefabObject:_handleLongPressEvent(eventType, x, y)
if self._longPressCallback then
if eventType == GConst.TOUCH_EVENT.DOWN then
if self._longPressSchedulerId then
self:unscheduleGlobal(self._longPressSchedulerId)
end
self._longPressSchedulerId = self:performWithDelayGlobal(function()
self._longPressSchedulerId = nil
if self._longPressCallback then
self._longPressCallback()
end
end, self._longPressTime)
elseif eventType ~= GConst.TOUCH_EVENT.DRAG then
if self._longPressSchedulerId then
self:unscheduleGlobal(self._longPressSchedulerId)
self._longPressSchedulerId = nil
end
end
end
end
function UIPrefabObject:removeTouchListener()
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener then
eventListener:RemoveEventListener()
end
self._addTouchFlag = false
self._longPressTime = nil
self._longPressCallback = nil
end
function UIPrefabObject:removeClickListener()
self:removeTouchListener()
end
function UIPrefabObject:checkHrefLink(x, y)
local uiCamera = UIManager:getUICameraComponent()
local textCom = self:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO)
local hrefId = CS.TMPro.TMP_TextUtilities.FindIntersectingLink(textCom, CS.UnityEngine.Vector3(x, y, 0), uiCamera)
return hrefId
end
function UIPrefabObject:setClickAnimation(enable)
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener then
self.isShowClickAnimation = enable
eventListener:SetShowClickAnimation(enable)
end
end
function UIPrefabObject:setTouchEnable(enable)
local maskableGraphic = self:getComponent(UI_MASKABLE_GRAPHIC)
if maskableGraphic then
maskableGraphic.raycastTarget = enable
end
local eventListener = self:getComponent(BF_UI_TOUCH_EVENT)
if eventListener then
eventListener:SetTouchEnable(enable)
end
end
function UIPrefabObject:setLanguageSprite(atlasName, spriteName, callback, com)
if string.isEmptyOrNil(atlasName) then
Logger.logError("atlasName 为空!!")
return
end
local languageName = I18N:getCurLanguage()
local name = spriteName .. "_" .. languageName
local path, _ = string.gsub(atlasName, "/atlas/", "/textures/")
local spritePath = string.sub(path, 1, -7) .. "/" .. name .. ".png"
if not ResourceManager:containsAsset(spritePath) then
languageName = I18N:getFallbackLanguage()
name = spriteName .. "_" .. languageName
spritePath = string.sub(path, 1, -7) .. "/" .. name .. ".png"
if not ResourceManager:containsAsset(spritePath) then
Logger.logError("fallback language " .. languageName .. " 不包含 " .. spritePath)
return
end
end
self:setSprite(atlasName, name, callback, com)
end
function UIPrefabObject:setSprite(atlasPath, spriteName, callback, com)
self:setSpriteHash(atlasPath, hash(spriteName), callback, com)
end
function UIPrefabObject:setSpriteHash(atlasPath, spriteHashName, callback, com)
com = com or self:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_IMAGE) or self:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SLIDER)
if not com then
return
end
if not self.resMap then
self.resMap = {}
end
if not self.resMap[atlasPath] then
TextureManager:loadAtlas(self, atlasPath, function(path, assets)
if self.resMap[atlasPath] then
TextureManager:unloadAtlas(atlasPath)
else
self.resMap[atlasPath] = assets
end
local sprite = assets:GetSprite(spriteHashName)
if sprite then
com.sprite = sprite
else
com.sprite = nil
Logger.logError("图集%s丢失精灵", atlasPath)
end
if callback then
callback(com)
end
end)
else
local sprite = self.resMap[atlasPath]:GetSprite(spriteHashName)
if sprite then
com.sprite = sprite
if callback then
callback(com)
end
else
com.sprite = nil
Logger.logError("图集%s丢失精灵", atlasPath)
end
end
end
function UIPrefabObject:setTexture(texturePath, callback)
local rawImage = self:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_RAW_IMAGE)
if not rawImage then
return
end
if not self.resMap then
self.resMap = {}
end
if self.resMap[texturePath] then
rawImage.texture = self.resMap[texturePath]
if callback then
callback(rawImage)
end
else
TextureManager:loadTextureAsync(self, texturePath,function (assetsPath, texture)
if self.resMap[assetsPath] then
TextureManager:unLoadTexture(texturePath)
else
self.resMap[assetsPath] = texture
end
rawImage.texture = texture
if callback then
callback(rawImage)
end
end)
end
end
function UIPrefabObject:setText(value, component)
--其他textcompnent在外部获取
component = component or self:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO)
if component then
component.text = value
else
Logger.logWarning("can't find text component!")
end
end
function UIPrefabObject:addRedPoint(offsetX, offsetY, scale, iconName, count, native)
if not self.redPoint then
if not self.loadRpOver then
self.loadRpOver = true
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/common/red_point_cell.prefab", self, function(prefabObject)
---@type UIPrefabObject
self.redPoint = prefabObject
prefabObject:initPrefabHelper()
local uiMap = prefabObject:genAllChildren()
self.redPoint:setAnchoredPosition(offsetX or 0, offsetY or 0)
self.redPoint:setLocalScale(scale, scale, scale)
iconName = iconName or "common_point"
self.redPoint:setSprite(GConst.ATLAS_PATH.COMMON, iconName)
GFunc.getShakeSeq(self.redPoint, false, scale, true)
if native then
self.redPoint:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_IMAGE):SetNativeSize()
end
self.redPointCountTx = uiMap["red_point_cell.count_tx"]
if count then
self.redPointCountTx:setText(count)
else
self.redPointCountTx:setText("")
end
end)
end
else
iconName = iconName or "common_point"
self.redPoint:setSprite(GConst.ATLAS_PATH.COMMON, iconName)
self.redPoint:setAnchoredPosition(offsetX or 0, offsetY or 0)
self.redPoint:setActive(true)
if native then
self.redPoint:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_IMAGE):SetNativeSize()
end
if self.redPointCountTx then
if count then
self.redPointCountTx:setText(count)
else
self.redPointCountTx:setText("")
end
end
end
end
function UIPrefabObject:removeRedPoint()
if self.redPoint then
self.redPoint:setActive(false)
end
end
function UIPrefabObject:addAdPoint(offsetX, offsetY, scale)
if not self.adPoint then
if not self.loadAdOver then
self.loadAdOver = true
UIPrefabManager:loadUIWidgetAsync("assets/prefabs/ui/common/ad_point_cell.prefab", self, function(prefabObject)
self.adPoint = prefabObject
prefabObject:initPrefabHelper()
self.adPoint:setAnchoredPosition(offsetX or 0, offsetY or 0)
GFunc.setAdsSprite(self.adPoint)
self.adPoint:setLocalScale(scale, scale, scale)
end)
end
else
GFunc.setAdsSprite(self.adPoint)
self.adPoint:setAnchoredPosition(offsetX or 0, offsetY or 0)
self.adPoint:setActive(true)
end
end
function UIPrefabObject:removeAdPoint()
if self.adPoint then
self.adPoint:setActive(false)
end
end
function UIPrefabObject:setGraphicFlip(horizontal, vertical)
local component = self:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_GRAPHIC_FLIP)
if component then
component.horizontal = horizontal or false
component.vertical = vertical or false
else
Logger.logWarning("can't find BF_GRAPHIC_FLIP component!")
end
end
function UIPrefabObject:onDestroy()
if self.resMap then
for assetPath, _ in pairs(self.resMap) do
ResourceManager:unload(assetPath)
end
self.resMap = nil
end
if self._addTouchFlag then
self._touchEventCallback = nil
self._longPressCallback = nil
if self._longPressSchedulerId then
self:unscheduleGlobal(self._longPressSchedulerId)
self._longPressSchedulerId = nil
end
end
self.redPoint = nil
self.loadRpOver = nil
self.prefabHelper = nil
BaseObject.onDestroy(self)
self.childMap = nil
end
function UIPrefabObject:setImageGray(grey)
local com = self:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_IMAGE)
if not com then
return
end
Color4.r = 1
if grey then
Color4.g = 0
self:setTouchEnable(false)
else
Color4.g = 1
self:setTouchEnable(true)
end
Color4.b = 1
Color4.a = 1
com.color = Color4
return true
end
function UIPrefabObject:setScrollRectCellName(nameIndex)
if self.prefabHelper then
self.prefabHelper:SetScrollRectCellName(self.objectIndex, nameIndex)
else
BaseObject.setScrollRectCellName(self, nameIndex)
end
end
return UIPrefabObject

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 250398d0feaa4c4429f85d8210747412
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,62 @@
BF = BF or {}
BF.Vector3 = function(x, y, z)
return {x = x, y = y, z = z}
end
BF.Vector4 = function(x, y, z, w)
return {x = x, y = y, z = z, w = w}
end
BF.Vector2 = function(x, y)
return {x = x, y = y}
end
BF.Vector2Zero = CS.UnityEngine.Vector2(0, 0)
BF.Vector3Zero = CS.UnityEngine.Vector3(0, 0, 0)
BF.Vector3Right = CS.UnityEngine.Vector3(1, 0, 0)
BF.Vector3Up = CS.UnityEngine.Vector3(0, 1, 0)
BF.Vector3Forward = CS.UnityEngine.Vector3(0, 0, 1)
BF.Color = function(r, g, b, a)
return {r = r, g = g, b = b, a = a}
end
BF.ColorWhite = CS.UnityEngine.Color(1, 1, 1, 1)
BF.ColorPurple = CS.UnityEngine.Color(1, 0, 1, 1)
BF.ColorWhiteAlpha = CS.UnityEngine.Color(1, 1, 1, 0)
BF.ColorBlack = CS.UnityEngine.Color(0, 0, 0, 1)
BF.ColorBlackAlpha = CS.UnityEngine.Color(0, 0, 0, 0)
BF.Vector2Cross = function (l, r)
return l.x * r.y - l.y * r.x
end
BF.Vector2Dot = function (l, r)
return l.x * r.x + l.y * r.y
end
BF.Vector2Magnitude = function(v)
return math.sqrt(v.x * v.x + v.y * v.y)
end
BF.Vector2Normalize = function (v)
local normal = BF.Vector2(0, 0)
local m = BF.Vector2Magnitude(v)
if m~=0 then
normal.x = v.x/m
normal.y = v.y/m
end
return normal
end
BF.Vector2Distance = function (v1, v2)
local deltax = v2.x - v1.x
local deltay = v2.y - v1.y
return math.sqrt(deltax*deltax + deltay*deltay)
end
BF.Vector3Magnitude = function(v)
return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
end

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 449df0d989bcd834c80d49b097189916
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,338 @@
local CharacterFSMManager = require "app/module/character_fsm/character_fsm_manager"
local BaseObject = require "app/bf/unity/base_object"
local WeaponObject = class("WeaponObject", BaseObject)
local BF_WEAPON_HELPER = GConst.TYPEOF_UNITY_CLASS.BF_WEAPON_HELPER
local ANIMATOR = GConst.TYPEOF_UNITY_CLASS.ANIMATOR
local ANIMATION_FRAME_PER_SECOND = 30
local SUPPORT_SHADER = {
["BF/Models/Character Battle"] = true,
}
local hash = GFunc.hash
local HashName = {}
local function getHashName(str)
local intName = HashName[str]
if intName == nil then
intName = hash(str)
HashName[str] = intName
end
return intName
end
local CHILDMAP_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local v = rawget(t, hash(k))
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
local Vector3 = BF.Vector3(0, 0, 0)
local abs = math.abs
function WeaponObject:ctor()
self.timeScale = 1
end
function WeaponObject:initWithPrefab(assetPath, prefab)
BaseObject.initWithPrefab(self, assetPath, prefab)
self.characterHelper = self:getComponent(BF_WEAPON_HELPER)
if self.characterHelper == nil then
self.characterHelper = self:addComponent(BF_WEAPON_HELPER)
end
self.mainModel = self.characterHelper:GetModelObject()
self.objectIndex = -1
self:_genAllBones()
end
function WeaponObject:initWithCharacterHelper(characterHelper, index, gameObject, name, admin)
self.characterHelper = characterHelper
self.objectIndex = index
self.gameObject = gameObject
self.name = name
self.admin = admin
end
function WeaponObject:_genAllBones()
local childMap = {}
if self.characterHelper then
local childNum = self.characterHelper:GetListCount()
for i = 0, childNum do
local gameObject = self.characterHelper:GetGameObjectByIndex(i)
local hashName = self.characterHelper:GetHashNameByIndex(i)
local child = WeaponObject:create()
child:initWithCharacterHelper(self.characterHelper, i, gameObject, hashName, self)
if childMap[hashName] == nil then
childMap[hashName] = child
end
table.insert(self.childList, child)
end
end
setmetatable(childMap, CHILDMAP_METATABLE)
self.childMap = childMap
end
function WeaponObject:getBoneByName(name)
return self.childMap[name]
end
function WeaponObject:fastGetPosition()
if self.characterHelper then
self.characterHelper:CachePosition(self.objectIndex)
return self.characterHelper.PositionX, self.characterHelper.PositionY, self.characterHelper.PositionZ
else
local position = self:getTransform().position
return position.x, position.y, position.z
end
end
function WeaponObject:getBonePositionByName(name)
return self.childMap[name]:fastGetPosition()
end
function WeaponObject:getHashCode()
local code = -1
if self.characterHelper then
code = self.characterHelper:GetModelHashCode()
end
return code
end
function WeaponObject:play(name, layer, normalizedTime)
layer = layer or -1
normalizedTime = normalizedTime or 0
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:Play(name, layer, normalizedTime)
end
else
self.mainAnimator:Play(name, layer, normalizedTime)
end
end
function WeaponObject:playHashName(hashName, layer, normalizedTime)
layer = layer or -1
normalizedTime = normalizedTime or 0
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:Play(hashName, layer, normalizedTime)
end
else
self.mainAnimator:Play(hashName, layer, normalizedTime)
end
end
function WeaponObject:setAnimatorBool(key, value)
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
self.mainAnimator:SetBool(key, value)
end
else
self.mainAnimator:SetBool(key, value)
end
end
function WeaponObject:getMainAnimator()
if self.mainAnimator == nil then
if self.mainModel then
self.mainAnimator = self.mainModel:GetComponent(ANIMATOR)
end
end
return self.mainAnimator
end
function WeaponObject:getMainModelTransform()
if self.mainModelTransform == nil then
self.mainModelTransform = self.mainModel and self.mainModel.transform or nil
end
return self.mainModelTransform
end
function WeaponObject:getMainModel()
return self.mainModel
end
function WeaponObject:getCurrentAnimationHash()
return CS.BF.Utils.GetCurrentAnimationHash(self:getMainAnimator())
end
function WeaponObject:setMainModelLocalScale(x, y, z)
local transform = self:getMainModelTransform()
if transform then
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localScale = Vector3
end
end
function WeaponObject:setMainModelLocalPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetMainModelLocalPosition(x, y, z)
else
local transform = self:getMainModelTransform()
if transform then
Vector3.x = x
Vector3.y = y
Vector3.z = z
transform.localPosition = Vector3
end
end
end
function WeaponObject:getStateTime(name)
local hashName = getHashName(name)
return self.characterHelper:GetStateTime(hashName)
end
function WeaponObject:getStateTimeHash(hashName)
return self.characterHelper:GetStateTime(hashName)
end
function WeaponObject:getStateKeyTime(name, index)
local hashName = getHashName(name)
local keyTime = self.characterHelper:GetStateKeyFrame(hashName, index) or 0
return keyTime/ANIMATION_FRAME_PER_SECOND
end
function WeaponObject:containsState(name)
return self:getStateTime(name) > 0.00001
end
function WeaponObject:setTimeScale(timeScale)
if abs(self.timeScale - timeScale) < 0.00001 then
return
end
self.timeScale = timeScale
local mainAnimator = self:getMainAnimator()
mainAnimator.speed = timeScale*(self.timeScaleAddition or 1)
end
function WeaponObject:setTimeScaleAddition(addition)
self.timeScaleAddition = addition
local timeScale = self.timeScale*addition
local mainAnimator = self:getMainAnimator()
mainAnimator.speed = timeScale
end
function WeaponObject:setCullingMode(cullingMode)
local mainAnimator = self:getMainAnimator()
if mainAnimator then
mainAnimator.cullingMode = cullingMode
end
end
function WeaponObject:getCharacterMaterials()
if not self.characterMaterials then
self.characterMaterials = {}
for k, prefabObj in pairs(self.childMap) do
local render = prefabObj:getComponent(GConst.TYPEOF_UNITY_CLASS.SKINNED_MESH_RENDERER)
if not CS.BF.Utils.IsNull(render) and not CS.BF.Utils.IsNull(render.material) and SUPPORT_SHADER[render.material.shader.name] then
table.insert(self.characterMaterials, render.material)
end
end
end
return self.characterMaterials
end
function WeaponObject:getCharacterMeshRenderer()
if not self.characterMeshRenders then
self.characterMeshRenders = {}
for k, prefabObj in pairs(self.childMap) do
local render = prefabObj:getComponent(GConst.TYPEOF_UNITY_CLASS.SKINNED_MESH_RENDERER)
if not CS.BF.Utils.IsNull(render) and not CS.BF.Utils.IsNull(render.material) and SUPPORT_SHADER[render.material.shader.name] then
table.insert(self.characterMeshRenders, render)
end
end
end
return self.characterMeshRenders
end
function WeaponObject:getMaterialPropertyBlock()
if not self.mpb then
self.mpb = CS.UnityEngine.MaterialPropertyBlock()
end
return self.mpb
end
function WeaponObject:setCustomShadowEnable(enabled)
local materials = self:getCharacterMaterials()
for _, material in ipairs(materials) do
material:SetShaderPassEnabled("Always", enabled)
end
end
function WeaponObject:setCharacterFSM(fsm)
self.fsm = fsm
end
function WeaponObject:setShadowColor(color)
local renderers = self:getCharacterMeshRenderer()
local mpBlock = self:getMaterialPropertyBlock()
for i, renderer in ipairs(renderers) do
renderer:GetPropertyBlock(mpBlock)
mpBlock:SetColor("_shadow_color", color)
renderer:SetPropertyBlock(mpBlock)
end
end
function WeaponObject:setLocalEulerAngles(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalEulerAngles(self.objectIndex, x, y, z)
else
BaseObject.setLocalEulerAngles(self, x, y, z)
end
end
function WeaponObject:setLocalPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalPosition(self.objectIndex, x, y, z)
else
BaseObject.setLocalPosition(self, x, y, z)
end
end
function WeaponObject:setPosition(x, y, z)
if self.characterHelper then
self.characterHelper:SetPosition(self.objectIndex, x, y, z)
else
BaseObject.setPosition(self, x, y, z)
end
end
function WeaponObject:setLocalScale(x, y, z)
if self.characterHelper then
self.characterHelper:SetLocalScale(self.objectIndex, x, y, z)
else
BaseObject.setLocalScale(self, x, y, z)
end
end
function WeaponObject:onDestroy()
if self.fsm then
CharacterFSMManager:stopFSM(self.fsm)
self.fsm = nil
end
BaseObject.onDestroy(self)
self.characterHelper = nil
self.mainModel = nil
self.mainAnimator = nil
self.childMap = nil
self.characterMaterials = nil
self.characterMeshRenders = nil
self.mpb = nil
end
return WeaponObject

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 70c3ad6fb587edf4994e34a7a27d7287
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

8
lua/app/common.meta Normal file
View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9e289b1795b0dd04db87ebbc68ebc485
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,255 @@
local AudioManager = {}
local BGM_VOLUME = 0.5
local MAX_EFFECT_NUM = 30
local AUDIO_CLIP = typeof(CS.UnityEngine.AudioClip)
AudioManager.BGM_ID = {
MAINCITY = "assets/arts/sounds/music/bgm_main.wav",
}
AudioManager.CLICK_ID = {
[1] = "assets/arts/sounds/sfx/ui/ui_button.wav",
}
AudioManager.EFFECT_ID = {
BUTTON = "assets/arts/sounds/sfx/ui/ui_button.wav",
REWARD = "assets/arts/sounds/sfx/ui/sfx_reward.wav",
SFX_TOAST = "assets/arts/sounds/sfx/ui/sfx_toast.wav",
SFX_SUMMON = "assets/arts/sounds/sfx/ui/sfx_summon.wav",
SFX_ITEM_9 = "assets/arts/sounds/sfx/ui/sfx_item_9.wav",
SFX_ITEM_10 = "assets/arts/sounds/sfx/ui/sfx_item_10.wav",
SFX_ITEM_11 = "assets/arts/sounds/sfx/ui/sfx_item_11.wav",
SFX_UPGRADE = "assets/arts/sounds/sfx/ui/sfx_upgrade.wav",
SFX_TRAIN = "assets/arts/sounds/sfx/ui/sfx_train.wav",
}
AudioManager.EFFECT_PREFIX = "assets/arts/sounds/sfx/ui/%s.wav"
function AudioManager:init()
self.musicEnabled = nil
self.effectEnabled = nil
self.musicVolume = 1
self.effectVolume = 1
self:setMusicVolume(LocalData:getAudioMusicVolume())
self:setEffectVolume(LocalData:getAudioEffectVolume())
self.audioSourcePool = {}
self.bgmAudioSource = nil
self.currentMusic = nil
end
function AudioManager:playMusic(audioPath, isLoop)
if audioPath == nil or audioPath == "" then
return
end
if not self.musicEnabled then
self.disableMusic = audioPath
self.disableMusicIsLoop = isLoop
return
end
if self.currentMusic == audioPath then
local as = self:getMusicSource()
if self.currentMusicIsLoop ~= isLoop then
if isLoop == nil then
as.loop = true
else
as.loop = isLoop
end
end
else
self.currentMusic = audioPath
self.currentMusicIsLoop = isLoop
if self.musicPath then
ResourceManager:unload(self.musicPath)
self.musicPath = nil
end
ResourceManager:loadOriginAssetAsync(audioPath, AUDIO_CLIP, function(path, audioClip)
if path == self.currentMusic then
self.musicPath = path
local as = self:getMusicSource()
as.clip = audioClip
if isLoop == nil then
isLoop = true
end
as.loop = isLoop
as:Play()
else
ResourceManager:unload(path)
end
end)
end
end
function AudioManager:stopMusicById(id, isClear)
if self.currentMusic == id then
self:stopMusic(isClear)
end
end
function AudioManager:stopMusic(isClear)
local bgmAudioSource = self:getMusicSource()
if bgmAudioSource then
bgmAudioSource:Stop()
if isClear then
bgmAudioSource.clip = nil
if self.musicPath then
ResourceManager:unload(self.musicPath)
self.musicPath = nil
end
self.currentMusic = nil
end
end
end
function AudioManager:pauseMusic()
local bgmAudioSource = self:getMusicSource()
if bgmAudioSource then
bgmAudioSource:Pause()
end
end
function AudioManager:resumeMusic()
local bgmAudioSource = self:getMusicSource()
if bgmAudioSource then
bgmAudioSource:UnPause()
end
end
function AudioManager:getAudioSourceFromPool(path)
local audioObj
for i, v in ipairs(self.audioSourcePool) do
if not v.audioSource.isPlaying then
audioObj = v
if v.path and v.path ~= path then
ResourceManager:unload(v.path)
v.path = path
end
break
end
end
if not audioObj and #self.audioSourcePool < MAX_EFFECT_NUM then
local audioSource = CS.BF.BFMain.Instance.SoundManager:addEffectAudioSource()
audioObj = {
path = path,
audioSource = audioSource
}
table.insert(self.audioSourcePool, audioObj)
end
return audioObj
end
function AudioManager:getMusicSource()
if not self.bgmAudioSource then
self.bgmAudioSource = CS.BF.BFMain.Instance.SoundManager:getMusicAudioSource()
end
self.bgmAudioSource.volume = self.musicVolume
return self.bgmAudioSource
end
function AudioManager:playEffect(audioPath, volume)
if audioPath == nil or audioPath == "" then
return
end
if not self.effectEnabled then
return
end
if volume then
volume = volume*self.effectVolume
else
volume = self.effectVolume
end
ResourceManager:loadOriginAssetAsync(audioPath, AUDIO_CLIP, function(path, audioClip)
if audioClip then
local asObj = self:getAudioSourceFromPool(path)
if asObj then
local audioSource = asObj.audioSource
audioSource.clip = audioClip
audioSource.loop = false
audioSource.volume = volume
audioSource:Play()
end
end
end)
end
function AudioManager:stopEffect(path)
for i, v in ipairs(self.audioSourcePool) do
if v.path and v.path == path then
v.audioSource:Stop()
end
end
end
function AudioManager:isMusicEnabled()
return self.musicEnabled
end
function AudioManager:isEffectEnabled()
return self.effectEnabled
end
function AudioManager:setMusicVolume(value)
self.musicVolume = value or 1
LocalData:setAudioMusicVolume(self.musicVolume)
self.musicEnabled = self.musicVolume > 0
if self.musicEnabled then
self:getMusicSource()
if self.disableMusic and self.disableMusic ~= "" then
self:playMusic(self.disableMusic, self.disableMusicIsLoop)
end
else
if self.currentMusic and self.currentMusic ~= "" then
self.disableMusic = self.currentMusic
self.disableMusicIsLoop = self.currentMusicIsLoop
end
self:stopMusic(true)
end
end
function AudioManager:getMusicVolume()
return self.musicVolume
end
function AudioManager:setEffectVolume(value)
self.effectVolume = value or 1
LocalData:setAudioEffectVolume(self.effectVolume)
self.effectEnabled = self.effectVolume > 0
if not self.effectEnabled then
self:stopAndClearAudioFx()
end
end
function AudioManager:getEffectVolume()
return self.effectVolume
end
function AudioManager:stopAndClearAudioFx()
if self.audioSourcePool then
for i, v in ipairs(self.audioSourcePool) do
v.audioSource:Stop()
if v.audioSource.clip then
v.audioSource.clip = nil
if v.path then
ResourceManager:unload(v.path)
v.path = nil
end
end
end
end
end
function AudioManager:clear()
self:stopMusic(true)
self:stopAndClearAudioFx()
self.bgmAudioSource = nil
self.audioSourcePool = nil
CS.BF.BFMain.Instance.SoundManager:clearAudioSource()
end
return AudioManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 221836402f4fd974c8ae11d1029dc2fb
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

1414
lua/app/common/bi_report.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 18b39d75878166f43a80036dd82df93c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,59 @@
local CameraManager = {}
local ADJUST_SCREEN_W = 720
local ADJUST_SCREEN_H = 1560
function CameraManager:init()
self.mainCamera = CS.UnityEngine.Camera.main
CS.UnityEngine.GameObject.DontDestroyOnLoad(self.mainCamera.gameObject)
self.originPosition = self.mainCamera.transform.position
self.originOrthographicSize = self.mainCamera.orthographicSize
-- self.originFieldOfView = self.mainCamera.gameObject:GetComponent(GConst.TYPEOF_UNITY_CLASS.BF_CAMERA_HELPER).OriginFieldOfView
-- self:adjustCameraForFight()
-- 战斗相机参数调整
self.mainCamera.transparencySortMode = CS.UnityEngine.TransparencySortMode.CustomAxis
self.mainCamera.transparencySortAxis = BF.Vector3(0, 0, 1)
end
function CameraManager:getMainCamera()
return self.mainCamera
end
function CameraManager:resetMainCamera()
self.mainCamera.transform.position = self.originPosition
self.mainCamera.orthographicSize = self.originOrthographicSize
end
function CameraManager:getMainCameraOriginPosition()
return self.originPosition
end
function CameraManager:getOriginOrthographicSize()
return self.originOrthographicSize
end
-- 适配战斗相机
function CameraManager:adjustCameraForFight()
local manualHeight
-- 然后得到当前屏幕的高宽比 和 你自定义需求的高宽比。通过判断他们的大小,来不同赋值
if CS.UnityEngine.Screen.height / CS.UnityEngine.Screen.width ~= ADJUST_SCREEN_H / ADJUST_SCREEN_W then
-- 如果屏幕的高宽比大于自定义的高宽比 。则通过公式 ADJUST_SCREEN_W * manualHeight = Screen.width * Screen.height
-- 来求得适应的manualHeight ,用它求出 实际高度与理想高度的比率 scale
manualHeight = ADJUST_SCREEN_W / CS.UnityEngine.Screen.width * CS.UnityEngine.Screen.height
else
-- 否则 直接给manualHeight 自定义的 ADJUST_SCREEN_H 的值那么相机的fieldOfView就会原封不动
manualHeight = ADJUST_SCREEN_H
end
-- Camera.fieldOfView 视野: 这是垂直视野水平FOV取决于视口的宽高比当相机是正交时fieldofView被忽略
-- 把实际高度与理想高度的比率scale乘加给Camera.fieldOfView。
-- 这样就能达到自动调节分辨率的效果
local scale = manualHeight / ADJUST_SCREEN_H
if scale < 0.7 then
scale = 0.7
end
self.mainCamera.fieldOfView = self.originFieldOfView*scale
end
return CameraManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ce97e1b52619a91449c6bc7a9c7ddb00
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,20 @@
local PrefabObject = require "app/bf/unity/uiprefab_object"
local CellManager = {}
function CellManager:loadCellAsync(path, cellComp, parent, callback)
UIPrefabManager:loadUIWidgetAsync(path, parent, function(prefab)
local cell = self:addCellComp(prefab, cellComp)
if callback then
callback(cell)
end
end)
end
function CellManager:addCellComp(prefab, type)
prefab:initPrefabHelper()
prefab:genAllChildren()
return prefab:addLuaComponent(type)
end
return CellManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5166b8127fdf5cc46b58c1436b7a0832
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,119 @@
local ConfigManager = {
configs = {}
}
local CONFIG_PATH = "app/config/"
function ConfigManager:_getConfig(configName)
local config = require(CONFIG_PATH .. configName)
self.configs[configName] = config
return config
end
function ConfigManager:getConfig(configName)
local config = self.configs[configName]
if config == nil then
config = self:_getConfig(configName)
end
return config.data
end
if NOT_PUBLISH then
ConfigManager.__getConfig = ConfigManager.getConfig
function ConfigManager:getConfig(configName)
if string.lower(configName) ~= configName then
Logger.logFatal("ConfigManager:getConfig 传入的表名不能有大写 " .. configName)
end
return self:__getConfig(configName)
end
end
function ConfigManager:reloadConfig(configName)
self:clearConfigCache(configName)
self.configs[configName] = nil
self:getConfig(configName)
end
function ConfigManager:getConfigNum(configName)
local config = self.configs[configName]
if config == nil then
config = self:_getConfig(configName)
end
return config.count
end
function ConfigManager:getConfigWithOtherKey(configName, keyName)
local config = self.configs[configName]
if config == nil then
config = self:_getConfig(configName)
end
if config.keys == nil then
return nil
end
return config.keys[keyName]
end
function ConfigManager:reloadAllConfig()
for configName, v in pairs(self.configs) do
self:reloadConfig(configName)
end
self:preLoadConfig()
end
function ConfigManager:preLoadConfig()
local monsterBase = self:_getConfig("monster_base")
self:clearConfigCache("monster_base")
local baseData = monsterBase.data
local monsterFullData = {}
local count = 0
local function handleMonsterGrow(name)
local monsterGrowConfig = self:_getConfig(name)
local growData = monsterGrowConfig.data
for k, v in pairs(growData) do
monsterFullData[k] = v
local data = baseData[v.monster_baseid]
if data then
monsterFullData[k].collision_radius = data.collision_radius
monsterFullData[k].model_id = data.model_id
monsterFullData[k].model_fight = data.model_fight
monsterFullData[k].fx_fight = data.fx_fight
monsterFullData[k].size = data.size
-- else
-- Logger.logHighlight("not data monster_baseid = " .. v.monster_baseid)
end
count = count + 1
end
self:clearConfigCache(name)
end
handleMonsterGrow("monster_stage")
self.configs["monster"] = {
data = monsterFullData,
count = count
}
if EDITOR_MODE then
local realCount = 0
for k, v in pairs(monsterFullData) do
realCount = realCount + 1
end
if count ~= realCount then
Logger.logFatal("same id in monster config")
end
end
end
function ConfigManager:getChapterConfig(id)
if not id then
return
end
local idx = math.ceil(id/5000)
local cfg = ConfigManager:getConfig("chapter" .. idx)
return cfg[id], cfg
end
function ConfigManager:clearConfigCache(configName)
package.loaded[CONFIG_PATH .. configName] = nil
end
return ConfigManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0086c4bdcaf18cc4ab0fa4c03ff47cf0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,379 @@
---@class DataManager
local DataManager = {
initByServer = false
}
function DataManager:init()
self.cdCallBack = {}
self._cacheManager = {}
self:initManager("GameSettingData", "app/userdata/game_setting/game_setting_data")
self:initManager("BattleData", "app/userdata/battle/battle_data")
self:initManager("PlayerData", "app/userdata/player/player_data")
self:initManager("BagData", "app/userdata/bag/bag_data")
self:initManager("SummonData", "app/userdata/summon/summon_data")
self:initManager("MallActData", "app/userdata/shop/mall_act_data")
self:initManager("MallDailyData", "app/userdata/shop/mall_daily_data")
self:initManager("MallRechargeData", "app/userdata/shop/mall_recharge_data")
self:initManager("HeroData", "app/userdata/hero/hero_data")
self:initManager("ShopData","app/userdata/shop/shop_data")
self:initManager("MasteryData", "app/userdata/mastery/mastery_data")
self:initManager("FightInfoData","app/userdata/fight_info/fight_info_data")
self:initManager("MiningData","app/userdata/mining/mining_data")
self:initManager("ChapterData", "app/userdata/chapter/chapter_data")
self:initManager("ResearchData", "app/userdata/research/research_data")
self:initManager("DungeonData", "app/userdata/dungeon/dungeon_data")
self:initManager("ArenaData", "app/userdata/arena/arena_data")
self:initManager("IdleData", "app/userdata/idle/idle_data")
self:initManager("DailyTaskData", "app/userdata/activity/daily_task/daily_task_data")
self:initManager("SevenDayData", "app/userdata/activity/seven_day/seven_day_data")
self:initManager("TutorialTaskData", "app/userdata/tutorial/tutorial_task_data")
self:initManager("TutorialData", "app/userdata/tutorial/tutorial_data")
self:initManager("BlessingData", "app/userdata/blessing/blessing_data")
self:initManager("AccelerationData", "app/userdata/acceleration/acceleration_data")
self:initManager("BountyData", "app/userdata/bounty/bounty_data")
self:initManager("CollectionData", "app/userdata/collection/collection_data")
self:initManager("MailData", "app/userdata/mail/mail_data")
self:initManager("FundChapterData", "app/userdata/fund/fund_chapter_data")
if EDITOR_MODE then
self:initDataForLazy()
end
end
function DataManager:initManager(name, path)
if self[name] then
self._cacheManager[name] = self[name]
end
self[name] = require(path):create()
end
function DataManager:checkDataBind()
local changeBindFunc = function(baseData, curBaseData)
local data = baseData.data
if data then
local bindList = baseData.bindList
if bindList then
for fieldName, list in pairs(bindList) do
for _, v in ipairs(list) do
if v.binder.unBind then
v.binder:unBind(baseData, fieldName)
end
if v.binder.bind then
if baseData.data[fieldName] ~= curBaseData.data[fieldName] then
v.binder:bind(curBaseData, fieldName, v.bindFunc, true)
else
v.binder:bind(curBaseData, fieldName, v.bindFunc)
end
end
end
end
end
baseData:clearBindAll()
end
end
if self._cacheManager then -- 如果已经存在就检查一下绑定
for name, baseData in pairs(self._cacheManager) do
if name == "BagData" then
changeBindFunc(baseData.ItemData, self[name].ItemData)
changeBindFunc(baseData.EquipData, self[name].EquipData)
changeBindFunc(baseData.LegacyData, self[name].LegacyData)
changeBindFunc(baseData.RuneData, self[name].RuneData)
else
changeBindFunc(baseData, self[name])
end
end
end
end
function DataManager:clear()
self.initWithServer = false
if self.cacheTimer then
SchedulerManager:unscheduleGlobal(self.cacheTimer)
self.cacheTimer = nil
end
self.cdCallBack = {}
self.BattleData:clear()
self.MasteryData:clear()
self.DailyTaskData:clear()
self.SevenDayData:clear()
self.TutorialTaskData:clear()
self.TutorialData:clear()
self.AccelerationData:clear()
self.BountyData:clear()
self.MailData:clear()
self.PlayerData:clear()
ModuleManager.TaskManager:clear()
end
function DataManager:initWithServerData(data)
self:init()
Logger.logHighlight("------------------initWithServerData-----------------------")
Logger.printTable(data)
Time:setServerTimeZone(0)
Time:updateServerTime(data.now_ts)
Time:updateServerTimeToday(data.today_ts)
self.initWithServer = true
self.signInfo = data.sign
self.todayFirstLogin = data.today_first_login
self.serverAttr = data.attrs
self.registerTs = (data.stat.register_ts or 0) // 1000
data.heros = {
{cfg_id = 60001, lv = 4, curHid = 60001}
}
self.PlayerData:init(data.basic_info)
self.BagData:init(data.bag)
self.ResearchData:init(data.mine)
self.FightInfoData:init(data.fight_info)
self.ShopData:init(data.mall)
self.SummonData:init(data.summon)
self.MasteryData:initData(data.mastery)
self.MiningData:init(data.mine)
self.ChapterData:init(data.chapter)
self.BattleData:init()
self.DungeonData:init(data.dungeon_info)
self.ArenaData:init(data.arena_info)
self.DailyTaskData:init(data.task_daily, true)
self.IdleData:init(data.idle)
self.SevenDayData:init(data.seven_day, true)
self.TutorialTaskData:init(data.task_tutor, true)
self.BlessingData:init(data.blessing)
self.CollectionData:init(data.collection)
-- 属性计算 依赖部分数据初始化
self.HeroData:init(data.heros)
self.TutorialData:init(data.guide)
self.AccelerationData:init(data.acceleration)
self.BountyData:init(data.battle_pass, true)
self.FundChapterData:init(data.fund)
-- self.MailData:init(data.mail_info)
-- self._cacheManager["HeroData"]:init(data.items)
--self.loginCount = data.loginCount or 1
--self.createPlayerTime = GFunc.formatTimeStep(data.infoData.registerTime or Time:getServerTime())
----********** init start *******************
--self.crossDayTS = Time:getOverOfServerToday()
self:scheduleGlobal()
self:checkDataBind()
-- 检查属性是否和服务器一致
GFunc.checkAttrWhitServerAttr()
end
function DataManager:onServerTimeBack(serverTime, loginCount, loginTime)
self.loginCount = loginCount or 1
self.loginTime = loginTime or Time:getServerTime()
self:scheduleGlobal()
end
-- 是否首次登录
function DataManager:getIsFirstLogin()
local nowTime = Time:getServerTime()
if self.registerTs%86400 == nowTime %8640 and self:getIsTodayFirstLogin() then
return true
end
return false
end
function DataManager:getIsTodayFirstLogin()
return self.todayFirstLogin or false
end
function DataManager:getIsInitWithServer()
return self.initWithServer
end
function DataManager:getLoginTime()
return self.loginTime or 0
end
function DataManager:registerDataCd(dataName)
if not dataName then
return
end
for k, v in ipairs(self.cdCallBack) do
if v == dataName then
return
end
end
table.insert(self.cdCallBack, dataName)
end
function DataManager:unregisterDataCd(dataName)
if not dataName then
return
end
for k, v in ipairs(self.cdCallBack) do
if v == dataName then
table.remove(self.cdCallBack, k)
break
end
end
end
function DataManager:registerCrossDayFunc(bindId, func)
if not bindId or not func then
return
end
if not self.crossDayCallbacks then
self.crossDayCallbacks = {}
end
for i, info in ipairs(self.crossDayCallbacks) do
if info.bindId == bindId then
self.crossDayCallbacks[i].func = func
self.crossDayCallbacks[i].open = true
return
end
end
table.insert(self.crossDayCallbacks,{
bindId = bindId,
func = func,
open = true
})
end
function DataManager:unregisterCrossDayFunc(bindId)
if not bindId then
return
end
if not self.crossDayCallbacks then
return
end
for i, info in ipairs(self.crossDayCallbacks) do
if info.bindId == bindId then
self.crossDayCallbacks[i].open = false
return
end
end
end
function DataManager:scheduleGlobal()
if self.cacheTimer then
return
end
self.crossDayTS = Time:getOverOfServerToday()
self.cacheTimer = SchedulerManager:scheduleGlobal(function (inter)
for k, v in ipairs(self.cdCallBack) do
if self[v] and self[v].updateCd then
self[v]:updateCd()
end
end
if Time:getServerTime() > self.crossDayTS then
self.crossDayTS = Time:getOverOfServerToday()
if self.crossDayCallbacks then
for i, info in ipairs(self.crossDayCallbacks) do
if info.func and info.open then
info.func()
end
end
end
ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_LOGIN_DAY)
end
end, 1)
end
-- 获取登录天数
function DataManager:getLoginCount()
return self.loginCount or 1
end
function DataManager:getSignInfo()
local nowTime = Time:getServerTime()
local lastSignTime = self.signInfo.latest_at // 1000
local todayBeginTime = nowTime - nowTime % 86400
local canSign = lastSignTime < todayBeginTime
if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.SIGNIN) then
canSign = false
end
return self.signInfo.count or 0, canSign, self.hasSigned
end
function DataManager:setSignCount(count)
self.hasSigned = true
self.signInfo.count = count
self.signInfo.latest_at = Time:getServerTime() * 1000
--Logger.logHighlight("签到成功次数:"..count)
end
function DataManager:resetSignInInfo()
self.hasSigned = false
end
function DataManager:setLoginSuccess(success)
self.loginSuccess = success
end
function DataManager:getLoginSuccess()
return self.loginSuccess
end
-- 获取建号时间
function DataManager:getCreatePlayerTime()
return self.createPlayerTime or Time:getServerTime()
end
-- 记录sync了多少次数据如果以后游戏中要回到登录界面则此值应当被清除
function DataManager:markSyncDataCount()
if not self.syncDataCount then
self.syncDataCount = 1
else
self.syncDataCount = self.syncDataCount + 1
end
end
function DataManager:getSyncDataCount()
return self.syncDataCount or 0
end
function DataManager:needDealGm()
return self:getSyncDataCount() >= 2
end
---方便检索,仅编辑器模式使用
function DataManager:initDataForLazy()
---@type BagData
self.BagData = self:getManager("BagData")
---@type PlayerData
self.PlayerData = self:getManager("PlayerData")
---@type SummonData
self.SummonData = self:getManager("SummonData")
---@type MallActData
self.MallActData = self:getManager("MallActData")
---@type MallDailyData
self.MallDailyData = self:getManager("MallDailyData")
---@type MallRechargeData
self.MallRechargeData = self:getManager("MallRechargeData")
---@type ShopData
self.ShopData = self:getManager("ShopData")
---@type MiningData
self.MiningData = self:getManager("MiningData")
---@type ResearchData
self.ResearchData = self:getManager("ResearchData")
---@type DungeonData
self.DungeonData = self:getManager("DungeonData")
---@type ChapterData
self.ChapterData = self:getManager("ChapterData")
---@type ArenaData
self.ArenaData = self:getManager("ArenaData")
---@type FundChapterData
self.FundChapterData = self:getManager("FundChapterData")
end
function DataManager:getManager(name, path)
if self[name] then
return self[name]
end
self[name] = require(path):create()
return self[name]
end
return DataManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2f79b49cc05702742bc7fe6f56fd83d4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,52 @@
local DeviceHelper = {}
local ThinkingAnalyticsAPI = CS.ThinkingAnalytics.ThinkingAnalyticsAPI
local PresetProperties = CS.ThinkingAnalytics.ThinkingAnalyticsAPI.GetPresetProperties()
-- 提供给其他模块的接口 ***************************************************************
-- 获取device_model
function DeviceHelper:getDeviceModel()
local name = CS.UnityEngine.SystemInfo.deviceModel
if not name or name == "" then
name = PresetProperties and PresetProperties.DeviceModel or ""
end
return name
end
-- 获取device_id
function DeviceHelper:getDeviceId()
-- local id = ""
-- if ThinkingAnalyticsAPI then
-- id = ThinkingAnalyticsAPI:GetDeviceId() or ""
-- end
-- if not id or id == "" then
-- id = CS.UnityEngine.SystemInfo.deviceUniqueIdentifier or ""
-- end
-- return id
return CS.UnityEngine.SystemInfo.deviceUniqueIdentifier
end
-- 获取os_version
function DeviceHelper:getOSVersion()
local version = CS.UnityEngine.SystemInfo.operatingSystem
if not version or version == "" then
version = PresetProperties and PresetProperties.OSVersion or ""
end
return version
end
-- 获取网络状态
function DeviceHelper:getNetworkType()
local networkType = "WIFI"
if CS.UnityEngine.Application.internetReachability == CS.UnityEngine.NetworkReachability.NotReachable then
networkType = "NONE"
elseif CS.UnityEngine.Application.internetReachability == CS.UnityEngine.NetworkReachability.ReachableViaCarrierDataNetwork then
networkType = "DATA"
elseif CS.UnityEngine.Application.internetReachability == CS.UnityEngine.NetworkReachability.ReachableViaLocalAreaNetwork then
networkType = "WIFI"
end
return networkType
end
return DeviceHelper

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4680cd9b6d735ce40a4167d4349a35c7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
local DOTweenManager = {}
local DOTweenSequence = CS.DG.Tweening.DOTween.Sequence
function DOTweenManager:init()
-- 三个参数分别是recycleAllByDefault useSafeMode logBehaviour
if IS_PUBLISH then
CS.DG.Tweening.DOTween.Init(false, false, CS.DG.Tweening.LogBehaviour.ErrorsOnly)
else
CS.DG.Tweening.DOTween.Init(false, false, CS.DG.Tweening.LogBehaviour.Default)
end
end
function DOTweenManager:createSeqWithIntId(id)
id = id or GConst.DOTWEEN_IDS.DEFAULT
local seq = DOTweenSequence()
seq:SetIntId(id)
return seq
end
function DOTweenManager:createDOTweenToWithIntId(id, getter, setter, to, duration)
id = id or GConst.DOTWEEN_IDS.DEFAULT
local tween = CS.DG.Tweening.DOTween.To(getter, setter, to, duration)
tween:SetIntId(id)
return tween
end
function DOTweenManager:createDOTweenTo(getter, setter, to, duration)
local tween = CS.DG.Tweening.DOTween.To(getter, setter, to, duration)
return tween
end
-- 返回一个跟gameObject绑定的Sequence,当gameObject销毁的时候这个Sequence会跟着一起销毁
-- 但是偶尔会有gameObject销毁的时候这个Sequence没有跟着一起销毁尚未查明原因所以谨慎使用
function DOTweenManager:createSeqWithGameObject(gameObject)
local seq = DOTweenSequence()
seq:SetLink(gameObject)
return seq
end
---@param trans UnityEngine.Transform
function DOTweenManager:doScale(trans,endValue, duration,onComplete)
---@type DG.Tweening.Tweener
local tween = trans:DOScale(endValue, duration)
tween.onComplete = function()
if onComplete then
onComplete()
end
end
end
return DOTweenManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 96fe20bcfb5550147baf975320c6fbb9
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,139 @@
local EffectObject = require "app/bf/unity/effect_object"
local EffectManager = {
battleCacheList = {},
battleCacheMap = {}
}
local TypeOfGameObject = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT
local BATTLE_CACHE_SIZE = 60 -- 战斗特效缓存容量s
local HERO_SHOW_FX_PATH = "assets/prefabs/effects/show/%s.prefab"
function EffectManager:loadUIEffectAsync(path, ui, parent, order, callback)
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if ui:isClosed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
if parent == nil or parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local effectObject = EffectObject:create()
effectObject:initWithPrefab(assetPath, prefab)
effectObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
ui:addEffect(effectObject, parent, order)
if callback then
callback(effectObject)
end
end)
end
function EffectManager:loadEffectAsync(path, parent, callback)
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local effectObject = EffectObject:create()
effectObject:initWithPrefab(assetPath, prefab)
effectObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
if parent then
effectObject:setParent(parent, false)
end
if callback then
callback(effectObject)
end
end)
end
function EffectManager:loadHeroShowEffectAsync(name, parent, callback)
local path = string.format(HERO_SHOW_FX_PATH, name)
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local effectObject = EffectObject:create()
effectObject:initWithPrefab(assetPath, prefab)
effectObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
if parent then
effectObject:setParent(parent, false)
end
if callback then
callback(effectObject)
end
end)
end
function EffectManager:loadBattleEffectAsync(path, parent, callback)
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local effectObject = EffectObject:create()
effectObject:initWithPrefab(assetPath, prefab)
effectObject:addUnloadCallback(function(obj)
local effectPath = obj:getAssetPath()
if self.battleCacheMap[effectPath] then
ResourceManager:unload(effectPath)
else
if #self.battleCacheList == BATTLE_CACHE_SIZE then
local headPath = table.remove(self.battleCacheList, 1)
ResourceManager:unload(headPath)
self.battleCacheMap[headPath] = nil
end
self.battleCacheMap[effectPath] = true
table.insert(self.battleCacheList, effectPath)
end
end)
if parent then
effectObject:setParent(parent, false)
end
if callback then
callback(effectObject)
end
end)
end
function EffectManager:markCache(path)
if #self.battleCacheList >= BATTLE_CACHE_SIZE then
return false
end
if self.battleCacheMap[path] == nil then
self.battleCacheMap[path] = true
table.insert(self.battleCacheList, path)
return true
end
return false
end
function EffectManager:isCacheFull()
return #self.battleCacheList == BATTLE_CACHE_SIZE
end
function EffectManager:getCacheMaxSize()
return BATTLE_CACHE_SIZE
end
function EffectManager:clearCache()
for _, path in ipairs(self.battleCacheList) do
ResourceManager:unload(path)
end
self.battleCacheList = {}
self.battleCacheMap = {}
end
return EffectManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a7961ab6279bf974aa9f71d8a2797922
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,277 @@
local EventManager = {
listeners = {},
listenerIndex = 0,
dispatchCount = 0,
waitRemoveMap = {},
waitAddMap = {},
}
EventManager.CUSTOM_EVENT = {
-- MAIN_SOCKET_MESSAGE = "MAIN_SOCKET_MESSAGE", -- 游戏主链接所有消息
-- UI_LOADING_PERCENT = "UI_LOADING_PERCENT", -- loading进度
ON_BATTLE_START = "ON_BATTLE_START", -- 战斗开始
BATTLE_OPERATION_FINISH = "BATTLE_OPERATION_FINISH", -- 战斗中操作完毕
BATTLE_OPERATION_START = "BATTLE_OPERATION_START", -- 战斗中当玩家开始操作时
BATTLE_END = "BATTLE_END", -- 战斗结束
UI_SHOW_COMPLETE = "UI_SHOW_COMPLETE", -- UI打开完毕
UI_CUSTOM_ANIMATION_COMPLETE = "UI_CUSTOM_ANIMATION_COMPLETE", -- UI自定义动画完毕
UI_CLOSE = "UI_CLOSE", -- UI关闭
-- I18N_CHANGE_LANGUAGE = "I18N_CHANGE_LANGUAGE", -- 切换语言
UPGRADE_EQUIP = "UPGRADE_EQUIP", -- 升级装备
STAGE_TEAM_UP_FORMATION = "STAGE_TEAM_UP_FORMATION", -- 关卡上阵英雄
-- SELL_EQUIP = "SELL_EQUIP", -- 战斗结算界面出售装备
LOGIN_REQ_SUCCESS = "LOGIN_REQ_SUCCESS", -- 登录请求成功,准备进入游戏
HERO_WEAR_EQUIP = "HERO_WEAR_EQUIP", -- 英雄穿上一件装备
GET_MAIN_TASK_REWARD = "GET_MAIN_TASK_REWARD", -- 主线任务奖励领取成功
-- MARKET_HAD_REFRESH = "MARKET_HAD_REFRESH", -- 市集已刷新
-- SHOW_MAIN_TASK_WEAK_FINGER = "SHOW_MAIN_TASK_WEAK_FINGER", -- 显示主线任务的弱引导手指
-- CLOSE_LV_UP_UI_WITHOUT_GOTO = "CLOSE_LV_UP_UI_WITHOUT_GOTO", -- 正常关闭升级界面,没有触发前往
-- BIND_SDK_SUCCESS = "BIND_SDK_SUCCESS", -- 绑定SDK成功
ON_TUTORIAL_BATTLE_TEAM_ENTER = "ON_TUTORIAL_BATTLE_TEAM_ENTER", -- 假战斗引导专用,当队伍入场完后
ON_BATTLE_INIT_OVER = "ON_BATTLE_INIT_OVER", -- 战斗初始化完成
-- EXPEDITION_SHOW_DOUBLE_CHECK_UI = "EXPEDITION_SHOW_DOUBLE_CHECK_UI", -- 远征展示二次确认框
-- EXPEDITION_RESET_HEAD_POS = "EXPEDITION_RESET_HEAD_POS", -- 远征重置头像位置
-- EXPEDITION_SHOW_BUFF_VFX = "EXPEDITION_SHOW_BUFF_VFX", -- 远征显示buff特效动画
MAIN_UI_CHECK_POP = "MAIN_UI_CHECK_POP", -- 主界面检查弹出界面
-- CHANGE_WELCOME_COMP = "CHANGE_WELCOME_COMP", -- 切换新手活动comp
-- 公会成员已达上限
-- GUILD_MEMBER_MAX = "GUILD_MEMBER_MAX", -- 公会成员已达上限
-- 装备上锁
-- EQUIP_LOCK = "EQUIP_LOCK", -- 装备上锁
-- 割草
CHANGE_MAIN_CITY_PAGE = "CHANGE_MAIN_CITY_PAGE", -- 切换主城页签
-- CHANGE_MAIN_CITY_PAGE_VIT = "CHANGE_MAIN_CITY_PAGE_VIT", -- 切换主城页签
-- 英雄降临
-- CHANGE_NEW_HERO_COMP = "CHANGE_NEW_HERO_COMP", -- 切换英雄活动COMP
-- 转盘
-- CHANGE_TURNTABLE_COMP = "CHANGE_TURNTABLE_COMP", -- 切换转盘活动COMP
-- 守护活动
-- CHANGE_GUARD_COMP = "CHANGE_GUARD_COMP", -- 切换守护活动COMP
-- EQUIP_LV_UP = "EQUIP_LV_UP", -- 装备升级成功
-- EQUIP_RESOLVE = "EQUIP_RESOLVE", -- 装备重置成功
-- EQUIP_MERGE = "EQUIP_MERGE", -- 装备合成成功
-- EQUIP_QUICK_MERGE = "EQUIP_QUICK_MERGE", -- 装备快速合成成功
-- EQUIP_REBACK = "EQUIP_REBACK", -- 装备回退成功
-- EQUIP_REFINE = "EQUIP_REFINE", -- 装备精炼成功
-- HERO_UNLOCK = "HERO_UNLOCK", -- 英雄解锁
-- HERO_STAR_UP = "HERO_STAR_UP", -- 英雄升星成功
-- HERO_LV_UP = "HERO_LV_UP", -- 英雄升级成功
-- TALENT_UP = "TALENT_UP", -- 天赋升级
-- BATTLE_FINISH = "BATTLE_FINISH", -- 战斗结束
-- CHAPTER_BOX_REWARD = "CHAPTER_BOX_REWARD", -- 领取宝箱奖励
-- UPDATE_DATA = "UPDATE_DATA", -- 更新数据
SUMMON_FINISH = "SUMMON_FINISH", -- 抽卡结束
-- REVIVE_SUCC = "REVIVE_SUCC", -- 战斗复活成功
-- CHANGE_ACTIVITY_NORMAL_COMP = "CHANGE_ACTIVITY_NORMAL_COMP", -- 切换活动COMP
-- NAME_REPEAT = "NAME_REPEAT", -- 重名
-- BUY_MONTH_CARD = "BUY_MONTH_CARD", -- 购买月卡
-- PLAY_FLY_ANI = "PLAY_FLY_ANI",
-- NEWSUMMON_OVER = "NEWSUMMON_OVER",
-- WISHSUMMON_OVER = "WISHSUMMON_OVER",
-- JEWELRY_MERGE_OVER = "JEWELRY_MERGE_OVER",
-- JEWELRY_AUTO_MERGE_OVER = "JEWELRY_AUTO_MERGE_OVER",
-- CDKEY_FINISH = "CDKEY_FINISH",
-- BLACK_SUMMON_OVER = "BLACK_SUMMON_OVER",
-- ON_CLAIMED_ASK_REWARD = "ON_CLAIMED_ASK_REWARD",
-- ON_CLAIMED_GUESS_REWARD = "ON_CLAIMED_GUESS_REWARD",
-- ON_ASKING_CONFIRM = "ON_ASKING_CONFIRM",
-- PLAY_DRAGON_BUILD_ANIMATION = "PLAY_DRAGON_BUILD_ANIMATION", -- 邪龙动画
-- SPRING_DUEL_CROSS_DAY = "SPRING_DUEL_CROSS_DAY",
-- SPRING_DUEL_REQUEST_RANK_LIST = "SPRING_DUEL_REQUEST_RANK_LIST",
-- ON_VIT_CHANGED = "ON_VIT_CHANGED", -- 体力变更时
-- B5新增
BATTLE_HERO_USE_ACTIVE_SKILL = "BATTLE_HERO_USE_ACTIVE_SKILL",
BATTLE_HERO_REFRESH_SKILL = "BATTLE_HERO_REFRESH_SKILL",
BATTLE_CHAPTER_CHANGE = "BATTLE_CHAPTER_CHANGE",
BATTLE_SHOW_CHAPTER_BLACK_UI = "BATTLE_SHOW_CHAPTER_BLACK_UI",
BATTLE_CLOSE_CHAPTER_BLACK_UI = "BATTLE_CLOSE_CHAPTER_BLACK_UI",
BATTLE_SHOW_TOAST = "BATTLE_SHOW_TOAST",
BATTLE_BLACK_UI_CLOSE = "BATTLE_BLACK_UI_CLOSE",
BATTLE_READY_ENTER_DUNGEON = "BATTLE_READY_ENTER_DUNGEON",
BATTLE_REVIVE = "BATTLE_REVIVE",
BATTLE_REVIVE_RSP = "BATTLE_REVIVE_RSP",
BATTLE_ADD_PASSIVE_SKILL = "BATTLE_ADD_PASSIVE_SKILL",
BATTLE_CHANGE_PAS_SKILL = "BATTLE_CHANGE_PAS_SKILL",
PLAYER_RENAME = "PLAYER_RENAME",
GET_ANY_KEY_DOWN = "GET_ANY_KEY_DOWN",
NAME_REPEAT = "NAME_REPEAT",
TRAIN_REBORN = "TRAIN_REBORN", -- 重生
TRAIN_PASS_UP = "TRAIN_PASS_UP", -- 速通
CLOSE_BATTLE_FAIL = "CLOSE_BATTLE_FAIL",
SIGN_IN_SUCCESS = "SIGN_IN_SUCCESS", -- 签到成功
CURRENCY_BAR_FLY = "CURRENCY_BAR_FLY",
CURRENCY_BAR_FLY_OVER = "CURRENCY_BAR_FLY_OVER",
-- 挂机广告
IDLE_DROP_AD_GET = "IDLE_DROP_AD_GET",
ATK_TRAIN_LEVEL_UP = "ATK_TRAIN_LEVEL_UP",
-- 装备变化
WEAR_WEAPON_CHANGE = "WEAR_WEAPON_CHANGE",
-- 速通结束
QUICK_PASS_FINISH = "QUICK_PASS_FINISH",
TUTORIAL_TASK_REWARD = "TUTORIAL_TASK_REWARD",
ATK_TRAIN_TUTORIAL_OVER = "ATK_TRAIN_TUTORIAL_OVER",
TUTORIAL_TASK_STOP = "TUTORIAL_TASK_STOP",
}
-- 此方法不能直接在外部调用请使用例如BaseUIBaseModule等封装好的接口
function EventManager:addEventListener(name, func, priority)
if self.listeners[name] == nil then
self.listeners[name] = {}
end
local tag = self.listenerIndex + 1
self.listenerIndex = tag
priority = priority or 0
if self.dispatchCount > 0 then
if not self.waitAddMap[name] then
self.waitAddMap[name] = {}
end
table.insert(self.waitAddMap[name], {func, tag, priority})
else
local insert = false
if priority > 0 then
for k, v in ipairs(self.listeners[name]) do
if priority <= v[3] then
insert = true
table.insert(self.listeners[name], k, {func, tag, priority})
break
end
end
end
if not insert then
table.insert(self.listeners[name], {func, tag, priority})
end
end
return tag
end
function EventManager:removeEventListener(name, tag)
if self.listeners[name] then
for k, v in ipairs(self.listeners[name]) do
if v[2] == tag then
if self.dispatchCount > 0 then
v[4] = 1
self.waitRemoveMap[name] = 1
else
table.remove(self.listeners[name], k)
end
break
end
end
end
if self.waitAddMap[name] then
local listenerList = self.waitAddMap[name]
for index, listener in ipairs(listenerList) do
if listener[2] == tag then
table.remove(listenerList, index)
break
end
end
end
end
function EventManager:removeEventListenersByEvent(name)
self.listeners[name] = nil
self.waitAddMap[name] = nil
self.waitRemoveMap[name] = nil
end
function EventManager:dispatchEvent(name, ...)
self.dispatchCount = self.dispatchCount + 1
local listenerList = self.listeners[name]
if listenerList then
local continue = nil
for k, v in ipairs(listenerList) do
if v[4] == nil then
continue = v[1](...)
if continue == false then
break
end
end
end
end
self.dispatchCount = self.dispatchCount - 1
if self.dispatchCount > 0 then
return
end
-- 处理等待移除
for removeName, v in pairs(self.waitRemoveMap) do
local listenerList = self.listeners[removeName]
if listenerList then
local count = #listenerList
for i = count, 1, -1 do
if listenerList[i] and listenerList[i][4] then
table.remove(listenerList, i)
end
end
end
self.waitRemoveMap[removeName] = nil
end
-- 处理等待添加
for addName, v in pairs(self.waitAddMap) do
for i = 1, #v do
local insert = false
local listener = table.remove(v)
local listenerPriority = listener[3]
if listenerPriority > 0 then
for k, existListener in ipairs(self.listeners[addName]) do
if listenerPriority <= existListener[3] then
insert = true
table.insert(self.listeners[addName], k, listener)
break
end
end
end
if not insert then
table.insert(self.listeners[addName], listener)
end
end
self.waitAddMap[addName] = nil
end
end
function EventManager:removeAllEventListeners()
self.listeners = {}
self.waitRemoveMap = {}
self.waitAddMap = {}
self.listenerIndex = 0
end
function EventManager:clear()
self:removeAllEventListeners()
end
if NOT_PUBLISH then
function EventManager:_checkDebugAddEventListenerFuncMap()
if self._debugAddEventListenerFuncMap == nil then
self._debugAddEventListenerFuncMap = {
[BaseUI.addEventListener] = true,
[BaseScene.addEventListener] = true,
[BaseModule.addEventListener] = true,
}
end
end
EventManager._releaseAddEventListener = EventManager.addEventListener
function EventManager:addEventListener(...)
self:_checkDebugAddEventListenerFuncMap()
local currFunc = debug.getinfo(2, "f").func
if self._debugAddEventListenerFuncMap[currFunc] == nil then
Logger.logFatal("you can not call EventManager:addEventListener directly")
end
return self:_releaseAddEventListener(...)
end
end
return EventManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1d164e3f2ae911e489e090f7155b2743
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,166 @@
local FontManager = {
defaultFontAssets = nil,
fallbackFontAssetsName = nil,
fallbackFontAssets = nil,
}
local DEFAULT_FONT_PATH = "assets/arts/fonts/tmpfonts/default/tmpfont/font_sdf.asset"
-- local DEFAULT_FONT_TITLE_PATH = "assets/arts/fonts/tmpfonts/default/tmpfont/font_title_sdf.asset"
local LANGUAGE_FONT_PATH = {
[GConst.LANGUAGE.CHINESE] = "assets/arts/fonts/tmpfonts/cn/tmpfont/font_sdf.asset",
[GConst.LANGUAGE.ENGLISH] = "assets/arts/fonts/tmpfonts/en/tmpfont/font_sdf.asset",
[GConst.LANGUAGE.CHINESE_TC] = "assets/arts/fonts/tmpfonts/zh/tmpfont/font_sdf.asset",
[GConst.LANGUAGE.RUSSIAN] = "assets/arts/fonts/tmpfonts/ru/tmpfont/font_sdf.asset",
[GConst.LANGUAGE.THAILAND] = "assets/arts/fonts/tmpfonts/th/tmpfont/font_sdf.asset",
[GConst.LANGUAGE.INDONESIA] = "assets/arts/fonts/tmpfonts/id/tmpfont/font_sdf.asset",
[GConst.LANGUAGE.VIETNAMESE] = "assets/arts/fonts/tmpfonts/vi/tmpfont/font_sdf.asset",
}
local LANGUAGE_FONT_TITLE_PATH = {
[GConst.LANGUAGE.CHINESE] = "assets/arts/fonts/tmpfonts/cn/tmpfont/font_title_sdf.asset",
[GConst.LANGUAGE.ENGLISH] = "assets/arts/fonts/tmpfonts/en/tmpfont/font_title_sdf.asset",
[GConst.LANGUAGE.CHINESE_TC] = "assets/arts/fonts/tmpfonts/zh/tmpfont/font_title_sdf.asset",
[GConst.LANGUAGE.RUSSIAN] = "assets/arts/fonts/tmpfonts/ru/tmpfont/font_title_sdf.asset",
[GConst.LANGUAGE.THAILAND] = "assets/arts/fonts/tmpfonts/th/tmpfont/font_title_sdf.asset",
[GConst.LANGUAGE.INDONESIA] = "assets/arts/fonts/tmpfonts/id/tmpfont/font_title_sdf.asset",
[GConst.LANGUAGE.VIETNAMESE] = "assets/arts/fonts/tmpfonts/vi/tmpfont/font_title_sdf.asset",
}
function FontManager:changeLanguage(language, callback)
self.fontLoaded = false
-- if not self.defaultFontAssets or not self.defaultFontTitleAssets then
if not self.defaultFontAssets then
local count = 0
-- local totalCount = 2
local totalCount = 1
local function finish()
count = count + 1
if count == totalCount then
self:_changeLanguage(language, callback)
end
end
ResourceManager:loadOriginAssetAsync(DEFAULT_FONT_PATH, GConst.TYPEOF_UNITY_CLASS.TMP_FONT_ASSET, function (path, obj)
self.defaultFontAssets = obj
-- --特殊处理下划线
-- local underlineCharater = self.defaultFontAssets:GetTMPCharacter(0x5F)
-- self.defaultFontAssets:ClearTMPCharacter()
-- self.defaultFontAssets:AddTMPCharacter(0x5F, underlineCharater)
finish()
end)
-- ResourceManager:loadOriginAssetAsync(DEFAULT_FONT_TITLE_PATH, GConst.TYPEOF_UNITY_CLASS.TMP_FONT_ASSET, function (path, obj)
-- self.defaultFontTitleAssets = obj
-- --特殊处理下划线
-- local underlineCharater = self.defaultFontTitleAssets:GetTMPCharacter(0x5F)
-- self.defaultFontTitleAssets:ClearTMPCharacter()
-- self.defaultFontTitleAssets:AddTMPCharacter(0x5F, underlineCharater)
-- finish()
-- end)
else
--特殊处理下划线
-- local underlineCharater = self.defaultFontAssets:GetTMPCharacter(0x5F)
-- self.defaultFontAssets:ClearTMPCharacter()
-- self.defaultFontAssets:AddTMPCharacter(0x5F, underlineCharater)
-- underlineCharater = self.defaultFontTitleAssets:GetTMPCharacter(0x5F)
-- self.defaultFontTitleAssets:ClearTMPCharacter()
-- self.defaultFontTitleAssets:AddTMPCharacter(0x5F, underlineCharater)
self:_changeLanguage(language, callback)
end
end
function FontManager:_changeLanguage(language, callback)
-- self.defaultFontAssets.fallbackFontAssetTable:Clear()
-- self.defaultFontTitleAssets.fallbackFontAssetTable:Clear()
-- local fontPath = LANGUAGE_FONT_PATH[language]
-- local fontTitlePath = LANGUAGE_FONT_TITLE_PATH[language]
-- if fontPath and fontTitlePath then
-- if fontPath then
-- local count = 0
-- local totalCount = 2
-- local totalCount = 1
-- local function finish()
-- count = count + 1
-- if count == totalCount then
-- self.fontLoaded = true
-- if callback then
-- callback()
-- end
-- if self.onFontLoadedCallback then
-- local func = self.onFontLoadedCallback
-- self.onFontLoadedCallback = nil
-- func()
-- end
-- end
-- end
-- if self.fallbackFontAssetsName then
-- ResourceManager:unload(self.fallbackFontAssetsName)
-- end
-- ResourceManager:loadOriginAssetAsync(fontPath, GConst.TYPEOF_UNITY_CLASS.TMP_FONT_ASSET, function (path, obj)
-- self.fallbackFontAssetsName = fontPath
-- self.fallbackFontAssets = obj
-- local faceInfo = self.fallbackFontAssets.faceInfo
-- self.defaultFontAssets.faceInfo = faceInfo
-- -- 编辑模式下就实例化一下否则对字体资源的fallback的修改会保存到本地
-- if EDITOR_MODE then
-- self.defaultFontAssets.fallbackFontAssetTable:Add(CS.UnityEngine.Object.Instantiate(self.fallbackFontAssets))
-- else
-- self.defaultFontAssets.fallbackFontAssetTable:Add(self.fallbackFontAssets)
-- end
-- finish()
-- end)
-- if self.fallbackFontTitleAssetsName then
-- ResourceManager:unload(self.fallbackFontTitleAssetsName)
-- end
-- ResourceManager:loadOriginAssetAsync(fontTitlePath, GConst.TYPEOF_UNITY_CLASS.TMP_FONT_ASSET, function (path, obj)
-- self.fallbackFontTitleAssetsName = fontTitlePath
-- self.fallbackFontTitleAssets = obj
-- local faceInfo = self.fallbackFontTitleAssets.faceInfo
-- self.defaultFontTitleAssets.faceInfo = faceInfo
-- -- 编辑模式下就实例化一下否则对字体资源的fallback的修改会保存到本地
-- if EDITOR_MODE then
-- self.defaultFontTitleAssets.fallbackFontAssetTable:Add(CS.UnityEngine.Object.Instantiate(self.fallbackFontTitleAssets))
-- else
-- self.defaultFontTitleAssets.fallbackFontAssetTable:Add(self.fallbackFontTitleAssets)
-- end
-- finish()
-- end)
-- else
-- self.fontLoaded = true
-- if callback then
-- callback()
-- end
-- if self.onFontLoadedCallback then
-- local func = self.onFontLoadedCallback
-- self.onFontLoadedCallback = nil
-- func()
-- end
-- Logger.logError("there is not this font path in const")
-- end
-- 动态字体图集
self.fontLoaded = true
if callback then
callback()
end
if self.onFontLoadedCallback then
local func = self.onFontLoadedCallback
self.onFontLoadedCallback = nil
func()
end
end
function FontManager:onFontLoaded(callback)
if self.fontLoaded then
return callback and callback()
end
self.onFontLoadedCallback = callback
end
return FontManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: be33ebb69c121324eb5cb07028b6d405
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,374 @@
local GlobalConst = require "app/config/localization/localization_global_const"
local FontMgr = require "app/common/font_manager"
local I18N = {
configs = {},
cacheGlobalFormatParamSequnce = {},
cacheNormalFormatParamSequnce = {},
cacheGlobalIndex = 0,
}
I18N.GlobalConst = GlobalConst
local MONSTER_METATABLE = {
__index = function(t, k)
if rawget(t, k) == nil then
local realId = ConfigManager:getConfig("monster")[k].monster_baseid
local v = t._realConfig[realId]
if v then
rawset(t, k, v)
end
return v
end
return rawget(t, k)
end
}
local CONFIG_PATH = "app/config/strings/%s/"
local SUPPORT_LANGUAGE_LIST = {
GConst.LANGUAGE.ENGLISH,
GConst.LANGUAGE.CHINESE,
GConst.LANGUAGE.CHINESE_TC,
-- -- GConst.LANGUAGE.RUSSIAN, -- 俄罗斯
-- -- GConst.LANGUAGE.THAILAND, -- 泰国
-- GConst.LANGUAGE.INDONESIA, -- 印度尼西亚
-- GConst.LANGUAGE.VIETNAMESE, -- 越南
-- GConst.LANGUAGE.FRENCH, -- 法语
-- -- GConst.LANGUAGE.ITALIAN, -- 意大利
-- GConst.LANGUAGE.GERMAN, -- 德国
-- -- GConst.LANGUAGE.SPANISH, -- 西班牙
-- GConst.LANGUAGE.PORTUGUESE, -- 葡萄牙
-- -- GConst.LANGUAGE.TURKISH, -- 土耳其
-- -- GConst.LANGUAGE.MALAYSIA, -- 马来西亚
-- GConst.LANGUAGE.JAPANESE, -- 日本
-- GConst.LANGUAGE.KOREAN, -- 韩国
}
local SUPPORT_SERVER_LANGUAGE = {
[GConst.LANGUAGE.ENGLISH] = "en_US",
[GConst.LANGUAGE.CHINESE] = "zh_CN",
[GConst.LANGUAGE.CHINESE_TC] = "zh_TW",
[GConst.LANGUAGE.FRENCH] = "fr_FR",
[GConst.LANGUAGE.GERMAN] = "de_DE",
[GConst.LANGUAGE.RUSSIAN] = "ru_RU",
[GConst.LANGUAGE.THAILAND] = "th_TH",
[GConst.LANGUAGE.INDONESIA] = "in_ID",
[GConst.LANGUAGE.VIETNAMESE] = "vi_VN",
[GConst.LANGUAGE.JAPANESE] = "ja_JP",
[GConst.LANGUAGE.KOREAN] = "ko_KR",
}
local LANGUAGE_NAME_KEY = {
[GConst.LANGUAGE.ENGLISH] = 1,
[GConst.LANGUAGE.CHINESE] = 1,
[GConst.LANGUAGE.CHINESE_TC] = 1,
[GConst.LANGUAGE.FRENCH] = 1,
-- [GConst.LANGUAGE.ITALIAN] = 1,
[GConst.LANGUAGE.GERMAN] = 1,
-- [GConst.LANGUAGE.SPANISH] = 1,
-- [GConst.LANGUAGE.RUSSIAN] = 1,
[GConst.LANGUAGE.PORTUGUESE] = 1,
-- [GConst.LANGUAGE.TURKISH] = 1,
-- [GConst.LANGUAGE.THAILAND] = 1,
-- [GConst.LANGUAGE.MALAYSIA] = 1,
[GConst.LANGUAGE.INDONESIA] = 1,
[GConst.LANGUAGE.VIETNAMESE] = 1,
[GConst.LANGUAGE.JAPANESE] = 1,
[GConst.LANGUAGE.KOREAN] = 1,
}
local MOBILE_LANG_MAP = {
["en"] = GConst.LANGUAGE.ENGLISH,
["cn"] = GConst.LANGUAGE.CHINESE,
["zh"] = GConst.LANGUAGE.CHINESE_TC,
["fr"] = GConst.LANGUAGE.FRENCH,
["it"] = GConst.LANGUAGE.ITALIAN,
["de"] = GConst.LANGUAGE.GERMAN,
["es"] = GConst.LANGUAGE.SPANISH,
["ru"] = GConst.LANGUAGE.RUSSIAN,
["pt"] = GConst.LANGUAGE.PORTUGUESE,
["tr"] = GConst.LANGUAGE.TURKISH,
["th"] = GConst.LANGUAGE.THAILAND,
["ms"] = GConst.LANGUAGE.MALAYSIA,
["in"] = GConst.LANGUAGE.INDONESIA,
["vi"] = GConst.LANGUAGE.VIETNAMESE,
["ja"] = GConst.LANGUAGE.JAPANESE,
["ko"] = GConst.LANGUAGE.KOREAN,
}
local LANGUAGE_NOMARL_SPRITE = {
[GConst.LANGUAGE.ENGLISH] = "setting_language_en1",
[GConst.LANGUAGE.CHINESE] = "setting_language_cn1",
[GConst.LANGUAGE.CHINESE_TC] = "setting_language_tw1",
[GConst.LANGUAGE.FRENCH] = "setting_language_fr1",
[GConst.LANGUAGE.ITALIAN] = "setting_language_it1",
[GConst.LANGUAGE.GERMAN] = "setting_language_de1",
[GConst.LANGUAGE.SPANISH] = "setting_language_sp1",
[GConst.LANGUAGE.RUSSIAN] = "setting_language_ru1",
[GConst.LANGUAGE.PORTUGUESE] = "setting_language_pt1",
[GConst.LANGUAGE.TURKISH] = "setting_language_tr1",
[GConst.LANGUAGE.THAILAND] = "setting_language_th1",
[GConst.LANGUAGE.MALAYSIA] = "setting_language_ms1",
[GConst.LANGUAGE.INDONESIA] = "setting_language_id1",
}
local LANGUAGE_HIGHLIGHT_SPRITE = {
[GConst.LANGUAGE.ENGLISH] = "setting_language_en2",
[GConst.LANGUAGE.CHINESE] = "setting_language_cn2",
[GConst.LANGUAGE.CHINESE_TC] = "setting_language_tw2",
[GConst.LANGUAGE.FRENCH] = "setting_language_fr2",
[GConst.LANGUAGE.ITALIAN] = "setting_language_it2",
[GConst.LANGUAGE.GERMAN] = "setting_language_de2",
[GConst.LANGUAGE.SPANISH] = "setting_language_sp2",
[GConst.LANGUAGE.RUSSIAN] = "setting_language_ru2",
[GConst.LANGUAGE.PORTUGUESE] = "setting_language_pt2",
[GConst.LANGUAGE.TURKISH] = "setting_language_tr2",
[GConst.LANGUAGE.THAILAND] = "setting_language_th2",
[GConst.LANGUAGE.MALAYSIA] = "setting_language_ms2",
[GConst.LANGUAGE.INDONESIA] = "setting_language_id2",
}
function I18N:init()
local curLanguage = LocalData:getSelectedLanguage()
if curLanguage == "" or not self:supportLanguage(curLanguage) then
curLanguage = self:getSystemLanguage()
if curLanguage == nil then
curLanguage = CS.BF.BFPlatform.GetCurrentLanguageInfo():GetFallbackLanguage()
end
end
local changeStatus = self:setLanguage(curLanguage, true)
if changeStatus then
FontMgr:changeLanguage(self.curLanguage or GConst.LANGUAGE.ENGLISH)
end
end
function I18N:supportLanguage(language)
return LANGUAGE_NAME_KEY[language]
end
function I18N:setLanguage(language, firstInit)
if not self:supportLanguage(language) then
local fallbackLanguage = CS.BF.BFPlatform.GetCurrentLanguageInfo():GetFallbackLanguage()
language = fallbackLanguage
end
if not language or language == self.curLanguage then
return
end
LocalData:setSelectedLanguage(language)
self:clear()
self.curLanguage = language
self.configPath = string.format(CONFIG_PATH, self.curLanguage)
local monsterTable = {
_realConfig = false
}
setmetatable(monsterTable, MONSTER_METATABLE)
self.configs["monster"] = {
data = monsterTable,
}
if not firstInit then
self:preLoadConfig()
end
Logger.logHighlight("setLanguage = %s", language)
return true
end
function I18N:onFontLoaded(callback)
FontMgr:onFontLoaded(callback)
end
function I18N:preLoadConfig()
-- local config = self:getConfig("monster")
-- if not config._realConfig then
-- config._realConfig = require(self.configPath .. "monster_base").data
-- end
end
function I18N:clear()
for name, v in pairs(self.configs) do
self:clearConfigCache(name)
self.configs[name] = nil
end
--清除缓存
self.cacheGlobalFormatParamSequnce = {}
self.cacheNormalFormatParamSequnce = {}
self.cacheGlobalIndex = 0
end
function I18N:clearConfigCache(configName)
package.loaded[self.configPath .. configName] = nil
end
function I18N:getCurLanguage()
return self.curLanguage
end
function I18N:getLanguageSprite(language)
return LANGUAGE_NOMARL_SPRITE[language]
end
function I18N:getSeletedSprite(language)
return LANGUAGE_HIGHLIGHT_SPRITE[language]
end
function I18N:getSystemLanguage()
local sdkLanguage = CS.BF.BFMain.Instance.SDKMgr:GetLanguage()
print("I18N get sdk language " .. sdkLanguage)
local languageInfo = string.split(sdkLanguage, "_")
if not languageInfo or #languageInfo ~= 2 then
print("I18N return system language nil")
return nil
end
local language = languageInfo[1]
local country = languageInfo[2]
if language and language == "zh" then
if country and country == "CN" then
language = "cn"
end
end
language = MOBILE_LANG_MAP[language]
if not self:supportLanguage(language) then
language = nil
end
if language then
Logger.log("I18N return system language %s", language)
else
Logger.log("I18N return system language nil")
end
return language
end
function I18N:getSupportLanguageList()
return SUPPORT_LANGUAGE_LIST
end
function I18N:_getConfig(configName)
local config
if configName == "global" then
config = {}
config.data = require(self.configPath .. configName)
else
config = require(self.configPath .. configName)
end
self.configs[configName] = config
return config
end
function I18N:getConfig(configName)
local config = self.configs[configName]
if config == nil then
config = self:_getConfig(configName)
end
return config.data
end
if NOT_PUBLISH then
I18N.__getConfig = I18N.getConfig
function I18N:getConfig(configName)
if string.lower(configName) ~= configName then
Logger.logFatal("I18N:getConfig 传入的表名不能有大写 " .. configName)
end
return self:__getConfig(configName)
end
end
function I18N:getConfigWithOtherKey(configName, keyName)
local config = self.configs[configName]
if config == nil then
config = self:_getConfig(configName)
end
if config.keys == nil then
return nil
end
return config.keys[keyName]
end
function I18N:getConfigNum(configName)
local config = self.configs[configName]
if config == nil then
config = self:_getConfig(configName)
end
return config.count
end
function I18N:getGlobalText(key, ...)
local config = self:getConfig("global")
local str = config[key]
if str == nil then
return ""
end
if ... then
local param = {...}
if self.cacheGlobalFormatParamSequnce[key] then
self.cacheGlobalIndex = 0
str = string.gsub(str, '{%d+}', function (s)
self.cacheGlobalIndex = self.cacheGlobalIndex + 1
return tostring(param[self.cacheGlobalFormatParamSequnce[key][self.cacheGlobalIndex]])
end)
else
self.cacheGlobalFormatParamSequnce[key] = {}
str = string.gsub(str, '{%d+}', function (s)
self.cacheGlobalIndex = tonumber(string.sub(s, 2,-2)) + 1
table.insert(self.cacheGlobalFormatParamSequnce[key], self.cacheGlobalIndex)
return tostring(param[self.cacheGlobalIndex])
end)
end
end
return str
end
function I18N:getText(configName, index, key, ...)
local config = self:getConfig(configName)
local row = config[index]
if row == nil then
return ""
end
local str = row[key]
if str == nil then
return ""
end
if ... then
local param = {...}
if self.cacheNormalFormatParamSequnce[key] then
self.cacheNormalIndex = 0
str = string.gsub(str, '{%d+}', function (s)
self.cacheNormalIndex = self.cacheNormalIndex + 1
return tostring(param[self.cacheNormalFormatParamSequnce[key][self.cacheNormalIndex]])
end)
else
self.cacheNormalFormatParamSequnce[key] = {}
str = string.gsub(str, '{%d+}', function (s)
self.cacheNormalIndex = tonumber(string.sub(s, 2,-2)) + 1
table.insert(self.cacheNormalFormatParamSequnce[key], self.cacheNormalIndex)
return tostring(param[self.cacheNormalIndex])
end)
end
end
return str
end
function I18N:getFallbackLanguage()
if not self.fallbackLanguage then
local languageInfo = CS.BF.BFPlatform.GetCurrentLanguageInfo()
self.fallbackLanguage = languageInfo:GetFallbackLanguage()
end
return self.fallbackLanguage
end
function I18N:getLanguageAndArea()
if SUPPORT_SERVER_LANGUAGE[self:getCurLanguage()] then
return SUPPORT_SERVER_LANGUAGE[self:getCurLanguage()]
end
return SUPPORT_SERVER_LANGUAGE[GConst.LANGUAGE.ENGLISH]
end
return I18N

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4ddf9f175f3302f4590842552214406d
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,313 @@
local LocalData ={}
local PlayerPrefs = CS.UnityEngine.PlayerPrefs
local LOCAL_DATA_KEY = {
SDK_UID = "SDK_UID",
AUDIO_MUSIC_VOLUME = "AUDIO_MUSIC_VOLUME",
AUDIO_EFFECT_VOLUME = "AUDIO_EFFECT_VOLUME",
SELECTED_LANGUAGE = "SELECTED_LANGUAGE",
GM_SHOW_FLOATING_ICON = "GM_SHOW_FLOATING_ICON",
MESSAGE_BOX_SHOW_TODAY = "MESSAGE_BOX_SHOW_TODAY",
GAME_QUALITY_LEVEL = "GAME_QUALITY_LEVEL", -- 游戏设置品质等级
LAST_LOGIN_URL = "LAST_LOGIN_URL",
LAST_LOGIN_INFO = "LAST_LOGIN_INFO", -- 上一次登录成功的信息
LAST_LOGIN_TYPE = "LAST_LOGIN_TYPE", -- 上次登录类型 token不记录
LAST_LOGIN_NAME = "LAST_LOGIN_NAME",
LAST_LOGIN_IP = "LAST_LOGIN_IP",
ACCOUNT_INFO = "ACCOUNT_INFO",
SEND_QUEUE = "SEND_QUEUE",
SDK_LOGIN_TYPE = "SDK_LOGIN_TYPE",
NEED_UPDATE = "NEED_UPDATE", -- 需要更新
IOS_ORDER_ID = "IOS_ORDER_ID",
IOS_PAY_INFO = "IOS_PAY_INFO",
SHAKE_MODE = "SHAKE_MODE", -- 震动模式
SAVE_POWER_MODE = "SAVE_POWER_MODE", -- 省电模式
LAST_MAIL_ID = "LAST_MAIL_ID",
}
LocalData.KEYS = LOCAL_DATA_KEY
function LocalData:save()
if self.dirty then
self.dirty = false
PlayerPrefs.Save()
end
end
function LocalData:setString(key, value)
self.dirty = true
PlayerPrefs.SetString(key, value)
end
function LocalData:getString(key, defaultValue)
if defaultValue then
return PlayerPrefs.GetString(key, defaultValue)
else
return PlayerPrefs.GetString(key)
end
end
function LocalData:setInt(key, value)
self.dirty = true
PlayerPrefs.SetInt(key, value)
end
function LocalData:getInt(key, defaultValue)
if defaultValue then
return PlayerPrefs.GetInt(key, defaultValue)
else
return PlayerPrefs.GetInt(key)
end
end
function LocalData:setFloat(key, value)
self.dirty = true
PlayerPrefs.SetFloat(key, value)
end
function LocalData:getFloat(key, defaultValue)
if defaultValue then
return PlayerPrefs.GetFloat(key, defaultValue)
else
return PlayerPrefs.GetFloat(key)
end
end
function LocalData:hasKey(key)
return PlayerPrefs.HasKey(key)
end
function LocalData:delKey(key)
self.dirty = true
PlayerPrefs.DeleteKey(key)
end
-- 跟角色挂钩的唯一id
function LocalData:getRoleKey(key)
local uid = DataManager.PlayerData:getUid()
if uid == "" then
Logger.logError("check roleid error!")
end
return key .. uid
end
--------------Implement-----------------
function LocalData:getAudioMusicVolume()
return self:getFloat(LOCAL_DATA_KEY.AUDIO_MUSIC_VOLUME, 1)
end
function LocalData:setAudioMusicVolume(value)
self:setFloat(LOCAL_DATA_KEY.AUDIO_MUSIC_VOLUME, value)
end
function LocalData:getAudioEffectVolume()
return self:getFloat(LOCAL_DATA_KEY.AUDIO_EFFECT_VOLUME, 1)
end
function LocalData:setAudioEffectVolume(value)
self:setFloat(LOCAL_DATA_KEY.AUDIO_EFFECT_VOLUME, value)
end
function LocalData:getSelectedLanguage()
return self:getString(LOCAL_DATA_KEY.SELECTED_LANGUAGE, "")
end
function LocalData:setSelectedLanguage(value)
self:setString(LOCAL_DATA_KEY.SELECTED_LANGUAGE, value)
end
function LocalData:getGMShowFloatingIcon()
return self:getInt(LOCAL_DATA_KEY.GM_SHOW_FLOATING_ICON, 0) == 1
end
function LocalData:setGMShowFloatingIcon(value)
self:setInt(LOCAL_DATA_KEY.GM_SHOW_FLOATING_ICON, value)
end
function LocalData:getMessageBoxShowTodayTime(key)
return self:getInt(LOCAL_DATA_KEY.MESSAGE_BOX_SHOW_TODAY .. key, 0)
end
function LocalData:setMessageBoxShowTodayTime(key, value)
self:setInt(LOCAL_DATA_KEY.MESSAGE_BOX_SHOW_TODAY .. key, value)
end
function LocalData:getGameQualityLevel()
return self:getInt(LOCAL_DATA_KEY.GAME_QUALITY_LEVEL, 0)
end
function LocalData:setGameQualityLevel(level)
self:setInt(LOCAL_DATA_KEY.GAME_QUALITY_LEVEL, level)
end
function LocalData:setTodayFirst(new)
self.isTodayFirst = new
end
function LocalData:getTodayFirst()
return self.isTodayFirst or false
end
function LocalData:setNeedUpdate(value)
value = value or "0.0.0"
self:setString(LOCAL_DATA_KEY.NEED_UPDATE, value)
end
function LocalData:getNeedUpdate()
self:getString(LOCAL_DATA_KEY.NEED_UPDATE, "0.0.0")
end
function LocalData:setIosPayInfo(iosPayInfo)
iosPayInfo = iosPayInfo or {}
local str = json.encode(iosPayInfo)
self:setString(LOCAL_DATA_KEY.IOS_PAY_INFO, str)
end
function LocalData:getIosPayInfo()
local str = self:getString(LOCAL_DATA_KEY.IOS_PAY_INFO, "")
if str == nil or str == "" then
return {}
else
local iosPayInfo = json.decode(str)
if iosPayInfo then
return iosPayInfo
else
return {}
end
end
end
function LocalData:setIosOrders(iosOrders)
iosOrders = iosOrders or {}
local str = json.encode(iosOrders)
self:setString(LOCAL_DATA_KEY.IOS_ORDER_ID, str)
end
function LocalData:getIosOrders()
local str = self:getString(LOCAL_DATA_KEY.IOS_ORDER_ID, "")
if str == nil or str == "" then
return {}
else
local iosOrders = json.decode(str)
if iosOrders then
return iosOrders
else
return {}
end
end
end
function LocalData:setLastLoginInfo(loginType, id, token)
local str = json.encode({
type = loginType,
id = id,
token = token
})
if not loginType then
self:setString(LOCAL_DATA_KEY.LAST_LOGIN_TYPE, "")
elseif loginType ~= "token" then
self:setString(LOCAL_DATA_KEY.LAST_LOGIN_TYPE, loginType)
end
self:setString(LOCAL_DATA_KEY.LAST_LOGIN_INFO, str)
end
function LocalData:getLastLoginInfo()
local str = self:getString(LOCAL_DATA_KEY.LAST_LOGIN_INFO, "{}")
local info = json.decode(str)
info.type = info.type or NetManager.LOGIN_TYPE.ANONYMOUS
info.id = info.id or DeviceHelper:getDeviceId()
info.token = info.token
return info
end
function LocalData:getLastLoginType()
local str = self:getString(LOCAL_DATA_KEY.LAST_LOGIN_TYPE, "")
if str == "" then
str = NetManager.LOGIN_TYPE.ANONYMOUS
end
if str ~= NetManager.LOGIN_TYPE.ANONYMOUS and
str ~= NetManager.LOGIN_TYPE.APPLE and
str ~= NetManager.LOGIN_TYPE.GOOGLE and
str ~= NetManager.LOGIN_TYPE.FACEBOOK
then
str = NetManager.LOGIN_TYPE.ANONYMOUS
end
return str
end
function LocalData:setLastLoginName(name)
name = name or ""
self:setString(LOCAL_DATA_KEY.LAST_LOGIN_NAME, name)
end
function LocalData:getLastLoginName()
return self:getString(LOCAL_DATA_KEY.LAST_LOGIN_NAME, "")
end
function LocalData:saveSendQueue(sendQueue)
local str = json.encode(sendQueue)
if EDITOR_MODE then
Logger.log("---------------------剩余消息队列缓存---------------------------------")
--Logger.logHighlight(str)
print(str)
end
self:setString(LOCAL_DATA_KEY.SEND_QUEUE, str)
end
function LocalData:getSendQueue()
local sendQueue = json.decode(self:getString(LOCAL_DATA_KEY.SEND_QUEUE, "{}"))
return sendQueue
end
function LocalData:setShakeMode(value) -- 0-close 1-open
self:setInt(self:getString(LOCAL_DATA_KEY.SHAKE_MODE), value)
end
function LocalData:getShakeMode()
self:getInt(self:getString(LOCAL_DATA_KEY.SHAKE_MODE), 1)
end
function LocalData:setSavePowerMode(value) -- 0-close 1-open
self:setInt(self:getString(LOCAL_DATA_KEY.SAVE_POWER_MODE), value)
end
function LocalData:getSavePowerMode()
self:getInt(self:getString(LOCAL_DATA_KEY.SAVE_POWER_MODE), 1)
end
function LocalData:getLastMailId()
return self:getInt(LOCAL_DATA_KEY.LAST_MAIL_ID, 0)
end
function LocalData:setLastMailId(id)
if not id then
return
end
self:setInt(LOCAL_DATA_KEY.LAST_MAIL_ID, id)
end
function LocalData:getAccountInfo()
local info = json.decode(self:getString(LOCAL_DATA_KEY.ACCOUNT_INFO, "{}"))
return info
end
function LocalData:setAccountInfo(info)
if not info then
return
end
local str = json.encode(info)
self:setString(LOCAL_DATA_KEY.ACCOUNT_INFO, str)
end
function LocalData:setLastLoginIp(ip)
ip = ip or ""
self:setString(LOCAL_DATA_KEY.LAST_LOGIN_IP, ip)
end
function LocalData:getLastLoginIp()
return self:getString(LOCAL_DATA_KEY.LAST_LOGIN_IP, "")
end
return LocalData

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: af04d753ce34d3f43a83b4bd28b46a25
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

263
lua/app/common/logger.lua Normal file
View File

@ -0,0 +1,263 @@
local Logger = {}
-- 全局的print,必须使用封装的Logger
if not EDITOR_MODE then
print = function(...)
Logger.log(...)
end
end
Logger.tab = " "
Logger.MANUAL_ENABLE_DEBUG = false -- 手动控制激活打印
Logger.ENABLE_TIMES = 5 -- 激活需要的操作次数
local function split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if (delimiter=='') then return false end
local pos,arr = 0, {}
-- for each divider found
for st,sp in function() return string.find(input, delimiter, pos, true) end do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end
local formatTable
formatTable = function(tal, _depth)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
if type(tal) ~= "table" then
return tostring(tal)
else
local _depth = _depth or 0
local getTab = function()
local r = ""
for _ = 1, _depth do
r = r.. Logger.tab
end
return r
end
local result = "{\n"
_depth = _depth + 1
for k, v in pairs(tal) do
if type(v) ~= "table" then
result = result.. getTab().. tostring(k).. " = ".. tostring(v).. "\n"
else
result = result.. getTab().. tostring(k).. " = ".. formatTable(v, _depth + 1) .. "\n"
end
end
result = result.. getTab().. "}"
return result
end
end
Logger.printTable = function(tbl)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger.log(formatTable(tbl))
end
Logger.printTableWarning = function(tbl)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger.logWarning(formatTable(tbl))
end
Logger.printTableError = function(tbl)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger.logError(formatTable(tbl))
end
Logger.log = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger._log("INFO", fmt, ...)
end
Logger.logTodo = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
local t = { string.format(tostring(fmt), ...), }
local traceback = split(debug.traceback("", 2), "\n")
CS.UnityEngine.Debug.Log("<color=magenta>[TODO] " .. table.concat(t) .. "</color>" .. table.concat(traceback, "\n"))
end
Logger.logHighlight = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
local t = { string.format(tostring(fmt), ...), }
local traceback = split(debug.traceback("", 2), "\n")
CS.UnityEngine.Debug.Log("<color=yellow>" .. table.concat(t) .. "</color>" .. table.concat(traceback, "\n"))
end
Logger.logWarning = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger._log("WARNING", fmt, ...)
end
Logger.logError = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger._log("ERROR", fmt, ...)
end
Logger.logFatal = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
Logger._log("FATAL", fmt, ...)
end
Logger.logWarningBox = function(fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
local content = Logger._log("WARNING", fmt, ...)
local params = {
content = content,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
noShowClose = true,
okFunc = function() end,
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
top = true,
}
GFunc.showMessageBox(params)
end
Logger._log = function(tag, fmt, ...)
if IS_PUBLISH and not Logger.MANUAL_ENABLE_DEBUG then
return
end
local str = Logger._checkPercentSign(fmt)
local t = { string.format(tostring(str), ...), }
local traceback = split(debug.traceback("", 2), "\n")
local output
if tag == "FATAL" then
output = table.concat(t) ..table.concat(traceback, "\n")
CS.UnityEngine.Debug.LogError(output)
elseif tag == "ERROR" then
CS.UnityEngine.Debug.Log("<color=red>" .. table.concat(t) .. "</color>" .. table.concat(traceback, "\n"))
elseif tag == "WARNING" then
output = table.concat(t) ..table.concat(traceback, "\n")
CS.UnityEngine.Debug.LogWarning(output)
else
output = table.concat(t) ..table.concat(traceback, "\n")
CS.UnityEngine.Debug.Log(output)
end
return output
end
local function dump_value_(v)
if type(v) == "string" then
v = "\"" .. v .. "\""
end
return tostring(v)
end
Logger.dump = function(value, description, nesting)
if IS_PUBLISH then
return
end
if type(nesting) ~= "number" then nesting = 3 end
local lookupTable = {}
local result = {}
local traceback = split(debug.traceback("", 2), "\n")
CS.UnityEngine.Debug.Log("dump from: " .. string.trim(traceback[3]))
local function dump_(value, description, indent, nest, keylen)
description = description or "<var>"
local spc = ""
if type(keylen) == "number" then
spc = string.rep(" ", keylen - string.len(dump_value_(description)))
end
if type(value) ~= "table" then
result[#result +1 ] = string.format("%s%s%s = %s", indent, dump_value_(description), spc, dump_value_(value))
elseif lookupTable[tostring(value)] then
result[#result +1 ] = string.format("%s%s%s = *REF*", indent, dump_value_(description), spc)
else
lookupTable[tostring(value)] = true
if nest > nesting then
result[#result +1 ] = string.format("%s%s = *MAX NESTING*", indent, dump_value_(description))
else
result[#result +1 ] = string.format("%s%s = {", indent, dump_value_(description))
local indent2 = indent.." "
local keys = {}
local keylen = 0
local values = {}
for k, v in pairs(value) do
keys[#keys + 1] = k
local vk = dump_value_(k)
local vkl = string.len(vk)
if vkl > keylen then keylen = vkl end
values[k] = v
end
table.sort(keys, function(a, b)
if type(a) == "number" and type(b) == "number" then
return a < b
else
return tostring(a) < tostring(b)
end
end)
for i, k in ipairs(keys) do
dump_(values[k], k, indent2, nest + 1, keylen)
end
result[#result +1] = string.format("%s}", indent)
end
end
end
dump_(value, description, "- ", 1)
for i, line in ipairs(result) do
CS.UnityEngine.Debug.Log(line)
end
end
Logger._checkPercentSign = function (str)
if str == nil then
return nil
end
str = tostring(str)
local strTable = {}
for i = 1, #str do
table.insert(strTable, str:sub(i,i))
end
local count = #strTable
local specialChars = {"s","p","c","w","a","l","u","d","x","z",}
for i = count, 1, -1 do
if strTable[i] == '%' and (i + 1) <= count then
local pattern = false
for _, char in ipairs(specialChars) do
if strTable[i + 1] == char then
pattern = true
break
end
end
if not pattern then
table.insert(strTable, i + 1, "%")
end
elseif strTable[i] == '%' and i == count then
table.insert(strTable, "%")
end
end
return table.concat(strTable)
end
return Logger

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 74b5b4b7ed3c12a408e31f57c98933b0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,212 @@
local CharacterFSMManager = require "app/module/character_fsm/character_fsm_manager"
local ModelObject = require "app/bf/unity/model_object"
local CharacterObject = require "app/bf/unity/character_object"
local WeaponObject = require "app/bf/unity/weapon_object"
local ModelManager = {
heroCacheList = {},
heroCacheMap = {}
}
local TypeOfGameObject = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT
local HERO_CACHE_SIZE = 10 -- 英雄缓存容量
function ModelManager:loadHeroAsync(id, parent, weaponAniName, weapon, callback)
local path = "assets/prefabs/models/characters/" .. id .. ".prefab"
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local characterObject = CharacterObject:create()
characterObject:initWithPrefab(assetPath, prefab, id)
characterObject:addUnloadCallback(function(obj)
local modelPath = obj:getAssetPath()
if self.heroCacheMap[modelPath] then
ResourceManager:unload(modelPath)
else
if #self.heroCacheList >= HERO_CACHE_SIZE then
local headPath = table.remove(self.heroCacheList, 1)
ResourceManager:unload(headPath)
self.heroCacheMap[headPath] = nil
end
self.heroCacheMap[modelPath] = true
table.insert(self.heroCacheList, modelPath)
end
end)
if parent then
characterObject:setParent(parent, false)
end
local fsm = CharacterFSMManager:getFsm(characterObject)
characterObject:setCharacterFSM(fsm)
local nodeName = "hand_r_weapon"
if weapon then
for k, name in pairs(GConst.HeroConst.WEAPON_NODE) do
local find = string.find(weapon, k)
if find then
local node = characterObject:getBoneByName(name)
if node then
nodeName = name
end
break
end
end
end
if weapon and characterObject:getBoneByName(nodeName) then
ModelManager:loadWeaponAsync(weapon, characterObject:getBoneByName(nodeName), function(weaponObj)
if weaponObj then
characterObject:setWeaponInfo(weaponAniName, weaponObj)
end
characterObject:play("idle")
if callback then
callback(characterObject, weaponObj)
end
end)
else
characterObject:play("idle")
if callback then
callback(characterObject)
end
end
end)
end
function ModelManager:loadWeaponAsync(weapon, parent, callback)
local path = "assets/prefabs/models/weapon/" .. weapon .. ".prefab"
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local modelObject = WeaponObject:create()
modelObject:initWithPrefab(assetPath, prefab)
modelObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
if parent then
modelObject:setParent(parent, false)
end
if callback then
callback(modelObject)
end
end)
end
function ModelManager:loadMonsterAsync(id, parent, callback)
local path = "assets/prefabs/models/characters/" .. id .. ".prefab"
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local characterObject = CharacterObject:create()
characterObject:initWithPrefab(assetPath, prefab)
characterObject:addUnloadCallback(function(obj)
local modelPath = obj:getAssetPath()
ResourceManager:unload(modelPath)
end)
if parent then
characterObject:setParent(parent, false)
end
local fsm = CharacterFSMManager:getFsm(characterObject)
characterObject:setCharacterFSM(fsm)
if callback then
callback(characterObject)
end
end)
end
function ModelManager:loadModelAsync(path, parent, callback)
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local modelObject = ModelObject:create()
modelObject:initWithPrefab(assetPath, prefab)
modelObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
if parent then
modelObject:setParent(parent, false)
end
if callback then
callback(modelObject)
end
end)
end
function ModelManager:loadHeroShowAsync(id, parent, callback)
local path = "assets/prefabs/models/characters_show/" .. id .. ".prefab"
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local characterObject = CharacterObject:create()
characterObject:initWithPrefab(assetPath, prefab, id)
characterObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
if parent then
characterObject:setParent(parent, false)
end
local fsm = CharacterFSMManager:getFsm(characterObject)
characterObject:setCharacterFSM(fsm)
if callback then
callback(characterObject)
end
end)
end
function ModelManager:getHeroModelPathById(id)
return "assets/prefabs/models/characters/" .. id .. ".prefab"
end
function ModelManager:markCache(path)
if #self.heroCacheList >= HERO_CACHE_SIZE then
return false
end
if self.heroCacheMap[path] == nil then
self.heroCacheMap[path] = true
table.insert(self.heroCacheList, path)
return true
end
return false
end
function ModelManager:isCacheFull()
return #self.heroCacheList >= HERO_CACHE_SIZE
end
function ModelManager:clearCache()
for _, path in ipairs(self.heroCacheList) do
ResourceManager:unload(path)
end
self.heroCacheList = {}
self.heroCacheMap = {}
end
return ModelManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a9dcf898d20140e4d92d50baccefc5e5
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,197 @@
local ModuleManager = {}
local MODULE_PATHS = {
LoginManager = "app/module/login/login_manager",
BattleManager = "app/module/battle/battle_manager",
TipsManager = "app/module/tips/tips_manager",
LoadingManager = "app/module/loading/loading_manager",
DevToolManager = "app/module/gm/dev_tool_manager",
MaincityManager = "app/module/maincity/maincity_manager",
SettingManager = "app/module/setting/setting_manager",
-- 引导
TutorialManager = "app/module/tutorial/tutorial_manager",
ToastManager = "app/ui/common/toast",
PlayerManager = "app/module/player/player_manager",
SummonManager = "app/module/summon/summon_manager",
-- 英雄
HeroManager = "app/module/hero/hero_manager",
-- 修炼
TrainManager = "app/module/train/train_manager",
-- 商城Manager
MallManager = "app/module/mall/mall_manager",
ItemManager = "app/module/item/item_manager",
MasteryManager = "app/module/mastery/mastery_manager",
MiningManager = "app/module/mining/mining_manager",
-- 章节关卡
ChapterManager = "app/module/chapter/chapter_manager",
-- 挂机
IdleManager = "app/module/idle/idle_manager",
-- 设置
GameSettingManager = "app/module/game_setting/game_setting_manager",
AudioManager = "app/module/game_setting/game_setting_manager",
DungeonManager = "app/module/dungeon/dungeon_manager",
ArenaManager = "app/module/arena_manager/arena_manager",
SignInManager = "app/module/signin/signin_manager",
DailyTaskManager = "app/module/activity/daily_task/daily_task_manager",
SevenDayManager = "app/module/activity/seven_day/seven_day_manager",
TaskManager = "app/module/task/task_manager",
ActivityManager = "app/module/activity/activity_manager",
BlessingManager = "app/module/blessing/blessing_manager",
TutorialTaskManager = "app/module/tutorial/tutorial_task_manager",
BountyManager = "app/module/bounty/bounty_manager",
CollectionManager = "app/module/collection/collection_manager",
MailManager = "app/module/mail/mail_manager",
}
-- 这里的key对应func_open里的id
ModuleManager.MODULE_KEY = {
DUNGEON_GOLD = "dungeon_gold",
DUNGEON_DIAMOND = "dungeon_diamond",
DUNGEON_RUNE = "dungeon_rune",
DUNGEON_CHARACTERISTIC = "dungeon_characteristic",
ARENA = "arena",
SUMMON_WEAPON = "summon_weapon",
SUMMON_ARMOR = "summon_armor",
SUMMON_LEGACY = "summon_legacy",
MINE = "mine",
MINE_RESEARCH = "mine_research",
IDLE = "idle",
COMPREHEND = "comprehend",
QUICK_PASS = "quick_pass",
TRAIN = "train",
MASTERY = "mastery",
RUNES = "runes",
SHOP = "shop",
SEVENDAY = "sevenday",
SIGNIN = "signin",
TUTORIALTASK = "tutorialtask",
DAILYTASK = "dailytask",
BLESSING = "blessing",
EQUIP = "equip",
COLLECTION = "collection",
AUTO_FIGHT = "auto_fight",
HERO_OPEN = "hero_open",
WEAPON_OPEN = "weapon_open",
ARMOR_OPEN = "armor_open",
LEGACY_OPEN = "legacy_open",
BATTLE_PASS = "battle_pass",
BATTLE_SPEED_UP = "battle_speed_up",
POWER_SAVE_MODE = "save_power_open",
FUND_OPEN = "fund_open",
MAIL_OPEN = "mail_open",
}
local _moduleMgrs = {}
local MODULE_METATABLE = {
__index = function(t, k)
local path = MODULE_PATHS[k]
if path == nil then
Logger.logError("%s path is not configure in ModuleManager.lua", k)
return
end
local v = require(path):create()
table.insert(_moduleMgrs, v)
rawset(t, k, v)
return v
end
}
setmetatable(ModuleManager, MODULE_METATABLE)
function ModuleManager:init()
if EDITOR_MODE then
---@type LoginManager
self.LoginManager = self.LoginManager or require("app/module/login/login_manager"):create()
---@type BattleManager
self.BattleManager = self.BattleManager or require("app/module/battle/battle_manager"):create()
---@type TipsManager
self.TipsManager = self.TipsManager or require("app/module/tips/tips_manager"):create()
---@type MaincityManager
self.MaincityManager = self.MaincityManager or require("app/module/maincity/maincity_manager"):create()
---@type SummonManager
self.SummonManager = self.SummonManager or require("app/module/summon/summon_manager"):create()
---@type MallManager
self.MallManager = self.MallManager or require("app/module/mall/mall_manager"):create()
---@type MiningManager
self.MiningManager = self.MiningManager or require("app/module/mining/mining_manager"):create()
---@type DungeonManager
self.DungeonManager = self.DungeonManager or require("app/module/dungeon/dungeon_manager"):create()
---@type ArenaManager
self.ArenaManager = self.ArenaManager or require("app/module/arena_manager/arena_manager"):create()
---@type SignInManager
self.SignInManager = self.SignInManager or require("app/module/signin/signin_manager"):create()
end
end
-- 功能是否开启
function ModuleManager:getIsOpen(key, hideToast)
local cfg = ConfigManager:getConfig("func_open")[key]
if cfg == nil then
return true
end
-- 优先判断等级
if cfg.level then
local isOpen = DataManager.PlayerData:getLv() >= cfg.level
if not hideToast and not isOpen then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.FUNC_OPEN_LEVEL, cfg.level))
end
return isOpen
elseif cfg.stage then -- 没有填等级字段就判断关卡
local isOpen = DataManager.ChapterData:getHistoryChapterId() >= cfg.stage
if not hideToast and not isOpen then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.FUNC_OPEN_STAGE, cfg.stage))
end
return isOpen
elseif cfg.task then -- 判断任务
local isOver = DataManager.TutorialTaskData:getTaskCollect(cfg.task)
if not hideToast and not isOver then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.FUNC_OPEN_TASK, cfg.task))
end
return isOver
end
return true
end
function ModuleManager:showPop(key)
local cfg = ConfigManager:getConfig("func_open")[key]
if not cfg then
return false
end
if cfg and cfg.pop_ups and cfg.pop_ups == 1 then
return false
end
return true
end
function ModuleManager:getNotOpenStr(key)
local cfg = ConfigManager:getConfig("func_open")[key]
if cfg == nil then
return GConst.EMPTY_STRING
end
-- 优先判断等级
if cfg.level then
return I18N:getGlobalText(I18N.GlobalConst.FUNC_OPEN_LEVEL, cfg.level)
elseif cfg.stage then -- 没有填等级字段就判断关卡
return I18N:getGlobalText(I18N.GlobalConst.FUNC_OPEN_STAGE, cfg.stage)
elseif cfg.task then
return I18N:getGlobalText(I18N.GlobalConst.FUNC_OPEN_TASK, cfg.task)
end
return GConst.EMPTY_STRING
end
function ModuleManager:getOpenStageId(key)
local cfg = ConfigManager:getConfig("func_open")[key]
if not cfg or cfg.level then
return
end
return cfg.stage
end
function ModuleManager:clear()
for k, v in ipairs(_moduleMgrs) do
v:_clear()
end
end
return ModuleManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 0d32af3473294284980d4fac90625efb
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,205 @@
local PayManager = class("PayManager", BaseModule)
local BLESSING_GIFT_ID = 30001
PayManager.PURCHARSE_TYPE = {
MALL_ACT = 1,
MALL_DAILY = 2,
MALL_TREASURE = 3,
}
PayManager.PURCHARSE_TYPE_CONFIG = {
[PayManager.PURCHARSE_TYPE.MALL_ACT] = "mall_act",
[PayManager.PURCHARSE_TYPE.MALL_DAILY] = "mall_daily",
[PayManager.PURCHARSE_TYPE.MALL_TREASURE] = "mall_treasure",
}
PayManager.BI_ITEM_GET_TYPE = {
[PayManager.PURCHARSE_TYPE.MALL_ACT] = {
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_POP_GIFT] = BIReport.ITEM_GET_TYPE.MALL_POP_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_SKIP_AD_GIFT] = BIReport.ITEM_GET_TYPE.MALL_SKIP_AD_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_SUBSCRIBE_BLESSING_GIFT] = BIReport.ITEM_GET_TYPE.MALL_SUBSCRIBE_BLESSING_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_MONTH_CARD] = BIReport.ITEM_GET_TYPE.MALL_MONTH_CARD,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_LIMIT_GIFT] = BIReport.ITEM_GET_TYPE.MALL_LIMIT_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_FIRST_RECHARGE_GIFT] = BIReport.ITEM_GET_TYPE.MALL_FIRST_RECHARGE_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_CHAPTER_FUND] = BIReport.ITEM_GET_TYPE.MALL_CHAPTER_FUND,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_BATTLE_PASS] = BIReport.ITEM_GET_TYPE.MALL_BATTLE_PASS,
},
[PayManager.PURCHARSE_TYPE.MALL_DAILY] = {
[1] = BIReport.ITEM_GET_TYPE.DAILY_GIFT,
[2] = BIReport.ITEM_GET_TYPE.WEEKLY_GIFT,
},
[PayManager.PURCHARSE_TYPE.MALL_TREASURE] = BIReport.ITEM_GET_TYPE.MALL_TREASURE,
}
PayManager.BI_GIFT_TYPE = {
[PayManager.PURCHARSE_TYPE.MALL_ACT] = {
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_POP_GIFT] = BIReport.GIFT_TYPE.MALL_POP_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_SKIP_AD_GIFT] = BIReport.GIFT_TYPE.MALL_SKIP_AD_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_SUBSCRIBE_BLESSING_GIFT] = BIReport.GIFT_TYPE.MALL_SUBSCRIBE_BLESSING_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_MONTH_CARD] = BIReport.GIFT_TYPE.MALL_MONTH_CARD,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_LIMIT_GIFT] = BIReport.GIFT_TYPE.MALL_LIMIT_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_FIRST_RECHARGE_GIFT] = BIReport.GIFT_TYPE.MALL_FIRST_RECHARGE_GIFT,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_CHAPTER_FUND] = BIReport.GIFT_TYPE.MALL_CHAPTER_FUND,
[ModuleManager.MallManager.MALL_ACT_TYPE.MALL_BATTLE_PASS] = BIReport.GIFT_TYPE.MALL_BATTLE_PASS,
},
[PayManager.PURCHARSE_TYPE.MALL_DAILY] = {
[1] = BIReport.GIFT_TYPE.DAILY_GIFT,
[2] = BIReport.GIFT_TYPE.WEEKLY_GIFT,
},
[PayManager.PURCHARSE_TYPE.MALL_TREASURE] = BIReport.GIFT_TYPE.MALL_TREASURE,
}
function PayManager:getItemGetType(purchaseType, id)
local cfgName = PayManager.PURCHARSE_TYPE_CONFIG[purchaseType]
if not cfgName then
return
end
local cfg = ConfigManager:getConfig(cfgName)
local typeMap = PayManager.BI_ITEM_GET_TYPE[purchaseType]
if not cfg or not cfg[id] or not typeMap then
return
end
local subType = cfg[id].type
if subType then
return typeMap[cfg[id].type]
else
if type(typeMap) ~= "table" then
return typeMap
end
end
end
function PayManager:getGiftType(purchaseType, id)
local cfgName = PayManager.PURCHARSE_TYPE_CONFIG[purchaseType]
if not cfgName then
return
end
local cfg = ConfigManager:getConfig(cfgName)
local typeMap = PayManager.BI_GIFT_TYPE[purchaseType]
if not cfg or not cfg[id] or not typeMap then
return
end
local subType = cfg[id].type
if subType then
return typeMap[cfg[id].type]
else
if type(typeMap) ~= "table" then
return typeMap
end
end
end
function PayManager:purchasePackage(id, purchaseType)
local cfgName = PayManager.PURCHARSE_TYPE_CONFIG[purchaseType]
if not cfgName then
return
end
local cfg = ConfigManager:getConfig(cfgName)
if not cfg or not cfg[id] then
return
end
local rechargeId = cfg[id].recharge_id
local giftType = PayManager:getGiftType(purchaseType, id)
local productId
if rechargeId then
local rechargeCfg = ConfigManager:getConfig("recharge")[rechargeId]
if rechargeCfg == nil then
return
end
productId = rechargeCfg.payId
BIReport:postPayClick(giftType, id, rechargeId)
end
self:checkAndPay(productId, id, purchaseType, rechargeId)
end
function PayManager:requestRewards(purchaseToken, orderId, originOrderId, giftType, id, rechargeId)
self:sendMsgToServer(purchaseToken, orderId, function(binder, msgData)
if msgData.status == 0 then
if msgData.rewards and table.nums(msgData.rewards) > 0 then -- 奖励改到邮件领取
GFunc.showRewardBox(msgData.rewards)
end
BIReport:postPayGet(giftType, id, rechargeId, orderId, originOrderId, 1, msgData.rewards or {})
local rechargeCfg = ConfigManager:getConfig("recharge")[rechargeId]
if rechargeCfg then
BIReport:postPurchase(rechargeCfg.price, rechargeCfg.payId, originOrderId, orderId)
end
table.foreach(msgData.gift, function(i, gift)
local rechargeId = DataManager.ShopData:getShopItemCfg(gift).recharge_id
DataManager.PlayerData:setPaymentCount(rechargeId)
DataManager.ShopData:updateGiftInfo(gift)
if gift.mall_type == PayManager.PURCHARSE_TYPE.MALL_ACT and gift.id == BLESSING_GIFT_ID then
DataManager.BlessingData:onBuyGift()
end
end)
-- 支付验证成功后消耗此订单
if purchaseToken then
SDKManager:consumePurchase(purchaseToken)
end
elseif msgData.status == 1010 then -- 验证异常,但是需要消耗订单
if purchaseToken then
SDKManager:consumePurchase(purchaseToken)
end
Logger.logError("重复验证")
else
Logger.logError("支付验证失败:%s", msgData.status)
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.PAY_FAILED_DESC_1),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
end
end)
end
function PayManager:checkAndPay(productId, id, purchaseType, rechargeId)
-- 检查是否可以支付
SDKManager:checkPay(productId, function(code)
if code == 0 then
self:sendMessage(ProtoMsgType.FromMsgEnum.MallPayReq, {id = id, mall_type = purchaseType}, {}, function(binder, msgData)
if msgData.status == 0 then
if msgData.uuid and msgData.uuid ~= GConst.EMPTY_STRING then
local giftType = PayManager:getGiftType(purchaseType, id)
BIReport:postPayTurn(giftType, id, rechargeId)
SDKManager:pay(productId, msgData.uuid, rechargeId, giftType, function(purchaseToken, orderId, originOrderId)
if purchaseToken and orderId then
self:requestRewards(purchaseToken, orderId, originOrderId, giftType, id, rechargeId)
end
end)
else -- 没有支付信息,直接发奖
if table.nums(msgData.rewards) > 0 then
GFunc.showRewardBox(msgData.rewards)
end
local giftData = {}
giftData.mall_type = msgData.mall_type
giftData.id = msgData.id
giftData.buy_count = DataManager.ShopData:getGiftBoughtNum(msgData.id, msgData.mall_type) + 1
giftData.latest_buy_at = Time:getServerTime() * 1000 -- 服务器都是毫秒
DataManager.ShopData:updateGiftInfo(giftData)
end
else
Logger.logError("预支付失败")
end
end)
end
end)
end
function PayManager:sendMsgToServer(purchaseToken, orderId, callback)
local args = {
uuid = {orderId},
channel = SDKManager:getSDKPayType(),
pay_token = purchaseToken
}
if EDITOR_MODE then
args.channel = SDKManager.PAY_TYPE.DEBUG
end
self:sendMessage(ProtoMsgType.FromMsgEnum.MallPaidResultReq, args, {}, callback)
end
return PayManager

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 64949f07ee1970147a70f0f73ef268d0
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

100
lua/app/common/platform.lua Normal file
View File

@ -0,0 +1,100 @@
local Platform = {}
local bfGateInfo = CS.BF.BFPlatform.GetCurrentGateInfo()
Platform.bfGateInfo = bfGateInfo
---- 获取包名
function Platform:getIdentifier()
return CS.UnityEngine.Application.identifier
end
---- 是否是内网包
function Platform:getIsDevChannel()
return CS.BF.BFPlatform.IsDevChannel()
end
---- 是否是release包
function Platform:getIsReleaseChannel()
return CS.BF.BFPlatform.IsReleaseChannel()
end
---- 是否是发布渠道
function Platform:getIsPublishChannel()
return CS.BF.BFPlatform.IsPublishChannel()
end
---- 获取主链接域名
function Platform:getMainDomain()
return bfGateInfo.mainDomain
end
---- 获取主链接端口
function Platform:getMainPort()
return bfGateInfo.mainPort
end
-- 平台
function Platform:getPlatform()
if self._platform then
return self._platform
end
if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then
self._platform = "Android"
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then
self._platform = "iOS"
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.OSXEditor then
self._platform = "Mac"
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.OSXPlayer then
self._platform = "Mac"
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.WindowsEditor then
self._platform = "Windows"
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.WindowsPlayer then
self._platform = "Windows"
else
self._platform = "Unknow"
end
return self._platform
end
-- 获取当前版本号
function Platform:getClientVersion()
if self.clientVersion == nil then
self.clientVersion = CS.BF.BFMain.Instance.GameLaunchMgr:GetCurrentVersion()
end
return self.clientVersion
end
-- 获取并处理当前版本号 例1.3.2 => 1*1000000 + 3 * 1000 + 2 = 1003002
function Platform:getClientVersionNum()
local version = Platform:getClientVersion()
local versionStrs = string.split(version, ".")
local versionNum1 = tonumber(versionStrs[1])
local versionNum2 = tonumber(versionStrs[2])
local versionNum3 = tonumber(versionStrs[3])
return versionNum1 * 1000000 + versionNum2 * 1000 + versionNum3
end
function Platform:isIosPlatform()
return self:getPlatform() == "iOS"
end
function Platform:isAndroidPlatform()
return self:getPlatform() == "Android"
end
-- 联网需求后端需要的平台字符串
function Platform:getPlatformStr()
if self.platformStr == nil then
if self:isIosPlatform() then
self.platformStr = "IOS"
elseif self:isAndroidPlatform() then
self.platformStr = "Android"
else
self.platformStr = "Unity"
end
end
return self.platformStr
end
return Platform

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9d8a481d7f7038b41a31ebe11b525efb
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,195 @@
local RenderConst = require "app/global/render_const"
local BFRenderMgr = CS.BF.BFMain.Instance.RenderMgr
local RenderManager = {}
RenderManager.POST_EFFECT_TYPE = {
BLOOM = 1,
VIVID_BLOOM = 2,
FXAA = 4,
}
local SUPPORTS_INSTANCING = CS.UnityEngine.SystemInfo.supportsInstancing
local SHADER_VARIANT_PATH = "assets/arts/shaders/shader_variants.shadervariants"
local UI_DEFAULT_MAT_PATH = "assets/arts/materials/ui/ui_default.mat"
local UI_TUTORIAL_MAT_PATH = "assets/arts/materials/ui/ui_tutorial.mat"
local MESH_OUTLINE_FILL_MAT_PATH = "assets/arts/materials/mesh/outline_fill.mat"
local MESH_OUTLINE_MASK_MAT_PATH = "assets/arts/materials/mesh/outline_mask.mat"
local BLUR_MAT_PATH = "assets/arts/materials/post_effect/blur.mat"
local VIVID_BLOOM_MAT_PATH = "assets/arts/materials/post_effect/vivid_bloom.mat"
local BLIT_COPY_MAT_PATH = "assets/arts/materials/post_effect/blit_copy.mat"
local FXAA_MAT_PATH = "assets/arts/materials/post_effect/fxaa.mat"
local RADIAL_BLUR_MAT_PATH = "assets/arts/materials/post_effect/radial_blur.mat"
local TypeOfShaderVariantCollection = typeof(CS.UnityEngine.ShaderVariantCollection)
local TypeOfMaterial = typeof(CS.UnityEngine.Material)
local TypeOfPostEffectBehaviour = typeof(CS.BF.PostEffectBehaviour)
function RenderManager:initRender(callBack)
if self.renderInited then
callBack()
return
end
self.renderInited = true
if USE_AB then
local time = os.clock()
ResourceManager:loadOriginAssetAsync(SHADER_VARIANT_PATH, TypeOfShaderVariantCollection, function(assetPath, asset)
asset:WarmUp()
self:initMaterials(callBack)
Logger.log("init render use time " .. (os.clock() - time))
end)
else
self:initMaterials(callBack)
end
end
function RenderManager:initMaterials(callback)
local loadCount = 4
ResourceManager:loadOriginAssetAsync(UI_DEFAULT_MAT_PATH, TypeOfMaterial, function(path, material)
self.uiDefaultMat = material
BFRenderMgr:SetUIDefaultMat(self.uiDefaultMat)
loadCount = loadCount - 1
if loadCount == 0 then
callback()
end
end)
ResourceManager:loadOriginAssetAsync(UI_TUTORIAL_MAT_PATH, TypeOfMaterial, function(path, material)
self.uiTutorialMat = material
BFRenderMgr:SetUITutorialMat(self.uiTutorialMat)
loadCount = loadCount - 1
if loadCount == 0 then
callback()
end
end)
ResourceManager:loadOriginAssetAsync(MESH_OUTLINE_FILL_MAT_PATH, TypeOfMaterial, function(path, material)
self.meshOutlineFillMat = material
BFRenderMgr:SetMeshOutlineFillMat(self.meshOutlineFillMat)
loadCount = loadCount - 1
if loadCount == 0 then
callback()
end
end)
ResourceManager:loadOriginAssetAsync(MESH_OUTLINE_MASK_MAT_PATH, TypeOfMaterial, function(path, material)
self.meshOutlineMaskMat = material
BFRenderMgr:SetMeshOutlineMaskMat(self.meshOutlineMaskMat)
loadCount = loadCount - 1
if loadCount == 0 then
callback()
end
end)
-- ResourceManager:loadOriginAssetAsync(BLUR_MAT_PATH, TypeOfMaterial, function(path, material)
-- self.blurMat = material
-- BFRenderMgr:SetBlurMat(self.blurMat)
-- loadCount = loadCount - 1
-- if loadCount == 0 then
-- callback()
-- end
-- end)
-- ResourceManager:loadOriginAssetAsync(VIVID_BLOOM_MAT_PATH, TypeOfMaterial, function(path, material)
-- self.vividBloomMat = material
-- BFRenderMgr:SetVividBloomMat(self.vividBloomMat)
-- loadCount = loadCount - 1
-- if loadCount == 0 then
-- callback()
-- end
-- end)
-- ResourceManager:loadOriginAssetAsync(BLIT_COPY_MAT_PATH, TypeOfMaterial, function(path, material)
-- self.blitCopyMat = material
-- BFRenderMgr:SetBlitCopyMat(self.blitCopyMat)
-- loadCount = loadCount - 1
-- if loadCount == 0 then
-- callback()
-- end
-- end)
-- ResourceManager:loadOriginAssetAsync(FXAA_MAT_PATH, TypeOfMaterial, function(path, material)
-- self.fxaaMat = material
-- BFRenderMgr:SetFxaaMat(self.fxaaMat)
-- loadCount = loadCount - 1
-- if loadCount == 0 then
-- callback()
-- end
-- end)
-- ResourceManager:loadOriginAssetAsync(RADIAL_BLUR_MAT_PATH, TypeOfMaterial, function(path, material)
-- self.radialBlurMat = material
-- BFRenderMgr:SetRadialBlur(self.radialBlurMat)
-- loadCount = loadCount - 1
-- if loadCount == 0 then
-- callback()
-- end
-- end)
end
function RenderManager:loadShaderAsync(shaderPath, callBack)
ResourceManager:loadOriginAssetAsync(shaderPath, GConst.TYPEOF_UNITY_CLASS.SHADER, callBack)
end
function RenderManager:unloadShader(shaderPath, immediately)
ResourceManager:unload(shaderPath, immediately)
end
function RenderManager:loadMaterialAsync(materialPath, callBack)
ResourceManager:loadOriginAssetAsync(materialPath, GConst.TYPEOF_UNITY_CLASS.MATERIAL, callBack)
end
function RenderManager:unloadMaterial(materialPath, immediately)
ResourceManager:unload(materialPath, immediately)
end
function RenderManager:closePostEffect(effectType, camera)
BFRenderMgr:ClosePostEffect(effectType, camera)
end
function RenderManager:closeFxaa(camera)
self:closePostEffect(RenderManager.POST_EFFECT_TYPE.FXAA, camera)
end
---- 传入一张图,返回高斯模糊图
function RenderManager:getBlurTexture(texture, width, height, iteration)
if not iteration then
iteration = 4
end
if not self.blurSizeID then
self.blurSizeID = CS.UnityEngine.Shader.PropertyToID("_BlurSize")
end
local CSRenderTexture = CS.UnityEngine.RenderTexture
local CSGraphics = CS.UnityEngine.Graphics
local rt0 = CSRenderTexture.GetTemporary(width, height)
for i = 1, iteration do
self.blurMat:SetFloat(self.blurSizeID, i)
local rt1 = CSRenderTexture.GetTemporary(width, height)
if i == 1 then
CSGraphics.Blit(texture, rt1, self.blurMat, 0)
else
CSGraphics.Blit(rt0, rt1, self.blurMat, 0)
end
CSRenderTexture.ReleaseTemporary(rt0)
rt0 = CSRenderTexture.GetTemporary(width, height)
CSGraphics.Blit(rt1, rt0, self.blurMat, 1)
CSRenderTexture.ReleaseTemporary(rt1)
end
return rt0
end
---- 是否支持gpu instancing
function RenderManager:isSupportInstancing()
return SUPPORTS_INSTANCING
end
function RenderManager:getUITutorialMat()
return self.uiTutorialMat
end
return RenderManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: accb08450dac62b4bb82e2b51dfd4424
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,115 @@
local ResourceManager = {
sceneAbPath = {}
}
local AB_SUFFIX = ".ab"
local ResMgr = CS.BF.BFMain.Instance.ResMgr
function ResourceManager:getSceneAssetBundlePath(path)
local abPath = self.sceneAbPath[path]
if abPath == nil then
local start_index = string.find(path, '/')
if start_index == nil then
abPath = path .. AB_SUFFIX
else
abPath = string.sub(path, start_index + 1) .. AB_SUFFIX
end
self.sceneAbPath[path] = abPath
end
return abPath
end
function ResourceManager:getSceneLoadPath(scenePath)
if USE_AB then
return ResMgr:GetSceneLoadPath(self:getSceneAssetBundlePath(scenePath))
else
return scenePath:gsub("^%l", string.upper)
end
end
function ResourceManager:loadAsync(path, type, callback)
return self:loadOriginAssetAsync(path, type, function(assetPath, asset)
local obj = CS.UnityEngine.Object.Instantiate(asset)
callback(assetPath, obj)
end)
end
function ResourceManager:loadOriginAssetAsync(path, type, callback)
return ResMgr:LoadAsync(path, type, callback)
end
function ResourceManager:loadSceneAsync(scenePath, callback)
ResMgr:LoadSceneAsync(self:getSceneAssetBundlePath(scenePath), callback)
end
function ResourceManager:unloadScene(path)
ResMgr:UnloadScene(self:getSceneAssetBundlePath(path))
end
function ResourceManager:unload(path, immediately)
if immediately then
ResMgr:Unload(path, true)
else
ResMgr:Unload(path, false)
end
end
function ResourceManager:unloadAllDelayAssets()
ResMgr:UnloadAllDelayAssets()
end
function ResourceManager:clear()
ResMgr:Clear()
end
function ResourceManager:destroyPrefab(prefab)
CS.UnityEngine.Object.Destroy(prefab)
end
function ResourceManager:containsAsset(assetPath)
return ResMgr:ContainsAsset(assetPath)
end
if NOT_PUBLISH then
ResourceManager._ReleaseloadOriginAssetAsync = ResourceManager.loadOriginAssetAsync
function ResourceManager:loadOriginAssetAsync(path, type, callback)
local function checkAsset(assetPath, asset)
if asset == nil then
Logger.logError("[LOAD_ERROR]load error:%s", assetPath)
end
callback(assetPath, asset)
end
self:_ReleaseloadOriginAssetAsync(path, type, checkAsset)
end
ResourceManager._ReleaseloadAsync = ResourceManager.loadAsync
function ResourceManager:loadAsync(...)
if self._debugLoadAsyncFuncMap == nil then
self._debugLoadAsyncFuncMap = {
[UIPrefabManager.loadUIWidgetAsync] = true,
[EffectManager.loadUIEffectAsync] = true,
[EffectManager.loadEffectAsync] = true,
[EffectManager.loadBattleEffectAsync] = true,
[EffectManager.loadHeroShowEffectAsync] = true,
[ModelManager.loadHeroAsync] = true,
[ModelManager.loadWeaponAsync] = true,
[ModelManager.loadModelAsync] = true,
[ModelManager.loadHeroShowAsync] = true,
[ModelManager.loadMonsterAsync] = true,
[SpineManager.loadUISpinePrefabAsync] = true,
[SpineManager.loadMeshSpinePrefabAsync] = true,
[SpineManager.loadHeroAsync] = true,
[SpineManager.loadBattleEffectAsync] = true,
}
end
local currFunc = debug.getinfo(2, "f").func
if self._debugLoadAsyncFuncMap[currFunc] == nil then
Logger.logFatal("you can not call ResourceManager:loadAsync directly")
end
self:_ReleaseloadAsync(...)
end
end
return ResourceManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7864dee2e1d007244b1cb5fac876cf94
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,25 @@
local SafeAreaManager = {}
local NOTCH_SCREEN_SIMULATE = "NOTCH_SCREEN_SIMULATE";
local DESIGN_WIDTH = 720
local DESIGN_HEIGHT = 1280
-- 获取刘海高度
function SafeAreaManager:getNotchScreenHeight()
-- local notchHeight = CS.BF.SafeAreaManager.GetNotchScreenHeight()
-- local width, height = GFunc.getScreenSize()
-- local sw = width / DESIGN_WIDTH -- 0.64
-- local sh = height / DESIGN_HEIGHT -- 0.52
-- local minScale = 1
-- if sw < sh then
-- minScale = sw
-- else
-- minScale = sh
-- end
-- return notchHeight / minScale
-- 此项目不用处理刘海屏适配
return 0
end
return SafeAreaManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 931388e31bda5984786825014172b52a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,187 @@
local SchedulerManager = {
crossDayCallbackMap = {}
}
local schedulerMap = {}
local waitRemoveList = {}
local waitSchedulerList = {}
local totalSid = 0
local totalNum = 0
local CSTime = CS.UnityEngine.Time
function SchedulerManager:update()
if totalNum > 0 then
--这里直接使用deltaTime可能有点不够精确因为计时开始的时间不一定是上一帧准点
local inter = CSTime.deltaTime or 0
for sid, info in pairs(schedulerMap) do
if not info.needRemove and not info.pause then
info.tick = info.tick + inter
if info.tick >= info.inter then
info.tick = info.tick - info.inter
local stop = not info.rep
-- 先设置为true避免func里面报错导致每帧调用都会报错
info.needRemove = true
if info.func then
local s = info.func(inter)
stop = stop or s
if stop then
self:unscheduleGlobal(sid)
else
info.needRemove = false
end
else
self:unscheduleGlobal(sid)
end
end
end
end
end
if self.dirty then
self.dirty = false
for i = 1, #waitRemoveList do
local sid = table.remove(waitRemoveList)
if schedulerMap[sid] then
schedulerMap[sid] = nil
totalNum = totalNum - 1
end
end
for i = 1, #waitSchedulerList do
local info = table.remove(waitSchedulerList)
schedulerMap[info.sid] = info
totalNum = totalNum + 1
end
end
end
function SchedulerManager:_startSchedule(func, inter, rep)
totalSid = totalSid + 1
local info = {sid = totalSid, inter = inter or 0, tick = 0, func = func, rep = rep}
table.insert(waitSchedulerList, info)
self.dirty = true
return totalSid
end
-- 此方法不能直接在外部调用请使用例如BaseUIBaseModule等封装好的接口
function SchedulerManager:scheduleGlobal(func, inter)
return self:_startSchedule(func, inter, true)
end
-- 此方法不能直接在外部调用请使用例如BaseUIBaseModule等封装好的接口
function SchedulerManager:performWithDelayGlobal(func, delay)
return self:_startSchedule(func, delay, false)
end
function SchedulerManager:unscheduleGlobal(sid)
local info = schedulerMap[sid]
if info then
info.needRemove = true
info.waitRemove = true
table.insert(waitRemoveList, sid)
self.dirty = true
else
for k, v in ipairs(waitSchedulerList) do
if sid == v.sid then
table.remove(waitSchedulerList, k)
break
end
end
end
end
function SchedulerManager:pause(sid)
local info = schedulerMap[sid]
if info then
if not info.pause and not info.waitRemove then
info.pause = true
end
else
for k, v in ipairs(waitSchedulerList) do
if sid == v.sid then
if not v.pause and not v.waitRemove then
v.pause = true
end
break
end
end
end
end
function SchedulerManager:resume(sid)
local info = schedulerMap[sid]
if info then
if info.pause and not info.waitRemove then
info.pause = false
end
else
for k, v in ipairs(waitSchedulerList) do
if sid == v.sid then
if v.pause and not v.waitRemove then
v.pause = false
end
break
end
end
end
end
function SchedulerManager:unscheduleAll()
schedulerMap = {}
waitRemoveList = {}
waitSchedulerList = {}
totalNum = 0
self.dirty = false
end
function SchedulerManager:clear()
self:unscheduleAll()
end
if NOT_PUBLISH then
function SchedulerManager:_checkDebugScheduleFuncMap()
if self._debugScheduleFuncMap == nil then
local ScrollRectBase = require "app/ui/common/scrollrect/scrollrect_base"
self._debugScheduleFuncMap = {
[BaseUI.performWithDelayGlobal] = true,
[BaseUI.scheduleGlobal] = true,
[BaseScene.performWithDelayGlobal] = true,
[BaseScene.scheduleGlobal] = true,
[BaseModule.performWithDelayGlobal] = true,
[BaseModule.scheduleGlobal] = true,
[BaseObject.performWithDelayGlobal] = true,
[BaseObject.scheduleGlobal] = true,
[SceneManager.scheduleGlobal] = true,
[SDKManager.doNextFrame] = true,
[SDKManager.initPayListener] = true,
[SDKManager.tryLoadRewardedAdDelay] = true,
[ScrollRectBase.refillCells] = true,
[DataManager.scheduleGlobal] = true,
[NetManager.performWithDelayGlobal] = true,
[NetManager.scheduleGlobal] = true,
}
end
end
SchedulerManager._releaseScheduleGlobal = SchedulerManager.scheduleGlobal
function SchedulerManager:scheduleGlobal(...)
self:_checkDebugScheduleFuncMap()
local currFunc = debug.getinfo(2, "f").func
if self._debugScheduleFuncMap[currFunc] == nil then
Logger.logFatal("you can not call SchedulerManager:scheduleGlobal directly")
end
return self:_releaseScheduleGlobal(...)
end
SchedulerManager._releasePerformWithDelayGlobal = SchedulerManager.performWithDelayGlobal
function SchedulerManager:performWithDelayGlobal(...)
self:_checkDebugScheduleFuncMap()
local currFunc = debug.getinfo(2, "f").func
if self._debugScheduleFuncMap[currFunc] == nil then
Logger.logFatal("you can not call SchedulerManager:performWithDelayGlobal directly")
end
return self:_releasePerformWithDelayGlobal(...)
end
end
return SchedulerManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b3781404e1c8481469887c4f5777c276
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,465 @@
local SDKManager = {
startLoginTime = 0
}
-- 新版本SDK部分 ********************************************************
SDKManager.BF_LOGIN_TYPE = {
NONE = 0,
TOKEN = 1,
GUEST = 2,
FACEBOOK = 3,
TEST = 4,
GOOGLE = 5,
APPLE = 6
}
SDKManager.BF_LOGIN_RESULT = {
Success = 0, -- 成功
TokenInvalid = 100, -- token失效
NotAccount = 101, -- 账号不存在
NotBinding = 102, -- 绑定失败
Data = 103, -- 数据错误
RepeatBinding = 104, -- 重复绑定
BindOtherAccount = 105, -- 已绑定其他账号
CheckToken = 106, -- 检查口令失败
}
-- 用于LoginReq
SDKManager.LOGIN_TYPE = {
[0] = "none",
[1] = "token",
[2] = "guest", -- 游客
[3] = "facebook",
[4] = "test",
[5] = "google",
[6] = "apple",
}
-- 支付方式
SDKManager.PAY_TYPE = {
NONE = 0,
GOOGLE = 1,
IOS = 2,
DEBUG = 10
}
local PAY_TYPE_IN_APP = "inapp"
local PAY_TYPE_SUBS = "subs"
local SDKPayMgr
if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then
SDKPayMgr = require "app/common/sdk_pay_google_manager"
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then
SDKPayMgr = require "app/common/sdk_pay_ios_manager"
else
SDKPayMgr = require "app/common/sdk_pay_default_manager"
end
function SDKManager:init()
Logger.logHighlight("SDK INIT ---------------")
-- 标记状态
self.isLogining = false
self.isLogouting = false
-- lazy init
local SDKMgr = CS.BF.BFMain.Instance.SDKMgr
self:initPay()
self:initPayListener()
self:initAdsListener()
-- 拿到firebasetoken
-- self:initFireBaseToken()
end
-- 支付相关接口 ********************************************************************** 开始
function SDKManager:initPay()
SDKPayMgr:init()
end
function SDKManager:initPayListener()
-- 设置支付回调,平时支付走正常回调,如果延迟到账则走延迟到账的回调
if not SDKPayMgr:needInit() then
return
end
if self.paySid then
SchedulerManager:unscheduleGlobal(self.paySid)
self.paySid = nil
end
self.paySid = SchedulerManager:performWithDelayGlobal(function()
self:initPayListener()
end, 5)
SDKPayMgr:initPay(function()
if self.paySid then
SchedulerManager:unscheduleGlobal(self.paySid)
self.paySid = nil
end
self:queryProducePrice()
end)
end
function SDKManager:queryProducePrice()
if self.priceSid then
SchedulerManager:unscheduleGlobal(self.priceSid)
self.priceSid = nil
end
Logger.log("queryProducePrice")
if SDKPayMgr:gotProduct() then
return
end
local products = SDKPayMgr:queryProducePrice() or {}
if #products <= 0 then
self.priceSid = SchedulerManager:performWithDelayGlobal(function()
self:queryProducePrice()
end, 5)
end
end
-- 查询付费产品信息
function SDKManager:queryProducts(callback)
SDKPayMgr:queryProducts(callback)
end
-- 处理未完成的订单
function SDKManager:doUncompleteOrder(callback, productId)
SDKPayMgr:doUncompleteOrder(callback, productId)
end
-- sdk接口 得到特定商品的price
function SDKManager:getProductPrice(skuId)
return SDKPayMgr:getProductPrice(skuId)
end
-- sdk接口 得到特定商品的priceAmountMicros
function SDKManager:getProductPriceAmountMicros(skuId)
return SDKPayMgr:getProductPriceAmountMicros(skuId)
end
-- sdk接口 得到特定商品的currency_code
function SDKManager:getPriceCurrencyCode(skuId)
return SDKPayMgr:getPriceCurrencyCode(skuId)
end
-- 获取支付方式,目前只有google支付
function SDKManager:getSDKPayType()
return SDKPayMgr:getSDKPayType()
end
function SDKManager:getIsSupportSDKPay()
return SDKPayMgr:getIsSupportSDKPay()
end
-- sdk将已完成的订单消耗掉
function SDKManager:consumePurchase(token, callback)
SDKPayMgr:consumePurchase(token, callback)
end
-- 检查是否可以支付
function SDKManager:checkPay(productId, callback)
if not productId or not Platform:getIsPublishChannel() or not SDKManager:getIsSupportSDKPay() then -- 没有productId、非正式渠道、不支持sdk支付的直接返回可支付
callback(0)
return
end
SDKPayMgr:checkPay(productId, callback)
end
-- 支付
function SDKManager:pay(productId, orderId, rechargeId, giftType, callback)
SDKPayMgr:pay(productId, orderId, rechargeId, giftType, callback)
end
function SDKManager:doUncompletePay(callback)
SDKPayMgr:doUncompletePay(callback)
end
-- 支付相关接口 ********************************************************************** 结束
-- 获取设备语言
function SDKManager:getLanguage()
return CS.BF.BFMain.Instance.SDKMgr:GetLanguage()
end
-- 获取设备时区
function SDKManager:getTimeZone()
return CS.BF.BFMain.Instance.SDKMgr:GetTimeZone()
end
function SDKManager:initFireBaseToken()
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetFirebaseToken(function(token)
self.firebaseToken = token
end)
end
function SDKManager:getFirebaseToken()
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetFirebaseToken(function(token)
self.firebaseToken = token
end)
return self.firebaseToken
end
function SDKManager:doNextFrame(callback)
SchedulerManager:performWithDelayGlobal(callback, 0)
end
--- 广告
function SDKManager:isAdLoaded()
if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then
return CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr.AdLoaded
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then
return CS.AdManager.Instance:IsRewardedAdReady()
elseif EDITOR_MODE then
return true
end
return false
end
function SDKManager:tryLoadRewardedAdDelay()
if self.adDelaySid then
SchedulerManager:unscheduleGlobal(self.adDelaySid)
self.adDelaySid = nil
end
self.adDelaySid = SchedulerManager:performWithDelayGlobal(function()
self.adDelaySid = nil
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr:TryLoadRewardedAd()
end, 5)
end
function SDKManager:initAdsListener()
if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr:SetAdShowCallback(function(code)
-- code 为0 表示广告播放成功
if code == 0 then
BIReport:postAdPlaySuccess(self.adsClickType)
else
self:tryLoadRewardedAdDelay()
end
end)
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr:SetAdLoadedCallback(function(code)
-- code 为0 表示广告加载成功
if code ~= 0 then
self:tryLoadRewardedAdDelay()
end
end)
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr:SetAdEarnedRewardCallback(function(code, result)
if self.adCallback then
self:adRewradAd()
self.adCallback()
BIReport:postAdRewardGet(self.adsClickType)
self.adsClickType = nil
self.adCallback = nil
end
end)
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then
-- 初始化一下
local adManager = CS.AdManager.Instance
end
end
function SDKManager:showFullScreenAds(adsClickType, adCallback)
if EDITOR_MODE then
if not adsClickType then
local params = {
content = "SDKManager showFullScreenAds has no adsClickType",
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
Logger.log("SDKManager showFullScreenAds has no adsClickType")
end
end
BIReport:postAdClick(adsClickType)
if EDITOR_MODE then
self:adRewradAd()
if adCallback then
adCallback()
end
return true
end
if NetManager:isNotReachable() then
-- 没有网
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NO_NETWORK))
return false
end
if NetManager:getIsBusy() then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NETWORK_ERROE_1))
return false
end
if DataManager.MallActData:skipAd() then
self:adRewradAd(true)
if adCallback then
adCallback()
end
return true
end
if CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.Android then
if not CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr.AdLoaded then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NO_ADS))
return false
end
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr:SetAdPlacement(adsClickType)
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr.AdLoaded = false
self.adCallback = adCallback
self.adsClickType = adsClickType
CS.BF.BFMain.Instance.SDKMgr.BFIronSourceSDKMgr:ShowFullScreenAds()
return true
elseif CS.UnityEngine.Application.platform == CS.UnityEngine.RuntimePlatform.IPhonePlayer then
if not CS.AdManager.Instance:IsRewardedAdReady() then
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.NO_ADS))
return false
end
self.adsClickType = adsClickType
BIReport:postAdPlaySuccess(self.adsClickType)
CS.AdManager.Instance:ShowRewardedAd(function(code)
if code == 0 then
self:adRewradAd()
if adCallback then
adCallback()
end
BIReport:postAdRewardGet(self.adsClickType)
self.adsClickType = nil
end
end)
return true
end
end
function SDKManager:adRewradAd(noReport)
Logger.logHighlight("-------------------")
ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_WATCH_AD)
if not noReport then
DataManager.PlayerData:addAdCount()
-- BIReport:postAdEvent()
end
end
function SDKManager:getServerList(callback)
local postData = {
project_id = "b5",
bundle_id = Platform:getIdentifier(),
version = Platform:getClientVersion(),
device_id = DeviceHelper:getDeviceId(),
env = "release",-- 暂时写死
}
local loginCenterUrl = CS.BF.BFPlatform.GetLoginCenterURL()
loginCenterUrl = loginCenterUrl .. "?platform=" .. CS.System.Uri.EscapeDataString(Platform:getPlatformStr())
-- lua这边直接构建好参数
for k, v in pairs(postData) do
loginCenterUrl = loginCenterUrl .. "&" .. k .. "=" .. CS.System.Uri.EscapeDataString(v)
end
local guid = CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetNewPlayerGuid()
loginCenterUrl = loginCenterUrl .. "&random=" .. CS.System.Uri.EscapeDataString(guid)
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:SetLuaServerListCallback(function(isSuccess, data)
if callback then
callback(isSuccess, data)
end
end)
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:GetServerList(loginCenterUrl)
end
function SDKManager:_login(callback, loginType)
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:SetLuaLoginCallback(callback)
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:Login(loginType)
end
function SDKManager:login(callback, loginType)
self:logout(function()
if self.isLogining then -- 正在登陆中
Logger.log("三方当前正在登陆中")
return
end
self.isLogining = true
self:_login(function(code, msg)
if code == SDKManager.BF_LOGIN_RESULT.Success then
if not msg then
self.isLogining = false
return
end
local msgTab = json.decode(msg)
if msgTab == nil or type(msgTab) ~= "table" then
self.isLogining = false
return
end
local loginResult = json.decode(msgTab.msg)
if loginResult == nil or type(loginResult) ~= "table" then
self.isLogining = false
return
end
local userId = loginResult.UserId
local token = loginResult.Token
local params = {}
if loginType == SDKManager.BF_LOGIN_TYPE.APPLE then
params = {
type = "apple",
id = tostring(userId),
token = tostring(token)
}
elseif loginType == SDKManager.BF_LOGIN_TYPE.GOOGLE then
params = {
type = "google",
id = tostring(userId),
id_token = tostring(token)
}
end
if callback then
callback(params)
end
end
self.isLogining = false
end, loginType)
end, loginType)
end
function SDKManager:_logout(callback, loginType)
if loginType == SDKManager.BF_LOGIN_TYPE.FACEBOOK or loginType == SDKManager.BF_LOGIN_TYPE.GOOGLE then
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:SetLuaLogoutCallback(callback)
CS.BF.BFMain.Instance.SDKMgr.BFLoginSDKMgr:Logout(loginType)
else
if callback then
callback(SDKManager.BF_LOGIN_RESULT.Success, nil)
end
end
end
function SDKManager:logout(callback, loginType)
if self.isLogouting then -- 正在登出
Logger.log("当前正在登出中")
return
end
self.isLogouting = true
self:_logout(function(code, msg)
if (code == SDKManager.BF_LOGIN_RESULT.Success) then
if callback then
callback()
end
else
if msg and msg ~= "" then
local jData = json.decode(msg)
if jData then
local type = jData.loginType
local msg = jData.msg
Logger.logError("登出失败 result:%s type:%s msg:%s", code, type, msg)
else
Logger.logError("登出失败 result:%s", code)
end
else
Logger.logError("登出失败")
end
if callback then
callback()
end
end
self.isLogouting = false
end, loginType)
end
return SDKManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e9724727c54602e43b70bcc7a11daa70
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,67 @@
local SDKPayDefaultManager = {}
function SDKPayDefaultManager:init()
end
function SDKPayDefaultManager:needInit()
return false
end
function SDKPayDefaultManager:initPay(callback)
self.products = {}
if callback then
callback()
end
end
function SDKPayDefaultManager:gotProduct()
return true
end
-- sdk接口 得到特定商品的price
function SDKPayDefaultManager:getProductPrice(skuId)
end
-- sdk接口 得到特定商品的priceAmountMicros
function SDKPayDefaultManager:getProductPriceAmountMicros(skuId)
end
-- sdk接口 得到特定商品的currency_code
function SDKPayDefaultManager:getPriceCurrencyCode(skuId)
end
function SDKPayDefaultManager:getSDKPayType()
return SDKManager.PAY_TYPE.NONE
end
-- 获取支付方式,目前只有google支付
function SDKPayDefaultManager:getIsSupportSDKPay()
return false
end
-- 检查是否可以支付
function SDKPayDefaultManager:checkPay(productId, callback)
callback(0)
end
-- 支付
function SDKPayDefaultManager:pay(productId, orderId, rechargeId, giftType, callback)
callback("", orderId)
end
function SDKPayDefaultManager:doUncompletePay(callback)
end
-- 查询付费产品信息
function SDKPayDefaultManager:queryProducts(callback)
end
-- 处理未完成的订单
function SDKPayDefaultManager:doUncompleteOrder(callback, productId)
end
-- sdk将已完成的订单消耗掉
function SDKPayDefaultManager:consumePurchase(token, callback)
end
return SDKPayDefaultManager

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: f3097630175c24a4dabdc87d46d828f4
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

View File

@ -0,0 +1,464 @@
local SDKPayGoogleManager = {}
local PAY_TYPE_IN_APP = "inapp"
local PAY_TYPE_SUBS = "subs"
function SDKPayGoogleManager:init()
end
function SDKPayGoogleManager:needInit()
return true
end
function SDKPayGoogleManager:initPay(callback)
self.products = {}
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:SetGoogleDelayPayCallback(SDKPayGoogleManager.onGooglePayDelayCallback)
if callback then
callback()
end
end
-- 这里定义的时候不能使用冒号,否则参数不对
function SDKPayGoogleManager.onGooglePayDelayCallback(code, msg)
if code == 0 and msg and msg ~= "" then
Logger.log("延迟支付到账:%s", msg)
local result = json.decode(msg)
local purchaseToken = result.purchaseToken
if purchaseToken == nil or purchaseToken == "" then
return
end
if result.obfuscatedAccountId then
PayManager:requestRewards(purchaseToken, result.obfuscatedAccountId)
end
end
end
-- 查询付费产品信息
function SDKPayGoogleManager:queryProducts(callback)
if self.queryProductsOver then -- 已经查询成功过了
if callback then
callback()
end
else
local rechargeCfg = ConfigManager:getConfig("recharge")
if rechargeCfg then
local inAppList = {} -- 内购类
local subsList = {} -- 订阅list
for _, rechargeInfo in ipairs(rechargeCfg) do
if rechargeInfo.subscribe then
table.insert(subsList, rechargeInfo.payId)
else
table.insert(inAppList, rechargeInfo.payId)
end
end
self.products = {}
self:queryProductInfo(PAY_TYPE_IN_APP, json.encode(inAppList), function(code, msg)
if code == 0 then
if msg and msg ~= "" then -- 更新products
Logger.logHighlight(msg)
local jData = json.decode(msg)
if jData and #jData > 0 then
for i = 1, #jData do
table.insert(self.products, jData[i])
end
end
end
if #subsList > 0 then
self:queryProductInfo(PAY_TYPE_SUBS, json.encode(subsList), function(code, msg)
if code == 0 then
if msg and msg ~= "" then -- 更新products
local jData = json.decode(msg)
if jData and #jData > 0 then
for i = 1, #jData do
table.insert(self.products, jData[i])
end
end
end
if callback then
callback()
end
end
end)
else
if callback then
callback()
end
end
end
end)
end
end
end
-- 商品数据
function SDKPayGoogleManager:queryProductInfo(payType, json, callback)
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:QueryProductInfo(payType, json, function(code, msg)
SDKManager:doNextFrame(function()
callback(code, msg)
end)
end)
end
-- 未完成的订单请求服务器 completeOrderState状态:
-- 0表示未完成订单消耗完成
-- 1表示存在和指定productId相同的支付中的订单
-- 2表示存在和指定productId相同的无法成功消耗的订单
-- 3表示存在无法成功消耗的订单但是其中没有和指定productId相同
function SDKPayGoogleManager:reqPayReward(uncompleteList, productId, callback)
local index = 1
local completeOrderState = 0
local function handleOrder(uncompleteOrder)
if uncompleteOrder == nil then
if callback then
callback(completeOrderState)
end
return
end
if uncompleteOrder.purchaseState == "2" then
-- 处理中的订单
index = index + 1
if uncompleteOrder.productId and uncompleteOrder.productId ~= "" and uncompleteOrder.productId == productId then
-- 存在和指定productId相同的支付中的订单
completeOrderState = 1
end
handleOrder(uncompleteList[index])
elseif uncompleteOrder.purchaseToken then
-- 去服务器验证
if uncompleteOrder.obfuscatedAccountId then
PayManager:requestRewards(uncompleteOrder.purchaseToken, uncompleteOrder.obfuscatedAccountId)
else
SDKManager:consumePurchase(uncompleteOrder.purchaseToken, function()
index = index + 1
handleOrder(uncompleteList[index])
end)
end
else
index = index + 1
handleOrder(uncompleteList[index])
end
end
handleOrder(uncompleteList[index])
end
-- 处理未完成的订单
function SDKPayGoogleManager:doUncompleteOrder(callback, productId)
self:queryUncompleteOrder(function(list)
if list and type(list) == "table" and #list > 0 then
self:reqPayReward(list, productId, callback)
else -- 没有未完成的订单
if callback then
callback(0)
end
end
end)
end
-- 查询未完成的订单
function SDKPayGoogleManager:queryUncompleteOrder(callback)
local list -- 查询到的数据,整合了内购
-- 查找内购
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:QueryUncompleteOrder(PAY_TYPE_IN_APP, function(code, msg)
-- 此查询接口没有失败的情况
if msg and msg ~= "" then
list = json.decode(msg)
end
if callback then
callback(list)
end
end)
end
-- 订阅到期查询订阅状态
function SDKPayGoogleManager:querySubscribeInfo()
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:QueryUncompleteOrder(PAY_TYPE_SUBS, function(code, msg)
-- 此查询接口没有失败的情况
local subsList
if msg and msg ~= "" then
subsList = json.decode(msg)
end
if subsList then
for _, order in ipairs(subsList) do
if order.purchaseState == 1 then -- 已购买
local args = {
purchase_token = order.purchaseToken,
order_id = order.obfuscatedAccountId
}
break
end
end
end
end)
end
function SDKPayGoogleManager:queryProducePrice()
return self.products
end
function SDKPayGoogleManager:gotProduct()
return true
end
-- sdk接口 得到特定商品的price
function SDKPayGoogleManager:getProductPrice(skuId)
if self.products and #self.products > 0 then
for _, data in ipairs(self.products) do
if data.sku == skuId then
return data.price
end
end
end
return nil
end
-- sdk接口 得到特定商品的priceAmountMicros
function SDKPayGoogleManager:getProductPriceAmountMicros(skuId)
if self.products and #self.products > 0 then
for _, data in ipairs(self.products) do
if data.sku == skuId then
return data.priceAmountMicros
end
end
end
return nil
end
-- sdk接口 得到特定商品的currency_code
function SDKPayGoogleManager:getPriceCurrencyCode(skuId)
if self.products and #self.products > 0 then
for _, data in ipairs(self.products) do
if data.sku == skuId then
return data.priceCurrencyCode
end
end
end
return nil
end
function SDKPayGoogleManager:getSDKPayType()
if Platform:getIsPublishChannel() then
return SDKManager.PAY_TYPE.GOOGLE
else
return SDKManager.PAY_TYPE.NONE
end
end
-- 获取支付方式,目前只有google支付
function SDKPayGoogleManager:getIsSupportSDKPay()
return true
end
function SDKPayGoogleManager:_getIsGoogleStoreConnected()
return CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr.ConnectStoreSucc
end
-- 检查是否可以支付
function SDKPayGoogleManager:checkPay(productId, callback)
if self:_getIsGoogleStoreConnected() then -- google商店是否初始化
self:doUncompleteOrder(function(code) -- 先处理未完成的订单
if code == 0 then
callback(0)
elseif code == 1 then -- 指定的productId存在支付状态中的订单
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_23),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
elseif code == 2 then -- 指定的productId存在未完成的订单消耗失败的情况
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_23),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
else -- 存在未完成的订单消耗失败的情况但是因为不是当前productId所以允许继续支付
callback(0)
end
end, productId)
else
self:connectGoogleStore(function(code)
if code == 0 then
self:doUncompleteOrder(function(consumeSucc)
if code == 0 then
callback(0)
elseif code == 1 then -- 指定的productId存在支付状态中的订单
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_23),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
elseif code == 2 then -- 指定的productId存在未完成的订单消耗失败的情况
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_23),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
else -- 存在未完成的订单消耗失败的情况但是因为不是当前productId所以允许继续支付
callback(0)
end
end, productId)
else
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_22),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
end
end)
end
end
-- 支付
function SDKPayGoogleManager:pay(productId, orderId, rechargeId, giftType, callback)
self:doGooglePay(productId, orderId, rechargeId, giftType, callback)
end
-- 连接Google商店
function SDKPayGoogleManager:connectGoogleStore(callback)
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:ConnectGoogleStore(function(code)
SDKManager:doNextFrame(function()
callback(code)
end)
end)
end
function SDKPayGoogleManager:doGooglePay(productId, orderId, rechargeId, giftType, callback)
local payType = PAY_TYPE_IN_APP
local rechargeCfg = ConfigManager:getConfig("recharge")[rechargeId]
if rechargeCfg.subscribe then
payType = PAY_TYPE_SUBS
end
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:Pay(payType, productId, orderId, function(code, msg)
if code == 0 then
-- 支付成功
Logger.log("pay success:%s", msg)
local result = json.decode(msg)
if callback then
callback(result.purchaseToken, result.obfuscatedAccountId, result.orderId)
end
elseif code == 1 then
-- 支付取消
GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_25))
BIReport:postPayCancel(productId, orderId, rechargeId, giftType)
else
-- 支付失败
Logger.log("pay failed")
BIReport:postPayFailed(productId, orderId, rechargeId, msg or GConst.EMPTY_STRING, giftType)
end
end)
end
-- sdk将已完成的订单消耗掉
function SDKPayGoogleManager:consumePurchase(token, callback)
if not token then
return
end
CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr:ConsumePurchase(token, function(code, msg)
if code == 0 then
Logger.log("consume %s success", token)
else
Logger.log("consume %s failed", token)
end
if callback then
callback(code)
end
end)
end
function SDKPayGoogleManager:doUncompletePay(callback)
-- 每次游戏的过程中只处理一次
if self.alreadyFinishUncompletePay then
return
end
if not DataManager:getLoginSuccess() then
return
end
if NetManager:getIsBusy() then
return
end
if self:_getIsGoogleStoreConnected() then
-- google商店是否初始化
self.alreadyFinishUncompletePay = true
SDKManager:queryProducts(function()
SDKManager:doUncompleteOrder()
end)
end
end
-- 第一步向服务器验证订单号
-- function SDKPayGoogleManager:_checkPurchaseOrder(result, productId, callback)
-- -- SDKPayGoogleManager:saveOrderId(result.orderId)
-- if DataManager.PlayerData:isInPermanentOrders(result.obfuscatedAccountId) then
-- return
-- end
-- local params = {}
-- params.receipt = {}
-- params.receipt.packageName = Platform:getIdentifier()
-- params.receipt.productId = productId
-- params.receipt.purchaseToken = result.purchaseToken
-- params.receipt.subscription = false
-- CS.BF.BFMain.Instance.ParseClientMgr:SetLuaCheckPurchaseOrderCallback(function (msg)
-- local serverResult = json.decode(msg)
-- local _result = serverResult.result
-- Logger.printTable(serverResult)
-- if _result and _result.data then
-- if _result.code == 0 then
-- -- SDKPayGoogleManager:delOrderId(_result.data.orderId)
-- SDKPayGoogleManager:saveOrderId(_result.data.obfuscatedExternalAccountId, params)
-- SDKPayGoogleManager:checkPurchaseConsume(_result.data.obfuscatedExternalAccountId, params, callback)
-- -- if callback then
-- -- callback(_result.data.purchaseToken, _result.data.obfuscatedAccountId, _result.data.orderId)
-- -- end
-- elseif _result.code == 137 then
-- -- SDKPayGoogleManager:delOrderId(_result.data.orderId)
-- SDKPayGoogleManager:consumePurchase(_result.data.purchaseToken)
-- else
-- -- @TODO 重试
-- end
-- end
-- end)
-- CS.BF.BFMain.Instance.ParseClientMgr:CheckPurchaseGPOrder(json.encode(params))
-- end
-- 第二步向服务器申请消耗订单
-- function SDKPayGoogleManager:checkPurchaseConsume(orderId, params, callback, callback1)
-- if not orderId or not params then
-- return
-- end
-- CS.BF.BFMain.Instance.ParseClientMgr:SetLuaCheckPurchaseConsumeCallback(function (msg)
-- local serverResult = json.decode(msg)
-- local _result = serverResult.result
-- Logger.printTable(serverResult)
-- if _result and _result.data then
-- if _result.code == 0 or _result.code == 137 then
-- SDKPayGoogleManager:delOrderId(orderId)
-- SDKPayGoogleManager:savePermanentOrderId(orderId)
-- if callback then
-- callback(_result.data.purchaseToken, _result.data.obfuscatedExternalAccountId, _result.data.orderId)
-- else
-- PayManager:requestRewards(_result.data.purchaseToken, orderId)
-- SDKPayGoogleManager:consumePurchase(_result.data.purchaseToken)
-- if callback1 then
-- callback1()
-- end
-- end
-- -- elseif _result.code == 137 then
-- -- SDKPayGoogleManager:delOrderId(orderId)
-- -- SDKPayGoogleManager:consumePurchase(_result.data.purchaseToken)
-- else
-- -- @TODO 重试
-- end
-- end
-- end)
-- CS.BF.BFMain.Instance.ParseClientMgr:CheckPurchaseGPConsume(json.encode(params))
-- end
-- 支付相关接口 ********************************************************************** 结束
return SDKPayGoogleManager

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: fbf58d426d968fd4b9adf30d353a2973
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

View File

@ -0,0 +1,394 @@
local SDKPayiOSManager = {}
function SDKPayiOSManager:init()
self.iosPayInfos = LocalData:getIosPayInfo()
self.iosOrders = LocalData:getIosOrders()
end
function SDKPayiOSManager:needInit()
return true
end
function SDKPayiOSManager:initPay(callback)
self.products = {}
CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr.initCallback = function (isSuccess, products, errorStr)
if isSuccess then
-- GFunc.showToast("初始化成功")
if callback then
callback()
end
BIReport:postPayInitSuccess()
else
Logger.log(errorStr)
BIReport:postPayInitFailed(errorStr)
end
end
CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr.buyCallback = function(isSuccess, result, errorStr)
if isSuccess then
-- if self.handleUncompleteIosOrder then
-- local payParams = self.iosPayInfos[result.transactionID]
-- local needConsumePurchase = true
-- if payParams ~= nil and payParams.order then
-- PayManager:requestRewards(result.receipt, payParams.order)
-- needConsumePurchase = false
-- end
-- if needConsumePurchase then
-- self:delIosPayInfo(result.transactionID)
-- self:delIosOrder(result.definition.id)
-- self:consumePurchase(result.definition.id)
-- BIReport:postPayFailed(result.definition.id, result.transactionID, nil, "error order")
-- end
-- else
-- -- 回调时机太早的话,就先保存起来,等后续补单的时候一起补
-- local order = self.iosOrders[result.definition.id]
-- if order then
-- self:saveIosPayInfo(result.transactionID, result.receipt, order, result.definition.id)
-- self:delIosOrder(result.definition.id)
-- else
-- -- 之前没有记录只能算掉单了
-- self:delIosPayInfo(result.transactionID)
-- self:delIosOrder(result.definition.id)
-- self:consumePurchase(result.definition.id)
-- BIReport:postPayFailed(result.definition.id, result.transactionID, nil, "not have order")
-- end
-- end
else
-- if errorStr and errorStr ~= "" then
-- BIReport:postPayFailed(result.definition.id, result.transactionID, nil, errorStr)
-- else
-- BIReport:postPayFailed(result.definition.id, result.transactionID, nil, "1")
-- end
end
end
local rechargeCfg = ConfigManager:getConfig("recharge")
local products = {}
for i,v in ipairs(rechargeCfg) do
table.insert(products, {productId = v.payId, type = CS.UnityEngine.Purchasing.ProductType.Consumable})
end
CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr:Init(products)
end
function SDKPayiOSManager:queryProducePrice()
if self.products and #self.products > 0 then
return self.products
end
local rechargeCfg = ConfigManager:getConfig("recharge")
self.products = {}
for _, v in ipairs(rechargeCfg) do
local price = CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr:GetLocalizedPrice(v.payId)
if price and price ~= "" then
Logger.log("product = %s, price = %s", v.payId, price)
table.insert(self.products, {sku = v.payId, price = price})
end
end
return self.products
end
function SDKPayiOSManager:queryProducts()
end
-- 处理未完成的订单
function SDKPayiOSManager:doUncompleteOrder(callback, productId)
self.handleUncompleteIosOrder = true
local orders = self.iosPayInfos
if orders == nil then
return callback and callback()
end
local uncompleteList = {}
for _, v in pairs(orders) do
table.insert(uncompleteList, v)
end
if #uncompleteList <= 0 then
return callback and callback()
end
local index = 1
local function handleOrder(uncompleteOrder)
if uncompleteOrder == nil then
return callback and callback()
end
-- 去服务器验证
if uncompleteOrder.order then
PayManager:requestRewards(uncompleteOrder.receipt, uncompleteOrder.order)
else
SDKManager:delIosPayInfo(uncompleteOrder.transactionID)
SDKManager:delIosOrder(uncompleteOrder.productId)
self:consumePurchase(uncompleteOrder.productId, function()
index = index + 1
handleOrder(uncompleteList[index])
end)
end
end
handleOrder(uncompleteList[index])
end
-- 查询未完成的订单
function SDKPayiOSManager:queryUncompleteOrder(callback)
end
-- 订阅到期查询订阅状态
function SDKPayiOSManager:querySubscribeInfo()
end
function SDKPayiOSManager:gotProduct()
if self.products and #self.products > 0 then
return true
end
return false
end
-- sdk接口 得到商品的price
function SDKPayiOSManager:getProductPrice(skuId)
if self.products and #self.products > 0 then
for _, data in ipairs(self.products) do
if data.sku == skuId then
return data.price
end
end
end
return nil
end
-- sdk接口 得到特定商品的priceAmountMicros
function SDKPayiOSManager:getProductPriceAmountMicros(skuId)
if self.products and #self.products > 0 then
for _, data in ipairs(self.products) do
if data.sku == skuId then
return data.priceAmountMicros
end
end
end
return nil
end
-- sdk接口 得到特定商品的currency_code
function SDKPayiOSManager:getPriceCurrencyCode(skuId)
if self.products and #self.products > 0 then
for _, data in ipairs(self.products) do
if data.sku == skuId then
return data.priceCurrencyCode
end
end
end
return nil
end
function SDKPayiOSManager:getSDKPayType()
if Platform:getIsPublishChannel() then
return SDKManager.PAY_TYPE.IOS
else
return SDKManager.PAY_TYPE.NONE
end
end
-- 获取支付方式,目前只有google支付
function SDKPayiOSManager:getIsSupportSDKPay()
return true
end
function SDKPayiOSManager:getIsGoogleStoreConnected()
return CS.BF.BFMain.Instance.SDKMgr.BFPaySDKMgr.ConnectStoreSucc
end
function SDKPayiOSManager:_getIsIosInitialized()
return CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr:IsInitialized()
end
-- 检查是否可以支付
function SDKPayiOSManager:checkPay(productId, callback)
if self:_getIsIosInitialized() then
SDKManager:doUncompleteOrder(function(code)
-- 先处理未完成的订单
if code == 0 then
callback(0)
elseif code == 1 then
-- 指定的productId存在支付状态中的订单
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_23),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
elseif code == 2 then
-- 指定的productId存在未完成的订单消耗失败的情况
local params = {
content = I18N:getGlobalText(I18N.GlobalConst.SETTING_DESC_23),
boxType = GConst.MESSAGE_BOX_TYPE.MB_OK,
okText = I18N:getGlobalText(I18N.GlobalConst.BTN_TEXT_OK),
}
GFunc.showMessageBox(params)
else
-- 存在未完成的订单消耗失败的情况但是因为不是当前productId所以允许继续支付
callback(0)
end
end)
end
end
-- 支付
function SDKPayiOSManager:pay(productId, orderId, rechargeId, giftType, callback)
self:doIosPay(productId, orderId, rechargeId, callback)
end
-- sdk将已完成的订单消耗掉
function SDKPayiOSManager:consumePurchase(token, callback)
CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr:ConsumePurchase(token)
if callback then
callback(0)
end
end
function SDKPayiOSManager:doIosPay(productId, orderId, rechargeId, giftType, callback)
self.blockTouch = true
UIManager:showWaitNet()
CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr.buyCallback = function(isSuccess, result, errorStr)
if self.blockTouch then
self.blockTouch = false
UIManager:hideWaitNet()
end
if isSuccess then
Logger.log("ios pay availableToPurchase = %s", result.availableToPurchase)
Logger.log("ios pay transactionID = %s", result.transactionID)
Logger.log("ios pay hasReceipt = %s", result.hasReceipt)
Logger.log("ios pay receipt = %s", result.receipt)
self:saveIosPayInfo(result.transactionID, result.receipt, orderId, productId)
if callback then
callback(result.receipt, orderId, result.transactionID)
end
else
if errorStr and errorStr ~= "" then
BIReport:postPayFailed(productId, orderId, rechargeId, errorStr, giftType)
else
BIReport:postPayFailed(productId, orderId, rechargeId, "1", giftType)
end
end
self:delIosOrder(productId)
end
self:saveIosOrder(productId, orderId)
CS.BF.BFMain.Instance.SDKMgr.IosPaySDKMgr:Buy(productId, orderId)
end
function SDKPayiOSManager:doUncompletePay(callback)
-- 每次游戏的过程中只处理一次
if self.alreadyFinishUncompletePay then
return
end
if not DataManager:getLoginSuccess() then
return
end
if NetManager:getIsBusy() then
return
end
if self:_getIsIosInitialized() then
self.alreadyFinishUncompletePay = true
SDKManager:doUncompleteOrder()
end
end
function SDKPayiOSManager:checkPurchaseOrder(result, productId, callback)
end
function SDKPayiOSManager:saveIosPayInfo(transactionID, receipt, order, productId)
self.iosPayInfos[transactionID] = {
order = order,
receipt = receipt,
transactionID = transactionID,
productId = productId
}
LocalData:setIosPayInfo(self.iosPayInfos)
LocalData:save()
end
function SDKPayiOSManager:saveIosOrder(productId, order)
self.iosOrders[productId] = order
LocalData:setIosOrders(self.iosOrders)
LocalData:save()
end
function SDKPayiOSManager:delIosOrder(productId)
self.iosOrders[productId] = nil
LocalData:setIosOrders(self.iosOrders)
LocalData:save()
end
-- 第一步向服务器验证订单号
-- function SDKPayiOSManager:checkPurchaseIOSOrder(result, productId, callback)
-- Logger.printTable(result)
-- Logger.log(productId)
-- local orderId = DataManager.PlayerData:getIosOrderId(result.transactionID)
-- if not orderId then
-- return
-- end
-- if DataManager.PlayerData:isInPermanentOrders(result.transactionID) then
-- return
-- end
-- local params = {}
-- -- params.receipt.packageName = Platform:getIdentifier()
-- -- params.receipt.productId = productId
-- params.receipt = result.receipt
-- params.transaction_id = result.transactionID
-- CS.BF.BFMain.Instance.ParseClientMgr:SetLuaCheckPurchaseIOSOrderCallback(function (msg)
-- local serverResult = json.decode(msg)
-- local _result = serverResult.result
-- Logger.printTable(serverResult)
-- -- 后端返回latest_receipt_info
-- if _result and _result.data then
-- if _result.code == 0 then
-- SDKPayiOSManager:saveOrderId(result.transactionID, params)
-- -- 第二次验证
-- SDKPayiOSManager:checkPurchaseConsume(result, params, callback)
-- elseif _result.code == 137 then
-- -- SDKPayiOSManager:delOrderId(_result.data.orderId)
-- -- 消耗订单
-- -- SDKPayiOSManager:consumePurchase(_result.data.purchaseToken)
-- else
-- -- @TODO 重试
-- end
-- end
-- end)
-- CS.BF.BFMain.Instance.ParseClientMgr:CheckPurchaseIOSOrder(json.encode(params))
-- end
-- 第二步向服务器申请消耗订单
-- function SDKPayiOSManager:checkPurchaseConsume(result, params, callback, callback1)
-- if not result or not params then
-- return
-- end
-- local orderId = DataManager.PlayerData:getIosOrderId(result.transactionID)
-- if not orderId then
-- return
-- end
-- CS.BF.BFMain.Instance.ParseClientMgr:SetLuaCheckPurchaseIOSConsumeCallback(function (msg)
-- local serverResult = json.decode(msg)
-- local _result = serverResult.result
-- Logger.printTable(serverResult)
-- if _result and _result.data then
-- if _result.code == 0 then
-- -- 处理本地存储订单
-- SDKPayiOSManager:delIosOrderId(result.transactionID)
-- SDKPayiOSManager:delOrderId(result.transactionID)
-- SDKPayiOSManager:savePermanentOrderId(result.transactionID)
-- if callback then
-- callback(result.receipt, orderId, result.transactionID)
-- else
-- -- SDKPayiOSManager:consumePurchase(_result.data.purchaseToken)
-- PayManager:requestRewards(_result.data.purchaseToken, orderId)
-- if callback1 then
-- callback1()
-- end
-- end
-- elseif _result.code == 137 then
-- else
-- -- @TODO 重试
-- end
-- end
-- end)
-- CS.BF.BFMain.Instance.ParseClientMgr:CheckPurchaseIOSConsume(json.encode(params))
-- end
-- 支付相关接口 ********************************************************************** 结束
return SDKPayiOSManager

View File

@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: da69c0aee3d32ea4c86e5844df968f98
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 3b8b241bab4a4ac9a22fcce9c64f1242, type: 3}

View File

@ -0,0 +1,27 @@
local ServerPushManager = {}
---- 注册推送监听
function ServerPushManager:addServerPushListener(msgName, module, callback)
NetManager:registerMsgCallback(msgName, module, callback)
end
---- 移除推送监听
function ServerPushManager:removeServerPushListener(msgName, module)
NetManager:unRegisterMsgCallback(msgName, module)
end
---- 初始化全局推送监听
function ServerPushManager:initWhenLogin()
self:addServerPushListener(ProtoMsgType.FromMsgEnum.KickOutNtf, UIManager, UIManager.showKickOut)
self:addServerPushListener(ProtoMsgType.FromMsgEnum.MallActTriggerGiftNtf, ModuleManager.MallManager, ModuleManager.MallManager.MallActTriggerGiftNtf)
self:addServerPushListener(ProtoMsgType.FromMsgEnum.BattlePassBoughtNtf, ModuleManager.BountyManager, ModuleManager.BountyManager.buyCardFinish)
self:addServerPushListener(ProtoMsgType.FromMsgEnum.SummonPoolLevelNtf, ModuleManager.SummonManager, ModuleManager.SummonManager.SummonPoolLevelNtf)
self:addServerPushListener(ProtoMsgType.FromMsgEnum.NewMailNtf, ModuleManager.MailManager, ModuleManager.MailManager.needUpdateMail)
end
---- 移除全局推送监听
function ServerPushManager:removeWhenLoginOut()
self:removeServerPushListener(ProtoMsgType.FromMsgEnum.KickOutNtf, UIManager)
end
return ServerPushManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1c64e57074a12a04a98c2bd95599566a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,194 @@
local UISpineObject = require "app/bf/unity/ui_spine_object"
local MeshSpineObject = require "app/bf/unity/mesh_spine_object"
local CharacterSpineObject = require "app/bf/unity/character_spine_object"
local SpineManager = {
heroCacheList = {},
heroCacheMap = {},
battleCacheList = {},
battleCacheMap = {},
heroSpineAsset = {}
}
local TYPE_OF_GAME_OBJECT = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT
local TYPE_OF_SPINE_ASSET = GConst.TYPEOF_UNITY_CLASS.SKELETON_DATA_ASSET
local UI_SPINE_PREFAB_PATH = "assets/prefabs/spine/ui/ui_spine_obj.prefab"
local MESH_SPINE_PREFAB_PATH = "assets/prefabs/spine/mesh/mesh_spine_obj.prefab"
local UI_SPINE_ASSET_PATH = "assets/arts/spines/ui/%s/%s_skeletondata.asset"
local MESH_SPINE_ASSET_PATH = "assets/arts/spines/mesh/%s/%s_skeletondata.asset"
local HERO_SPINE_ASSET_PATH = "assets/arts/spines/characters/%s/%s_skeletondata.asset"
local HERO_CACHE_SIZE = 10 -- 英雄缓存容量
local BATTLE_CACHE_SIZE = 30 -- 战斗特效缓存容量
---- canvas renderer
function SpineManager:loadUISpineWidgetAsync(name, parent, callback)
local path = string.format(UI_SPINE_ASSET_PATH, name, name)
ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset)
if parent and parent:isDestroyed() then
ResourceManager:unload(spineAssetPath)
return
end
self:loadUISpinePrefabAsync(parent, spineAssetPath, spineAsset, callback)
end)
end
function SpineManager:loadUISpinePrefabAsync(parent, spineAssetPath, spineAsset, callback)
ResourceManager:loadAsync(UI_SPINE_PREFAB_PATH, TYPE_OF_GAME_OBJECT, function(prefabPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(spineAssetPath)
ResourceManager:unload(prefabPath)
return
end
local uiSpineObject = UISpineObject:create()
uiSpineObject:initWithPrefab(UI_SPINE_PREFAB_PATH, prefab)
uiSpineObject:getAnimationState()
uiSpineObject:initSkeletonDataAsset(spineAsset)
uiSpineObject:addUnloadCallback(function(obj)
ResourceManager:unload(spineAssetPath)
ResourceManager:unload(prefabPath)
end)
if parent then
uiSpineObject:setParent(parent, false)
end
if callback then
callback(uiSpineObject)
end
end)
end
function SpineManager:loadHeroAsync(id, parent, callback)
local path = "assets/prefabs/spine/mesh/characters/" .. id .. ".prefab"
ResourceManager:loadAsync(path, TYPE_OF_GAME_OBJECT, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local characterObject = CharacterSpineObject:create()
characterObject:initWithPrefab(assetPath, prefab)
characterObject:addUnloadCallback(function(obj)
local modelPath = obj:getAssetPath()
if self.heroCacheMap[modelPath] then
ResourceManager:unload(modelPath)
else
if #self.heroCacheList >= HERO_CACHE_SIZE then
local headPath = table.remove(self.heroCacheList, 1)
ResourceManager:unload(headPath)
self.heroCacheMap[headPath] = nil
end
self.heroCacheMap[modelPath] = true
table.insert(self.heroCacheList, modelPath)
end
end)
if parent then
characterObject:setParent(parent, false)
end
if callback then
callback(characterObject)
end
end)
end
function SpineManager:loadHeroSpineAssetAsync(id, parent, callback)
if self.heroSpineAsset[id] then
callback(self.heroSpineAsset[id])
else
local path = string.format(HERO_SPINE_ASSET_PATH, id, id)
ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset)
if parent and parent:isDestroyed() then
ResourceManager:unload(spineAssetPath)
return
end
if self.heroSpineAsset[id] then
ResourceManager:unload(spineAssetPath)
else
self.heroSpineAsset[id] = spineAsset
end
callback(spineAsset)
end)
end
end
function SpineManager:loadBattleSpineAssetAsync(path, parent, callback)
ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset)
if parent and parent:isDestroyed() then
ResourceManager:unload(spineAssetPath)
return
end
callback(spineAssetPath, spineAsset)
end)
end
function SpineManager:loadBattleEffectAsync(path, parent, callback)
ResourceManager:loadAsync(path, TYPE_OF_GAME_OBJECT, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local spineObject = CharacterSpineObject:create()
spineObject:initWithPrefab(assetPath, prefab)
spineObject:addUnloadCallback(function(obj)
local effectPath = obj:getAssetPath()
if self.battleCacheMap[effectPath] then
ResourceManager:unload(effectPath)
else
if #self.battleCacheList == BATTLE_CACHE_SIZE then
local headPath = table.remove(self.battleCacheList, 1)
ResourceManager:unload(headPath)
self.battleCacheMap[headPath] = nil
end
self.battleCacheMap[effectPath] = true
table.insert(self.battleCacheList, effectPath)
end
end)
if parent then
spineObject:setParent(parent, false)
end
if callback then
callback(spineObject)
end
end)
end
---- mesh renderer
function SpineManager:loadMeshSpineAsync(name, parent, callback)
local path = string.format(MESH_SPINE_ASSET_PATH, name, name)
ResourceManager:loadOriginAssetAsync(path, TYPE_OF_SPINE_ASSET, function(spineAssetPath, spineAsset)
if parent and parent:isDestroyed() then
ResourceManager:unload(spineAssetPath)
return
end
self:loadMeshSpinePrefabAsync(parent, spineAssetPath, spineAsset, callback)
end)
end
function SpineManager:loadMeshSpinePrefabAsync(parent, spineAssetPath, spineAsset, callback)
ResourceManager:loadAsync(MESH_SPINE_PREFAB_PATH, TYPE_OF_GAME_OBJECT, function(prefabPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(spineAssetPath)
ResourceManager:unload(prefabPath)
return
end
local meshSpineObject = MeshSpineObject:create()
meshSpineObject:initWithPrefab(MESH_SPINE_PREFAB_PATH, prefab)
meshSpineObject:getAnimationState()
meshSpineObject:initSkeletonDataAsset(spineAsset)
meshSpineObject:addUnloadCallback(function(obj)
ResourceManager:unload(spineAssetPath)
ResourceManager:unload(prefabPath)
end)
if parent then
meshSpineObject:setParent(parent, false)
end
if callback then
callback(meshSpineObject)
end
end)
end
return SpineManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: edb03cc9c3cdb6a459f95589941d04b4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,35 @@
local StateMachineManager = {
fsmList = {}
}
---- 添加一个状态机
function StateMachineManager:addStateMachine(fsm)
for k, v in ipairs(self.fsmList) do
if v == fsm then
return
end
end
table.insert(self.fsmList, fsm)
end
---- 移除一个状态机
function StateMachineManager:removeStateMachine(fsm)
for index, value in ipairs(self.fsmList) do
if fsm == value then
fsm:stop()
table.remove(self.fsmList, index)
break
end
end
end
---- 每帧tick
function StateMachineManager:tick()
for _, fsm in ipairs(self.fsmList) do
if fsm:getIsActive() then
fsm:tick()
end
end
end
return StateMachineManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8e40f566f0955d44d827d10d8bec59e0
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
local TextureManager = { }
function TextureManager:loadAtlas(prefabObject, atlasPath, callback)
ResourceManager:loadOriginAssetAsync(atlasPath, GConst.TYPEOF_UNITY_CLASS.BF_ATLAS, function(assetPath, asset)
if prefabObject:isDestroyed() then
ResourceManager:unload(assetPath)
return
end
callback(assetPath, asset)
end)
end
function TextureManager:unloadAtlas(atlasPath)
ResourceManager:unload(atlasPath)
end
function TextureManager:loadTextureAsync(prefabObject, texturePath, callback)
ResourceManager:loadOriginAssetAsync(texturePath, GConst.TYPEOF_UNITY_CLASS.TEXTURE_2D, function(assetPath, texture)
if prefabObject:isDestroyed() then
ResourceManager:unload(assetPath)
return
end
if callback then
callback(assetPath, texture)
end
end)
end
function TextureManager:unLoadTexture(texturePath)
ResourceManager:unload(texturePath)
end
return TextureManager

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c8a7ad54687bb0e4f84d61f30da3cf17
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

291
lua/app/common/time.lua Normal file
View File

@ -0,0 +1,291 @@
local Time = {
timeZoneOffset = 0,
differenceTime = 0,
todayTime = 0,
}
local SECONDS_PRE_DAY = 86400
local SECONDS_PRE_HOUR = 3600
local SECONDS_PRE_MINUTE = 60
local DAY_PER_HOUR = 24
local ZERO_TIME_STR = "00:00:00"
local ZERO_TIME_STR_2 = "00:00"
local UnityTime = CS.UnityEngine.Time
-- 获取服务器的当前时间戳
function Time:getServerTime()
if not self.serverTime then
return os.time()
end
return self.serverTime + self.differenceTime + GFunc.getTickCount()
end
function Time:getRealtimeSinceStartup()
return UnityTime.realtimeSinceStartup
end
-- 获取客户端时间戳
-- function Time:getClientTime()
-- return os.time()
-- end
-- 得到特定时间的时间戳
function Time:getCertainTime(data)
local year = data.year or 0
local month = data.month or 0
local day = data.day or 0
local hour = data.hour or 0
local minute = data.minute or 0
local second = data.second or 0
return os.time({day = day, month = month, year = year, hour = hour, min = minute, sec = second})
end
-- 得到特定时间的时间戳
-- 没有算时区差异优先使用getCertainTimeByStr2
function Time:getCertainTimeByStr(timeStr)
-- "2022-08-9 00:00:00"
if type(timeStr) ~= "string" then
return 0
end
timeStr = string.trim(timeStr)
local timeTab = {}
for i,v in string.gmatch(timeStr, "%d+") do
-- print(i, v)
table.insert(timeTab, i)
end
local year = timeTab[1]
local month = timeTab[2]
local day = timeTab[3]
local hour = timeTab[4]
local minute = timeTab[5]
local second = timeTab[6]
return os.time({day = day, month = month, year = year, hour = hour, min = minute, sec = second})
end
function Time:getCertainTimeByStr2(timeStr)
-- "2022-08-9 00:00:00"
if type(timeStr) ~= "string" then
return 0
end
timeStr = string.trim(timeStr)
local timeTab = {}
for i,v in string.gmatch(timeStr, "%d+") do
-- print(i, v)
table.insert(timeTab, i)
end
local year = timeTab[1]
local month = timeTab[2]
local day = timeTab[3]
local hour = timeTab[4]
local minute = timeTab[5]
local second = timeTab[6]
local time = os.time({day = day, month = month, year = year, hour = hour, min = minute, sec = second}) + Time:getClientTimeZone()*3600
return math.floor(time)
end
-- 格式化时间返回os.data(finalTime)
function Time:formatTimeExact(time)
local endTime = self:getServerTime() + time
return os.date("*t", endTime)
end
-- 格式化y/m/d时间返回os.data(finalTime)
function Time:formatTimeYMD(time)
time = time or Time:getServerTime()
local date = os.date("!*t", time)
return date.year .. "/" .. date.month .. "/" .. date.day
end
-- 格式化y/m/d/h/m/s时间返回os.data(finalTime)
function Time:formatTimeYMDHMS(time)
time = time or Time:getServerTime()
local date = os.date("!*t", time)
return date.year .. "/" .. date.month .. "/" .. date.day .. " " .. date.hour .. ":" .. date.min .. ":" .. date.sec
end
function Time:updateServerTimeToday(todayTime)
todayTime = todayTime or 0
self.todayTime = GFunc.formatTimeStep(todayTime)
end
function Time:updateServerTime(serverTime)
self.serverTime = (serverTime or 0) // 1000
self.differenceTime = -GFunc.getTickCount()
if EDITOR_MODE then
Logger.log("updateServerTime:%s", self.differenceTime)
end
end
function Time:updateByServer(serverTime, todayTime)
self:updateServerTime(serverTime)
self:updateServerTimeToday(todayTime)
end
function Time:setServerTimeZone(timeZone)
self.timeZoneOffset = timeZone - self:getClientTimeZone()
end
function Time:getClientTimeZone()
return os.difftime(os.time(), os.time(os.date("!*t", os.time())))/SECONDS_PRE_HOUR
end
function Time:getTimeZoneOffset()
return self.timeZoneOffset
end
function Time:getBeginningOfServerToday()
if Time:getServerTime() > self.todayTime + 86400 then
self.todayTime = self.todayTime + 86400
end
return self.todayTime
end
function Time:getOverOfServerToday(time)
if time then
local passS = time % SECONDS_PRE_DAY
if passS > 0 then
return time + SECONDS_PRE_DAY - passS
end
return time + SECONDS_PRE_DAY
end
return self:getBeginningOfServerToday() + SECONDS_PRE_DAY
end
function Time:getBeginningOfToday()
local now = os.date('*t', self:getServerTime() + self:getTimeZoneOffset()*SECONDS_PRE_HOUR)
local beginDay = os.time{year = now.year, month = now.month, day = now.day, hour = 0}
return beginDay - self:getTimeZoneOffset()*SECONDS_PRE_HOUR
end
function Time:getBeginningOfOneDay(t)
local now = os.date('*t', t + self:getTimeZoneOffset()*SECONDS_PRE_HOUR)
local beginDay = os.time{year = now.year, month = now.month, day = now.day, hour = 0}
return beginDay - self:getTimeZoneOffset()*SECONDS_PRE_HOUR
end
-- 判断时间是否是大于等于今天
function Time:getTimeIsToday(time)
local todayBegin = self:getBeginningOfToday()
return time >= todayBegin
end
function Time:splitTime(time)
time = math.floor(time)
local reduceD = time % SECONDS_PRE_DAY
local day = math.floor(time/SECONDS_PRE_DAY)
local reduceH = reduceD % SECONDS_PRE_HOUR
local hour = math.floor(reduceD/SECONDS_PRE_HOUR)
local minute = math.floor(reduceH / SECONDS_PRE_MINUTE)
local second = reduceH % SECONDS_PRE_MINUTE
return day, hour, minute, second
end
-- 根据秒换算成向上取整hour的时间
function Time:getCeilHourTime(time)
local count = time // 3600
if time % 3600 > 0 then
count = count + 1
end
return count
end
--每几秒 向上取整
function Time:getCeilPerSecend(time, per)
local count = time // per
if time % per > 0 then
count = count + 1
end
return count
end
function Time:getDayofWeek(time)
local curTime = time or self:getServerTime()
local day = tonumber(os.date("%w", curTime))
day = day == 0 and 7 or day
return day
end
-- 00:00:00
function Time:formatNumTime(time)
if time <= 0 then
return ZERO_TIME_STR
end
local reduceH = time % SECONDS_PRE_HOUR
local hour = math.floor(time / SECONDS_PRE_HOUR)
local minute = math.floor(reduceH / SECONDS_PRE_MINUTE)
local second = reduceH % SECONDS_PRE_MINUTE
return string.format("%.2d:%.2d:%.2d", hour, minute, second)
end
-- 00:00
function Time:formatNumTimeMS(time)
if time <= 0 then
return ZERO_TIME_STR_2
end
local minute = math.floor(time / SECONDS_PRE_MINUTE)
local second = time % SECONDS_PRE_MINUTE
return string.format("%.2d:%.2d", minute, second)
end
-- 大于1天显示X天X时 globalkey:ACTIVITY_TIME_STR_DH 小于1天显示X时X分 globalkey:ACTIVITY_TIME_STR_HM 小于1小时显示X分X秒 globalkey:ACTIVITY_TIME_STR_MS
function Time:formatNumTimeStr(time)
if time <= 0 then
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_MS, 0, 0)
end
local day, hour, minute, second = Time:splitTime(time)
if time >= SECONDS_PRE_DAY then -- 大于1天显示X天X时
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_DH, day, hour)
else
if time >= SECONDS_PRE_HOUR then -- 小于1天显示X时X分
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_HM, hour, minute)
else --小于1小时显示X分X秒
return I18N:getGlobalText(I18N.GlobalConst.TIME_STR_MS, minute, second)
end
end
end
---- 得到time周开始时的时间戳
function Time:getWeekBeginTimeStamp(time)
time = time or self:getServerTime()
local remainDay = -self:getDayofWeek(time)
return self:getOverOfServerToday(time) + remainDay * SECONDS_PRE_DAY
end
---- 得到time周结束时的时间戳
function Time:getWeekOverTimeStamp(time)
time = time or self:getServerTime()
local remainDay = 7 - self:getDayofWeek(time)
return self:getOverOfServerToday(time) + remainDay * SECONDS_PRE_DAY
end
---- 得到time月结束的时间戳
function Time:getMonthOverTimeStamp(time)
time = time or self:getServerTime()
local now = os.date('!*t', time)
now.month = now.month + 1
if now.month > 12 then
now.year = now.year + now.month // 12
now.month = now.month % 12
end
local remainDay = os.date("%d", os.time({year = now.year, month = now.month, day = 0})) - now.day
return self:getOverOfServerToday(time) + remainDay * SECONDS_PRE_DAY
end
---- 得到当前处于本月的第几天
function Time:getDayByTimeStamp(time)
time = time or self:getServerTime()
local now = os.date('!*t', time)
return now.day
end
-- 转换服务器时间字符串(ISO 8601)的对应的时间戳,例如2022-09-10T18:10:00.000Z
function Time:convertServerTimeStringToTimestamp(str)
local dateTime = CS.System.DateTime.Parse(str)
local dateTimeOffset = CS.System.DateTimeOffset(dateTime)
return dateTimeOffset:ToUnixTimeSeconds()
end
return Time

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d9c1c2a447bacad408ce60760a6ea5b4
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,29 @@
local UIPrefabObject = require "app/bf/unity/uiprefab_object"
local UIPrefabManager = {}
local TypeOfGameObject = GConst.TYPEOF_UNITY_CLASS.GAME_OBJECT
function UIPrefabManager:loadUIWidgetAsync(path, parent, callback)
ResourceManager:loadAsync(path, TypeOfGameObject, function(assetPath, prefab)
if parent and parent:isDestroyed() then
ResourceManager:destroyPrefab(prefab)
ResourceManager:unload(assetPath)
return
end
local prefabObject = UIPrefabObject:create()
prefabObject:initWithPrefab(assetPath, prefab)
prefabObject:initPrefabHelper()
prefabObject:addUnloadCallback(function(obj)
ResourceManager:unload(obj:getAssetPath())
end)
if parent then
prefabObject:setParent(parent, false)
end
if callback then
callback(prefabObject)
end
end)
end
return UIPrefabManager

Some files were not shown because too many files have changed in this diff Show More