pre cw with probe and a bunch script to read game behavior
This commit is contained in:
1 parent
5120219ae2
commit
da8a32f60d
310 files changed
+219693
-872
No files matched your search
+180
-39
@@ -10,11 +10,12 @@ local Camera = CS.UnityEngine.Camera
|
||||
-- Never target an ancestor shared by HUD and character/reward dialogs.
|
||||
local HUD_PATHS = {
|
||||
"UIRoot/Page/MazeMainPage(Clone)",
|
||||
-- Fallback for clients where the phase's private HudPage field is absent
|
||||
-- or does not include every battle overlay.
|
||||
"UIRoot/Page/BattleGamePhaseUI(Clone)",
|
||||
"UIRoot/BelowPage/AdventureWaypointsPage(Clone)",
|
||||
"UIRoot/BelowPage/MazeJumpingText(Clone)",
|
||||
"UIRoot/BelowPage/MazeMonsterWarningPage(Clone)",
|
||||
"UIRoot/AboveDialog/BetaHintDialog(Clone)",
|
||||
-- Character controls observed under AvatarMainPage/Root. Keep RankPanel
|
||||
-- and dialogs intact so Eidolon illustrations are not hidden with menus.
|
||||
"UIRoot/Page/AvatarMainPage(Clone)/Root/AvatarSubMenuPanel_Vertical",
|
||||
@@ -23,12 +24,11 @@ local HUD_PATHS = {
|
||||
"UIRoot/Page/AvatarMainPage(Clone)/Root/AvatarListPanel",
|
||||
"UIRoot/Page/AvatarMainPage(Clone)/Root/BtnClose",
|
||||
"UIRoot/Page/AvatarMainPage(Clone)/Root/TopBarArea",
|
||||
"VersionText"
|
||||
}
|
||||
|
||||
-- The old script did not record CanvasGroup state. Undo its blanket hide once
|
||||
-- on live upgrade; a fresh Client session avoids any lost legacy fade state.
|
||||
if _G.__HIDE_UI_REGISTERED and _G.__HIDE_UI_SCHEMA ~= 2 and _G.__HIDE_UI_ENABLED then
|
||||
if _G.__HIDE_UI_REGISTERED and (_G.__HIDE_UI_SCHEMA or 0) < 2 and _G.__HIDE_UI_ENABLED then
|
||||
pcall(function()
|
||||
local cams = Camera.allCameras
|
||||
for i = 0, cams.Length - 1 do
|
||||
@@ -54,7 +54,6 @@ if _G.__HIDE_UI_REGISTERED and _G.__HIDE_UI_SCHEMA ~= 2 and _G.__HIDE_UI_ENABLED
|
||||
for i = 0, canvases.Length - 1 do restore(canvases[i].gameObject) end
|
||||
end)
|
||||
end
|
||||
_G.__HIDE_UI_SCHEMA = 2
|
||||
_G.__HIDE_UI_ENABLED = _G.__HIDE_UI_ENABLED or false
|
||||
_G.__HIDE_UI_TARGETS = _G.__HIDE_UI_TARGETS or {}
|
||||
|
||||
@@ -75,26 +74,151 @@ local function restore_hud()
|
||||
end
|
||||
end
|
||||
|
||||
local function protected_name(name)
|
||||
local n = string.lower(tostring(name))
|
||||
return string.find(n, "uid", 1, true) ~= nil and string.find(n, "guide", 1, true) == nil
|
||||
or n == "versiontext" or n == "betahintdialog(clone)"
|
||||
end
|
||||
|
||||
local function hide_object(obj)
|
||||
if not obj or protected_name(obj.name) then return end
|
||||
local id = obj:GetInstanceID()
|
||||
local state = _G.__HIDE_UI_TARGETS[id]
|
||||
if not state then
|
||||
local group = obj:GetComponent(typeof(CanvasGroup))
|
||||
local added = not group
|
||||
if added then group = obj:AddComponent(typeof(CanvasGroup)) end
|
||||
state = {group=group, added=added, alpha=group.alpha,
|
||||
raycast=group.blocksRaycasts, interactable=group.interactable}
|
||||
_G.__HIDE_UI_TARGETS[id] = state
|
||||
end
|
||||
state.group.alpha = 0
|
||||
state.group.blocksRaycasts = false
|
||||
state.group.interactable = false
|
||||
end
|
||||
|
||||
-- Keep UID/branding subtrees visible even if they belong to a HUD container.
|
||||
local function hide_hud_tree(obj)
|
||||
if not obj then return end
|
||||
local protected = {}
|
||||
local ts = obj:GetComponentsInChildren(typeof(CS.UnityEngine.Transform), true)
|
||||
for i = 0, ts.Length - 1 do
|
||||
if protected_name(ts[i].name) then
|
||||
local t = ts[i]
|
||||
while t do
|
||||
protected[t:GetInstanceID()] = true
|
||||
if t == obj.transform then break end
|
||||
t = t.parent
|
||||
end
|
||||
end
|
||||
end
|
||||
local function visit(t)
|
||||
if protected_name(t.name) then return end
|
||||
if not protected[t:GetInstanceID()] then
|
||||
hide_object(t.gameObject)
|
||||
-- Battle HUD widgets have their own CanvasGroups and some ignore
|
||||
-- their parent's alpha. Hide those groups too, preserving each
|
||||
-- original state for restoration when the toggle is disabled.
|
||||
local groups = t:GetComponentsInChildren(typeof(CanvasGroup), true)
|
||||
for i = 0, groups.Length - 1 do
|
||||
hide_object(groups[i].gameObject)
|
||||
end
|
||||
return
|
||||
end
|
||||
for i = 0, t.childCount - 1 do visit(t:GetChild(i)) end
|
||||
end
|
||||
visit(obj.transform)
|
||||
end
|
||||
|
||||
-- EX/Eidolon artwork is an image. Hide interactive controls and labels,
|
||||
-- never the page's Canvas/camera or the illustration's parent container.
|
||||
local function hide_control_components(root, kind)
|
||||
local ok, controls = pcall(function()
|
||||
return root:GetComponentsInChildren(kind, true)
|
||||
end)
|
||||
if not ok or not controls then return end
|
||||
for i = 0, controls.Length - 1 do
|
||||
local component = controls[i]
|
||||
if component and component.gameObject and not protected_name(component.gameObject.name) then
|
||||
-- Hiding each control directly avoids rescanning its entire
|
||||
-- subtree for every Button/LocalizedText pair on the page.
|
||||
hide_object(component.gameObject)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function hide_rank_controls(root)
|
||||
if not root or not root.activeInHierarchy then return end
|
||||
hide_control_components(root, typeof(CS.RPG.Client.LocalizedText))
|
||||
-- Selectable includes buttons, toggles, sliders, dropdowns and scrollbars;
|
||||
-- some rank-page controls have no text or Button component of their own.
|
||||
hide_control_components(root, typeof(CS.UnityEngine.UI.Selectable))
|
||||
-- Skill icons use SkillIcon sprites; illustrations use separate portrait
|
||||
-- assets. Do not hide arbitrary images or the illustration container.
|
||||
local images = root:GetComponentsInChildren(typeof(CS.UnityEngine.UI.Image), true)
|
||||
for i = 0, images.Length - 1 do
|
||||
local sprite = images[i].sprite
|
||||
if sprite and string.lower(tostring(sprite.name)):find("skillicon",1,true) then
|
||||
hide_object(images[i].gameObject)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function hide_hud()
|
||||
for _, path in ipairs(HUD_PATHS) do
|
||||
pcall(function()
|
||||
local obj = GameObject.Find(path)
|
||||
if not obj then return end
|
||||
local id = obj:GetInstanceID()
|
||||
local state = _G.__HIDE_UI_TARGETS[id]
|
||||
if not state then
|
||||
local group = obj:GetComponent(typeof(CanvasGroup))
|
||||
local added = not group
|
||||
if added then group = obj:AddComponent(typeof(CanvasGroup)) end
|
||||
state = {group=group, added=added, alpha=group.alpha,
|
||||
raycast=group.blocksRaycasts, interactable=group.interactable}
|
||||
_G.__HIDE_UI_TARGETS[id] = state
|
||||
end
|
||||
state.group.alpha = 0
|
||||
state.group.blocksRaycasts = false
|
||||
state.group.interactable = false
|
||||
end)
|
||||
pcall(function() hide_hud_tree(GameObject.Find(path)) end)
|
||||
end
|
||||
local ok, err = pcall(function()
|
||||
local flags = CS.System.Enum.ToObject(typeof(CS.System.Reflection.BindingFlags), 60)
|
||||
_G.__HIDE_UI_PHASE_FIELD = _G.__HIDE_UI_PHASE_FIELD
|
||||
or typeof(CS.RPG.Client.GamePhaseManager):GetField("_CurrentPhase", flags)
|
||||
_G.__HIDE_UI_BATTLE_HUD_FIELD = _G.__HIDE_UI_BATTLE_HUD_FIELD
|
||||
or typeof(CS.RPG.Client.BattleGamePhase):GetField("_HudPage", flags)
|
||||
local manager = CS.RPG.Client.GlobalVars.s_GamePhaseManager
|
||||
local phase = manager and _G.__HIDE_UI_PHASE_FIELD:GetValue(manager)
|
||||
if phase and typeof(CS.RPG.Client.BattleGamePhase):IsInstanceOfType(phase) then
|
||||
local hud = _G.__HIDE_UI_BATTLE_HUD_FIELD:GetValue(phase)
|
||||
if hud and hud.Trans then hide_hud_tree(hud.Trans.gameObject) end
|
||||
if hud and hud.ChildDialogs then
|
||||
local dialogs = hud.ChildDialogs
|
||||
for i = 0, dialogs.Count - 1 do
|
||||
if dialogs[i].Trans then hide_hud_tree(dialogs[i].Trans.gameObject) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
if not ok and _G.__HIDE_UI_LAST_ERROR ~= tostring(err) then
|
||||
_G.__HIDE_UI_LAST_ERROR = tostring(err)
|
||||
CS.UnityEngine.Debug.Log("[GaC HideUI] Battle HUD: " .. tostring(err))
|
||||
end
|
||||
pcall(function()
|
||||
local ui = CS.RPG.Client.GlobalVars.s_UIManager
|
||||
local pages = ui:GetAllPageNames()
|
||||
for i = 0, pages.Count - 1 do
|
||||
local name = tostring(pages[i]); local lower = string.lower(name)
|
||||
local page = ui:GetPageByName(name)
|
||||
if page and page.ChildDialogs then
|
||||
for j = 0, page.ChildDialogs.Count - 1 do
|
||||
local dialog = page.ChildDialogs[j]
|
||||
local dialogName = string.lower(tostring(dialog.Name))
|
||||
if dialog.Trans and (dialogName:find("rank",1,true) or dialogName:find("eidolon",1,true)) then
|
||||
hide_rank_controls(dialog.Trans.gameObject)
|
||||
end
|
||||
end
|
||||
end
|
||||
if lower:find("battle",1,true) then
|
||||
local page = ui:GetPageByName(name)
|
||||
if page and page.Trans and page.Trans.gameObject.activeInHierarchy then
|
||||
hide_hud_tree(page.Trans.gameObject)
|
||||
end
|
||||
end
|
||||
if lower:find("rank",1,true) or lower:find("eidolon",1,true) then
|
||||
local page = ui:GetPageByName(name)
|
||||
if page and page.Trans then hide_rank_controls(page.Trans.gameObject) end
|
||||
end
|
||||
end
|
||||
hide_rank_controls(GameObject.Find("UIRoot/Page/AvatarMainPage(Clone)/Root/AvatarRankPanel"))
|
||||
end)
|
||||
end
|
||||
|
||||
function _G.__HIDE_UI_TICK()
|
||||
@@ -107,32 +231,49 @@ function _G.__HIDE_UI_TICK()
|
||||
_G.__HIDE_UI_ENABLED = not _G.__HIDE_UI_ENABLED
|
||||
if not _G.__HIDE_UI_ENABLED then restore_hud() end
|
||||
end
|
||||
-- Only the small named HUD list is checked, four times a second.
|
||||
-- The page/child scan walks Unity UI trees, so keep it to once a second.
|
||||
-- New pages/dialogs never inherit a hidden UIRoot or UI camera.
|
||||
if _G.__HIDE_UI_ENABLED then
|
||||
local now = Time.unscaledTime
|
||||
if toggled or now >= (_G.__HIDE_UI_NEXT_SCAN or 0) then
|
||||
_G.__HIDE_UI_NEXT_SCAN = now + 0.25
|
||||
_G.__HIDE_UI_NEXT_SCAN = now + 1.0
|
||||
hide_hud()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- Hook into render pipeline
|
||||
if not _G.__HIDE_UI_REGISTERED then
|
||||
_G.__HIDE_UI_REGISTERED = true
|
||||
|
||||
local function hook(target, evt)
|
||||
pcall(function() target[evt]('+', function(c) _G.__HIDE_UI_TICK() end) end)
|
||||
pcall(function() target[evt] = target[evt] + function(c) _G.__HIDE_UI_TICK() end end)
|
||||
end
|
||||
|
||||
hook(Camera, "onPreRender")
|
||||
hook(Camera, "onPreCull")
|
||||
hook(Camera, "onPostRender")
|
||||
pcall(function() CS.UnityEngine.Application.onBeforeRender('+', function() _G.__HIDE_UI_TICK() end) end)
|
||||
pcall(function() CS.UnityEngine.Application.onBeforeRender = CS.UnityEngine.Application.onBeforeRender + function() _G.__HIDE_UI_TICK() end end)
|
||||
|
||||
CS.UnityEngine.Debug.Log("<color=#FF00FF>[UI Toggle Script]</color> HUD-only HideUI loaded! Press 'ฃ' to toggle UI.")
|
||||
-- Restore targets from the previous policy (including VersionText) on upgrade.
|
||||
if _G.__HIDE_UI_SCHEMA ~= 5 then
|
||||
restore_hud()
|
||||
_G.__HIDE_UI_SCHEMA = 5
|
||||
_G.__HIDE_UI_NEXT_SCAN = 0
|
||||
end
|
||||
|
||||
-- Use one render callback. Registering all camera events plus before-render
|
||||
-- made the toggle callback run redundantly several times per frame.
|
||||
if not _G.__HIDE_UI_REGISTERED then
|
||||
local callback = function() _G.__HIDE_UI_TICK() end
|
||||
local ok = pcall(function()
|
||||
CS.UnityEngine.Application.onBeforeRender('+', callback)
|
||||
end)
|
||||
if not ok then
|
||||
ok = pcall(function()
|
||||
CS.UnityEngine.Application.onBeforeRender = CS.UnityEngine.Application.onBeforeRender + callback
|
||||
end)
|
||||
end
|
||||
if not ok then
|
||||
ok = pcall(function()
|
||||
Camera.onPostRender('+', callback)
|
||||
end)
|
||||
if not ok then
|
||||
ok = pcall(function() Camera.onPostRender = Camera.onPostRender + callback end)
|
||||
end
|
||||
end
|
||||
_G.__HIDE_UI_REGISTERED = ok
|
||||
if ok then
|
||||
CS.UnityEngine.Debug.Log("<color=#FF00FF>[UI Toggle Script]</color> HUD-only HideUI loaded! Press 'ฃ' to toggle UI.")
|
||||
else
|
||||
CS.UnityEngine.Debug.Log("[GaC HideUI] Could not register a render callback.")
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user