Initial version - 1.2.0.60

EN: 1.2.0.60
CN: 1.2.0.61
JP: 1.2.0.63
KR: 1.2.0.67
This commit is contained in:
SL1900
2025-12-03 01:00:00 +09:00
commit 5e0d58cfad
3595 changed files with 9373562 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+755
View File
@@ -0,0 +1,755 @@
local BubbleVoiceManager = {}
local File = CS.System.IO.File
local RapidJson = require("rapidjson")
local TimerManager = require("GameCore.Timer.TimerManager")
local Actor2DManager = require("Game.Actor2D.Actor2DManager")
local PlayerBaseData = PlayerData.Base
local map_BubbleData = {}
local map_BubbleOffset = {}
local map_VoResLen = {}
local mapDisplayData = {
{
0,
"",
""
},
{
0,
"",
""
},
{
0,
"",
""
},
{
0,
"",
""
}
}
local mapDisplayOffset = {
left = true,
x = 0,
y = 0,
cgLeft = true,
cgX = 0,
cgY = 0
}
local nCurTxtLanIndex = GetLanguageIndex(Settings.sCurrentTxtLanguage)
local sLanFolder = GetLanguageSurfixByIndex(nCurTxtLanIndex)
local sPath_BubbleData = ""
local sPath_BubbleOffset = ""
local sPath_VoResLen = ""
local InUnityEditor = NovaAPI.IsEditorPlatform()
local bLoaded = false
local LoadAll = function()
if InUnityEditor == true then
sPath_BubbleData = NovaAPI.ApplicationDataPath .. "/../../GameDataTables/text_data/bubble/" .. sLanFolder .. "/BubbleData.json"
sPath_BubbleOffset = NovaAPI.ApplicationDataPath .. "/../../GameDataTables/text_data/bubble/BubbleOffset.json"
sPath_VoResLen = NovaAPI.ApplicationDataPath .. "/../../GameDataTables/text_data/bubble/VoResLen.json"
elseif RUNNING_BBV_EDITOR == true then
sPath_BubbleData = NovaAPI.StreamingAssetsPath .. "/../../../" .. sLanFolder .. "/BBV/BubbleData.json"
sPath_BubbleOffset = NovaAPI.StreamingAssetsPath .. "/../../../_cn/BBV/BubbleOffset.json"
sPath_VoResLen = NovaAPI.StreamingAssetsPath .. "/../../../_cn/BBV/VoResLen.json"
else
sPath_BubbleData = "bubble/" .. sLanFolder .. "/BubbleData.json"
sPath_BubbleOffset = "bubble/BubbleOffset.json"
sPath_VoResLen = "bubble/VoResLen.json"
end
local sJsonText
if InUnityEditor == true or RUNNING_BBV_EDITOR == true then
sJsonText = File.ReadAllText(sPath_BubbleData)
map_BubbleData = RapidJson.decode(sJsonText)
sJsonText = File.ReadAllText(sPath_BubbleOffset)
map_BubbleOffset = RapidJson.decode(sJsonText)
sJsonText = File.ReadAllText(sPath_VoResLen)
map_VoResLen = RapidJson.decode(sJsonText)
else
sJsonText = NovaAPI.LoadTextData(sPath_BubbleData)
map_BubbleData = RapidJson.decode(sJsonText)
sJsonText = NovaAPI.LoadTextData(sPath_BubbleOffset)
map_BubbleOffset = RapidJson.decode(sJsonText)
sJsonText = NovaAPI.LoadTextData(sPath_VoResLen)
map_VoResLen = RapidJson.decode(sJsonText)
end
bLoaded = true
end
local map_BubbleData_Cn, map_BubbleData_Jp
local LoadSpecificData = function(sLanFolder)
local sPath
if InUnityEditor == true then
sPath = NovaAPI.ApplicationDataPath .. "/../../GameDataTables/text_data/bubble/" .. sLanFolder .. "/BubbleData.json"
elseif RUNNING_BBV_EDITOR == true then
sPath = NovaAPI.StreamingAssetsPath .. "/../../../" .. sLanFolder .. "/BBV/BubbleData.json"
else
sPath = "text_data/bubble/" .. sLanFolder .. "/BubbleData.json"
end
local sJsonText
if InUnityEditor == true or RUNNING_BBV_EDITOR == true then
sJsonText = File.ReadAllText(sPath)
else
sJsonText = NovaAPI.LoadTableData(sPath)
end
return RapidJson.decode(sJsonText)
end
local tbCheckOrder, _sVoLan, _bIsMale
function GetCheckOrder()
local sVoLan = Settings.sCurrentVoLanguage
local bIsMale = PlayerBaseData:GetPlayerSex()
if _sVoLan ~= sVoLan or _bIsMale ~= bIsMale then
_sVoLan = sVoLan
_bIsMale = bIsMale
tbCheckOrder = nil
end
if tbCheckOrder == nil then
local sTextLan = Settings.sCurrentTxtLanguage
local tbTemp = {}
if sTextLan == AllEnum.Language.CN then
table.insert(tbTemp, "female_cn")
if bIsMale == true then
table.insert(tbTemp, "male_cn")
end
if sVoLan == AllEnum.Language.JP then
table.insert(tbTemp, "female_jp")
if bIsMale == true then
table.insert(tbTemp, "male_jp")
end
end
elseif sTextLan == AllEnum.Language.JP then
table.insert(tbTemp, "female_jp")
if bIsMale == true then
table.insert(tbTemp, "male_jp")
end
elseif sTextLan == AllEnum.Language.TW or sTextLan == AllEnum.Language.EN or sTextLan == AllEnum.Language.KR then
table.insert(tbTemp, "female_jp")
if bIsMale == true then
table.insert(tbTemp, "male_jp")
end
if sVoLan == AllEnum.Language.CN then
table.insert(tbTemp, "female_cn")
if bIsMale == true then
table.insert(tbTemp, "male_cn")
end
end
end
tbCheckOrder = {}
for i = #tbTemp, 1, -1 do
table.insert(tbCheckOrder, tbTemp[i])
end
end
end
local tbDefaultText = {
"error",
"",
"",
""
}
local GetText = function(mapTextData)
local nCheckTotal = #tbCheckOrder
for i = 1, nCheckTotal do
local _sKey = tbCheckOrder[i]
local _tbText = mapTextData[_sKey]
if type(_tbText) == "table" and type(_tbText[1]) == "string" and _tbText[1] ~= "" then
return _tbText
end
end
return tbDefaultText
end
local tbDefaultTime = {
1,
0,
0,
0
}
local GetTime = function(mapTimeData)
local nCheckTotal = #tbCheckOrder
for i = 1, nCheckTotal do
local _sKey = tbCheckOrder[i]
local _tbTime = mapTimeData[_sKey]
if type(_tbTime) == "table" and type(_tbTime[1]) == "number" and _tbTime[1] > 0 then
return _tbTime
end
end
return tbDefaultTime
end
local tbDefaultAnim = {
"",
"",
"",
""
}
local GetAnim = function(mapAnimData)
local func_Available = function(_tb)
if type(_tb) == "table" then
for ii, vv in ipairs(_tb) do
if type(vv) == "string" and vv ~= "" then
return _tb
end
end
end
end
local nCheckTotal = #tbCheckOrder
for i = 1, nCheckTotal do
local _sKey = tbCheckOrder[i]
local _tbAnim = mapAnimData[_sKey]
_tbAnim = func_Available(_tbAnim)
if _tbAnim ~= nil then
return _tbAnim
end
end
return tbDefaultAnim
end
local GetBubbleData = function(sVoResName, nCharSkinId, bTextOnly)
if bLoaded ~= true then
LoadAll()
end
GetCheckOrder()
local data = map_BubbleData[sVoResName]
if data == nil then
printError("气泡语音 数据未配置:" .. sVoResName)
return false
end
local tbTextData = GetText(data.text)
if bTextOnly == true then
return true, tbTextData
end
local tbTimeData = GetTime(data.time)
local tbAnimData = GetAnim(data.anim)
for i = 1, 4 do
mapDisplayData[i][1] = 1 < i and tbTimeData[i] - tbTimeData[i - 1] or tbTimeData[i]
mapDisplayData[i][2] = tbTextData[i]
mapDisplayData[i][3] = tbAnimData[i]
end
local offset, offset_
if type(nCharSkinId) == "number" then
offset = map_BubbleOffset[tostring(nCharSkinId)]
local mapCfgData_CharacterSkin = ConfigTable.GetData("CharacterSkin", nCharSkinId)
if mapCfgData_CharacterSkin ~= nil and mapCfgData_CharacterSkin.Type == GameEnum.skinType.ADVANCE then
local mapCfgData_Character = ConfigTable.GetData("Character", mapCfgData_CharacterSkin.CharId)
if mapCfgData_Character ~= nil then
local nCharDefaultSkinId = mapCfgData_Character.DefaultSkinId
if type(nCharDefaultSkinId) == "number" then
offset_ = map_BubbleOffset[tostring(nCharDefaultSkinId)]
end
end
end
end
mapDisplayOffset.left = offset == nil and true or offset.left
mapDisplayOffset.x = offset == nil and 0 or offset.x
mapDisplayOffset.y = offset == nil and 0 or offset.y
mapDisplayOffset.cgLeft = offset == nil and true or offset.cgLeft
mapDisplayOffset.cgX = offset == nil and 0 or offset.cgX
mapDisplayOffset.cgY = offset == nil and 0 or offset.cgY
if offset_ ~= nil then
mapDisplayOffset.cgLeft = offset_.cgLeft
mapDisplayOffset.cgX = offset_.cgX
mapDisplayOffset.cgY = offset_.cgY
end
return true
end
local LocalData = require("GameCore.Data.LocalData")
local CheckEnable = function()
local sBool = LocalData.GetPlayerLocalData("BubbleVoiceEnable")
return sBool == nil or sBool == "true"
end
local anim, TMP, nCurIndex, timer, nCharIdx
local function SetBubble()
if anim == nil or TMP == nil then
return
end
local bBubbleDone = false
nCurIndex = nCurIndex + 1
local tbData = mapDisplayData[nCurIndex]
if tbData ~= nil then
local nTime = tbData[1]
local sText = tbData[2]
local sAnim = tbData[3]
if sText ~= "" and 0 < nTime then
sText = string.gsub(sText, "==RT==", "\n")
sText = string.gsub(sText, "==PLAYER_NAME==", PlayerBaseData:GetPlayerNickName())
NovaAPI.SetTMPText(TMP, sText)
anim:Play("bb_in", -1, 0)
if sAnim ~= "" then
if RUNNING_BBV_EDITOR == true then
Actor2DManager.PlayL2DAnim_InBBVEditor(sAnim)
else
Actor2DManager.PlayAnim(sAnim, true, nCharIdx)
end
end
timer = TimerManager.Add(1, nTime, nil, SetBubble, true, true, true, nil)
else
bBubbleDone = true
end
else
bBubbleDone = true
end
if bBubbleDone == true then
anim:Play("bb_out", -1, 0)
anim = nil
TMP = nil
timer = nil
end
end
function BubbleVoiceManager.Init(bEditor)
if bEditor == true then
LoadAll()
if Settings.sCurrentTxtLanguage ~= AllEnum.Language.CN and Settings.sCurrentTxtLanguage ~= AllEnum.Language.JP then
map_BubbleData_Cn = LoadSpecificData("_cn")
map_BubbleData_Jp = LoadSpecificData("_jp")
end
end
end
function BubbleVoiceManager.PlayBubbleAnim(goBubbleRoot, sVoResName, nCharSkinId, bIsCG, nCharIndex)
if nCharIndex == nil then
nCharIndex = 1
end
nCharIdx = nCharIndex
if CheckEnable() == false then
return
end
BubbleVoiceManager.StopBubbleAnim(true)
if goBubbleRoot == nil or goBubbleRoot:IsNull() == true then
return
end
if GetBubbleData(sVoResName, nCharSkinId) == true then
local tr
local bIsLeft = false
if bIsCG == true then
bIsLeft = mapDisplayOffset.cgLeft
else
bIsLeft = mapDisplayOffset.left
end
local n = bIsLeft == true and 0 or 1
for i = 0, 1 do
local trBubble = goBubbleRoot.transform:GetChild(i)
trBubble.gameObject:SetActive(i == n)
if i == n then
tr = trBubble
end
end
if tr ~= nil then
local x = bIsCG == true and mapDisplayOffset.cgX or mapDisplayOffset.x
local y = bIsCG == true and mapDisplayOffset.cgY or mapDisplayOffset.y
local rt = goBubbleRoot:GetComponent("RectTransform")
rt.anchoredPosition = Vector2(x, y)
anim = tr:GetComponent("Animator")
TMP = tr:GetComponentInChildren(typeof(CS.TMPro.TMP_Text))
nCurIndex = 0
SetBubble()
end
end
end
function BubbleVoiceManager.StopBubbleAnim(bNoAnim)
if CheckEnable() == false then
return
end
if anim ~= nil then
if bNoAnim ~= true then
anim:Play("bb_out", -1, 0)
end
anim = nil
end
if timer ~= nil then
timer:Cancel()
timer = nil
end
TMP = nil
Actor2DManager.PlayAnim("idle", true, nCharIdx)
end
function BubbleVoiceManager.PauseBubbleAnim()
if CheckEnable() == false then
return
end
if timer ~= nil then
timer:Pause(true)
end
end
function BubbleVoiceManager.ResumeBubbleAnim()
if CheckEnable() == false then
return
end
if timer ~= nil then
timer:Pause(false)
end
end
function BubbleVoiceManager.PlayFixedBubbleAnim(goBubbleRoot, sVoResName, nCharIndex)
if nCharIndex == nil then
nCharIndex = 1
end
nCharIdx = nCharIndex
if CheckEnable() == false then
return
end
BubbleVoiceManager.StopBubbleAnim(true)
if goBubbleRoot == nil or goBubbleRoot:IsNull() == true then
return
end
if GetBubbleData(sVoResName) == true then
anim = goBubbleRoot:GetComponent("Animator")
TMP = goBubbleRoot:GetComponentInChildren(typeof(CS.TMPro.TMP_Text))
nCurIndex = 0
SetBubble()
end
end
function BubbleVoiceManager.GetBubbleText(sVoResName)
local tb = {
"",
"",
"",
""
}
if type(sVoResName) == "string" and sVoResName ~= "" then
if CacheTable.GetData("_CharGetLines", "vo_103_ui_gachaNew_001") == nil then
local func_Parse_CharGetLines = function(mapData)
CacheTable.SetData("_CharGetLines", mapData.voResource, mapData)
end
ForEachTableLine(DataTable.CharGetLines, func_Parse_CharGetLines)
end
local mapData = CacheTable.GetData("_CharGetLines", sVoResName)
if mapData ~= nil then
local sContent = mapData.Lines
local sContent = string.gsub(sContent, "==PLAYER_NAME==", PlayerBaseData:GetPlayerNickName())
tb[1] = sContent
return tb
end
end
return tb
end
function BubbleVoiceManager.GetVoResLen(sVoResName)
if type(map_VoResLen) == "table" then
local nCurTxtLanIndex = GetLanguageIndex(Settings.sCurrentTxtLanguage)
local sLanFolder = GetLanguageSurfixByIndex(nCurTxtLanIndex)
local nDuration = map_VoResLen[sVoResName .. sLanFolder]
if nDuration == nil then
nDuration = 0
end
return nDuration
end
end
local mapDisplayData_EX = {
{
0,
"",
""
},
{
0,
"",
""
},
{
0,
"",
""
},
{
0,
"",
""
}
}
local mapDisplayOffset_EX = {
left = true,
x = 0,
y = 0,
cgLeft = true,
cgX = 0,
cgY = 0
}
local anim_EX, TMP_EX, nCurIndex_EX, timer_EX
local GetBubbleData_EX = function(sVoResName, nCharSkinId, bTextOnly)
if bLoaded ~= true then
LoadAll()
end
GetCheckOrder()
local data = map_BubbleData[sVoResName]
if data == nil then
printError("气泡语音 数据未配置:" .. sVoResName)
return false
end
local tbTextData = GetText(data.text)
if bTextOnly == true then
return true, tbTextData
end
local tbTimeData = GetTime(data.time)
local tbAnimData = GetAnim(data.anim)
for i = 1, 4 do
mapDisplayData_EX[i][1] = 1 < i and tbTimeData[i] - tbTimeData[i - 1] or tbTimeData[i]
mapDisplayData_EX[i][2] = tbTextData[i]
mapDisplayData_EX[i][3] = tbAnimData[i]
end
local offset
if type(nCharSkinId) == "number" then
offset = map_BubbleOffset[tostring(nCharSkinId)]
end
mapDisplayOffset_EX.left = offset == nil and true or offset.left
mapDisplayOffset_EX.x = offset == nil and 0 or offset.x
mapDisplayOffset_EX.y = offset == nil and 0 or offset.y
mapDisplayOffset_EX.cgLeft = offset == nil and true or offset.cgLeft
mapDisplayOffset_EX.cgX = offset == nil and 0 or offset.cgX
mapDisplayOffset_EX.cgY = offset == nil and 0 or offset.cgY
return true
end
local function SetBubble_EX()
if anim_EX == nil or TMP_EX == nil then
return
end
local bBubbleDone = false
nCurIndex_EX = nCurIndex_EX + 1
local tbData = mapDisplayData_EX[nCurIndex_EX]
if tbData ~= nil then
local nTime = tbData[1]
local sText = tbData[2]
local sAnim = tbData[3]
if sText ~= "" and 0 < nTime then
sText = string.gsub(sText, "==RT==", "\n")
sText = string.gsub(sText, "==PLAYER_NAME==", PlayerBaseData:GetPlayerNickName())
NovaAPI.SetTMPText(TMP_EX, sText)
anim_EX:Play("bb_in", -1, 0)
if sAnim ~= "" then
if RUNNING_BBV_EDITOR == true then
Actor2DManager.PlayL2DAnim_InBBVEditor(sAnim)
else
Actor2DManager.PlayAnim(sAnim, true, 2)
end
end
timer_EX = TimerManager.Add(1, nTime, nil, SetBubble_EX, true, true, true, nil)
else
bBubbleDone = true
end
else
bBubbleDone = true
end
if bBubbleDone == true then
anim_EX:Play("bb_out", -1, 0)
anim_EX = nil
TMP_EX = nil
timer_EX = nil
end
end
function BubbleVoiceManager.PlayFixedBubbleAnim_EX(goBubbleRoot, sVoResName)
if CheckEnable() == false then
return
end
sVoResName = sVoResName .. "_EX"
BubbleVoiceManager.StopBubbleAnim_EX(true)
if goBubbleRoot == nil or goBubbleRoot:IsNull() == true then
return
end
if GetBubbleData_EX(sVoResName) == true then
anim_EX = goBubbleRoot:GetComponent("Animator")
TMP_EX = goBubbleRoot:GetComponentInChildren(typeof(CS.TMPro.TMP_Text))
nCurIndex_EX = 0
SetBubble_EX()
end
end
function BubbleVoiceManager.StopBubbleAnim_EX(bNoAnim)
if CheckEnable() == false then
return
end
if anim_EX ~= nil then
if bNoAnim ~= true then
anim_EX:Play("bb_out", -1, 0)
end
anim_EX = nil
end
if timer_EX ~= nil then
timer_EX:Cancel()
timer_EX = nil
end
TMP_EX = nil
Actor2DManager.PlayAnim("idle", true, 2)
end
local WriteToJsonFile = function(sPath, sJsonText)
local fs = CS.System.IO.FileStream(sPath, CS.System.IO.FileMode.Create)
local sw = CS.System.IO.StreamWriter(fs, CS.System.Text.UTF8Encoding(false))
sw:Write(sJsonText)
sw:Close()
fs:Close()
end
local sEditingVoResName
function BubbleVoiceManager.GetBubbleData_All(sVoResName)
sEditingVoResName = sVoResName
local mapEditingData = map_BubbleData[sVoResName]
local bIsNewData = mapEditingData == nil
if bIsNewData == true then
mapEditingData = {
text = {
male_cn = {
"",
"",
"",
""
},
female_cn = {
"",
"",
"",
""
},
male_jp = {
"",
"",
"",
""
},
female_jp = {
"",
"",
"",
""
}
},
time = {
male_cn = {
0,
0,
0,
0
},
female_cn = {
0,
0,
0,
0
},
male_jp = {
0,
0,
0,
0
},
female_jp = {
0,
0,
0,
0
}
},
anim = {
male_cn = {
"",
"",
"",
""
},
female_cn = {
"",
"",
"",
""
},
male_jp = {
"",
"",
"",
""
},
female_jp = {
"",
"",
"",
""
}
}
}
end
return mapEditingData, bIsNewData
end
function BubbleVoiceManager.GetReuseData(sLan)
if sEditingVoResName == nil then
return
end
if sLan == AllEnum.Language.CN then
return map_BubbleData_Cn[sEditingVoResName]
elseif sLan == AllEnum.Language.JP then
return map_BubbleData_Jp[sEditingVoResName]
end
end
function BubbleVoiceManager.DoSaveData(_mapData)
if type(sEditingVoResName) == "string" and sEditingVoResName ~= "" then
map_BubbleData[sEditingVoResName] = _mapData
for k, v in pairs(map_BubbleData) do
for kk, vv in pairs(v.text) do
for i, sContent in ipairs(vv) do
sContent = string.gsub(sContent, "\r==RT==", "==RT==")
sContent = string.gsub(sContent, "\r", "==RT==")
vv[i] = sContent
end
end
end
local sJsonText = RapidJson.encode(map_BubbleData, {
pretty = true,
sort_keys = true,
empty_table_as_array = true
})
WriteToJsonFile(sPath_BubbleData, sJsonText)
end
end
function BubbleVoiceManager.BBVEditor_GetBBPos(nCharSkinId, bIsCG)
local bIsLeft, x, y
local mapOffset = map_BubbleOffset[tostring(nCharSkinId)]
if mapOffset == nil then
mapOffset = {
left = true,
x = 0,
y = 0,
cgLeft = true,
cgX = 0,
cgY = 0
}
end
bIsLeft = bIsCG == true and mapOffset.cgLeft or mapOffset.left
x = bIsCG == true and mapOffset.cgX or mapOffset.x
y = bIsCG == true and mapOffset.cgY or mapOffset.y
return bIsLeft, x, y
end
function BubbleVoiceManager.DoSaveOffset(nCharSkinId, bIsCG, bIsLeft, x, y)
local mapOffset = map_BubbleOffset[tostring(nCharSkinId)]
if mapOffset == nil then
mapOffset = {
left = true,
x = 0,
y = 0,
cgLeft = true,
cgX = 0,
cgY = 0
}
end
if bIsCG == true then
mapOffset.cgX = x
mapOffset.cgY = y
mapOffset.cgLeft = bIsLeft
else
mapOffset.x = x
mapOffset.y = y
mapOffset.left = bIsLeft
end
map_BubbleOffset[tostring(nCharSkinId)] = mapOffset
local sJsonText = RapidJson.encode(map_BubbleOffset, {
pretty = true,
sort_keys = true,
empty_table_as_array = true
})
WriteToJsonFile(sPath_BubbleOffset, sJsonText)
end
function BubbleVoiceManager.HasNewDataToSave(tbVoResName)
local bResult = false
for i, v in ipairs(tbVoResName) do
if BubbleVoiceManager.IsNew(v) == true then
printLog(v)
bResult = true
end
end
return bResult
end
function BubbleVoiceManager.IsNew(sVoResName)
if type(sVoResName) == "string" and sVoResName ~= "" then
return map_BubbleData[sVoResName] == nil
else
return false
end
end
return BubbleVoiceManager
@@ -0,0 +1,653 @@
local Actor2DEditorCtrl = class("Actor2DEditorCtrl", BaseCtrl)
local PanelDefine = require("GameCore.UI.PanelDefine")
local AvgPreset = require("Game.UI.Avg.AvgPreset")
local Actor2DManager = require("Game.Actor2D.Actor2DManager")
local GameResourceLoader = require("Game.Common.Resource.GameResourceLoader")
local ResType = GameResourceLoader.ResType
local ListString = CS.System.Collections.Generic.List(CS.System.String)
local Directory = CS.System.IO.Directory
local SearchOption = CS.System.IO.SearchOption
local Actor2DOffsetData = CS.Actor2DOffsetData
local EventTrigger = CS.UnityEngine.EventSystems.EventTrigger
local EventTriggerType = CS.UnityEngine.EventSystems.EventTriggerType
local ConfigActor2DEditor = CS.ConfigActor2DEditor
local typeof = typeof
Actor2DEditorCtrl._mapNodeConfig = {
trUIInsRoot = {
sNodeName = "-- ui in root --",
sComponentName = "Transform"
},
eventTriggerEditPos = {
sNodeName = "et_pos",
sComponentName = "EventTrigger"
},
imgEditPos = {sNodeName = "et_pos", sComponentName = "Image"},
sldScale = {
sNodeName = "sld_scale",
sComponentName = "Slider",
callback = "OnValueChanged_SliderScale"
},
inputScale = {
sNodeName = "input_scale",
sComponentName = "InputField_onEndEdit",
callback = "OnEditEnd_InputScale"
},
togEditEmoji = {
sNodeName = "tog_edit_emoji",
sComponentName = "Toggle",
callback = "OnTog_EditEmoji"
},
togMirrorEmoji = {
sNodeName = "tog_mirror_emoji",
sComponentName = "Toggle",
callback = "OnTog_MirrorEmoji"
},
ddSelectChannel = {
sNodeName = "dd_select_game_channel",
sComponentName = "Dropdown",
callback = "OnDD_SelectChannel"
},
ddSelectPngLive2D = {
sNodeName = "dd_select_png_live2d",
sComponentName = "Dropdown",
callback = "OnDD_SelectPngLive2D"
},
ddSelectPanel = {
sNodeName = "dd_select_panel",
sComponentName = "Dropdown",
callback = "OnDD_SelectPanel"
},
ddSelectActor = {
sNodeName = "dd_char",
sComponentName = "Dropdown",
callback = "OnDD_SelectActor"
},
ddSelectPose = {
sNodeName = "dd_pose",
sComponentName = "Dropdown",
callback = "OnDD_SelectPose"
},
ddSelectEmoji = {
sNodeName = "ddEmoji",
sComponentName = "Dropdown",
callback = "OnDD_SelectEmoji"
},
ddSelectFullOrHalf = {
sNodeName = "dd_full_half",
sComponentName = "Dropdown",
callback = "OnDD_SelectFullOrHalf"
},
ddSelectAvgCharHeadFrame = {
sNodeName = "dd_select_avg_char_head_frame",
sComponentName = "Dropdown",
callback = "OnDD_SelectAvgCharFrame"
},
btnReset = {
sNodeName = "btn_reset",
sComponentName = "Button",
callback = "OnBtnClick_Reset"
},
btnRefresh = {
sNodeName = "btn_refresh",
sComponentName = "Button",
callback = "OnBtnClick_Refresh"
},
btnSave = {
sNodeName = "btn_save",
sComponentName = "Button",
callback = "OnBtnClick_Save"
}
}
Actor2DEditorCtrl._mapEventConfig = {}
local tbPanelPreference = {}
local ECharType = {
Char = 0,
AvgChar = 1,
Npc = 2,
CharNpc = 3
}
function Actor2DEditorCtrl:Awake()
local tr = GameObject.Find("==== UI ROOT ====/----Actor2D_OffScreen_Renderer----/----Renderer----/1").transform
self.trRendererActorOffset = tr:Find("animator/panel_offset/free_drag/actor_offset")
self.trActorOffset = nil
self.trEmojiOffset = nil
local goFPSCounter = GameObject.Find("==== UI ROOT ====/---- UI OVERLAY ----/_FPSCounter")
goFPSCounter:SetActive(false)
self:CacheActor2DEditorConfig()
self.tbAllPose = {}
for _, sPose in ipairs(AvgPreset.CharPose_0) do
table.insert(self.tbAllPose, sPose)
end
for _, sPose in ipairs(AvgPreset.CharPose_1) do
table.insert(self.tbAllPose, sPose)
end
self.nAvgCharHeadMirrorFactor = 1
end
function Actor2DEditorCtrl:OnEnable()
self.tbCallback = {}
self._mapNode.ddSelectPngLive2D.gameObject:SetActive(false)
local nIndex = 0
nIndex = nIndex + 1
self.tbCallback[nIndex] = ui_handler(self, self.OnBeginDrag, self._mapNode.eventTriggerEditPos)
local entryBegin = EventTrigger.Entry()
entryBegin.eventID = EventTriggerType.BeginDrag
entryBegin.callback:AddListener(self.tbCallback[nIndex])
self._mapNode.eventTriggerEditPos.triggers:Add(entryBegin)
nIndex = nIndex + 1
self.tbCallback[nIndex] = ui_handler(self, self.OnDrag, self._mapNode.eventTriggerEditPos)
local entryDrag = EventTrigger.Entry()
entryDrag.eventID = EventTriggerType.Drag
entryDrag.callback:AddListener(self.tbCallback[nIndex])
self._mapNode.eventTriggerEditPos.triggers:Add(entryDrag)
nIndex = nIndex + 1
self.tbCallback[nIndex] = ui_handler(self, self.OnEndDrag, self._mapNode.eventTriggerEditPos)
local entryEnd = EventTrigger.Entry()
entryEnd.eventID = EventTriggerType.EndDrag
entryEnd.callback:AddListener(self.tbCallback[nIndex])
self._mapNode.eventTriggerEditPos.triggers:Add(entryEnd)
self:SetUIList()
self:OnDD_SelectPanel(self._mapNode.ddSelectPanel)
self:SetPoseList()
self:SetEmojiList()
self:SetEditable(false)
end
function Actor2DEditorCtrl:OnDisable()
local nIndex = 0
nIndex = nIndex + 1
local cb_begindrag = self.tbCallback[nIndex]
nIndex = nIndex + 1
local cb_drag = self.tbCallback[nIndex]
nIndex = nIndex + 1
local cb_enddrag = self.tbCallback[nIndex]
local nCount = self._mapNode.eventTriggerEditPos.triggers.Count - 1
for i = nCount, 0, -1 do
local entry = self._mapNode.eventTriggerEditPos.triggers[i]
if entry.eventID == EventTriggerType.BeginDrag then
entry.callback:RemoveListener(cb_begindrag)
elseif entry.eventID == EventTriggerType.Drag then
entry.callback:RemoveListener(cb_drag)
elseif entry.eventID == EventTriggerType.EndDrag then
entry.callback:RemoveListener(cb_enddrag)
end
self._mapNode.eventTriggerEditPos.triggers:Remove(entry)
end
self.tbCallback = nil
end
function Actor2DEditorCtrl:CacheActor2DEditorConfig()
local assetConfig = GameResourceLoader.LoadAsset(ResType.Any, "Assets/AssetBundles/UI/CommonEx/Preference/Actor2DEditor.asset", typeof(ConfigActor2DEditor))
local nLen = assetConfig.arrData.Length - 1
for i = 0, nLen do
local data = assetConfig.arrData[i]
local nPanelId = assetConfig:GetPanelId(i)
local nReusePanelId = assetConfig:GetReusePanelId(i)
local _nCharType = assetConfig:GetCharType(i)
table.insert(tbPanelPreference, {
nId = nPanelId,
nReuse = nReusePanelId,
nCharType = _nCharType,
bInUI = data.InUI,
bFull = data.CanEditFull,
bEmoji = data.CanEditEmoji,
bPose = data.CanEditPose,
sName = data.UIName,
nSpIdx = data.PrefabIndex,
sNodePath = data.NodePath
})
end
end
function Actor2DEditorCtrl:SetUIList()
local listUIName = ListString()
for i, v in ipairs(tbPanelPreference) do
listUIName:Add(v.sName)
end
NovaAPI.ClearDropDownOptions(self._mapNode.ddSelectPanel)
NovaAPI.DropDownAddOptions(self._mapNode.ddSelectPanel, listUIName)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectPanel, 0)
end
function Actor2DEditorCtrl:SetActorList(mapPreference)
local listActor2D = ListString()
local func_CollectChar = function(sPath)
local tbActorIdFolders = Directory.GetDirectories(self:GetABRootPath() .. sPath, "*.*", SearchOption.TopDirectoryOnly)
local nCount = tbActorIdFolders.Length - 1
for i = 0, nCount do
local tb = string.split(tbActorIdFolders[i], "/")
local sFolderName = tb[#tb]
listActor2D:Add(sFolderName)
end
end
if mapPreference.nCharType == ECharType.Char then
func_CollectChar("Actor2D/Character/")
elseif mapPreference.nCharType == ECharType.AvgChar then
func_CollectChar("Actor2D/CharacterAvg/")
elseif mapPreference.nCharType == ECharType.Npc then
func_CollectChar("Actor2D/NPC/")
elseif mapPreference.nCharType == ECharType.CharNpc then
func_CollectChar("Actor2D/Character/")
func_CollectChar("Actor2D/NPC/")
end
NovaAPI.ClearDropDownOptions(self._mapNode.ddSelectActor)
NovaAPI.DropDownAddOptions(self._mapNode.ddSelectActor, listActor2D)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectActor, 0)
end
function Actor2DEditorCtrl:SetPoseList()
local nAllCount = #self.tbAllPose
local listPose = ListString()
for i = 1, nAllCount do
listPose:Add(self.tbAllPose[i])
end
NovaAPI.ClearDropDownOptions(self._mapNode.ddSelectPose)
NovaAPI.DropDownAddOptions(self._mapNode.ddSelectPose, listPose)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectPose, 0)
end
function Actor2DEditorCtrl:SetEmojiList()
self.tbEmojiPrefabPath = {}
local tbCharEmoji = AvgPreset.CharEmoji
local nAllCount = #tbCharEmoji
local listEmoji = ListString()
for i = 3, nAllCount do
local mapEmoji = tbCharEmoji[i]
listEmoji:Add(mapEmoji[2])
table.insert(self.tbEmojiPrefabPath, mapEmoji[3])
end
NovaAPI.ClearDropDownOptions(self._mapNode.ddSelectEmoji)
NovaAPI.DropDownAddOptions(self._mapNode.ddSelectEmoji, listEmoji)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectEmoji, 0)
end
function Actor2DEditorCtrl:SetEditable(bCanEdit, bPreferSetEmoji)
NovaAPI.SetImageRaycastTarget(self._mapNode.imgEditPos, bCanEdit == true)
NovaAPI.SetSliderInteractable(self._mapNode.sldScale, bCanEdit == true)
NovaAPI.SetInputFieldInteractable(self._mapNode.inputScale, bCanEdit == true)
if bPreferSetEmoji == nil then
NovaAPI.SetToggleInteractable(self._mapNode.togEditEmoji, bCanEdit == true)
NovaAPI.SetToggleInteractable(self._mapNode.togMirrorEmoji, bCanEdit == true)
else
NovaAPI.SetToggleInteractable(self._mapNode.togEditEmoji, bCanEdit == true and bPreferSetEmoji == true)
NovaAPI.SetToggleInteractable(self._mapNode.togMirrorEmoji, bCanEdit == true and bPreferSetEmoji == true)
end
end
function Actor2DEditorCtrl:GetABRootPath()
local nSelectedChannel = NovaAPI.GetDropDownValue(self._mapNode.ddSelectChannel)
local sABRootPath = "Assets/AssetBundles"
if nSelectedChannel == 0 then
sABRootPath = sABRootPath .. "/"
elseif nSelectedChannel == 1 then
sABRootPath = sABRootPath .. "_cen/"
end
return sABRootPath
end
function Actor2DEditorCtrl:GetCharEmojiIndex(sEmoji)
for i, v in ipairs(AvgPreset.CharEmoji) do
if v[3] == sEmoji then
return v[1]
end
end
return 0
end
function Actor2DEditorCtrl:IsAvgCharInTalkFrameBg(sPose, sAvgCharId)
if sAvgCharId ~= "avg3_100" and sAvgCharId ~= "avg3_101" then
return false
end
local nCount = 2
local nAllCount = #self.tbAllPose
local bMatch = false
for i = 1, nCount do
if self.tbAllPose[nAllCount] == sPose then
bMatch = true
break
end
nAllCount = nAllCount - 1
end
return bMatch
end
function Actor2DEditorCtrl:GetAvgCharHeadFrameIndex(nValue)
local nIdx = nValue
if nIdx == 2 then
nIdx = 3
end
return nIdx
end
function Actor2DEditorCtrl:ClearAll()
Actor2DManager.UnsetActor2D_ForActor2DEditor()
if self.trEmojiOffset ~= nil then
delChildren(self.trEmojiOffset)
self.trEmojiOffset = nil
end
delChildren(self._mapNode.trUIInsRoot.gameObject)
self:SetEditable(false)
self.Offset = nil
self.nCurPanelId = 0
self.nReusePanelId = 0
self.bInUI = false
self._mapNode.ddSelectPngLive2D.gameObject:SetActive(NovaAPI.GetDropDownValue(self._mapNode.ddSelectPanel) == 2 and NovaAPI.GetDropDownValue(self._mapNode.ddSelectFullOrHalf) == 1)
self._mapNode.ddSelectAvgCharHeadFrame.gameObject:SetActive(NovaAPI.GetDropDownValue(self._mapNode.ddSelectPanel) == 0)
self.nAvgCharHeadMirrorFactor = 1
end
function Actor2DEditorCtrl:CreatePanelTempIns(nIndex)
self:ClearAll()
local mapPreference = tbPanelPreference[nIndex]
if mapPreference == nil then
return
end
local nSpIdx = mapPreference.nSpIdx or 1
local panel = require(PanelDefine[mapPreference.nId])
local sPanelPrefabPath = Settings.AB_ROOT_PATH .. "UI/" .. panel._tbDefine[nSpIdx].sPrefabPath
local objPrefab = GameResourceLoader.LoadAsset(ResType.Any, sPanelPrefabPath, typeof(Object))
local goIns = instantiate(objPrefab, self._mapNode.trUIInsRoot)
goIns.transform.localScale = Vector3.one
local rt = goIns:GetComponent("RectTransform")
rt.anchoredPosition = Vector2.zero
rt.pivot = Vector2(0.5, 0.5)
rt.anchorMin = Vector2.zero
rt.anchorMax = Vector2.one
local sTargetPath = mapPreference.sNodePath
local bEditAvgHeadFrame = false
if mapPreference.nId == PanelId.AvgST then
bEditAvgHeadFrame = NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame) > 0
goIns.transform:Find("----Full_Rect----/--char_head_frame--").gameObject:SetActive(bEditAvgHeadFrame)
NovaAPI.SetImageSprite(goIns.transform:Find("----Full_Rect----/BG"):GetComponent("Image"), "Assets/AssetBundles/ImageAvg/AvgBg/city_street_daylight.png")
if bEditAvgHeadFrame == true then
local sIndex = tostring(NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame))
goIns.transform:Find(string.format("----Full_Rect----/--char_head_frame--/rtFrame_%s", sIndex)).gameObject:SetActive(true)
sTargetPath = string.format("----Full_Rect----/--char_head_frame--/rtFrame_%s/rtFrameOffset/rtFramePos/goCharMask/rtCharOffset_%s/----Actor2D_PNG----", sIndex, sIndex)
NovaAPI.SetToggleIsOn(self._mapNode.togEditEmoji, false)
local nValue = NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame)
if nValue == 1 or nValue == 5 then
self.nAvgCharHeadMirrorFactor = -1
end
end
end
local trRawImg = goIns.transform:Find(sTargetPath)
trRawImg.gameObject:SetActive(true)
local rawImg = trRawImg:GetComponent("RawImage")
local goEmojiRoot = GameObject("trEmojiOffset")
self.trEmojiOffset = goEmojiRoot.transform
self.trEmojiOffset:SetParent(trRawImg.parent)
self.trEmojiOffset.localPosition = Vector3.zero
self.trEmojiOffset.localScale = Vector3.one
self:SetEditable(0 >= mapPreference.nReuse, mapPreference.bEmoji == true and bEditAvgHeadFrame == false)
self.nCurPanelId = mapPreference.nId
self.nCharType = mapPreference.nCharType
self.nReusePanelId = mapPreference.nReuse
self.bInUI = mapPreference.bInUI
self:ProcFadeInUI(goIns)
return trRawImg, rawImg
end
function Actor2DEditorCtrl:ProcFadeInUI(goIns)
if self.nCurPanelId == PanelId.MainView then
goIns.transform:Find("----SafeAreaRoot----"):GetComponent("Animator"):SetTrigger("tLogin")
elseif self.nCurPanelId == PanelId.CharUpPanel then
goIns.transform:Find("----SafeAreaRoot----/----FunctionPanel----/--NodeInfo--/advancePreviewInfo").gameObject:SetActive(false)
end
end
function Actor2DEditorCtrl:OnDD_SelectChannel(dd)
self:ClearAll()
self:SetActorList()
end
function Actor2DEditorCtrl:OnDD_SelectPngLive2D(dd)
self:ClearAll()
end
function Actor2DEditorCtrl:OnDD_SelectPanel(dd)
self:ClearAll()
local nValue = NovaAPI.GetDropDownValue(dd)
local mapPreference = tbPanelPreference[nValue + 1]
self:SetActorList(mapPreference)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectFullOrHalf, 0)
NovaAPI.SetDDInteractable(self._mapNode.ddSelectFullOrHalf, mapPreference.bFull == true)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectEmoji, 0)
NovaAPI.SetDDInteractable(self._mapNode.ddSelectEmoji, mapPreference.bEmoji == true)
NovaAPI.SetToggleIsOn(self._mapNode.togEditEmoji, false)
NovaAPI.SetToggleIsOn(self._mapNode.togMirrorEmoji, false)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectPose, 0)
NovaAPI.SetDDInteractable(self._mapNode.ddSelectPose, mapPreference.bPose == true)
end
function Actor2DEditorCtrl:OnDD_SelectActor(dd)
self:ClearAll()
NovaAPI.SetDropDownValue(self._mapNode.ddSelectFullOrHalf, 0)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectEmoji, 0)
NovaAPI.SetDropDownValue(self._mapNode.ddSelectPose, 0)
end
function Actor2DEditorCtrl:OnDD_SelectPose(dd)
self:ClearAll()
end
function Actor2DEditorCtrl:OnDD_SelectEmoji(dd)
self:ClearAll()
end
function Actor2DEditorCtrl:OnDD_SelectFullOrHalf(dd)
self:ClearAll()
end
function Actor2DEditorCtrl:OnDD_SelectAvgCharFrame(dd)
self:ClearAll()
end
local v2BeginDragPos, v3CurOffsetPos, v3DragPos
local nFactor = 100
function Actor2DEditorCtrl:OnBeginDrag(eventTrigger, eventData)
v2BeginDragPos = eventData.position
v3CurOffsetPos = self.trActorOffset.localPosition
if NovaAPI.GetDDInteractable(self._mapNode.ddSelectEmoji) == true and NovaAPI.GetToggleIsOn(self._mapNode.togEditEmoji) == true then
v3CurOffsetPos = self.trEmojiOffset.localPosition
end
nFactor = self.bInUI == true and 1 or 100
end
function Actor2DEditorCtrl:OnDrag(eventTrigger, eventData)
local v2Del = eventData.position - v2BeginDragPos
if CS.InputManager.Instance:GetKey(CS.UnityEngine.InputSystem.Key.LeftShift) == true then
v2Del.y = 0
end
if CS.InputManager.Instance:GetKey(CS.UnityEngine.InputSystem.Key.LeftAlt) == true then
v2Del.x = 0
end
if NovaAPI.GetDDInteractable(self._mapNode.ddSelectEmoji) == true and NovaAPI.GetToggleIsOn(self._mapNode.togEditEmoji) == true then
v3DragPos = Vector3(v3CurOffsetPos.x + v2Del.x, v3CurOffsetPos.y + v2Del.y, 0)
self.trEmojiOffset.localPosition = v3DragPos
else
if self.nCurPanelId == PanelId.AvgST then
v3DragPos = Vector3(v3CurOffsetPos.x + v2Del.x * self.nAvgCharHeadMirrorFactor, v3CurOffsetPos.y + v2Del.y, 0)
else
v3DragPos = Vector3(v3CurOffsetPos.x + v2Del.x / nFactor, v3CurOffsetPos.y + v2Del.y / nFactor, 0)
end
self.trActorOffset.localPosition = v3DragPos
end
end
function Actor2DEditorCtrl:OnEndDrag(eventTrigger, eventData)
v2BeginDragPos = nil
v3CurOffsetPos = nil
v3DragPos = nil
end
function Actor2DEditorCtrl:OnEditEnd_InputScale()
local nS = tonumber(NovaAPI.GetInputFieldText(self._mapNode.inputScale))
NovaAPI.SetSliderValue(self._mapNode.sldScale, nS)
if NovaAPI.GetToggleIsOn(self._mapNode.togEditEmoji) == true then
local nFactor = 1
if NovaAPI.GetToggleIsOn(self._mapNode.togMirrorEmoji) == true then
nFactor = -1
end
self.trEmojiOffset.localScale = Vector3(nS * nFactor, nS, 1)
else
self.trActorOffset.localScale = Vector3(nS * self.nAvgCharHeadMirrorFactor, nS, 1)
end
end
function Actor2DEditorCtrl:OnValueChanged_SliderScale()
local nS = NovaAPI.GetSliderValue(self._mapNode.sldScale)
NovaAPI.SetInputFieldText(self._mapNode.inputScale, tostring(nS))
if NovaAPI.GetToggleIsOn(self._mapNode.togEditEmoji) == true then
local nFactor = 1
if NovaAPI.GetToggleIsOn(self._mapNode.togMirrorEmoji) == true then
nFactor = -1
end
self.trEmojiOffset.localScale = Vector3(nS * nFactor, nS, 1)
else
self.trActorOffset.localScale = Vector3(nS * self.nAvgCharHeadMirrorFactor, nS, 1)
end
end
function Actor2DEditorCtrl:OnTog_EditEmoji()
if NovaAPI.GetToggleIsOn(self._mapNode.togEditEmoji) == true then
if self.trEmojiOffset ~= nil and self.trEmojiOffset:IsNull() == false then
NovaAPI.SetSliderValue(self._mapNode.sldScale, self.trEmojiOffset.localScale.y)
NovaAPI.SetInputFieldText(self._mapNode.inputScale, tostring(self.trEmojiOffset.localScale.y))
end
elseif self.trActorOffset ~= nil and self.trActorOffset:IsNull() == false then
NovaAPI.SetSliderValue(self._mapNode.sldScale, self.trActorOffset.localScale.y)
NovaAPI.SetInputFieldText(self._mapNode.inputScale, tostring(self.trActorOffset.localScale.y))
end
end
function Actor2DEditorCtrl:OnTog_MirrorEmoji()
if self.trEmojiOffset ~= nil and self.trEmojiOffset:IsNull() == false then
local v3Scale = self.trEmojiOffset.localScale
self.trEmojiOffset.localScale = Vector3(v3Scale.x * -1, v3Scale.y, 1)
end
end
function Actor2DEditorCtrl:OnBtnClick_Reset()
if self.Offset == nil or self.nReusePanelId > 0 then
return
end
NovaAPI.SetToggleIsOn(self._mapNode.togMirrorEmoji, false)
self.trActorOffset.localPosition = Vector3.zero
self.trActorOffset.localScale = Vector3.one
self.trEmojiOffset.localPosition = Vector3.zero
self.trEmojiOffset.localScale = Vector3.one
NovaAPI.SetSliderValue(self._mapNode.sldScale, 1)
NovaAPI.SetInputFieldText(self._mapNode.inputScale, "1")
local sId = NovaAPI.GetCurDDOptionsText(self._mapNode.ddSelectActor)
local sPose = "a"
if NovaAPI.GetDDInteractable(self._mapNode.ddSelectPose) == true then
sPose = NovaAPI.GetCurDDOptionsText(self._mapNode.ddSelectPose)
end
if self:IsAvgCharInTalkFrameBg(sPose, sId) == true then
self.trActorOffset.localPosition = Vector3(0, 540, 0)
self.trActorOffset.localScale = Vector3.one
end
end
function Actor2DEditorCtrl:OnBtnClick_Refresh()
local trRawImg, rawImg = self:CreatePanelTempIns(NovaAPI.GetDropDownValue(self._mapNode.ddSelectPanel) + 1)
if self.nCurPanelId == PanelId.AvgST then
self.trActorOffset = trRawImg:GetChild(0):GetChild(0)
if 0 < NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame) then
self.trActorOffset = trRawImg.parent
end
else
self.trActorOffset = self.bInUI == true and trRawImg:GetChild(0):GetChild(0) or self.trRendererActorOffset
end
local sId = NovaAPI.GetCurDDOptionsText(self._mapNode.ddSelectActor)
local bFull = NovaAPI.GetDropDownValue(self._mapNode.ddSelectFullOrHalf) == 1
local bL2D = NovaAPI.GetDropDownValue(self._mapNode.ddSelectPngLive2D) == 1 and self._mapNode.ddSelectPngLive2D.gameObject.activeSelf == true
local sPose = "a"
local sFolder = ""
local bIsNpc = false
if self.nCharType == ECharType.Char then
sFolder = "Actor2D/Character/"
elseif self.nCharType == ECharType.AvgChar then
sPose = NovaAPI.GetCurDDOptionsText(self._mapNode.ddSelectPose)
sFolder = "Actor2D/CharacterAvg/"
elseif self.nCharType == ECharType.Npc then
sFolder = "Actor2D/NPC/"
bIsNpc = true
elseif self.nCharType == ECharType.CharNpc then
sFolder = "Actor2D/Character/"
end
local sAssetPath = string.format("%s%s%s/%s.asset", self:GetABRootPath(), sFolder, sId, sId)
self.Offset = CS.UnityEditor.AssetDatabase.LoadAssetAtPath(sAssetPath, typeof(Actor2DOffsetData))
if self.Offset == nil and self.nCharType == ECharType.CharNpc then
sFolder = "Actor2D/NPC/"
sAssetPath = string.format("%s%s%s/%s.asset", self:GetABRootPath(), sFolder, sId, sId)
self.Offset = CS.UnityEditor.AssetDatabase.LoadAssetAtPath(sAssetPath, typeof(Actor2DOffsetData))
bIsNpc = true
end
CS.UnityEditor.Selection.activeObject = self.Offset
local nX, nY, nL2DX, nL2DY = 0, 0, 0, 0
local nPanelId = self.nCurPanelId
if 0 < self.nReusePanelId then
nPanelId = self.nReusePanelId
end
local s, x, y = self.Offset:GetOffsetData(nPanelId, indexOfPose(sPose), bFull ~= true, nX, nY)
local l2ds, l2dx, l2dy = self.Offset:GetL2DData(nL2DX, nL2DY)
if l2ds <= 0 then
l2dx, l2dy, l2ds = 0, 0, 1
end
if self.nCurPanelId == PanelId.AvgST then
if self:IsAvgCharInTalkFrameBg(sPose, sId) == true then
s, x, y = 1, 0, 540
NovaAPI.SetToggleIsOn(self._mapNode.togEditEmoji, true)
NovaAPI.SetToggleInteractable(self._mapNode.togEditEmoji, false)
end
Actor2DManager.SetActor2D_PNG_ForActor2DEditor(self.nCurPanelId, trRawImg, sId, self:GetABRootPath() .. sFolder .. sId, s, x, y, sPose)
if 0 < NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame) then
local nFrameIndex = self:GetAvgCharHeadFrameIndex(NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame))
local _nAvgCharHeadFrameX, _nAvgCharHeadFrameY = 0, 0
local nAvgCharHeadFrameS, nAvgCharHeadFrameX, nAvgCharHeadFrameY = self.Offset:Get_AvgCharHeadFrameData(nPanelId, indexOfPose(sPose), nFrameIndex, _nAvgCharHeadFrameX, _nAvgCharHeadFrameY)
self.trActorOffset.localPosition = Vector3(nAvgCharHeadFrameX, nAvgCharHeadFrameY, 0)
self.trActorOffset.localScale = Vector3(nAvgCharHeadFrameS, math.abs(nAvgCharHeadFrameS), 1)
end
elseif self.bInUI == true then
Actor2DManager.SetActor2D_PNG_ForActor2DEditor(self.nCurPanelId, trRawImg, sId, self:GetABRootPath() .. sFolder .. sId, s, 100 * x, 100 * y)
else
local trL2D = Actor2DManager.SetActor2D_ForActor2DEditor(self.nCurPanelId, rawImg, sId, bFull, self:GetABRootPath() .. sFolder, s, x, y, bL2D, l2dx, l2dy, l2ds, bIsNpc == true)
if trL2D ~= nil then
self.trActorOffset = trL2D
end
end
NovaAPI.SetSliderValue(self._mapNode.sldScale, self.trActorOffset.localScale.y)
NovaAPI.SetInputFieldText(self._mapNode.inputScale, tostring(self.trActorOffset.localScale.y))
if NovaAPI.GetDDInteractable(self._mapNode.ddSelectEmoji) == true then
local nValue = NovaAPI.GetDropDownValue(self._mapNode.ddSelectEmoji)
local sEmojiPrefabName = self.tbEmojiPrefabPath[nValue + 1]
local objEmojiPrefab = CS.UnityEditor.AssetDatabase.LoadAssetAtPath(Settings.AB_ROOT_PATH .. "UI/Avg/AnimEmoji/" .. sEmojiPrefabName .. ".prefab", typeof(Object))
local goEmojiIns = instantiate(objEmojiPrefab, self.trEmojiOffset)
local anim = goEmojiIns:GetComponent("Animator")
anim:SetTrigger("tEditor")
local _nX, _nY = 0, 0
local _s, _x, _y = self.Offset:GetEmojiData(self.nCurPanelId, indexOfPose(sPose), self:GetCharEmojiIndex(sEmojiPrefabName), _nX, _nY)
if self:IsAvgCharInTalkFrameBg(sPose, sId) == true then
_y = _y + 540
end
NovaAPI.SetToggleIsOn(self._mapNode.togMirrorEmoji, _s < 0)
self.trEmojiOffset.localPosition = Vector3(_x, _y, 0)
self.trEmojiOffset.localScale = Vector3(_s, math.abs(_s), 1)
if NovaAPI.GetToggleIsOn(self._mapNode.togEditEmoji) == true then
NovaAPI.SetSliderValue(self._mapNode.sldScale, self.trEmojiOffset.localScale.y)
NovaAPI.SetInputFieldText(self._mapNode.inputScale, tostring(self.trEmojiOffset.localScale.y))
end
end
end
function Actor2DEditorCtrl:OnBtnClick_Save()
if self.Offset == nil or self.nReusePanelId > 0 then
return
end
local sId = NovaAPI.GetCurDDOptionsText(self._mapNode.ddSelectActor)
local sPose = "a"
if NovaAPI.GetDDInteractable(self._mapNode.ddSelectPose) == true then
sPose = NovaAPI.GetCurDDOptionsText(self._mapNode.ddSelectPose)
end
local v3Pos = self.trActorOffset.localPosition
local v3Scale = self.trActorOffset.localScale
if self._mapNode.ddSelectPngLive2D.gameObject.activeSelf == true and NovaAPI.GetDropDownValue(self._mapNode.ddSelectPngLive2D) == 1 then
self.Offset:SetL2DData(v3Pos.x, v3Pos.y, v3Scale.x)
elseif self.nCurPanelId == PanelId.AvgST and 0 < NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame) then
local nFrameIndex = self:GetAvgCharHeadFrameIndex(NovaAPI.GetDropDownValue(self._mapNode.ddSelectAvgCharHeadFrame))
self.Offset:Set_AvgCharHeadFrameData(self.nCurPanelId, indexOfPose(sPose), nFrameIndex, v3Pos.x, v3Pos.y, v3Scale.x)
else
local x, y, s = v3Pos.x, v3Pos.y, v3Scale.x
if self:IsAvgCharInTalkFrameBg(sPose, sId) == true and self.nCurPanelId == PanelId.AvgST then
y = y - 540
end
if self.bInUI == true and self.nCurPanelId ~= PanelId.AvgST then
x = x / 100
y = y / 100
end
self.Offset:SetOffsetData(self.nCurPanelId, indexOfPose(sPose), NovaAPI.GetDropDownValue(self._mapNode.ddSelectFullOrHalf) == 0, x, y, s)
end
if NovaAPI.GetDDInteractable(self._mapNode.ddSelectEmoji) == true then
local v3EmojiPos = self.trEmojiOffset.localPosition
local v3EmojiScale = self.trEmojiOffset.localScale
local nValue = NovaAPI.GetDropDownValue(self._mapNode.ddSelectEmoji)
local sEmojiPrefabName = self.tbEmojiPrefabPath[nValue + 1]
local y = v3EmojiPos.y
if self:IsAvgCharInTalkFrameBg(sPose, sId) == true and self.nCurPanelId == PanelId.AvgST then
y = y - 540
end
self.Offset:SetEmojiData(self.nCurPanelId, indexOfPose(sPose), self:GetCharEmojiIndex(sEmojiPrefabName), v3EmojiPos.x, y, v3EmojiScale.x)
end
CS.UnityEditor.EditorUtility.SetDirty(self.Offset)
CS.UnityEditor.AssetDatabase.SaveAssets()
CS.UnityEditor.AssetDatabase.Refresh()
end
return Actor2DEditorCtrl
@@ -0,0 +1,8 @@
local Actor2DEditorPanel = class("Actor2DEditorPanel", BasePanel)
Actor2DEditorPanel._tbDefine = {
{
sPrefabPath = "Actor2DEditor/Actor2DEditor.prefab",
sCtrlName = "Game.Actor2D.Editor.Actor2DEditorCtrl"
}
}
return Actor2DEditorPanel
+6
View File
@@ -0,0 +1,6 @@
require("GameCore.GameCore")
RUNNING_ACTOR2D_EDITOR = true
local goLaunchUI = GameObject.Find("==== Builtin UI ====/LaunchUI")
GameObject.Destroy(goLaunchUI)
CS.WwiseAudioManager.Instance.MusicVolume = 0
EventManager.Hit(EventId.OpenPanel, PanelId.Actor2DEditor)
@@ -0,0 +1,401 @@
local BBVEditorCtrl = class("BBVEditorCtrl", BaseCtrl)
local BubbleVoiceManager = require("Game.Actor2D.BubbleVoiceManager")
local Actor2DManager = require("Game.Actor2D.Actor2DManager")
BBVEditorCtrl._mapNodeConfig = {
rawImage = {
sNodeName = "----Actor2D----",
sComponentName = "RawImage"
},
ipt_SrcContent = {sComponentName = "InputField"},
dd_PlayerSex = {
sComponentName = "Dropdown",
callback = "OnDD_PlayerSex"
},
dd_Language_Vo = {
sComponentName = "Dropdown",
callback = "OnEvent_SwitchVoLan"
},
dd_Language_Txt = {
sComponentName = "Dropdown",
callback = "OnEvent_SwitchTxtLan"
},
btn_SaveSplitContent = {},
btn_UseCn_Time_Anim = {
sComponentName = "Button",
callback = "OnBtn_ReuseCnTimeAnim"
},
btn_UseJp_Time_Anim = {
sComponentName = "Button",
callback = "OnBtn_ReuseJpTimeAnim"
},
btn_SaveByDefault = {
sComponentName = "Button",
callback = "OnBtn_SaveNewDataByDefault"
},
dd_VoResName = {sComponentName = "Dropdown"},
btn_Back = {sComponentName = "Button", callback = "OnBtn_Back"},
tog_CnM = {sComponentName = "Toggle"},
tog_CnF = {sComponentName = "Toggle"},
tog_JpM = {sComponentName = "Toggle"},
CnMText = {nCount = 4, sComponentName = "InputField"},
CnMTextFallback = {nCount = 4, sComponentName = "Text"},
CnMTime = {nCount = 4, sComponentName = "InputField"},
CnMTimeFallback = {nCount = 4, sComponentName = "Text"},
CnMAnim = {nCount = 4, sComponentName = "Dropdown"},
CnFText = {nCount = 4, sComponentName = "InputField"},
CnFTextFallback = {nCount = 4, sComponentName = "Text"},
CnFTime = {nCount = 4, sComponentName = "InputField"},
CnFTimeFallback = {nCount = 4, sComponentName = "Text"},
CnFAnim = {nCount = 4, sComponentName = "Dropdown"},
JpMText = {nCount = 4, sComponentName = "InputField"},
JpMTextFallback = {nCount = 4, sComponentName = "Text"},
JpMTime = {nCount = 4, sComponentName = "InputField"},
JpMTimeFallback = {nCount = 4, sComponentName = "Text"},
JpMAnim = {nCount = 4, sComponentName = "Dropdown"},
JpFText = {nCount = 4, sComponentName = "InputField"},
JpFTextFallback = {nCount = 4, sComponentName = "Text"},
JpFTime = {nCount = 4, sComponentName = "InputField"},
JpFTimeFallback = {nCount = 4, sComponentName = "Text"},
JpFAnim = {nCount = 4, sComponentName = "Dropdown"},
goBubbleRoot = {
sNodeName = "----bubble----"
},
rtBubbleRoot = {
sNodeName = "----bubble----",
sComponentName = "RectTransform"
},
dd_BBLeftRight = {sComponentName = "Dropdown"},
tmp_CurVosResLen = {sComponentName = "TMP_Text"}
}
BBVEditorCtrl._mapEventConfig = {
BBVE_SetTextTime = "onEvent_SetTextTime",
BBVE_SaveTextTime = "onEvent_SaveTextTime",
BBVE_SetCharL2D = "onEvent_SetCharL2D",
BBVE_SaveOffset = "onEvent_SaveOffset",
BBVE_Play = "onEvent_Play",
BBVE_Stop = "onEvent_Stop",
BBVE_Pause = "onEvent_Pause",
BBVE_Resume = "onEvent_Resume",
BBVE_CheckNewData = "onEvent_CheckNewData"
}
function BBVEditorCtrl:OnEnable()
if Settings.sCurrentTxtLanguage == AllEnum.Language.CN then
NovaAPI.SetToggleIsOn(self._mapNode.tog_CnF, true)
NovaAPI.SetToggleInteractable(self._mapNode.tog_CnM, false)
NovaAPI.SetToggleInteractable(self._mapNode.tog_JpM, false)
for i = 1, 4 do
self._mapNode.CnFAnim[i].gameObject:SetActive(true)
self._mapNode.JpFAnim[i].gameObject:SetActive(false)
end
else
if Settings.sCurrentTxtLanguage == AllEnum.Language.JP then
NovaAPI.SetToggleInteractable(self._mapNode.tog_CnM, false)
NovaAPI.SetToggleInteractable(self._mapNode.tog_CnF, false)
else
end
end
local ListString = CS.System.Collections.Generic.List(CS.System.String)
local listLanguage = ListString()
for i, v in ipairs(AllEnum.LanguageInfo) do
listLanguage:Add(v[2])
end
NovaAPI.ClearDropDownOptions(self._mapNode.dd_Language_Vo)
NovaAPI.DropDownAddOptions(self._mapNode.dd_Language_Vo, listLanguage)
NovaAPI.SetDDValueWithoutNotify(self._mapNode.dd_Language_Vo, GetLanguageIndex(Settings.sCurrentVoLanguage) - 1)
self.mapText = {
male_cn = self._mapNode.CnMText,
female_cn = self._mapNode.CnFText,
male_jp = self._mapNode.JpMText,
female_jp = self._mapNode.JpFText
}
self.mapTextFallback = {
male_cn = self._mapNode.CnMTextFallback,
female_cn = self._mapNode.CnFTextFallback,
male_jp = self._mapNode.JpMTextFallback,
female_jp = self._mapNode.JpFTextFallback
}
self.mapTime = {
male_cn = self._mapNode.CnMTime,
female_cn = self._mapNode.CnFTime,
male_jp = self._mapNode.JpMTime,
female_jp = self._mapNode.JpFTime
}
self.mapTimeFallback = {
male_cn = self._mapNode.CnMTimeFallback,
female_cn = self._mapNode.CnFTimeFallback,
male_jp = self._mapNode.JpMTimeFallback,
female_jp = self._mapNode.JpFTimeFallback
}
self.mapAnim = {
male_cn = self._mapNode.CnMAnim,
female_cn = self._mapNode.CnFAnim,
male_jp = self._mapNode.JpMAnim,
female_jp = self._mapNode.JpFAnim
}
self.tbCheckOrder = {
"male_cn",
"female_cn",
"male_jp",
"female_jp"
}
if Settings.sCurrentTxtLanguage == AllEnum.Language.CN then
self.tbCheckOrder = {
"male_jp",
"female_jp",
"male_cn",
"female_cn"
}
elseif Settings.sCurrentTxtLanguage == AllEnum.Language.JP then
self.tbCheckOrder = {"male_jp", "female_jp"}
end
self:InitL2DAnimDD()
BubbleVoiceManager.Init(true)
local bReuseFunc = Settings.sCurrentTxtLanguage ~= AllEnum.Language.CN and Settings.sCurrentTxtLanguage ~= AllEnum.Language.JP
self._mapNode.btn_UseCn_Time_Anim.gameObject:SetActive(bReuseFunc)
self._mapNode.btn_UseJp_Time_Anim.gameObject:SetActive(bReuseFunc)
end
function BBVEditorCtrl:OnDisable()
Actor2DManager.DestroyL2D_InBBVEditor()
end
function BBVEditorCtrl:InitL2DAnimDD()
self.tbAnimName = {
"",
"presents_a",
"presents_b",
"chat_a",
"chat_b",
"chat_c",
"chat_d",
"think_a",
"shy_a",
"special_a",
"special_b"
}
local ListString = CS.System.Collections.Generic.List(CS.System.String)
local listAnim = ListString()
for i, v in ipairs(self.tbAnimName) do
listAnim:Add(v)
end
for i = 1, 4 do
NovaAPI.ClearDropDownOptions(self._mapNode.CnMAnim[i])
NovaAPI.ClearDropDownOptions(self._mapNode.CnFAnim[i])
NovaAPI.ClearDropDownOptions(self._mapNode.JpMAnim[i])
NovaAPI.ClearDropDownOptions(self._mapNode.JpFAnim[i])
end
for i = 1, 4 do
NovaAPI.DropDownAddOptions(self._mapNode.CnMAnim[i], listAnim)
NovaAPI.DropDownAddOptions(self._mapNode.CnFAnim[i], listAnim)
NovaAPI.DropDownAddOptions(self._mapNode.JpMAnim[i], listAnim)
NovaAPI.DropDownAddOptions(self._mapNode.JpFAnim[i], listAnim)
end
end
function BBVEditorCtrl:OnDD_PlayerSex()
local bIsMale = NovaAPI.GetDropDownValue(self._mapNode.dd_PlayerSex) == 1
PlayerData.Base:SetPlayerSex(bIsMale)
end
function BBVEditorCtrl:OnBtn_Back()
EventManager.Hit(EventId.OpenPanel, PanelId.ExeEditor)
end
function BBVEditorCtrl:OnEvent_SwitchVoLan(dd)
local nIndex = NovaAPI.GetDropDownValue(dd)
local sVoLan = AllEnum.LanguageInfo[nIndex + 1][1]
if sVoLan ~= AllEnum.Language.CN and sVoLan ~= AllEnum.Language.JP then
sVoLan = Settings.sCurrentVoLanguage
nIndex = GetLanguageIndex(sVoLan)
NovaAPI.SetDDValueWithoutNotify(dd, nIndex - 1)
return
end
local bDownloaded, nTotalSize, nNeedDownloadSize = NovaAPI.HasDownload_VoLanguage(sVoLan)
if bDownloaded == false and 0 < nNeedDownloadSize then
NovaAPI.Enable_VoLanguage(sVoLan)
PanelManager.OnConfirmBackToLogIn()
return
end
NovaAPI.SetCur_VoiceLanguage(sVoLan)
Settings.sCurrentVoLanguage = sVoLan
end
function BBVEditorCtrl:OnEvent_SwitchTxtLan(dd)
local nLanIdx = NovaAPI.GetDropDownValue(dd) + 1
local sLan = GetLanguageByIndex(nLanIdx)
NovaAPI.SetCur_TextLanguage(sLan)
Settings.sCurrentTxtLanguage = sLan
PanelManager.OnConfirmBackToLogIn()
end
function BBVEditorCtrl:_ReuseData(_sLan, _sKey)
local data = BubbleVoiceManager.GetReuseData(_sLan)
if data == nil then
return
end
local tbFallbackTime = {
0,
0,
0,
0
}
local nCount = #self.tbCheckOrder
for i = nCount, 1, -1 do
local sKey = self.tbCheckOrder[i]
local bTimeFB = false
for ii = 1, 4 do
local nTime = data.time[sKey][ii]
bTimeFB = nTime <= 0
if bTimeFB == false then
tbFallbackTime[ii] = nTime
end
local _nTime = tbFallbackTime[ii]
NovaAPI.SetInputFieldText(self.mapTime[sKey][ii], bTimeFB == true and "" or tostring(nTime))
NovaAPI.SetText(self.mapTimeFallback[sKey][ii], bTimeFB == true and tostring(_nTime) or "")
if sKey == "female_jp" then
local nDDIndex = table.indexof(self.tbAnimName, data.anim[_sKey][ii]) - 1
NovaAPI.SetDropDownValue(self.mapAnim[sKey][ii], nDDIndex)
end
end
end
self._mapNode.btn_SaveSplitContent:SetActive(true)
end
function BBVEditorCtrl:OnBtn_ReuseCnTimeAnim()
self:_ReuseData(AllEnum.Language.CN, "female_cn")
end
function BBVEditorCtrl:OnBtn_ReuseJpTimeAnim()
self:_ReuseData(AllEnum.Language.JP, "female_jp")
end
function BBVEditorCtrl:OnBtn_SaveNewDataByDefault()
local sCurVoResName = self.sVoResName
self.bSaveByDefault = true
if type(self.tbVoResName) == "table" then
for i, sVoResName in ipairs(self.tbVoResName) do
if BubbleVoiceManager.IsNew(sVoResName) == true then
NovaAPI.SetDropDownValue(self._mapNode.dd_VoResName, i - 1)
end
end
end
self.bSaveByDefault = nil
NovaAPI.SetDropDownValue(self._mapNode.dd_VoResName, table.indexof(self.tbVoResName, sCurVoResName) - 1)
end
function BBVEditorCtrl:onEvent_SetTextTime(sVoResName)
self.sVoResName = sVoResName
self.mapAllData, self.bIsNewData = BubbleVoiceManager.GetBubbleData_All(sVoResName)
local tbFallbackText = {
"",
"",
"",
""
}
local tbFallbackTime = {
0,
0,
0,
0
}
local nCount = #self.tbCheckOrder
NovaAPI.SetTMPText(self._mapNode.tmp_CurVosResLen, tostring(BubbleVoiceManager.GetVoResLen(sVoResName)))
if self.bIsNewData == true then
local sKey = self.tbCheckOrder[nCount]
self.mapAllData.text[sKey][1] = NovaAPI.GetInputFieldText(self._mapNode.ipt_SrcContent)
self.mapAllData.time[sKey][1] = BubbleVoiceManager.GetVoResLen(sVoResName)
end
for i = nCount, 1, -1 do
local sKey = self.tbCheckOrder[i]
local bTextFB = false
local bTimeFB = false
for ii = 1, 4 do
local sText = self.mapAllData.text[sKey][ii]
local nTime = self.mapAllData.time[sKey][ii]
sText = string.gsub(sText, "==RT==", "\n")
if ii == 1 and i ~= nCount then
bTextFB = sText == ""
bTimeFB = nTime <= 0
end
if bTextFB == false then
tbFallbackText[ii] = sText
end
if bTimeFB == false then
tbFallbackTime[ii] = nTime
end
local _sText = tbFallbackText[ii]
local _nTime = tbFallbackTime[ii]
NovaAPI.SetInputFieldText(self.mapText[sKey][ii], bTextFB == true and "" or sText)
NovaAPI.SetText(self.mapTextFallback[sKey][ii], bTextFB == true and _sText or "")
NovaAPI.SetInputFieldText(self.mapTime[sKey][ii], bTimeFB == true and "" or tostring(nTime))
NovaAPI.SetText(self.mapTimeFallback[sKey][ii], bTimeFB == true and tostring(_nTime) or "")
if i == nCount then
local nDDIndex = table.indexof(self.tbAnimName, self.mapAllData.anim[sKey][ii]) - 1
NovaAPI.SetDropDownValue(self.mapAnim[sKey][ii], nDDIndex)
end
end
end
if self.bSaveByDefault == true then
self:onEvent_SaveTextTime()
else
self._mapNode.btn_SaveSplitContent:SetActive(self.bIsNewData == true)
end
end
function BBVEditorCtrl:onEvent_SaveTextTime()
if self.mapAllData ~= nil then
local nCount = #self.tbCheckOrder
for i = 1, nCount do
local sKey = self.tbCheckOrder[i]
local bTextFB = false
local bTimeFB = false
for ii = 1, 4 do
local sText = NovaAPI.GetInputFieldText(self.mapText[sKey][ii])
local sTime = NovaAPI.GetInputFieldText(self.mapTime[sKey][ii])
sText = string.gsub(sText, "\r\n", "==RT==")
sText = string.gsub(sText, "\r", "==RT==")
sText = string.gsub(sText, "\n", "==RT==")
sText = string.gsub(sText, "\\", "")
sText = string.gsub(sText, "\"", "\"")
if ii == 1 and i ~= nCount then
bTextFB = sText == ""
bTimeFB = sTime == ""
end
if sTime == "" then
sTime = "0"
end
self.mapAllData.text[sKey][ii] = bTextFB == true and "" or sText
self.mapAllData.time[sKey][ii] = bTimeFB == true and 0 or tonumber(sTime)
if i == nCount then
local nDDIndex = NovaAPI.GetDropDownValue(self.mapAnim[sKey][ii]) + 1
self.mapAllData.anim[sKey][ii] = self.tbAnimName[nDDIndex]
end
end
end
BubbleVoiceManager.DoSaveData(self.mapAllData)
if self.bSaveByDefault ~= true then
self:onEvent_SetTextTime(self.sVoResName)
end
end
end
function BBVEditorCtrl:onEvent_SetCharL2D(bIsNpc, nCharSkinId, bIsCG)
Actor2DManager.SetL2D_InBBVEditor(self._mapNode.rawImage, bIsNpc, nCharSkinId, bIsCG)
local bIsLeft, x, y = BubbleVoiceManager.BBVEditor_GetBBPos(nCharSkinId, bIsCG)
self._mapNode.rtBubbleRoot.anchoredPosition = Vector2(x, y)
NovaAPI.SetDDValueWithoutNotify(self._mapNode.dd_BBLeftRight, bIsLeft == true and 0 or 1)
end
function BBVEditorCtrl:onEvent_SaveOffset(nCharSkinId, bIsCG, bIsLeft, x, y)
BubbleVoiceManager.DoSaveOffset(nCharSkinId, bIsCG, bIsLeft, x / 100, y / 100)
end
function BBVEditorCtrl:onEvent_Play(sVoResName, nCharSkinId, bIsCG)
BubbleVoiceManager.PlayBubbleAnim(self._mapNode.goBubbleRoot, sVoResName, nCharSkinId, bIsCG)
end
function BBVEditorCtrl:onEvent_Stop()
BubbleVoiceManager.StopBubbleAnim()
end
function BBVEditorCtrl:onEvent_Pause()
BubbleVoiceManager.PauseBubbleAnim()
end
function BBVEditorCtrl:onEvent_Resume()
BubbleVoiceManager.ResumeBubbleAnim()
end
function BBVEditorCtrl:onEvent_CheckNewData(listVoResName, nCount)
self.tbVoResName = {}
nCount = nCount - 1
for i = 0, nCount do
local sVoResName = listVoResName[i]
if type(sVoResName) == "string" then
table.insert(self.tbVoResName, sVoResName)
end
end
self._mapNode.btn_SaveByDefault.gameObject:SetActive(BubbleVoiceManager.HasNewDataToSave(self.tbVoResName) == true)
end
return BBVEditorCtrl
@@ -0,0 +1,8 @@
local BBVEditorPanel = class("BBVEditorPanel", BasePanel)
BBVEditorPanel._tbDefine = {
{
sPrefabPath = "BubbleVoiceEditor/BubbleVoiceEditorPanel.prefab",
sCtrlName = "Game.Actor2D.Editor_BBV.BBVEditorCtrl"
}
}
return BBVEditorPanel
@@ -0,0 +1,164 @@
local ExeEditorCtrl = class("ExeEditorCtrl", BaseCtrl)
ExeEditorCtrl._mapNodeConfig = {
btn_AvgEditor = {
sComponentName = "Button",
callback = "onBtn_AvgEditor"
},
btn_BubbleVoiceEditor = {
sComponentName = "Button",
callback = "onBtn_BubbleVoiceEditor"
},
btn_TEST = {sComponentName = "Button", callback = "onBtn_TEST"}
}
ExeEditorCtrl._mapEventConfig = {}
function ExeEditorCtrl:onBtn_AvgEditor()
require("Game.UI.Avg.Editor.main")
EventManager.Hit(EventId.OpenPanel, PanelId.AvgEditor)
end
function ExeEditorCtrl:onBtn_BubbleVoiceEditor()
require("Game.Actor2D.Editor_BBV.main")
EventManager.Hit(EventId.OpenPanel, PanelId.BBVEditor)
end
function ExeEditorCtrl:onBtn_TEST()
end
function ExeEditorCtrl:CheckMissingAvgCharacterId()
local rootPath = CS.UnityEngine.Application.dataPath .. "/../Lua/Game/UI/Avg/"
local sourceDir = {
rootPath .. "_cn/Config",
rootPath .. "_en/Config",
rootPath .. "_jp/Config",
rootPath .. "_kr/Config",
rootPath .. "_tw/Config"
}
local targetFile = rootPath .. "AvgCharacter/AvgCharacter.lua"
local cmdGroup = self:ScanCmdGetParamTarget()
local allFields = {}
for k, v in ipairs(sourceDir) do
print("开始扫描源目录: " .. v)
local sourceFiles = self:ScanDirectoryForLuaFiles(v)
for _, filePath in ipairs(sourceFiles) do
local allParamTables = self:ExtractFieldsFromFile(filePath, cmdGroup)
allFields[filePath] = allParamTables
end
end
local missing = self:CheckFieldsInTarget(allFields, targetFile)
self:ExportTxtFile(missing)
end
function ExeEditorCtrl:ScanCmdGetParamTarget()
local filePath = "D:/NewNovaProject/Nova_Client/Lua/Game/UI/Avg/Editor/CmdInfo.lua"
local paramTables = {}
if CS.System.IO.File.Exists(filePath) then
local lines = CS.System.IO.File.ReadAllLines(filePath)
local funcName = ""
for i = 0, lines.Length - 1 do
local line = lines[i]
if line:match("function") then
funcName = line:match("_([^%(]+)%(")
end
if funcName ~= "" and line:match("SetAvgCharId") then
local number = line:match("%[(%d+)%]")
if number ~= nil then
paramTables[funcName] = tonumber(number)
end
end
end
end
return paramTables
end
function ExeEditorCtrl:ScanDirectoryForLuaFiles(directory)
local files = {}
if CS.System.IO.Directory.Exists(directory) then
local fileEntries = CS.System.IO.Directory.GetFiles(directory, "*.lua", CS.System.IO.SearchOption.AllDirectories)
for i = 0, fileEntries.Length - 1 do
table.insert(files, fileEntries[i])
end
else
print("[错误] 目录不存在: " .. directory)
end
return files
end
function ExeEditorCtrl:ExtractFieldsFromFile(filePath, tbCmd)
local paramTables = {}
if CS.System.IO.File.Exists(filePath) then
local lines = CS.System.IO.File.ReadAllLines(filePath)
for i = 0, lines.Length - 1 do
do
local line = lines[i]
local content = line:match("cmd=\"(.-)\"")
if tbCmd[content] ~= nil then
local paramTableStr = line:match("param%s*=%s*(%b{})")
if paramTableStr then
do
local success, result = pcall(function()
local env = {
table = table
}
local func, err = load("return " .. paramTableStr, "tmp", "t", env)
if func then
return func()
else
print("[解析错误] 行 " .. i + 1 .. ": " .. err)
return nil
end
end)
if success and result then
local num = tbCmd[content]
local AvgCharacterId = result[num]
table.insert(paramTables, {
line = i + 1,
value = AvgCharacterId
})
end
end
end
end
end
end
end
return paramTables
end
function ExeEditorCtrl:CheckFieldsInTarget(fields, targetDir)
local missing = {}
local tbAllIds = {}
if CS.System.IO.File.Exists(targetDir) then
local lines = CS.System.IO.File.ReadAllLines(targetDir)
for i = 0, lines.Length - 1 do
local line = lines[i]
local content = line:match("id = \"(.-)\"")
if content ~= nil then
table.insert(tbAllIds, content)
end
end
end
for k, v in pairs(fields) do
if 0 < #v then
for _, param in ipairs(v) do
if 0 >= table.indexof(tbAllIds, param.value) then
if missing[k] == nil then
missing[k] = {}
end
table.insert(missing[k], param)
end
end
end
end
return missing
end
function ExeEditorCtrl:ExportTxtFile(missing)
local exportDir = CS.UnityEngine.Application.dataPath .. "/../AvgCharacterMissingId/"
local filePath = exportDir .. "output.txt"
if not CS.System.IO.Directory.Exists(exportDir) then
CS.System.IO.Directory.CreateDirectory(exportDir)
end
local streamWriter = CS.System.IO.File.CreateText(filePath)
for filePath, params in pairs(missing) do
streamWriter:WriteLine(filePath)
for _, param in pairs(params) do
local line = string.format(" 第%s行, name:%s", param.line, param.value)
streamWriter:WriteLine(line)
end
end
streamWriter:Close()
print("导出成功!路径: " .. filePath)
end
return ExeEditorCtrl
@@ -0,0 +1,5 @@
EXE_EDITOR = true
require("GameCore.GameCore")
EventManager.Hit(EventId.OpenPanel, PanelId.ExeEditor)
local goLaunchUI = GameObject.Find("==== Builtin UI ====/LaunchUI")
GameObject.Destroy(goLaunchUI)
@@ -0,0 +1,8 @@
local ExeEditorPanel = class("ExeEditorPanel", BasePanel)
ExeEditorPanel._tbDefine = {
{
sPrefabPath = "BubbleVoiceEditor/ExeEditorPanel.prefab",
sCtrlName = "Game.Actor2D.Editor_BBV.ExeEditorCtrl"
}
}
return ExeEditorPanel
+1
View File
@@ -0,0 +1 @@
RUNNING_BBV_EDITOR = true