Feat: 场景视图mod,UI框架更换标题
This commit is contained in:
@@ -10,63 +10,60 @@ namespace UIFrame
|
||||
{
|
||||
public class GameOriginMainMenuUI
|
||||
{
|
||||
public GameObject mainMenuContainer;
|
||||
public Image? title;
|
||||
public TMP_Text[]? allTexts;
|
||||
|
||||
public Sprite titleSprite;
|
||||
|
||||
public bool linkMainMenu=false;
|
||||
// public SpriteRenderer? title;
|
||||
// public TMP_Text[]? allTexts;
|
||||
public static Sprite? titleSprite=null;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
SceneLoader.onAfterSceneInitialize += OnAfterSceneInitialize;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
SceneLoader.onAfterSceneInitialize -= OnAfterSceneInitialize;
|
||||
}
|
||||
// public void Initialize()
|
||||
// {
|
||||
// SceneManager.sceneLoaded += OnSceneLoaded;
|
||||
// // SceneLoader.onAfterSceneInitialize += OnAfterSceneInitialize;
|
||||
// LinkMainMenuObj();
|
||||
// }
|
||||
//
|
||||
// public void Cleanup()
|
||||
// {
|
||||
// SceneManager.sceneLoaded -= OnSceneLoaded;
|
||||
// // SceneLoader.onAfterSceneInitialize -= OnAfterSceneInitialize;
|
||||
// }
|
||||
//
|
||||
// private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
|
||||
// {
|
||||
// Debug.Log("Loading game origin main menu...");
|
||||
// LinkMainMenuObj();
|
||||
// }
|
||||
// // private void OnAfterSceneInitialize(SceneLoadingContext sceneLoadingContext)
|
||||
// // {
|
||||
// //
|
||||
// // }
|
||||
//
|
||||
// public void LinkMainMenuObj()
|
||||
// {
|
||||
// var logoObj=GameObjectTool.FindObjectByPath("TimelineContent/LOGO/Logo");
|
||||
// title = logoObj?.GetComponent<SpriteRenderer>();
|
||||
// }
|
||||
|
||||
private void OnAfterSceneInitialize(SceneLoadingContext sceneLoadingContext)
|
||||
{
|
||||
linkMainMenu = false;
|
||||
LinkMainMenuObj();
|
||||
}
|
||||
|
||||
public void LinkMainMenuObj()
|
||||
{
|
||||
mainMenuContainer = GameObject.Find("MainMenuContainer");
|
||||
if(!mainMenuContainer)
|
||||
{
|
||||
Debug.LogWarning("Could not find Main Menu Container");
|
||||
return;
|
||||
}
|
||||
Debug.Log("Main Menu Container initialized");
|
||||
allTexts = mainMenuContainer.GetComponentsInChildren<TMP_Text>();
|
||||
title = GameObjectTool.FindChildByName(mainMenuContainer.transform, "MainTitle")?.GetComponent<Image>();
|
||||
linkMainMenu = true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public bool SetFont(TMP_FontAsset font)
|
||||
{
|
||||
if(allTexts == null || allTexts.Length == 0)
|
||||
return false;
|
||||
foreach (var text in allTexts)
|
||||
{
|
||||
text.font = font;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// public bool SetFont(TMP_FontAsset font)
|
||||
// {
|
||||
// if(allTexts == null || allTexts.Length == 0)
|
||||
// return false;
|
||||
// foreach (var text in allTexts)
|
||||
// {
|
||||
// text.font = font;
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public bool SetTitle(Sprite texture)
|
||||
{
|
||||
titleSprite=texture;
|
||||
if(title==null)
|
||||
return false;
|
||||
title.sprite = texture;
|
||||
// Debug.Log("Setting title...");
|
||||
titleSprite = texture;
|
||||
// if(title==null)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// title.sprite = texture;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using Duckov.UI;
|
||||
using Duckov.UI.Animations;
|
||||
using Duckov.Utilities;
|
||||
using HarmonyLib;
|
||||
using SodaCraft.Localizations;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UIFrame
|
||||
@@ -16,7 +17,11 @@ namespace UIFrame
|
||||
private GameObject? workerObject;
|
||||
|
||||
private Harmony? harmony;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnAfterSetup()
|
||||
{
|
||||
CreateAPIObject();
|
||||
@@ -31,6 +36,7 @@ namespace UIFrame
|
||||
|
||||
protected override void OnBeforeDeactivate()
|
||||
{
|
||||
|
||||
ClearAPIObject();
|
||||
harmony?.UnpatchAll(MOD_ID);
|
||||
harmony = null;
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace UIFrame.Patch
|
||||
{
|
||||
[HarmonyLib.HarmonyPatch(typeof(SceneLoader), "LoadMainMenu")]
|
||||
public class PatchSceneLoaderLoadMainMenu
|
||||
{
|
||||
public static void Postfix()
|
||||
{
|
||||
Debug.Log("LoadMainMenu called");
|
||||
}
|
||||
}
|
||||
}
|
||||
34
UIFrame/Patch/PatchSpriteRendererLocalizorRefresh.cs
Normal file
34
UIFrame/Patch/PatchSpriteRendererLocalizorRefresh.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using HarmonyLib;
|
||||
using SodaCraft.Localizations;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UIFrame.Patch
|
||||
{
|
||||
[HarmonyPatch(typeof(SpriteRendererLocalizor), "Refresh")]
|
||||
public class PatchSpriteRendererLocalizorRefresh
|
||||
{
|
||||
private static FieldInfo spriteRendererField = AccessTools.Field(typeof(SpriteRendererLocalizor), "spriteRenderer");
|
||||
|
||||
public static void Postfix(SpriteRendererLocalizor __instance)
|
||||
{
|
||||
if (GameOriginMainMenuUI.titleSprite != null && spriteRendererField != null)
|
||||
{
|
||||
SpriteRenderer targetSpriteRenderer = spriteRendererField.GetValue(__instance) as SpriteRenderer;
|
||||
|
||||
if (targetSpriteRenderer != null)
|
||||
{
|
||||
targetSpriteRenderer.sprite = GameOriginMainMenuUI.titleSprite;
|
||||
}
|
||||
else
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"Harmony Patch: Failed to get SpriteRenderer from {__instance.gameObject.name} (SpriteRendererLocalizor component)'s spriteRenderer field. Value was null or not a SpriteRenderer.");
|
||||
}
|
||||
} else if (GameOriginMainMenuUI.titleSprite == null) {
|
||||
UnityEngine.Debug.LogWarning("Harmony Patch: GameOriginMainMenuUI.titleSprite is null, skipping sprite assignment.");
|
||||
} else if (spriteRendererField == null){
|
||||
UnityEngine.Debug.LogError("Harmony Patch: Failed to find 'spriteRenderer' field in SpriteRendererLocalizor. Is the field name correct or has it changed?");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,9 @@
|
||||
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\ItemStatsSystem.dll" Private="False" />
|
||||
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\Unity*" Private="False" />
|
||||
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\FMODUnity.dll" Private="False" />
|
||||
<Reference Include="SodaLocalization">
|
||||
<HintPath>..\..\..\steam\steamapps\common\Escape from Duckov\Duckov_Data\Managed\SodaLocalization.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lib.Harmony" Version="2.4.1" />
|
||||
|
||||
@@ -38,13 +38,14 @@ namespace UIFrame
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _apiComponent&&_apiComponent.SetTitleImage(texture);
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置标题图片(游戏中的标题是图片)
|
||||
/// 设置标题图片(游戏中的启动界面Logo)
|
||||
/// </summary>
|
||||
/// <param name="sprite">贴图</param>
|
||||
/// <returns></returns>
|
||||
/// <returns>返回false表示函数调用时设置失败,之后会自动再次尝试设置</returns>
|
||||
public static bool SetGameTitle(Sprite sprite)
|
||||
{
|
||||
return _apiComponent&&_apiComponent.SetTitleImage(sprite);
|
||||
|
||||
@@ -5,16 +5,16 @@ namespace UIFrameAPI
|
||||
{
|
||||
public abstract class UIFrameAPIComponent:MonoBehaviour
|
||||
{
|
||||
public abstract bool CreateCanvas(string name);
|
||||
// public abstract bool CreateCanvas(string name);
|
||||
|
||||
//设置游戏主菜单的原版标题
|
||||
public abstract bool SetTitleImage(Sprite sprite);
|
||||
|
||||
//创建一个TMP字体
|
||||
public abstract TMP_FontAsset CreateFontAsset(string fontFilePath);
|
||||
|
||||
//设置游戏字体
|
||||
public abstract bool SetFont(TMP_FontAsset font);
|
||||
// //创建一个TMP字体
|
||||
// public abstract TMP_FontAsset CreateFontAsset(string fontFilePath);
|
||||
//
|
||||
// //设置游戏字体
|
||||
// public abstract bool SetFont(TMP_FontAsset font);
|
||||
|
||||
public abstract Texture2D? LoadTexture(string imageFilePath);
|
||||
}
|
||||
|
||||
@@ -14,21 +14,16 @@ namespace UIFrame
|
||||
public Dictionary<string, Canvas> canvasDic = new Dictionary<string, Canvas>();
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
gameOriginMainMenuUI.Initialize();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
gameOriginMainMenuUI.Cleanup();
|
||||
}
|
||||
|
||||
|
||||
public override bool CreateCanvas(string name)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// private void Awake()
|
||||
// {
|
||||
// gameOriginMainMenuUI.Initialize();
|
||||
// }
|
||||
//
|
||||
// private void OnDestroy()
|
||||
// {
|
||||
// gameOriginMainMenuUI.Cleanup();
|
||||
// }
|
||||
|
||||
|
||||
public override bool SetTitleImage(Sprite sprite)
|
||||
{
|
||||
@@ -36,26 +31,26 @@ namespace UIFrame
|
||||
}
|
||||
|
||||
|
||||
public override TMP_FontAsset CreateFontAsset(string fontFilePath)
|
||||
{
|
||||
var font = Font.CreateDynamicFontFromOSFont(fontFilePath, 24);
|
||||
var tmpFont = TMP_FontAsset.CreateFontAsset(
|
||||
font,
|
||||
samplingPointSize: 72, // 采样点大小,影响字体质量
|
||||
atlasPadding: 4, // 图集内字符间距
|
||||
renderMode: GlyphRenderMode.SDFAA, // 推荐使用 SDF 抗锯齿模式
|
||||
atlasWidth: 1024, // 图集宽度 (2的幂)
|
||||
atlasHeight: 1024, // 图集高度 (2的幂)
|
||||
atlasPopulationMode: AtlasPopulationMode.Dynamic, // 动态填充
|
||||
enableMultiAtlasSupport: true // 启用多图集支持
|
||||
);
|
||||
return tmpFont;
|
||||
}
|
||||
// public override TMP_FontAsset CreateFontAsset(string fontFilePath)
|
||||
// {
|
||||
// var font = Font.CreateDynamicFontFromOSFont(fontFilePath, 24);
|
||||
// var tmpFont = TMP_FontAsset.CreateFontAsset(
|
||||
// font,
|
||||
// samplingPointSize: 72, // 采样点大小,影响字体质量
|
||||
// atlasPadding: 4, // 图集内字符间距
|
||||
// renderMode: GlyphRenderMode.SDFAA, // 推荐使用 SDF 抗锯齿模式
|
||||
// atlasWidth: 1024, // 图集宽度 (2的幂)
|
||||
// atlasHeight: 1024, // 图集高度 (2的幂)
|
||||
// atlasPopulationMode: AtlasPopulationMode.Dynamic, // 动态填充
|
||||
// enableMultiAtlasSupport: true // 启用多图集支持
|
||||
// );
|
||||
// return tmpFont;
|
||||
// }
|
||||
|
||||
public override bool SetFont(TMP_FontAsset font)
|
||||
{
|
||||
return gameOriginMainMenuUI.SetFont(font);
|
||||
}
|
||||
// public override bool SetFont(TMP_FontAsset font)
|
||||
// {
|
||||
// return gameOriginMainMenuUI.SetFont(font);
|
||||
// }
|
||||
|
||||
public override Texture2D? LoadTexture(string imageFilePath)
|
||||
{
|
||||
|
||||
@@ -1,66 +1,76 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace UIFrame.Utilities
|
||||
{
|
||||
public class GameObjectTool
|
||||
{
|
||||
/// <summary>
|
||||
/// 在指定父对象下,查找第一个匹配名称的子GameObject(可以是孙子、曾孙等)
|
||||
/// 根据Unity对象路径查找场景中的GameObject,包括隐藏(非激活)对象。
|
||||
/// 路径示例:"RootObject/ChildObject/GrandchildObject"
|
||||
/// </summary>
|
||||
/// <param name="parent">要查找的父Transform。</param>
|
||||
/// <param name="name">要查找的GameObject的名称。</param>
|
||||
/// <param name="path">要查找的GameObject的层级路径。</param>
|
||||
/// <returns>找到的GameObject,如果未找到则返回null。</returns>
|
||||
public static GameObject? FindChildByName(Transform parent, string name)
|
||||
public static GameObject FindObjectByPath(string path)
|
||||
{
|
||||
// 查找父对象本身是否就是目标对象
|
||||
if (parent.name.Equals(name))
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
return parent.gameObject;
|
||||
Debug.LogWarning("FindObjectByPath: Provided path is null, empty, or whitespace. Returning null.");
|
||||
return null;
|
||||
}
|
||||
// 遍历所有直接子对象
|
||||
foreach (Transform child in parent)
|
||||
|
||||
string[] pathParts = path.Split(new char[] { '/' }, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
// 如果路径分割后没有有效部分(例如:"/" 或空字符串),则直接返回null
|
||||
if (pathParts.Length == 0)
|
||||
{
|
||||
// 检查当前子对象是否是目标对象
|
||||
if (child.name.Equals(name))
|
||||
Debug.LogWarning(
|
||||
$"FindObjectByPath: Path '{path}' resulted in no valid segments after splitting. Returning null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
GameObject currentObject = null;
|
||||
// GetRootGameObjects() 会返回场景中所有根级别的GameObject,无论它们是否激活。
|
||||
Scene activeScene = SceneManager.GetActiveScene();
|
||||
GameObject[] rootGameObjects = activeScene.GetRootGameObjects();
|
||||
foreach (GameObject rootObj in rootGameObjects)
|
||||
{
|
||||
if (rootObj.name == pathParts[0])
|
||||
{
|
||||
return child.gameObject;
|
||||
}
|
||||
// 递归查找子对象的子对象
|
||||
var found = FindChildByName(child, name);
|
||||
if (found)
|
||||
{
|
||||
return found;
|
||||
currentObject = rootObj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 在指定父对象下,查找所有匹配名称的子GameObject(可以是孙子、曾孙等),不区分大小写。
|
||||
/// </summary>
|
||||
/// <param name="parent">要查找的父Transform。</param>
|
||||
/// <param name="name">要查找的GameObject的名称。</param>
|
||||
/// <returns>所有找到的GameObject列表。</returns>
|
||||
public static List<GameObject> FindChildrenByName(Transform parent, string name)
|
||||
{
|
||||
var foundObjects = new List<GameObject>();
|
||||
FindChildrenByNameRecursive(parent, name, foundObjects);
|
||||
return foundObjects;
|
||||
}
|
||||
private static void FindChildrenByNameRecursive(Transform currentTransform, string name, List<GameObject> foundObjects)
|
||||
{
|
||||
// 检查当前对象是否是目标对象
|
||||
if (currentTransform.name.Equals(name))
|
||||
|
||||
// 如果根对象未找到,则路径无效
|
||||
if (currentObject == null)
|
||||
{
|
||||
foundObjects.Add(currentTransform.gameObject);
|
||||
Debug.LogWarning($"FindObjectByPath: Root object '{pathParts[0]}' not found in the active scene. Returning null.");
|
||||
return null;
|
||||
}
|
||||
// 遍历所有子对象并递归查找
|
||||
foreach (Transform child in currentTransform)
|
||||
|
||||
for (int i = 1; i < pathParts.Length; i++)
|
||||
{
|
||||
FindChildrenByNameRecursive(child, name, foundObjects);
|
||||
if (currentObject == null)
|
||||
{
|
||||
Debug.LogError(
|
||||
$"FindObjectByPath: Unexpected null currentObject while traversing path segment '{pathParts[i]}'. This indicates an internal logic error.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// transform.Find() 能够查找包括非激活状态的子对象
|
||||
Transform childTransform = currentObject.transform.Find(pathParts[i]);
|
||||
if (childTransform == null)
|
||||
{
|
||||
Debug.LogWarning($"FindObjectByPath: Child object '{pathParts[i]}' not found under '{currentObject.name}'. Path invalid. Returning null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
currentObject = childTransform.gameObject;
|
||||
}
|
||||
|
||||
return currentObject;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("UIFrame")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0206a83f56b5a794fe2f173b4a047cc4f0d4cd90")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("UIFrame")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("UIFrame")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
befe5a7453194406b1676f68d219a8c86bdf2f4cea49adddbaad5a1bb5006b5d
|
||||
911460e450d98a36d352c39840be04d55f4d5ae8227da097050ab185b491cbc7
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -13,7 +13,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("UIFrame")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5d69efbc3f80a5422cef0884e02fb27adf20b467")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("UIFrame")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("UIFrame")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
2fde23c3fee254f6fc8f4689686f8631f1cec9f5b900327d5b657c6830a03267
|
||||
d9927e767d78bd001547a17de1674f3773a1c4e78cf329975757d4b609c6bada
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
8df4ddcbe4b7016ad51bf9e0b9ea8b606b36f4d0bbae7f1650b893a49036873e
|
||||
0ee34f07c3de41359bb7fcfd63f21e2bd997731e7e65df6cde5e62762235bbce
|
||||
|
||||
@@ -5,3 +5,4 @@ D:\vs_project\DuckovMods\UIFrame\obj\Release\UIFrame.AssemblyInfoInputs.cache
|
||||
D:\vs_project\DuckovMods\UIFrame\obj\Release\UIFrame.AssemblyInfo.cs
|
||||
D:\vs_project\DuckovMods\UIFrame\obj\Release\UIFrame.csproj.CoreCompileInputs.cache
|
||||
D:\vs_project\DuckovMods\UIFrame\obj\Release\UIFrame.dll
|
||||
D:\vs_project\DuckovMods\UIFrame\obj\Release\UIFrame.csproj.Up2Date
|
||||
|
||||
0
UIFrame/obj/Release/UIFrame.csproj.Up2Date
Normal file
0
UIFrame/obj/Release/UIFrame.csproj.Up2Date
Normal file
Binary file not shown.
@@ -1 +1 @@
|
||||
17620796287866771
|
||||
17623343068138064
|
||||
Reference in New Issue
Block a user