feat:场景视图添加属性编辑,添加轮廓显示

This commit is contained in:
m0_75251201
2025-11-13 16:24:49 +08:00
parent 9b91218973
commit 8fcbdc5649
95 changed files with 2836 additions and 445 deletions

View File

@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<DuckovPath>D:\steam\steamapps\common\Escape from Duckov</DuckovPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>D:\steam\steamapps\common\Escape from Duckov\Duckov_Data\Mods\CharacterPreview</OutputPath>
<GenerateDependencyFile>false</GenerateDependencyFile>
<DebugType>none</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>D:\steam\steamapps\common\Escape from Duckov\Duckov_Data\Mods\CharacterPreview</OutputPath>
<GenerateDependencyFile>false</GenerateDependencyFile>
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" Private="False"/>
<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="Eflatun.SceneReference">
<HintPath>..\..\..\steam\steamapps\common\Escape from Duckov\Duckov_Data\Managed\Eflatun.SceneReference.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lib.Harmony" Version="2.4.1"/>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,134 @@
using System;
using System.Linq;
using System.Reflection;
using Duckov.Utilities;
using Saves;
using UnityEngine;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
namespace CharacterPreview
{
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
private static CharacterModel characterModel;
private const string characterFaceSaveKey = "CustomFace_MainCharacter";
private OnPointerClick? instance;
private const string ModelName = "CharacterPreviewModel";
protected override void OnAfterSetup()
{
MainMenu.OnMainMenuAwake += CreateCharacterModel;
//
// if (!instance)
// {
// instance = GetPointerClickEventReceiver();
// if (instance == null)
// {
// Debug.LogError("未能找到 SceneLoader.Instance.pointerClickEventRecevier!");
// }
// else
// {
// instance.onPointerClick.AddListener((t) => CreateCharacterModel());
// }
//
// }
}
protected override void OnBeforeDeactivate()
{
MainMenu.OnMainMenuAwake -= CreateCharacterModel;
if (characterModel)
{
Destroy(characterModel.gameObject);
}
}
public static void CreateCharacterModel()
{
if (characterModel)
{
Debug.LogWarning("CharacterModel is already created");
return;
}
if (SceneManager.GetActiveScene().name != "MainMenu")
{
Debug.LogWarning("非主菜单");
return;
}
if (!characterModel)
{
var prefab = GetCharacterModelPrefab_Reflection();
if (prefab == null)
{
Debug.LogError("未能获取 CharacterModel 预制体!");
return;
}
characterModel = Instantiate(prefab);
}
if (characterModel)
{
characterModel.name = ModelName;
var customFaceSettingData = SavesSystem.Load<CustomFaceSettingData>(characterFaceSaveKey);
if (!customFaceSettingData.savedSetting)
{
Debug.LogError("未能找到或加载 CustomFaceSettingData !");
customFaceSettingData = GameplayDataSettings.CustomFaceData.DefaultPreset.settings;
}
characterModel.CustomFace.LoadFromData(customFaceSettingData);
characterModel.gameObject.AddComponent<ModelMove>();
}
}
OnPointerClick GetPointerClickEventReceiver()
{
var sl = SceneLoader.Instance;
// 使用反射获取 SceneLoader 中的 pointerClickEventReceiver 字段
var field = typeof(SceneLoader).GetField("pointerClickEventRecevier", BindingFlags.Instance | BindingFlags.NonPublic);
if (field == null)
{
Debug.LogError("pointerClickEventRecevier 字段在 SceneLoader 中未找到!");
return null;
}
// 获取字段值并转换为 OnPointerClick
var eventReceiver = field.GetValue(sl) as OnPointerClick;
if (eventReceiver == null)
{
Debug.LogError("pointerClickEventRecevier 字段的值为空!");
return null;
}
return eventReceiver;
}
private static CharacterModel GetCharacterModelPrefab_Reflection()
{
// 获取 LevelManager 实例
var lm = GameplayDataSettings.Prefabs.LevelManagerPrefab;
if (lm == null)
{
Debug.LogError("LevelManager 实例未找到!");
return null;
}
// 使用反射获取 LevelManager 中的 characterModel 字段
var field = typeof(LevelManager).GetField("characterModel", BindingFlags.Instance | BindingFlags.NonPublic);
if (field == null)
{
Debug.LogError("characterModel 字段在 LevelManager 中未找到!");
return null;
}
// 获取字段值并转换为 CharacterModel
var modelPrefab = field.GetValue(lm) as CharacterModel;
if (modelPrefab == null)
{
Debug.LogError("characterModel 字段的值为空!");
return null;
}
return modelPrefab;
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using UnityEngine;
namespace CharacterPreview
{
public class ModelMove:MonoBehaviour
{
private Camera _camera;
public Camera currentCamera
{
get
{
if (!_camera)
{
_camera = Camera.main;
if (!_camera)
{
_camera = FindObjectOfType<Camera>();
}
}
return _camera;
}
}
private void Start()
{
if (currentCamera)
{
var worldPos = CameraLocalToWorld(currentCamera, new Vector3(1, -1, 1));
transform.position = worldPos;
}
else
{
transform.position = new Vector3(8, 8, -16);
}
}
/// <summary>
/// 将摄像机局部坐标系中的点转换为世界坐标系中的点。
/// 假设摄像机局部坐标系:前向为 +Z右为 +X上为 +Y。
/// </summary>
/// <param name="camera">目标摄像机</param>
/// <param name="localPoint">在摄像机局部坐标系中的点</param>
/// <returns>对应的世界坐标</returns>
public static Vector3 CameraLocalToWorld(Camera camera, Vector3 localPoint)
{
if (camera == null)
throw new System.ArgumentNullException(nameof(camera));
Transform camTransform = camera.transform;
// 旋转局部点到世界方向,然后加上摄像机位置
return camTransform.position + camTransform.rotation * localPoint;
}
}
}

View File

@@ -0,0 +1,13 @@
// using HarmonyLib;
//
// namespace CharacterPreview
// {
// [HarmonyPatch(typeof(SceneLoader), "NotifyPointerClick")]
// public class PatchSceneLoaderNotifyPointerClick
// {
// public static void Postfix(SceneLoader __instance)
// {
// ModBehaviour.CreateCharacterModel();
// }
// }
// }

View File

@@ -0,0 +1,79 @@
{
"format": 1,
"restore": {
"D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj": {}
},
"projects": {
"D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj",
"projectName": "CharacterPreview",
"projectPath": "D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj",
"packagesPath": "C:\\Users\\Lenovo\\.nuget\\packages\\",
"outputPath": "D:\\vs_project\\DuckovMods\\CharacterPreview\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"D:\\vsShare\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\Lenovo\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"netstandard2.1"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"netstandard2.1": {
"targetAlias": "netstandard2.1",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.300"
},
"frameworks": {
"netstandard2.1": {
"targetAlias": "netstandard2.1",
"dependencies": {
"Lib.Harmony": {
"target": "Package",
"version": "[2.4.1, )"
}
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"NETStandard.Library": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.306\\RuntimeIdentifierGraph.json"
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\Lenovo\.nuget\packages\;D:\vsShare\NuGetPackages</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.14.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="C:\Users\Lenovo\.nuget\packages\" />
<SourceRoot Include="D:\vsShare\NuGetPackages\" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" />

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyTitleAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
3bcd831ea4f29882c4ad0e74553f21cd67857c5ac8ecf673bf0a5c0e6b28519c

View File

@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = CharacterPreview
build_property.ProjectDir = D:\vs_project\DuckovMods\CharacterPreview\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =

View File

@@ -0,0 +1 @@
c29902ba5d072858998bd0700a0022b61d2b982553e1d41c36961a930ba99211

View File

@@ -0,0 +1,8 @@
D:\steam\steamapps\common\Escape from Duckov\Duckov_Data\Mods\CharacterPreview\CharacterPreview.dll
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\CharacterPreview.csproj.AssemblyReference.cache
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\CharacterPreview.GeneratedMSBuildEditorConfig.editorconfig
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\CharacterPreview.AssemblyInfoInputs.cache
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\CharacterPreview.AssemblyInfo.cs
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\CharacterPreview.csproj.CoreCompileInputs.cache
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\CharacterPreview.dll
D:\vs_project\DuckovMods\CharacterPreview\obj\Debug\Characte.69A9E5B8.Up2Date

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyTitleAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
cdbee0654e5bd2c9896d77407e3d7ce5ae6183e3f37c36106e534970cbdd063c

View File

@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = CharacterPreview
build_property.ProjectDir = D:\vs_project\DuckovMods\CharacterPreview\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =

View File

@@ -0,0 +1 @@
356db5ad935a1120367a47fbf381e8f0de76f293776515bb91fa0b0cadad25c7

View File

@@ -0,0 +1,7 @@
D:\steam\steamapps\common\Escape from Duckov\Duckov_Data\Mods\CharacterPreview\CharacterPreview.dll
D:\vs_project\DuckovMods\CharacterPreview\obj\Release\CharacterPreview.csproj.AssemblyReference.cache
D:\vs_project\DuckovMods\CharacterPreview\obj\Release\CharacterPreview.GeneratedMSBuildEditorConfig.editorconfig
D:\vs_project\DuckovMods\CharacterPreview\obj\Release\CharacterPreview.AssemblyInfoInputs.cache
D:\vs_project\DuckovMods\CharacterPreview\obj\Release\CharacterPreview.AssemblyInfo.cs
D:\vs_project\DuckovMods\CharacterPreview\obj\Release\CharacterPreview.csproj.CoreCompileInputs.cache
D:\vs_project\DuckovMods\CharacterPreview\obj\Release\CharacterPreview.dll

Binary file not shown.

View File

@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]

View File

@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyTitleAttribute("CharacterPreview")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// 由 MSBuild WriteCodeFragment 类生成。

View File

@@ -0,0 +1 @@
cdbee0654e5bd2c9896d77407e3d7ce5ae6183e3f37c36106e534970cbdd063c

View File

@@ -0,0 +1,8 @@
is_global = true
build_property.RootNamespace = CharacterPreview
build_property.ProjectDir = D:\vs_project\DuckovMods\CharacterPreview\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =

View File

@@ -0,0 +1,239 @@
{
"version": 3,
"targets": {
".NETStandard,Version=v2.1": {
"Lib.Harmony/2.4.1": {
"type": "package",
"dependencies": {
"Lib.Harmony.Ref": "2.4.1"
},
"compile": {
"lib/netstandard2.0/_._": {}
},
"runtime": {
"lib/netstandard2.0/_._": {}
}
},
"Lib.Harmony.Ref/2.4.1": {
"type": "package",
"dependencies": {
"System.Reflection.Emit": "4.7.0"
},
"compile": {
"ref/netstandard2.0/0Harmony.dll": {
"related": ".xml"
}
}
},
"System.Reflection.Emit/4.7.0": {
"type": "package",
"compile": {
"ref/netstandard2.1/_._": {}
},
"runtime": {
"lib/netstandard2.1/_._": {}
}
}
}
},
"libraries": {
"Lib.Harmony/2.4.1": {
"sha512": "iLTZi/kKKB18jYEIwReZSx2xXyVUh4J1swReMgvYBBBn4tzA1Nd0PJlVyntY5BDdSiXSxzmvjc/3OYfFs0YwFg==",
"type": "package",
"path": "lib.harmony/2.4.1",
"files": [
".nupkg.metadata",
".signature.p7s",
"HarmonyLogo.png",
"LICENSE",
"README.md",
"lib.harmony.2.4.1.nupkg.sha512",
"lib.harmony.nuspec",
"lib/net35/0Harmony.dll",
"lib/net35/0Harmony.pdb",
"lib/net35/0Harmony.xml",
"lib/net452/0Harmony.dll",
"lib/net452/0Harmony.pdb",
"lib/net452/0Harmony.xml",
"lib/net472/0Harmony.dll",
"lib/net472/0Harmony.pdb",
"lib/net472/0Harmony.xml",
"lib/net48/0Harmony.dll",
"lib/net48/0Harmony.pdb",
"lib/net48/0Harmony.xml",
"lib/net5.0/0Harmony.dll",
"lib/net5.0/0Harmony.pdb",
"lib/net5.0/0Harmony.xml",
"lib/net6.0/0Harmony.dll",
"lib/net6.0/0Harmony.pdb",
"lib/net6.0/0Harmony.xml",
"lib/net7.0/0Harmony.dll",
"lib/net7.0/0Harmony.pdb",
"lib/net7.0/0Harmony.xml",
"lib/net8.0/0Harmony.dll",
"lib/net8.0/0Harmony.pdb",
"lib/net8.0/0Harmony.xml",
"lib/net9.0/0Harmony.dll",
"lib/net9.0/0Harmony.pdb",
"lib/net9.0/0Harmony.xml",
"lib/netcoreapp3.0/0Harmony.dll",
"lib/netcoreapp3.0/0Harmony.pdb",
"lib/netcoreapp3.0/0Harmony.xml",
"lib/netcoreapp3.1/0Harmony.dll",
"lib/netcoreapp3.1/0Harmony.pdb",
"lib/netcoreapp3.1/0Harmony.xml",
"lib/netstandard2.0/_._"
]
},
"Lib.Harmony.Ref/2.4.1": {
"sha512": "+u1y2Qd6OlSUQ8JtrsrSo3adnAsrXMJ2YPYtbW+FAmdPI5yw34M9VX4bKl8ZwRuUzaGzZIz+oGMbn/yS4fWtZw==",
"type": "package",
"path": "lib.harmony.ref/2.4.1",
"files": [
".nupkg.metadata",
".signature.p7s",
"HarmonyLogo.png",
"LICENSE",
"README.md",
"lib.harmony.ref.2.4.1.nupkg.sha512",
"lib.harmony.ref.nuspec",
"ref/netstandard2.0/0Harmony.dll",
"ref/netstandard2.0/0Harmony.xml"
]
},
"System.Reflection.Emit/4.7.0": {
"sha512": "VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==",
"type": "package",
"path": "system.reflection.emit/4.7.0",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"lib/MonoAndroid10/_._",
"lib/MonoTouch10/_._",
"lib/net45/_._",
"lib/netcore50/System.Reflection.Emit.dll",
"lib/netcoreapp2.0/_._",
"lib/netstandard1.1/System.Reflection.Emit.dll",
"lib/netstandard1.1/System.Reflection.Emit.xml",
"lib/netstandard1.3/System.Reflection.Emit.dll",
"lib/netstandard2.0/System.Reflection.Emit.dll",
"lib/netstandard2.0/System.Reflection.Emit.xml",
"lib/netstandard2.1/_._",
"lib/xamarinios10/_._",
"lib/xamarinmac20/_._",
"lib/xamarintvos10/_._",
"lib/xamarinwatchos10/_._",
"ref/MonoAndroid10/_._",
"ref/MonoTouch10/_._",
"ref/net45/_._",
"ref/netcoreapp2.0/_._",
"ref/netstandard1.1/System.Reflection.Emit.dll",
"ref/netstandard1.1/System.Reflection.Emit.xml",
"ref/netstandard1.1/de/System.Reflection.Emit.xml",
"ref/netstandard1.1/es/System.Reflection.Emit.xml",
"ref/netstandard1.1/fr/System.Reflection.Emit.xml",
"ref/netstandard1.1/it/System.Reflection.Emit.xml",
"ref/netstandard1.1/ja/System.Reflection.Emit.xml",
"ref/netstandard1.1/ko/System.Reflection.Emit.xml",
"ref/netstandard1.1/ru/System.Reflection.Emit.xml",
"ref/netstandard1.1/zh-hans/System.Reflection.Emit.xml",
"ref/netstandard1.1/zh-hant/System.Reflection.Emit.xml",
"ref/netstandard2.0/System.Reflection.Emit.dll",
"ref/netstandard2.0/System.Reflection.Emit.xml",
"ref/netstandard2.1/_._",
"ref/xamarinios10/_._",
"ref/xamarinmac20/_._",
"ref/xamarintvos10/_._",
"ref/xamarinwatchos10/_._",
"runtimes/aot/lib/netcore50/System.Reflection.Emit.dll",
"runtimes/aot/lib/netcore50/System.Reflection.Emit.xml",
"system.reflection.emit.4.7.0.nupkg.sha512",
"system.reflection.emit.nuspec",
"useSharedDesignerContext.txt",
"version.txt"
]
}
},
"projectFileDependencyGroups": {
".NETStandard,Version=v2.1": [
"Lib.Harmony >= 2.4.1"
]
},
"packageFolders": {
"C:\\Users\\Lenovo\\.nuget\\packages\\": {},
"D:\\vsShare\\NuGetPackages": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj",
"projectName": "CharacterPreview",
"projectPath": "D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj",
"packagesPath": "C:\\Users\\Lenovo\\.nuget\\packages\\",
"outputPath": "D:\\vs_project\\DuckovMods\\CharacterPreview\\obj\\",
"projectStyle": "PackageReference",
"fallbackFolders": [
"D:\\vsShare\\NuGetPackages"
],
"configFilePaths": [
"C:\\Users\\Lenovo\\AppData\\Roaming\\NuGet\\NuGet.Config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
],
"originalTargetFrameworks": [
"netstandard2.1"
],
"sources": {
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"netstandard2.1": {
"targetAlias": "netstandard2.1",
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "9.0.300"
},
"frameworks": {
"netstandard2.1": {
"targetAlias": "netstandard2.1",
"dependencies": {
"Lib.Harmony": {
"target": "Package",
"version": "[2.4.1, )"
}
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"frameworkReferences": {
"NETStandard.Library": {
"privateAssets": "all"
}
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\9.0.306\\RuntimeIdentifierGraph.json"
}
}
}
}

View File

@@ -0,0 +1,12 @@
{
"version": 2,
"dgSpecHash": "7zqX1jgBbf8=",
"success": true,
"projectFilePath": "D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj",
"expectedPackageFiles": [
"C:\\Users\\Lenovo\\.nuget\\packages\\lib.harmony\\2.4.1\\lib.harmony.2.4.1.nupkg.sha512",
"C:\\Users\\Lenovo\\.nuget\\packages\\lib.harmony.ref\\2.4.1\\lib.harmony.ref.2.4.1.nupkg.sha512",
"C:\\Users\\Lenovo\\.nuget\\packages\\system.reflection.emit\\4.7.0\\system.reflection.emit.4.7.0.nupkg.sha512"
],
"logs": []
}

View File

@@ -0,0 +1 @@
"restore":{"projectUniqueName":"D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj","projectName":"CharacterPreview","projectPath":"D:\\vs_project\\DuckovMods\\CharacterPreview\\CharacterPreview.csproj","outputPath":"D:\\vs_project\\DuckovMods\\CharacterPreview\\obj\\","projectStyle":"PackageReference","fallbackFolders":["D:\\vsShare\\NuGetPackages"],"originalTargetFrameworks":["netstandard2.1"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"netstandard2.1":{"targetAlias":"netstandard2.1","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.300"}"frameworks":{"netstandard2.1":{"targetAlias":"netstandard2.1","dependencies":{"Lib.Harmony":{"target":"Package","version":"[2.4.1, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"NETStandard.Library":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\9.0.306\\RuntimeIdentifierGraph.json"}}

View File

@@ -0,0 +1 @@
17627872868371582

View File

@@ -0,0 +1 @@
17627872868371582

View File

@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Theme", "Theme\Theme.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SceneView", "SceneView\SceneView.csproj", "{87AA16B9-C7F9-456E-8F57-CE05F393D91F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CharacterPreview", "CharacterPreview\CharacterPreview.csproj", "{4D2577DB-5915-40AC-869B-68C37D28AC8F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -45,6 +47,10 @@ Global
{87AA16B9-C7F9-456E-8F57-CE05F393D91F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87AA16B9-C7F9-456E-8F57-CE05F393D91F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87AA16B9-C7F9-456E-8F57-CE05F393D91F}.Release|Any CPU.Build.0 = Release|Any CPU
{4D2577DB-5915-40AC-869B-68C37D28AC8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D2577DB-5915-40AC-869B-68C37D28AC8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D2577DB-5915-40AC-869B-68C37D28AC8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D2577DB-5915-40AC-869B-68C37D28AC8F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,10 +1,12 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Ccommon_005CEscape_0020from_0020Duckov_005CDuckov_005FData_005CManaged_005CEflatun_002ESceneReference_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Ccommon_005CEscape_0020from_0020Duckov_005CDuckov_005FData_005CManaged_005CFMODUnity_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Ccommon_005CEscape_0020from_0020Duckov_005CDuckov_005FData_005CManaged_005CSodaLocalization_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Cworkshop_005Ccontent_005C3167020_005C3589088839_005CHarmonyLoadMod_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Cworkshop_005Ccontent_005C3167020_005C3590674339_005CModConfig_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Cworkshop_005Ccontent_005C3167020_005C3591672666_005Cqingye_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=D_003A_005Csteam_005Csteamapps_005Cworkshop_005Ccontent_005C3167020_005C3596659565_005CCustomQuack_002Edll/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAIMainBrain_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F9a_003F06cede9f_003FAIMainBrain_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAIMainBrain_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F52_003F7c426cea_003FAIMainBrain_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAimTargetFinder_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003Fa9_003F4ac92f25_003FAimTargetFinder_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAudioManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F95_003F5092a809_003FAudioManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -17,13 +19,17 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACameraArm_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003Fdc_003Fc73e8a9f_003FCameraArm_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACameraArm_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Ff6_003F5678008c_003FCameraArm_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterCreator_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003F06_003Ff3fe5490_003FCharacterCreator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterCreator_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F2d_003Fdafe66b2_003FCharacterCreator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterCreator_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fd3_003F2e360998_003FCharacterCreator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterEquipmentController_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F35_003F0c1fbbe5_003FCharacterEquipmentController_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterMainControl_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003F2c_003Fe5626d7e_003FCharacterMainControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterMainControl_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F3e_003Fdd1453e6_003FCharacterMainControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterMainControl_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F4c_003Faffc257a_003FCharacterMainControl_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterRandomPreset_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fd5_003Fb696ff66_003FCharacterRandomPreset_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACopyTextButton_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fc4_003F9995fb11_003FCopyTextButton_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACustomFaceInstance_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F5d_003F39ead7d8_003FCustomFaceInstance_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACustomFaceInstance_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Ff5_003F7e299618_003FCustomFaceInstance_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACustomFaceManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003Ffe_003F78a87e79_003FCustomFaceManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADamageInfo_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F0b_003F36368d2b_003FDamageInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADamageTypes_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Faf_003Fe7c272fb_003FDamageTypes_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADuckovScreenCapturer_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003F59_003F92754824_003FDuckovScreenCapturer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -31,17 +37,24 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFadeGroup_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F4e_003F69f8fcae_003FFadeGroup_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFogOfWarManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fd3_003Fb21152a5_003FFogOfWarManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameCamera_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003Fd2_003F4160411a_003FGameCamera_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F92_003F37e04f57_003FGameManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F94_003Fdd33b16b_003FGameManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameObject_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc39a522eee05469b8171a6cfeb646c591543b0_003F52_003F998640fe_003FGameObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameplayDataSettings_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003Fa4_003Ffea6779d_003FGameplayDataSettings_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameplayDataSettings_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F1f_003F8b814bde_003FGameplayDataSettings_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameplayUIManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fcc_003Fe767eb5a_003FGameplayUIManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGameRulesManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fb1_003Ff82c3168_003FGameRulesManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHarmonyPatch_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8e06e6c4d12e4db29fecbb8a1ed2864918400_003F11_003F77145916_003FHarmonyPatch_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInventoryData_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F71a3d79537274de2b084d0fd207549d617200_003F5e_003F6152b6b7_003FInventoryData_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AItemDisplay_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F73_003Fa6db3a6c_003FItemDisplay_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALevelConfig_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003Fcc_003Fcfd90334_003FLevelConfig_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALevelManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003Ff1_003F866b116e_003FLevelManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALevelManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fe0_003F6f24caa1_003FLevelManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALocalizationDataModel_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F85f08cf721894642b6034bb4eee4d75b4000_003F79_003F52786d7e_003FLocalizationDataModel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ALocalizationManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F85f08cf721894642b6034bb4eee4d75b4000_003F2c_003Ff9202561_003FLocalizationManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMainCharacterStatValueDisplay_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F08_003Fd04928fd_003FMainCharacterStatValueDisplay_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMainMenuCamera_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003Fdc_003F4aa81a69_003FMainMenuCamera_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMainMenu_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F72_003F2cdb714d_003FMainMenu_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMainMenu_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003F21_003F0ec534a6_003FMainMenu_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AModBehaviour_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F15eaac0daac842bca117926c0c9be2781a00_003F37_003Fa09d99b2_003FModBehaviour_002Ecs_002Fz_003A4_002D3/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AModBehaviour_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4784c8b601ed4e3c93b990a18b8bd7a4a800_003F3e_003Fb80788cb_003FModBehaviour_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
@@ -57,11 +70,15 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOcclusionFadeChecker_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003F05_003F7aa60d94_003FOcclusionFadeChecker_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOcclusionFadeChecker_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fa8_003Fd12e1cf7_003FOcclusionFadeChecker_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOcclusionFadeManager_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F492b6cef9eac4cd497c1ffcbfcb9161f197200_003F70_003F6aba3c97_003FOcclusionFadeManager_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOnPointerClick_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003F25_003Fba6ddb49_003FOnPointerClick_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AOptionsPanel_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fe1_003Fac8e1feb_003FOptionsPanel_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APrefabPool_00601_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F2fb2e03687cc4f6182420d823a41eca07200_003F05_003F8982f5f5_003FPrefabPool_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneLoader_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F7c82da41edbe4051b5c92d726719f58b199200_003Fdd_003Fa610281f_003FSceneLoader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASceneLoadingContext_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fbf_003F2b3732af_003FSceneLoadingContext_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AScriptableObject_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc39a522eee05469b8171a6cfeb646c591543b0_003F4d_003F1a33cb14_003FScriptableObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASpriteRendererLocalizor_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F85f08cf721894642b6034bb4eee4d75b4000_003F8f_003F9f8025e8_003FSpriteRendererLocalizor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASystemLanguage_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc39a522eee05469b8171a6cfeb646c591543b0_003F5f_003Ffb4a10f4_003FSystemLanguage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextLocalizor_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F85f08cf721894642b6034bb4eee4d75b4000_003Fce_003F46f8a570_003FTextLocalizor_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATitle_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fe8_003F42124cdd_003FTitle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AUIPrefabsReference_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b55f2e79e4a30b19151f53aa9af29197600_003Fb5_003F49d2159e_003FUIPrefabsReference_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AVolumeComponent_002Ecs_002Fl_003AC_0021_003FUsers_003FLenovo_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fb02e352b027d497b8571da05e536c2f682000_003F36_003F74cee2c4_003FVolumeComponent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("折纸的小箱子")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.1")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.1+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.1+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("HideCharacter")]
[assembly: System.Reflection.AssemblyTitleAttribute("HideCharacter")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.1")]

View File

@@ -1 +1 @@
5da31913e91a183301e6883819f7ba57fc0b3e4eba9910ae6ee0eafc05d2af54
dc9e2512ec7accc32370dea781198b720358eb9814b7c9c591d009607f13a5e8

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("折纸的小箱子")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.1")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.1+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.1+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("HideCharacter")]
[assembly: System.Reflection.AssemblyTitleAttribute("HideCharacter")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.1")]

View File

@@ -1 +1 @@
12b8810f5c5efba722348e9a42589fd931584289646df256a80c8a5aac0c67b6
71229c5bb112e72727f560fc4c2dcb61c8790b85769f99a1131c10e137989a56

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyTitleAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
011b05448cb33a5df382363baa29281f37b1217de1b772941e072e5e1e318697
368a9f7418aefa097e80abe04f0e70d25ca97877e818b633d54a07496a4eb4d6

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyTitleAttribute("HitFeedback")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
d5e421014b0d794da78442d8a65960e244ed2b8a5d6b7b2541d1354650cfeae5
11eb56433e596da88b772bc3383f597712eafe48622740bf0786e8030e13d6e9

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("折纸的小箱子")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("SceneSnapshot")]
[assembly: System.Reflection.AssemblyTitleAttribute("SceneSnapshot")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0")]

View File

@@ -1 +1 @@
d0b14bb5a2fe44e4165960f86b2001d300338f5655dddb8b391c1544fb8fcca4
993bfd6f35451c9a8b17b20fe9cf49f2468dd9f29516d3ea773a01d0f4d44c33

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("折纸的小箱子")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("SceneSnapshot")]
[assembly: System.Reflection.AssemblyTitleAttribute("SceneSnapshot")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0")]

View File

@@ -1 +1 @@
0377007546f92d23941a0c0e6a0cef8c6022db4ce07a6a7b98556714f9c594f1
ca1555b48da049a281894ed9d271c1d8ac9ceef6558c6d583a8608bf7fa55818

View File

@@ -6,13 +6,35 @@ namespace SceneView
{
public class CanvasControl : MonoBehaviour
{
public SceneViewPanel? sceneViewPanel;
public const string ViewCanvasName = "_SceneViewCanvas";
public const string ShowAim = "";
public static Vector2 panelSize = new Vector2(500, 800);
public const string ViewCanvasName = "_SceneViewCanvas";
public const string ShowAim = "LOGO";
private static GameObject _focusObject;
public SceneViewPanel? sceneViewPanel;
public ParametersPanel? parametersPanel;
public static GameObject FocusGameObject
{
get => _focusObject;
set
{
if (value != _focusObject)
{
if (_focusObject)
{
var outline=_focusObject.GetComponent<Outline>();
if (outline)
Destroy(outline);
}
_focusObject = value;
_focusObject.AddComponent<Outline>();
OnChangeFocusObject?.Invoke(value);
}
}
}
private void Start()
{
InitCanvas();
@@ -20,17 +42,26 @@ namespace SceneView
public void Update()
{
if (Input.GetKeyDown(KeyCode.F2))
if (Input.GetKeyDown(KeyCode.F3))
{
Debug.Log("切换");
// Debug.Log("切换");
parametersPanel.gameObject.SetActive(!parametersPanel.gameObject.activeSelf);
sceneViewPanel.gameObject.SetActive(!sceneViewPanel.gameObject.activeSelf);
if (sceneViewPanel.gameObject.activeSelf)
{
sceneViewPanel.Refresh();
}
}
// if (sceneViewPanel.gameObject.activeSelf)
// {
// sceneViewPanel.Refresh();
// }
}
private void OnDestroy()
{
if (sceneViewPanel) Destroy(sceneViewPanel.gameObject);
if (parametersPanel) Destroy(parametersPanel.gameObject);
}
public static event Action<GameObject> OnChangeFocusObject;
private void InitCanvas()
{
var canvasObj = new GameObject(ViewCanvasName);
@@ -41,11 +72,13 @@ namespace SceneView
canvasObj.AddComponent<GraphicRaycaster>();
DontDestroyOnLoad(canvasObj);
sceneViewPanel=CreateSceneViewPanel(canvasObj.transform);
sceneViewPanel = CreateSceneViewPanel(canvasObj.transform);
parametersPanel = CreateParametersPanel(canvasObj.transform);
}
public static SceneViewPanel CreateSceneViewPanel(Transform parent)
{
var panelObj = new GameObject("SceneViewPanel");
var panelObj = new GameObject(ViewCanvasName);
panelObj.transform.SetParent(parent, false);
var sceneViewPanel = panelObj.AddComponent<SceneViewPanel>();
var panelImage = panelObj.AddComponent<Image>();
@@ -56,5 +89,15 @@ namespace SceneView
return sceneViewPanel;
}
public ParametersPanel CreateParametersPanel(Transform parent)
{
var panelObj = new GameObject(ViewCanvasName);
panelObj.transform.SetParent(parent, false);
var parametersViewPanel = panelObj.AddComponent<ParametersPanel>();
var panelImage = panelObj.AddComponent<Image>();
panelImage.color = new Color(0.5f, 0.5f, 0.5f, 0.3f);
return parametersViewPanel;
}
}
}

View File

@@ -1,11 +1,14 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UnityEngine;
using System;
using System.Collections.Generic;
using TMPro;
namespace SceneView
{
[Serializable]
public struct RectTransformConfig
{
@@ -19,13 +22,24 @@ namespace SceneView
// 默认配置
public static readonly RectTransformConfig Default = new RectTransformConfig(
anchorMin: new Vector2(0, 1),
anchorMax: new Vector2(0, 1),
anchoredPosition: Vector2.zero,
sizeDelta: Vector2.zero,
offsetMin: Vector2.zero,
offsetMax: Vector2.zero,
pivot: new Vector2(0.5f, 0.5f) // 默认居中轴心点
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.up, // 锚点最大:左上角 (0, 1)
Vector2.zero,
Vector2.zero,
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f) // 默认居中轴心点
);
// 填充父级的配置
public static readonly RectTransformConfig FillParent = new RectTransformConfig(
Vector2.zero, // 锚点最小:左下角 (0, 0)
Vector2.one, // 锚点最大:右上角 (1, 1)
Vector2.zero,
Vector2.zero, // sizeDelta为零表示通过offsetMin/Max来控制尺寸
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
);
public RectTransformConfig(
@@ -58,12 +72,12 @@ namespace SceneView
public bool RaycastTarget;
public static readonly ButtonConfig Default = new ButtonConfig(
rectConfig: RectTransformConfig.Default,
backgroundColor: new Color(0.2f, 0.2f, 0.2f, 1f),
text: "Button",
fontSize: 18,
textColor: Color.white,
raycastTarget: true
RectTransformConfig.Default,
new Color(0.2f, 0.2f, 0.2f, 1f),
"Button",
18,
Color.white,
true
);
public ButtonConfig(
@@ -122,7 +136,7 @@ namespace SceneView
[Serializable]
public struct ScrollViewConfig
{
public Vector2 SizeDelta; // ScrollView 的尺寸
public RectTransformConfig RectConfig; // 新增:ScrollView自身的RectTransform配置
public bool Vertical;
public bool Horizontal;
public Color BackgroundColor;
@@ -130,7 +144,15 @@ namespace SceneView
public static readonly ScrollViewConfig Default = new ScrollViewConfig
{
SizeDelta = new Vector2(400, 300),
RectConfig = new RectTransformConfig(
new Vector2(0.5f, 0.5f), // 锚点最小:中心 (0.5, 0.5)
new Vector2(0.5f, 0.5f), // 锚点最大:中心 (0.5, 0.5)
Vector2.zero,
new Vector2(400, 300), // 默认尺寸
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
),
Vertical = true,
Horizontal = false,
BackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.8f),
@@ -151,18 +173,20 @@ namespace SceneView
public TextAlignmentOptions TextAlignment;
public TMP_InputField.CharacterValidation CharacterValidation;
public int CharacterLimit;
public static readonly InputFieldConfig Default = new InputFieldConfig(
rectConfig: RectTransformConfig.Default,
backgroundColor: new Color(0.2f, 0.2f, 0.2f, 1f),
placeholderText: "Enter text here",
placeholderFontSize: 14,
placeholderTextColor: new Color(0.7f, 0.7f, 0.7f, 1f),
textColor: Color.white,
fontSize: 18,
textAlignment: TextAlignmentOptions.Left,
characterValidation: TMP_InputField.CharacterValidation.None,
characterLimit: 0
RectTransformConfig.Default,
new Color(0.2f, 0.2f, 0.2f, 1f),
"Enter text here",
14,
new Color(0.7f, 0.7f, 0.7f, 1f),
Color.white,
18,
TextAlignmentOptions.Left,
TMP_InputField.CharacterValidation.None,
0
);
public InputFieldConfig(
RectTransformConfig rectConfig,
Color backgroundColor,
@@ -188,6 +212,143 @@ namespace SceneView
}
}
[Serializable]
public struct LabeledInputFieldConfig
{
public RectTransformConfig RectConfig; // 整个控件(标签+输入框)的配置
public string LabelText;
public int LabelFontSize;
public Color LabelTextColor;
public float LabelWidth; // 标签部分的固定宽度
public float Spacing; // 标签和输入框之间的间距
public InputFieldConfig InputFieldConfig; // 复用已有的输入框配置
public static readonly LabeledInputFieldConfig Default = new LabeledInputFieldConfig
{
RectConfig = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.one, // 锚点最大:右上角 (1, 1),默认水平拉伸
Vector2.zero,
new Vector2(0, 30), // 默认高度30
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 1) // 轴心点:顶部居中
),
LabelText = "Label",
LabelFontSize = 18,
LabelTextColor = Color.white,
LabelWidth = 100f,
Spacing = 10f,
InputFieldConfig = InputFieldConfig.Default
};
}
[Serializable]
public struct DropdownConfig
{
public RectTransformConfig RectConfig;
public List<string> Options;
public Color BackgroundColor;
public int CaptionFontSize; // 下拉框当前选中项的文本大小
public Color CaptionTextColor;
public int ItemFontSize; // 下拉列表每一项的文本大小
public Color ItemTextColor;
public static readonly DropdownConfig Default = new DropdownConfig(
new RectTransformConfig(
new Vector2(0.5f, 0.5f), // 锚点最小:中心 (0.5, 0.5)
new Vector2(0.5f, 0.5f), // 锚点最大:中心 (0.5, 0.5)
Vector2.zero,
new Vector2(160, 30),
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
),
new List<string> { "Option A", "Option B", "Option C" },
new Color(0.2f, 0.2f, 0.2f, 1f),
18,
Color.white,
16,
Color.white
);
public DropdownConfig(RectTransformConfig rectConfig, List<string> options, Color backgroundColor,
int captionFontSize, Color captionTextColor, int itemFontSize, Color itemTextColor)
{
RectConfig = rectConfig;
Options = options;
BackgroundColor = backgroundColor;
CaptionFontSize = captionFontSize;
CaptionTextColor = captionTextColor;
ItemFontSize = itemFontSize;
ItemTextColor = itemTextColor;
}
}
[Serializable]
public struct LabeledDropdownConfig
{
public RectTransformConfig RectConfig;
public string LabelText;
public int LabelFontSize;
public Color LabelTextColor;
public float LabelWidth;
public float Spacing;
public DropdownConfig DropdownConfig;
public static readonly LabeledDropdownConfig Default = new LabeledDropdownConfig
{
RectConfig = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.one, // 锚点最大:右上角 (1, 1)
Vector2.zero,
new Vector2(0, 30),
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 1)
),
LabelText = "Label",
LabelFontSize = 18,
LabelTextColor = Color.white,
LabelWidth = 100f,
Spacing = 10f,
DropdownConfig = DropdownConfig.Default
};
}
[Serializable]
public struct ToggleConfig
{
public RectTransformConfig RectConfig;
public string LabelText;
public int LabelFontSize;
public Color LabelTextColor;
public Color BackgroundColor;
public Color CheckmarkColor;
public float Spacing; // 开关图形和标签之间的间距
public bool IsOnByDefault;
public static readonly ToggleConfig Default = new ToggleConfig
{
RectConfig = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.up, // 锚点最大:左上角 (0, 1)
Vector2.zero,
new Vector2(160, 20),
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
),
LabelText = "Toggle",
LabelFontSize = 18,
LabelTextColor = Color.white,
BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f),
CheckmarkColor = new Color(0.1f, 0.6f, 1f, 1f),
Spacing = 10f,
IsOnByDefault = false
};
}
public static class ControlUtilities
{
// 通用方法:将 RectTransformConfig 应用于 RectTransform
@@ -197,9 +358,12 @@ namespace SceneView
rectTransform.anchorMax = config.AnchorMax;
rectTransform.pivot = config.Pivot;
var isStretched = config.SizeDelta == Vector2.zero;
if (isStretched)
// 当sizeDelta为Vector2.zero时我们假定用户希望通过offsetMin/Max来拉伸元素
// 否则使用anchoredPosition和sizeDelta来定位和设置尺寸
if (config.SizeDelta == Vector2.zero && (config.OffsetMin != Vector2.zero ||
config.OffsetMax != Vector2.zero ||
(config.AnchorMin == Vector2.zero &&
config.AnchorMax == Vector2.one)))
{
rectTransform.offsetMin = config.OffsetMin;
rectTransform.offsetMax = config.OffsetMax;
@@ -211,45 +375,48 @@ namespace SceneView
}
}
// ========================
// 矩形对象创建
// ========================
/// <summary>
/// 创建一个带有 RectTransform 组件的空 GameObject。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="name">GameObject 的名称。</param>
/// <param name="config">RectTransform 的配置。</param>
/// <returns>创建的 RectTransform 组件。</returns>
public static RectTransform CreateRect(Transform parent, string name, RectTransformConfig config)
{
var obj = new GameObject(name);
var rect = obj.AddComponent<RectTransform>();
rect.SetParent(parent, false); // false表示不保留世界坐标而是以父级为基准
ApplyRectTransformConfig(rect, config);
return rect;
}
// ========================
// 按钮创建
// ========================
public static (Button? button, TextMeshProUGUI? text) CreateButton(RectTransform? parent, ButtonConfig config,
UnityAction? onClick)
{
var btnObj = new GameObject(config.Text + "Button");
var btnRect = btnObj.AddComponent<RectTransform>();
btnRect.SetParent(parent, false);
// 使用 CreateRect 创建按钮根对象并应用配置
var btnRect = CreateRect(parent, config.Text + "Button", config.RectConfig);
ApplyRectTransformConfig(btnRect, config.RectConfig);
var button = btnObj.AddComponent<Button>();
var image = btnObj.AddComponent<Image>();
var button = btnRect.gameObject.AddComponent<Button>();
var image = btnRect.gameObject.AddComponent<Image>();
image.color = config.BackgroundColor;
button.image = image;
// 创建文本子对象
var txtObj = new GameObject("Text (TMP)");
var txtRect = txtObj.AddComponent<RectTransform>();
txtRect.SetParent(btnRect, false);
// 创建文本子对象,并使其填充按钮
var txtRect = CreateRect(btnRect, "Text (TMP)", RectTransformConfig.FillParent);
// 文本始终填满按钮(常见做法)
ApplyRectTransformConfig(txtRect, new RectTransformConfig(
anchorMin: Vector2.zero,
anchorMax: Vector2.one,
anchoredPosition: Vector2.zero,
sizeDelta: Vector2.zero,
offsetMin: Vector2.zero,
offsetMax: Vector2.zero,
pivot: new Vector2(0.5f, 0.5f)
));
var tmpText = txtObj.AddComponent<TextMeshProUGUI>();
var tmpText = txtRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = config.Text;
tmpText.color = config.TextColor;
tmpText.alignment = TextAlignmentOptions.Center;
tmpText.fontSize = config.FontSize;
tmpText.raycastTarget = config.RaycastTarget;
tmpText.raycastTarget = config.RaycastTarget; // 文本RaycastTarget通常为false除非文本本身需要互动
if (onClick != null)
button.onClick.AddListener(onClick);
return (button, tmpText);
@@ -267,13 +434,10 @@ namespace SceneView
public static TextMeshProUGUI CreateText(Transform parent, TextConfig config)
{
var textObj = new GameObject(config.Text + "Text");
var textRect = textObj.AddComponent<RectTransform>();
textRect.SetParent(parent, false);
// 使用 CreateRect 创建文本对象并应用配置
var textRect = CreateRect(parent, config.Text + "Text", config.RectConfig);
ApplyRectTransformConfig(textRect, config.RectConfig);
var tmpText = textObj.AddComponent<TextMeshProUGUI>();
var tmpText = textRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = config.Text;
tmpText.color = config.TextColor;
tmpText.alignment = config.Alignment;
@@ -283,8 +447,6 @@ namespace SceneView
return tmpText;
}
// ========================
// 滚动视图创建
// ========================
@@ -293,34 +455,23 @@ namespace SceneView
ScrollViewConfig config)
{
// 1. ScrollView 根对象
var scrollViewObj = new GameObject("ScrollView");
var scrollViewRect = scrollViewObj.AddComponent<RectTransform>();
scrollViewRect.SetParent(parent, false);
scrollViewRect.sizeDelta = config.SizeDelta;
var scrollViewRect = CreateRect(parent, "ScrollView", config.RectConfig);
var scrollView = scrollViewObj.AddComponent<ScrollRect>();
var scrollViewImage = scrollViewObj.AddComponent<Image>();
var scrollView = scrollViewRect.gameObject.AddComponent<ScrollRect>();
var scrollViewImage = scrollViewRect.gameObject.AddComponent<Image>();
scrollViewImage.color = config.BackgroundColor;
scrollViewImage.raycastTarget = true;
// 2. Viewport 子对象
var viewportObj = new GameObject("Viewport");
var viewportRect = viewportObj.AddComponent<RectTransform>();
viewportRect.SetParent(scrollViewRect, false);
viewportRect.anchorMin = Vector2.zero;
viewportRect.anchorMax = Vector2.one;
viewportRect.offsetMin = Vector2.zero;
viewportRect.offsetMax = Vector2.zero;
viewportRect.pivot = new Vector2(0.5f, 0.5f);
// 2. Viewport 子对象 (始终填充 ScrollView)
var viewportRect = CreateRect(scrollViewRect, "Viewport", RectTransformConfig.FillParent);
var viewportMask = viewportObj.AddComponent<RectMask2D>(); // 或 Mask但 RectMask2D 性能更好
var viewportImage = viewportObj.AddComponent<Image>();
viewportRect.gameObject.AddComponent<RectMask2D>(); // 或 Mask但 RectMask2D 性能更好
var viewportImage = viewportRect.gameObject.AddComponent<Image>();
viewportImage.color = Color.clear; // 透明背景
// 3. Content 子对象
var contentObj = new GameObject("Content");
var contentRect = contentObj.AddComponent<RectTransform>();
contentRect.SetParent(viewportRect, false);
var contentRect =
CreateRect(viewportRect, "Content", RectTransformConfig.Default); // 初始使用Default后续会根据滚动方向调整
// 设置 Content 的锚点:根据滚动方向决定
if (config.Vertical && !config.Horizontal)
@@ -331,6 +482,7 @@ namespace SceneView
contentRect.pivot = new Vector2(0.5f, 1);
contentRect.anchoredPosition = new Vector2(0, -config.ContentPadding.y);
contentRect.sizeDelta = new Vector2(-2 * config.ContentPadding.x, 0); // 左右留边距
// 添加 VerticalLayoutGroup 通常是需要的,但这里只创建基础结构
}
else if (config.Horizontal && !config.Vertical)
{
@@ -340,15 +492,16 @@ namespace SceneView
contentRect.pivot = new Vector2(0, 0.5f);
contentRect.anchoredPosition = new Vector2(config.ContentPadding.x, 0);
contentRect.sizeDelta = new Vector2(0, -2 * config.ContentPadding.y);
// 添加 HorizontalLayoutGroup 通常是需要的
}
else
{
// 双向滚动:自由布局
contentRect.anchorMin = Vector2.zero;
contentRect.anchorMax = Vector2.zero;
// 双向滚动:自由布局,通常锚点设为左上角
contentRect.anchorMin = new Vector2(0, 1);
contentRect.anchorMax = new Vector2(0, 1);
contentRect.pivot = new Vector2(0, 1);
contentRect.anchoredPosition = Vector2.zero;
contentRect.sizeDelta = Vector2.zero;
contentRect.anchoredPosition = new Vector2(config.ContentPadding.x, -config.ContentPadding.y);
contentRect.sizeDelta = new Vector2(0, 0); // 自适应
}
// 4. 关联 ScrollRect
@@ -369,64 +522,278 @@ namespace SceneView
public static (TMP_InputField inputField, TextMeshProUGUI text) CreateInputField(Transform parent,
InputFieldConfig config)
{
var inputFieldObj = new GameObject("InputField");
var inputFieldRect = inputFieldObj.AddComponent<RectTransform>();
inputFieldRect.SetParent(parent, false);
ApplyRectTransformConfig(inputFieldRect, config.RectConfig);
var inputField = inputFieldObj.AddComponent<TMP_InputField>();
// 使用 CreateRect 创建输入框根对象并应用配置
var inputFieldRect = CreateRect(parent, "InputField", config.RectConfig);
var inputField = inputFieldRect.gameObject.AddComponent<TMP_InputField>();
// 背景图像
var backgroundImage = inputFieldObj.AddComponent<Image>();
var backgroundImage = inputFieldRect.gameObject.AddComponent<Image>();
// 注意Resources.Load 会在运行时加载,推荐通过 Inspector 赋值或使用 Addressables
// 为了保持原有功能暂时保留如果提示找不到请确保路径正确或导入默认UI资源
backgroundImage.sprite = Resources.Load<Sprite>("UI/Skins/Background");
backgroundImage.type = Image.Type.Sliced;
backgroundImage.color = config.BackgroundColor;
// 输入框文本组件
var textObj = new GameObject("Text (TMP)");
var textRect = textObj.AddComponent<RectTransform>();
textRect.SetParent(inputFieldRect, false);
// 文本始终填满输入框
ApplyRectTransformConfig(textRect, new RectTransformConfig(
anchorMin: Vector2.zero,
anchorMax: Vector2.one,
anchoredPosition: Vector2.zero,
sizeDelta: Vector2.zero,
offsetMin: Vector2.zero,
offsetMax: Vector2.zero,
pivot: new Vector2(0.5f, 0.5f)
));
var tmpText = textObj.AddComponent<TextMeshProUGUI>();
inputField.image = backgroundImage; // 设置TMP_InputField的图片引用
// 输入框文本组件 (始终填充输入框)
var textRect = CreateRect(inputFieldRect, "Text (TMP)", RectTransformConfig.FillParent);
var tmpText = textRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = "";
tmpText.color = config.TextColor;
tmpText.alignment = config.TextAlignment;
tmpText.fontSize = config.FontSize;
tmpText.raycastTarget = false;
inputField.textComponent = tmpText;
// 占位符文本组件
var placeholderObj = new GameObject("Placeholder");
var placeholderRect = placeholderObj.AddComponent<RectTransform>();
placeholderRect.SetParent(inputFieldRect, false);
// 占位符文本始终填满输入框
ApplyRectTransformConfig(placeholderRect, new RectTransformConfig(
anchorMin: Vector2.zero,
anchorMax: Vector2.one,
anchoredPosition: Vector2.zero,
sizeDelta: Vector2.zero,
offsetMin: Vector2.zero,
offsetMax: Vector2.zero,
pivot: new Vector2(0.5f, 0.5f)
));
var placeholderText = placeholderObj.AddComponent<TextMeshProUGUI>();
tmpText.raycastTarget = false; // 输入框内的文本通常不需要射线检测
inputField.textComponent = tmpText; // 设置TMP_InputField的文字组件引用
// 占位符文本组件 (始终填充输入框)
var placeholderRect = CreateRect(inputFieldRect, "Placeholder", RectTransformConfig.FillParent);
var placeholderText = placeholderRect.gameObject.AddComponent<TextMeshProUGUI>();
placeholderText.text = config.PlaceholderText;
placeholderText.color = config.PlaceholderTextColor;
placeholderText.alignment = config.TextAlignment;
placeholderText.fontSize = config.PlaceholderFontSize;
placeholderText.raycastTarget = false;
inputField.placeholder = placeholderText;
placeholderText.raycastTarget = false; // 占位符通常不需要射线检测
inputField.placeholder = placeholderText; // 设置TMP_InputField的占位符引用
// 配置输入字段属性
inputField.characterValidation = config.CharacterValidation;
inputField.characterLimit = config.CharacterLimit;
return (inputField, tmpText);
}
}
}
/// <summary>
/// 创建一个网格布局容器,用于自动排列子对象。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="name">GameObject 名称。</param>
/// <param name="rectConfig">容器的 RectTransform 配置。</param>
/// <param name="constraintCount">每行或每列的元素数量。</param>
/// <param name="cellSize">每个单元格的大小。</param>
/// <param name="spacing">单元格之间的间距。</param>
/// <param name="constraint">约束类型(按行数或列数)。</param>
/// <returns>创建的网格容器的 RectTransform。</returns>
public static RectTransform CreateGridLayoutContainer(
Transform parent,
string name,
RectTransformConfig rectConfig,
int constraintCount,
Vector2 cellSize,
Vector2 spacing,
GridLayoutGroup.Constraint constraint = GridLayoutGroup.Constraint.FixedColumnCount)
{
var containerRect = CreateRect(parent, name, rectConfig);
var gridLayout = containerRect.gameObject.AddComponent<GridLayoutGroup>();
gridLayout.constraint = constraint;
if (constraint == GridLayoutGroup.Constraint.FixedColumnCount)
gridLayout.constraintCount = constraintCount;
else if (constraint == GridLayoutGroup.Constraint.FixedRowCount)
gridLayout.constraintCount = constraintCount;
gridLayout.cellSize = cellSize;
gridLayout.spacing = spacing;
return containerRect;
}
/// <summary>
/// 创建一个带标签的输入框(左边文字,右边输入)。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含根对象、标签和输入框的元组。</returns>
public static (RectTransform root, TextMeshProUGUI label, TMP_InputField inputField) CreateLabeledInputField(
Transform parent, LabeledInputFieldConfig config)
{
// 1. 创建根容器并添加水平布局
var rootRect = CreateRect(parent, config.LabelText + " LabeledInput", config.RectConfig);
var layoutGroup = rootRect.gameObject.AddComponent<HorizontalLayoutGroup>();
layoutGroup.childControlWidth = true;
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandWidth = false;
layoutGroup.spacing = config.Spacing;
// 2. 创建标签
var labelConfig = new TextConfig(
config.LabelText,
config.LabelFontSize,
config.LabelTextColor,
TextAlignmentOptions.Left,
false,
RectTransformConfig.Default // RectTransform由LayoutGroup控制
);
var label = CreateText(rootRect, labelConfig);
var labelLayout = label.gameObject.AddComponent<LayoutElement>();
labelLayout.preferredWidth = config.LabelWidth;
labelLayout.flexibleWidth = 0; // 不参与弹性宽度分配
// 3. 创建输入框
var (inputField, _) = CreateInputField(rootRect, config.InputFieldConfig);
var inputLayout = inputField.gameObject.AddComponent<LayoutElement>();
inputLayout.flexibleWidth = 1; // 占据剩余所有宽度
return (rootRect, label, inputField);
}
/// <summary>
/// 创建一个下拉框控件。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含下拉框组件和其主标签的元组。</returns>
public static (TMP_Dropdown dropdown, TextMeshProUGUI captionText) CreateDropdown(Transform parent,
DropdownConfig config)
{
// Unity 从代码创建 Dropdown 比较繁琐,因为它依赖于一个预设的模板结构。
// 以下代码将手动构建这个结构。
// 1. Root Dropdown Object
var dropdownRect = CreateRect(parent, "Dropdown", config.RectConfig);
var dropdownImage = dropdownRect.gameObject.AddComponent<Image>();
dropdownImage.color = config.BackgroundColor;
var dropdown = dropdownRect.gameObject.AddComponent<TMP_Dropdown>();
// 2. Label (Caption Text)
var labelRect = CreateRect(dropdownRect, "Label", RectTransformConfig.FillParent);
labelRect.offsetMin = new Vector2(10, 0);
labelRect.offsetMax = new Vector2(-25, 0);
var labelText = labelRect.gameObject.AddComponent<TextMeshProUGUI>();
labelText.alignment = TextAlignmentOptions.Left;
labelText.color = config.CaptionTextColor;
labelText.fontSize = config.CaptionFontSize;
dropdown.captionText = labelText;
// 3. Arrow
var arrowRect = CreateRect(dropdownRect, "Arrow", new RectTransformConfig(
new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(-15, 0), new Vector2(20, 20), Vector2.zero,
Vector2.zero, new Vector2(0.5f, 0.5f)
));
var arrowImage = arrowRect.gameObject.AddComponent<Image>();
arrowImage.color = new Color(0.8f, 0.8f, 0.8f); // 默认箭头颜色
// 4. Template (Scroll View, the dropdown list) - 必须默认禁用
var templateRect = CreateRect(dropdownRect, "Template", new RectTransformConfig(
new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 2), new Vector2(0, 150), Vector2.zero,
Vector2.zero, new Vector2(0.5f, 1)
));
var templateImage = templateRect.gameObject.AddComponent<Image>();
templateImage.color = config.BackgroundColor;
var scrollRect = templateRect.gameObject.AddComponent<ScrollRect>();
scrollRect.movementType = ScrollRect.MovementType.Clamped;
templateRect.gameObject.SetActive(false);
dropdown.template = templateRect;
// 5. Viewport
var viewportRect = CreateRect(templateRect, "Viewport", RectTransformConfig.FillParent);
viewportRect.gameObject.AddComponent<RectMask2D>();
scrollRect.viewport = viewportRect;
// 6. Content
var contentRect = CreateRect(viewportRect, "Content", new RectTransformConfig(
new Vector2(0, 1), new Vector2(1, 1), Vector2.zero, new Vector2(0, 28), Vector2.zero, Vector2.zero,
new Vector2(0.5f, 1)
));
scrollRect.content = contentRect;
// 7. Item (The template for each option)
var itemRect = CreateRect(contentRect, "Item", new RectTransformConfig(
new Vector2(0, 1), new Vector2(1, 1), Vector2.zero, new Vector2(0, 20), Vector2.zero, Vector2.zero,
new Vector2(0.5f, 1)
));
var itemToggle = itemRect.gameObject.AddComponent<Toggle>();
itemToggle.targetGraphic = itemRect.gameObject.AddComponent<Image>(); // Add an image to be the background
var itemLabelRect = CreateRect(itemRect, "Item Label", RectTransformConfig.FillParent);
itemLabelRect.offsetMin = new Vector2(10, 0);
itemLabelRect.offsetMax = new Vector2(-10, 0);
var itemLabel = itemLabelRect.gameObject.AddComponent<TextMeshProUGUI>();
itemLabel.color = config.ItemTextColor;
itemLabel.fontSize = config.ItemFontSize;
dropdown.itemText = itemLabel;
// 8. Populate options
dropdown.ClearOptions();
dropdown.AddOptions(config.Options);
return (dropdown, labelText);
}
/// <summary>
/// 创建一个带标签的下拉框(左边文字,右边下拉)。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含根对象、标签和下拉框的元组。</returns>
public static (RectTransform root, TextMeshProUGUI label, TMP_Dropdown dropdown) CreateLabeledDropdown(
Transform parent, LabeledDropdownConfig config)
{
// 1. 创建根容器并添加水平布局
var rootRect = CreateRect(parent, config.LabelText + " LabeledDropdown", config.RectConfig);
var layoutGroup = rootRect.gameObject.AddComponent<HorizontalLayoutGroup>();
layoutGroup.childControlWidth = true;
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandWidth = true;
layoutGroup.spacing = config.Spacing;
// 2. 创建标签
var labelConfig = new TextConfig(
config.LabelText,
config.LabelFontSize,
config.LabelTextColor,
TextAlignmentOptions.Left,
false,
RectTransformConfig.Default
);
var label = CreateText(rootRect, labelConfig);
var labelLayout = label.gameObject.AddComponent<LayoutElement>();
labelLayout.preferredWidth = config.LabelWidth;
labelLayout.flexibleWidth = 0;
// 3. 创建下拉框
var (dropdown, _) = CreateDropdown(rootRect, config.DropdownConfig);
var dropdownLayout = dropdown.gameObject.AddComponent<LayoutElement>();
dropdownLayout.flexibleWidth = 1;
return (rootRect, label, dropdown);
}
/// <summary>
/// 创建一个切换开关控件。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含Toggle组件、标签和勾选标记图像的元组。</returns>
public static (Toggle toggle, TextMeshProUGUI label, Image checkmark) CreateToggle(Transform parent,
ToggleConfig config)
{
// 1. Root Toggle Object
var toggleRect = CreateRect(parent, "Toggle", config.RectConfig);
var toggle = toggleRect.gameObject.AddComponent<Toggle>();
toggle.isOn = config.IsOnByDefault;
// 2. Background
var backgroundRect = CreateRect(toggleRect, "Background", new RectTransformConfig(
new Vector2(0, 0.5f), new Vector2(0, 0.5f), Vector2.zero, new Vector2(20, 20), Vector2.zero,
Vector2.zero, new Vector2(0, 0.5f)
));
var backgroundImage = backgroundRect.gameObject.AddComponent<Image>();
backgroundImage.color = config.BackgroundColor;
toggle.targetGraphic = backgroundImage;
// 3. Checkmark
var checkmarkRect = CreateRect(backgroundRect, "Checkmark", RectTransformConfig.FillParent);
checkmarkRect.offsetMin = new Vector2(3, 3);
checkmarkRect.offsetMax = new Vector2(-3, -3);
var checkmarkImage = checkmarkRect.gameObject.AddComponent<Image>();
checkmarkImage.color = config.CheckmarkColor;
toggle.graphic = checkmarkImage;
// 4. Label
var labelRect = CreateRect(toggleRect, "Label", new RectTransformConfig(
new Vector2(0, 0), new Vector2(1, 1), Vector2.zero, new Vector2(-config.Spacing - 20, 0),
new Vector2(config.Spacing + 20, 0), Vector2.zero, new Vector2(0, 0.5f)
));
var label = labelRect.gameObject.AddComponent<TextMeshProUGUI>();
label.text = config.LabelText;
label.color = config.LabelTextColor;
label.fontSize = config.LabelFontSize;
label.alignment = TextAlignmentOptions.Left;
return (toggle, label, checkmarkImage);
}
}
}

View File

@@ -10,8 +10,8 @@ namespace SceneView
private static readonly Dictionary<string, TMP_FontAsset> _fontCache = new Dictionary<string, TMP_FontAsset>();
/// <summary>
/// 根据字体名称从操作系统加载字体,并创建 TMP_FontAsset带缓存
/// 非常遗憾,用不了
/// 根据字体名称从操作系统加载字体,并创建 TMP_FontAsset带缓存
/// 非常遗憾,用不了
/// </summary>
/// <param name="fontName">系统字体名称,如 "Arial", "Microsoft YaHei" 等</param>
/// <returns>对应的 TMP_FontAsset失败则返回 null</returns>
@@ -22,7 +22,7 @@ namespace SceneView
if (_fontCache.TryGetValue(fontName, out var cached))
return cached;
var baseFont = Font.CreateDynamicFontFromOSFont(fontName, 12); // 12 是临时大小,不影响 TMP 字体质量
if (baseFont == null || baseFont.dynamic == false)
@@ -34,13 +34,13 @@ namespace SceneView
// 创建 TMP 字体资源
var tmpFont = TMP_FontAsset.CreateFontAsset(
baseFont,
samplingPointSize: 72,
atlasPadding: 4,
renderMode: GlyphRenderMode.SDFAA,
atlasWidth: 1024,
atlasHeight: 1024,
atlasPopulationMode: AtlasPopulationMode.Dynamic,
enableMultiAtlasSupport: true
72,
4,
GlyphRenderMode.SDFAA,
1024,
1024,
AtlasPopulationMode.Dynamic,
true
);
if (tmpFont != null)
@@ -57,7 +57,7 @@ namespace SceneView
}
/// <summary>
/// 清空缓存(谨慎使用,通常不需要)
/// 清空缓存(谨慎使用,通常不需要)
/// </summary>
public static void ClearCache()
{

View File

@@ -1,44 +1,42 @@
using System;
using HarmonyLib;
using UnityEngine;
using UnityEngine;
namespace SceneView
{
public class ModBehaviour:Duckov.Modding.ModBehaviour
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
public const string MOD_ID="SceneView";
private Harmony? harmony;
// public const string MOD_ID="SceneView";
// private Harmony? harmony;
private GameObject? component;
private CanvasControl myCanvas;
protected override void OnAfterSetup()
{
CreateComponents();
if (harmony == null)
{
harmony=new Harmony(MOD_ID);
}
harmony.PatchAll();
// if (harmony == null)
// {
// harmony=new Harmony(MOD_ID);
// }
// harmony.PatchAll();
}
protected override void OnBeforeDeactivate()
{
RemoveComponents();
if (harmony != null)
{
harmony.UnpatchAll(harmony.Id);
}
harmony = null;
// if (harmony != null)
// {
// harmony.UnpatchAll(harmony.Id);
// }
//
// harmony = null;
}
private void CreateComponents()
{
if(component==null)
if (component == null)
{
component = new GameObject("SceneViewControl");
myCanvas= component.AddComponent<CanvasControl>();
myCanvas = component.AddComponent<CanvasControl>();
component.SetActive(true);
DontDestroyOnLoad(component);
}
@@ -48,7 +46,7 @@ namespace SceneView
{
if (component != null)
{
GameObject.Destroy(component);
Destroy(component);
component = null;
}
}

View File

@@ -0,0 +1,340 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace SceneView
{
public class ParametersPanel : MonoBehaviour, IDragHandler, IBeginDragHandler
{
public RectTransform rectTransform;
public const float wide = 400;
public (TMP_InputField x, TMP_InputField y, TMP_InputField z)
position, localPosition, localScale; // 删除了 'scale',因为它在 Awake 中被注释掉了
public (TMP_InputField x, TMP_InputField y, TMP_InputField z, TMP_InputField w)
rotation, localRotation;
private Vector2 shift;
private int timer = 0;
private int refreshTime = 10; // 每10帧刷新一次
// 新增:标志位,表示是否有输入框正在被编辑
private bool isEditingInputField = false;
private void Awake()
{
if (!rectTransform) rectTransform = GetComponent<RectTransform>();
if (!rectTransform) rectTransform = gameObject.AddComponent<RectTransform>();
rectTransform.sizeDelta = new Vector2(wide, 500);
rectTransform.anchoredPosition = new Vector2(wide / 2 + 10, 0);
CanvasControl.OnChangeFocusObject += OnChangeFocusObject;
var title = RectTransformConfig.Default;
title.AnchorMin = Vector2.up;
title.AnchorMax = Vector2.one;
title.Pivot = new Vector2(0.5f, 0);
title.SizeDelta = new Vector2(0, 50);
title.AnchoredPosition = new Vector2(0, 0);
var titleObj = ControlUtilities.CreateRect(transform, "标题", title);
titleObj.gameObject.AddComponent<Image>().color = new Color(0.3f, 0.3f, 0.3f, 0.8f);
var titleText = TextConfig.Default;
titleText.RectConfig = RectTransformConfig.FillParent;
titleText.Text = "焦点参数";
ControlUtilities.CreateText(titleObj, titleText);
var contentConfig = RectTransformConfig.FillParent;
var content = ControlUtilities.CreateRect(transform, "内容", contentConfig);
var vLayout = content.gameObject.AddComponent<VerticalLayoutGroup>();
vLayout.padding = new RectOffset(2, 2, 2, 2);
vLayout.childAlignment = TextAnchor.UpperCenter;
vLayout.childControlWidth = true;
vLayout.childControlHeight = true;
vLayout.spacing = 2;
var labelConfig = TextConfig.Default;
// 全局位置
labelConfig.Text = "全局位置";
ControlUtilities.CreateText(content, labelConfig);
position = CreateVector3InputField(content, ApplyWorldPositionChange);
// 全局旋转 (使用Quaternion)
labelConfig.Text = "全局旋转";
ControlUtilities.CreateText(content, labelConfig);
rotation = CreateVector4InputField(content, ApplyWorldRotationChange);
// 局部位置
labelConfig.Text = "局部位置";
ControlUtilities.CreateText(content, labelConfig);
localPosition = CreateVector3InputField(content, ApplyLocalPositionChange);
// 局部缩放
labelConfig.Text = "局部缩放";
ControlUtilities.CreateText(content, labelConfig);
localScale = CreateVector3InputField(content, ApplyLocalScaleChange);
// 局部旋转 (使用Quaternion)
labelConfig.Text = "局部旋转";
ControlUtilities.CreateText(content, labelConfig);
localRotation = CreateVector4InputField(content, ApplyLocalRotationChange);
}
private void OnDestroy()
{
CanvasControl.OnChangeFocusObject -= OnChangeFocusObject;
}
private void Update()
{
timer++;
// 只有当没有输入框被编辑时才刷新
if (timer >= refreshTime && !isEditingInputField)
{
timer = 0;
Refresh();
}
}
public void OnChangeFocusObject(GameObject obj)
{
// 焦点对象改变时,立即刷新
Refresh();
}
private void Refresh()
{
if (!CanvasControl.FocusGameObject)
{
ClearAllInputFields();
return;
}
var targetTransform = CanvasControl.FocusGameObject.transform;
// --- 全局位置 (World Position) ---
var currentPosition = targetTransform.position;
position.x.text = currentPosition.x.ToString("F3"); // "F3" 表示保留3位小数
position.y.text = currentPosition.y.ToString("F3");
position.z.text = currentPosition.z.ToString("F3");
// --- 局部位置 (Local Position) ---
var currentLocalPosition = targetTransform.localPosition;
localPosition.x.text = currentLocalPosition.x.ToString("F3");
localPosition.y.text = currentLocalPosition.y.ToString("F3");
localPosition.z.text = currentLocalPosition.z.ToString("F3");
// --- 局部缩放 (Local Scale) ---
var currentLocalScale = targetTransform.localScale;
localScale.x.text = currentLocalScale.x.ToString("F3");
localScale.y.text = currentLocalScale.y.ToString("F3");
localScale.z.text = currentLocalScale.z.ToString("F3");
// --- 全局旋转 (World Rotation) - Quaternion ---
var currentRotation = targetTransform.rotation;
rotation.x.text = currentRotation.x.ToString("F3");
rotation.y.text = currentRotation.y.ToString("F3");
rotation.z.text = currentRotation.z.ToString("F3");
rotation.w.text = currentRotation.w.ToString("F3");
// --- 局部旋转 (Local Rotation) - Quaternion ---
var currentLocalRotation = targetTransform.localRotation;
localRotation.x.text = currentLocalRotation.x.ToString("F3");
localRotation.y.text = currentLocalRotation.y.ToString("F3");
localRotation.z.text = currentLocalRotation.z.ToString("F3");
localRotation.w.text = currentLocalRotation.w.ToString("F3");
}
private void ClearAllInputFields()
{
position.x.text = ""; position.y.text = ""; position.z.text = "";
localPosition.x.text = ""; localPosition.y.text = ""; localPosition.z.text = "";
localScale.x.text = ""; localScale.y.text = ""; localScale.z.text = "";
rotation.x.text = ""; rotation.y.text = ""; rotation.z.text = ""; rotation.w.text = "";
localRotation.x.text = ""; localRotation.y.text = ""; localRotation.z.text = ""; localRotation.w.text = "";
}
// Helper method to add common input field event listeners
private void AddInputFieldListeners(TMP_InputField inputField)
{
inputField.onSelect.AddListener((_) => isEditingInputField = true);
inputField.onDeselect.AddListener((_) =>
{
isEditingInputField = false;
// 在失去焦点后立即刷新,以更新可能的非用户输入引起的改变或重新格式化用户输入
Refresh();
});
}
// 修改 CreateVector3InputField接受一个Action用于处理onEndEdit
public (TMP_InputField x, TMP_InputField y, TMP_InputField z) CreateVector3InputField(Transform parent, Action<string, int> onEndEditCallback)
{
var rectConfig = RectTransformConfig.Default;
var pack = ControlUtilities.CreateRect(parent, "向量组", rectConfig);
var hLayout = pack.gameObject.AddComponent<HorizontalLayoutGroup>();
hLayout.childForceExpandHeight = true;
hLayout.childForceExpandWidth = true;
hLayout.childControlWidth = true;
hLayout.childControlHeight = true;
hLayout.spacing = 2;
hLayout.padding = new RectOffset(2, 2, 2, 2);
var inputConfig = LabeledInputFieldConfig.Default;
inputConfig.InputFieldConfig.BackgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.7f);
inputConfig.LabelWidth = 15;
inputConfig.LabelFontSize = 14;
inputConfig.Spacing = 0;
inputConfig.LabelText = "X";
var inputX = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputX.inputField);
inputX.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 0));
inputConfig.LabelText = "Y";
var inputY = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputY.inputField);
inputY.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 1));
inputConfig.LabelText = "Z";
var inputZ = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputZ.inputField);
inputZ.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 2));
return (inputX.inputField, inputY.inputField, inputZ.inputField);
}
// 修改 CreateVector4InputField接受一个Action用于处理onEndEdit
public (TMP_InputField x, TMP_InputField y, TMP_InputField z, TMP_InputField w) CreateVector4InputField(
Transform parent, Action<string, int> onEndEditCallback)
{
var rectConfig = RectTransformConfig.Default;
var pack = ControlUtilities.CreateRect(parent, "向量组", rectConfig);
var hLayout = pack.gameObject.AddComponent<HorizontalLayoutGroup>();
hLayout.childForceExpandHeight = true;
hLayout.childForceExpandWidth = true;
hLayout.childControlWidth = true;
hLayout.childControlHeight = true;
hLayout.spacing = 2;
hLayout.padding = new RectOffset(2, 2, 2, 2);
var inputConfig = LabeledInputFieldConfig.Default;
inputConfig.InputFieldConfig.BackgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.7f);
inputConfig.LabelWidth = 15;
inputConfig.LabelFontSize = 14;
inputConfig.Spacing = 0;
inputConfig.LabelText = "X";
var inputX = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputX.inputField);
inputX.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 0));
inputConfig.LabelText = "Y";
var inputY = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputY.inputField);
inputY.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 1));
inputConfig.LabelText = "Z";
var inputZ = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputZ.inputField);
inputZ.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 2));
inputConfig.LabelText = "W";
var inputW = ControlUtilities.CreateLabeledInputField(pack, inputConfig);
AddInputFieldListeners(inputW.inputField);
inputW.inputField.onEndEdit.AddListener(text => onEndEditCallback?.Invoke(text, 3));
return (inputX.inputField, inputY.inputField, inputZ.inputField, inputW.inputField);
}
private void ApplyWorldPositionChange(string text, int axisIndex)
{
if (CanvasControl.FocusGameObject == null) return;
var targetTransform = CanvasControl.FocusGameObject.transform;
if (float.TryParse(text, out var newValue))
{
var pos = targetTransform.position;
if (axisIndex == 0) pos.x = newValue;
else if (axisIndex == 1) pos.y = newValue;
else if (axisIndex == 2) pos.z = newValue;
targetTransform.position = pos;
}
Refresh(); // 刷新以确保所有相关字段如localPosition都已更新
}
private void ApplyLocalPositionChange(string text, int axisIndex)
{
if (CanvasControl.FocusGameObject == null) return;
var targetTransform = CanvasControl.FocusGameObject.transform;
if (float.TryParse(text, out var newValue))
{
var localPos = targetTransform.localPosition;
if (axisIndex == 0) localPos.x = newValue;
else if (axisIndex == 1) localPos.y = newValue;
else if (axisIndex == 2) localPos.z = newValue;
targetTransform.localPosition = localPos;
}
Refresh();
}
private void ApplyLocalScaleChange(string text, int axisIndex)
{
if (CanvasControl.FocusGameObject == null) return;
var targetTransform = CanvasControl.FocusGameObject.transform;
if (float.TryParse(text, out var newValue))
{
var localScale = targetTransform.localScale;
if (axisIndex == 0) localScale.x = newValue;
else if (axisIndex == 1) localScale.y = newValue;
else if (axisIndex == 2) localScale.z = newValue;
targetTransform.localScale = localScale;
}
Refresh();
}
private void ApplyWorldRotationChange(string text, int axisIndex)
{
if (CanvasControl.FocusGameObject == null) return;
var targetTransform = CanvasControl.FocusGameObject.transform;
if (float.TryParse(text, out var newValue))
{
var rot = targetTransform.rotation;
if (axisIndex == 0) rot.x = newValue;
else if (axisIndex == 1) rot.y = newValue;
else if (axisIndex == 2) rot.z = newValue;
else if (axisIndex == 3) rot.w = newValue;
targetTransform.rotation = rot; // Quaternion需要整体重新赋值
}
Refresh();
}
private void ApplyLocalRotationChange(string text, int axisIndex)
{
if (CanvasControl.FocusGameObject == null) return;
var targetTransform = CanvasControl.FocusGameObject.transform;
if (float.TryParse(text, out var newValue))
{
var localRot = targetTransform.localRotation;
if (axisIndex == 0) localRot.x = newValue;
else if (axisIndex == 1) localRot.y = newValue;
else if (axisIndex == 2) localRot.z = newValue;
else if (axisIndex == 3) localRot.w = newValue;
targetTransform.localRotation = localRot; // Quaternion需要整体重新赋值
}
Refresh();
}
public void OnBeginDrag(PointerEventData eventData)
{
shift = transform.position - new Vector3(eventData.position.x, eventData.position.y);
}
public void OnDrag(PointerEventData eventData)
{
transform.position = eventData.position + shift;
}
}
}

View File

@@ -1,14 +0,0 @@
using HarmonyLib;
using UnityEngine;
namespace SceneView
{
// [HarmonyPatch(typeof(GameObject), "Internal_CreateGameObject")]
// public class PatchGameObjectStart
// {
// static void Postfix(GameObject __instance)
// {
// Debug.Log($"{__instance.name}初始化了");
// }
// }
}

View File

@@ -1,15 +0,0 @@
using System;
using HarmonyLib;
using Object = UnityEngine.Object;
namespace SceneView
{
[HarmonyPatch(typeof(Object), nameof(Object.Destroy), new Type[] { typeof(Object)})]
public class PatchObjectDestroy
{
private static void Postfix(Object __instance)
{
}
}
}

View File

@@ -13,13 +13,13 @@
<DebugType>none</DebugType>
</PropertyGroup>
<ItemGroup>
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" Private="False" />
<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="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" Private="False"/>
<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"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lib.Harmony" Version="2.4.1" />
<PackageReference Include="Lib.Harmony" Version="2.4.1"/>
</ItemGroup>
</Project>

View File

@@ -1,5 +1,3 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
@@ -9,26 +7,36 @@ namespace SceneView
public class SceneViewPanel : MonoBehaviour, IDragHandler, IBeginDragHandler
{
public const float titleHeight = 50;
private Vector2 shift;
public ScrollRect? scrollRect;
private TreeViewNode? treeViewNode;
public string currentAimObj;
private Vector2 shift;
private TreeViewNode? treeViewNode;
private void Start()
{
currentAimObj = CanvasControl.ShowAim;
CreateUI();
}
public void OnBeginDrag(PointerEventData eventData)
{
shift = transform.position - new Vector3(eventData.position.x, eventData.position.y);
}
public void OnDrag(PointerEventData eventData)
{
transform.position = eventData.position + shift;
}
private void CreateUI()
{
CreateTitleBar();
var scrollConfig = ScrollViewConfig.Default;
scrollConfig.Horizontal = true;
scrollConfig.SizeDelta = CanvasControl.panelSize - new Vector2(0, titleHeight);
scrollConfig.RectConfig.SizeDelta = CanvasControl.panelSize - new Vector2(0, titleHeight);
var scrollRectArr = ControlUtilities.CreateScrollView(transform, scrollConfig);
scrollRect = scrollRectArr.scrollRect;
if (scrollRect == null)
@@ -83,7 +91,7 @@ namespace SceneView
inputConfig.RectConfig.AnchorMax = Vector2.right;
inputConfig.RectConfig.Pivot = new Vector2(0.5f, 1);
inputConfig.RectConfig.SizeDelta = new Vector2(0, titleHeight);
inputConfig.PlaceholderText = "输入搜索对象";
inputConfig.PlaceholderText = "输入对象名称";
var inputObj = ControlUtilities.CreateInputField(transform, inputConfig);
inputObj.inputField.onEndEdit.AddListener(s =>
{
@@ -92,7 +100,7 @@ namespace SceneView
});
Refresh();
// Refresh();
}
private void CreateTitleBar()
@@ -117,10 +125,7 @@ namespace SceneView
titleTextConfig.RectConfig.AnchorMax = Vector2.one;
var titleText = ControlUtilities.CreateText(titleBar, titleTextConfig);
if (titleText == null)
{
Debug.LogError("Failed to create TitleText.");
}
if (titleText == null) Debug.LogError("Failed to create TitleText.");
var refreshButtonConfig = ButtonConfig.Default;
refreshButtonConfig.Text = "刷新";
@@ -143,8 +148,9 @@ namespace SceneView
{
if (treeViewNode)
{
var canvas = FindIncludingHidden(currentAimObj);
if (!canvas)
var canvas = GameObject.Find(currentAimObj);
// var canvas = FindIncludingHidden(currentAimObj);
if (!canvas && !string.IsNullOrEmpty(currentAimObj))
{
Debug.LogError($"{currentAimObj} not found.");
return;
@@ -155,27 +161,16 @@ namespace SceneView
}
}
public void OnDrag(PointerEventData eventData)
{
transform.position = eventData.position + shift;
}
public void OnBeginDrag(PointerEventData eventData)
{
shift = transform.position - new Vector3(eventData.position.x, eventData.position.y);
}
/// <summary>
/// 按名称查找场景中的GameObject包括隐藏非激活对象和DontDestroyOnLoad对象。
/// 此方法会遍历所有当前加载到内存中的GameObject实例。
///
/// **重要提示:**
/// 1. **性能开销较大:** 该方法会遍历所有已加载的GameObject性能开销相对较高。
/// 因此,**不建议在Update、FixedUpdate等帧循环中频繁调用。**
/// 2. **适用场景:** 更适合在初始化、加载场景、调试或不频繁的查找操作中使用
/// 3. **同名对象:** 如果场景中存在多个同名对象,此方法将返回它遇到的第一个匹配项
/// 4. **DontDestroyOnLoad** 自动包含在DontDestroyOnLoad根下的对象。
/// 5. **隐藏对象:** 自动包含Hierarchy中非激活隐藏的对象。
/// 按名称查找场景中的GameObject包括隐藏非激活对象和DontDestroyOnLoad对象。
/// 此方法会遍历所有当前加载到内存中的GameObject实例。
/// **重要提示:**
/// 1. **性能开销较大:** 该方法会遍历所有已加载的GameObject性能开销相对较高。
/// 因此,**不建议在Update、FixedUpdate等帧循环中频繁调用。**
/// 2. **适用场景:** 更适合在初始化、加载场景、调试或不频繁的查找操作中使用。
/// 3. **同名对象:** 如果场景中存在多个同名对象,此方法将返回它遇到的第一个匹配项
/// 4. **DontDestroyOnLoad** 自动包含在DontDestroyOnLoad根下的对象
/// 5. **隐藏对象:** 自动包含Hierarchy中非激活隐藏的对象。
/// </summary>
/// <param name="name">要查找的GameObject的名称。</param>
/// <returns>找到的第一个GameObject如果未找到则返回null。</returns>
@@ -187,34 +182,12 @@ namespace SceneView
Debug.LogWarning("FindIncludingHidden: Provided name is null, empty, or whitespace. Returning null.");
return null;
}
// 2. 获取所有已加载的GameObject
// Resources.FindObjectsOfTypeAll<GameObject>() 是实现需求的关键。
// 它会找到所有当前加载到内存中的GameObject实例不论它们是否激活属于哪个场景包括 DontDestroyOnLoad 场景),
// 甚至可能包括一些编辑器内部使用的隐藏GameObject。
GameObject[] allGameObjects = Resources.FindObjectsOfTypeAll<GameObject>();
// 3. 遍历并比较名称
foreach (GameObject obj in allGameObjects)
{
// Unity中存在许多内部GameObject例如场景视图的相机、光照探头组等
// 它们的hideFlags属性可能被设置为HideInHierarchy、HideAndDontSave等。
// 题目要求“包括隐藏”,并未明确排除这些内部或编辑器对象。
// 因此这里我们采取最宽松的策略只要GameObject的name属性与传入的name匹配就返回。
// 如果未来需要排除特定类型的隐藏对象(例如只查找用户创建的游戏对象),
// 可以根据 obj.scene.name 来过滤 DontDestroyOnLoad 场景中的对象,
// 或者根据 obj.hideFlags 来排除编辑器内部对象。
var allGameObjects = Resources.FindObjectsOfTypeAll<GameObject>();
foreach (var obj in allGameObjects)
if (obj.name == name)
{
return obj; // 4. 返回第一个匹配项
}
}
// 5. 未找到则返回 null
// 通常查找函数在未找到结果时静默返回null是更常见的API行为。
// 调用方可以根据返回值自行决定是否输出日志。
// Debug.LogWarning($"FindIncludingHidden: GameObject with name '{name}' not found. Returning null.");
return null;
}
}
}
}

View File

@@ -1,14 +1,15 @@
using System;
using System.Collections;
using SceneView;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
namespace SceneView
{
public class TreeViewNode : MonoBehaviour
{
public TreeViewNode? parent = null;
public TreeViewNode? parent;
public RectTransform? rectTransform;
public TextMeshProUGUI? text;
@@ -23,7 +24,7 @@ namespace SceneView
private string originalText = "";
private void Awake()
{
@@ -37,10 +38,7 @@ namespace SceneView
if (rectTransform == null)
{
rectTransform = GetComponent<RectTransform>();
if (rectTransform == null)
{
rectTransform = gameObject.AddComponent<RectTransform>();
}
if (rectTransform == null) rectTransform = gameObject.AddComponent<RectTransform>();
if (rectTransform == null)
{
@@ -62,7 +60,7 @@ namespace SceneView
// 创建按钮并检查是否已存在
if (label == null)
{
var button = ControlUtilities.CreateButton(rectTransform, buttonConfig, Expand);
var button = ControlUtilities.CreateButton(rectTransform, buttonConfig, null);
label = button.button;
text = button.text;
if (text == null)
@@ -78,10 +76,10 @@ namespace SceneView
{
var button = ControlUtilities.CreateButton(rectTransform, buttonConfig, null);
objectEnable = button.button;
objectText= button.text;
objectText = button.text;
button.text.text = "-";
button.button.image.color = Color.yellow;
var rect=objectEnable.GetComponent<RectTransform>();
var rect = objectEnable.GetComponent<RectTransform>();
rect.anchorMin = Vector2.one;
rect.anchorMax = Vector2.one;
rect.pivot = Vector2.one / 2;
@@ -154,18 +152,21 @@ namespace SceneView
verticalLayout.childControlWidth = true;
sizeFitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
}
public void InsertChild(RectTransform childRectTransform)
{
if (child != null && childRectTransform != null)
{
// 将子节点添加到 content 容器中
childRectTransform.SetParent(child.transform, false);
}
}
private void OnExpand(GameObject go)
{
if (!go) return;
CanvasControl.FocusGameObject = go;
Expand();
}
private void Expand()
{
if (child == null)
@@ -198,14 +199,10 @@ namespace SceneView
}
if (child.activeSelf)
{
rectTransform.sizeDelta =
new Vector2(rectTransform.sizeDelta.x, buttonHeight + childRectTransform.sizeDelta.y);
}
else
{
rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, buttonHeight);
}
if (parent != null)
{
@@ -214,24 +211,53 @@ namespace SceneView
}
}
public IEnumerator DisplayGameObjectStructureCoroutine(GameObject targetObject, int depth = 0)
private IEnumerator DisplayGameObjectStructureCoroutineImpl(GameObject targetObject, int depth,
Action onComplete = null)
{
if (targetObject == null)
{
Debug.LogError("Target object is null.");
// 如果目标对象为空,则遍历场景中的所有对象
var rootObjects = SceneManager.GetActiveScene().GetRootGameObjects();
var totalRootObjects = rootObjects.Length;
var completedRootObjects = 0;
originalText = $"场景{SceneManager.GetActiveScene().name}";
if (text) text.text = originalText;
foreach (var rootObject in rootObjects)
{
if (!rootObject) continue;
var childNode = new GameObject($"{rootObject.name}").AddComponent<TreeViewNode>();
childNode.transform.SetParent(childRectTransform, false);
childNode.parent = this;
childNode.CreateUI();
StartCoroutine(childNode.DisplayGameObjectStructureCoroutineImpl(rootObject, depth + 1,
() =>
{
completedRootObjects++;
if (completedRootObjects == totalRootObjects)
{
// 所有根对象及其子对象都已处理完成
onComplete?.Invoke();
Expand();
}
}));
yield return null;
}
yield break;
}
if (targetObject.name == CanvasControl.ViewCanvasName)
yield break;
label?.onClick.RemoveAllListeners();
label?.onClick.AddListener(() =>OnExpand(targetObject));
ClearChildNodes();
originalText = GetIndentedName(targetObject.name, depth);
if (text != null) text.text = originalText;
objectEnable.onClick.AddListener(() => OnObjectEnable(targetObject, objectEnable, objectText));
UpdateObjButton(targetObject,objectEnable,objectText);
objectEnable.onClick.AddListener(() => OnObjectEnable(targetObject, objectEnable, objectText));
UpdateObjButton(targetObject, objectEnable, objectText);
var components = targetObject.GetComponents<Behaviour>();
foreach (var component in components)
@@ -262,7 +288,6 @@ namespace SceneView
// 计数器,用于跟踪子协程的数量
var childCount = targetObject.transform.childCount;
var completedChildren = 0;
var allChildrenExpanded = false;
// 遍历目标对象的所有子对象
@@ -278,121 +303,35 @@ namespace SceneView
childNode.transform.SetParent(childRectTransform, false);
childNode.parent = this;
childNode.CreateUI();
StartCoroutine(childNode.DisplayGameObjectStructureCoroutine(childTransform.gameObject, depth + 1, () =>
{
completedChildren++;
if (completedChildren == childCount)
StartCoroutine(childNode.DisplayGameObjectStructureCoroutineImpl(childTransform.gameObject, depth + 1,
() =>
{
allChildrenExpanded = true;
}
}));
completedChildren++;
if (completedChildren == childCount) allChildrenExpanded = true;
}));
yield return null;
}
// 等待所有子协程完成
while (!allChildrenExpanded && childCount > 0)
{
yield return null;
}
while (!allChildrenExpanded && childCount > 0) yield return null;
// 调用完成回调
onComplete?.Invoke();
// 在所有子节点初始化完毕后调用Expand
Expand();
}
public IEnumerator DisplayGameObjectStructureCoroutine(GameObject targetObject, int depth,
System.Action onComplete)
public IEnumerator DisplayGameObjectStructureCoroutine(GameObject targetObject, int depth = 0)
{
if (targetObject == null)
{
Debug.LogError("Target object is null.");
yield break;
}
ClearChildNodes();
originalText = GetIndentedName(targetObject.name, depth);
if (text != null) text.text = originalText;
objectEnable.onClick.AddListener(() => OnObjectEnable(targetObject, objectEnable, objectText));
UpdateObjButton(targetObject,objectEnable,objectText);
var components = targetObject.GetComponents<Behaviour>();
foreach (var component in components)
{
if (childRectTransform == null)
{
Debug.LogError("childRectTransform is null");
continue;
}
var config = ButtonConfig.Default;
config.RectConfig.SizeDelta = new Vector2(0, 40);
config.BackgroundColor = Color.green;
config.Text = new string(' ', (depth + 1) * 2) + component.GetType().Name;
var buttonBack = ControlUtilities.CreateButton(childRectTransform, config, null);
if (buttonBack.button == null)
{
Debug.LogError("buttonBack.button is null");
continue;
}
var button = buttonBack.button;
var comp = component;
buttonBack.button.onClick.AddListener(() => OnButtonClick(button, comp));
yield return null;
}
// 计数器,用于跟踪子协程的数量
var childCount = targetObject.transform.childCount;
var completedChildren = 0;
var allChildrenExpanded = false;
// 遍历目标对象的所有子对象
foreach (Transform childTransform in targetObject.transform)
{
if (childTransform == null)
{
Debug.LogError("Child transform is null.");
continue;
}
var childNode = new GameObject($"{childTransform.gameObject.name}").AddComponent<TreeViewNode>();
childNode.transform.SetParent(childRectTransform, false);
childNode.parent = this;
childNode.CreateUI();
StartCoroutine(childNode.DisplayGameObjectStructureCoroutine(childTransform.gameObject, depth + 1, () =>
{
completedChildren++;
if (completedChildren == childCount)
{
allChildrenExpanded = true;
}
}));
yield return null;
}
// 等待所有子协程完成
while (!allChildrenExpanded && childCount > 0)
{
yield return null;
}
// 在所有子节点初始化完毕后调用Expand
Expand();
// 调用完成回调
onComplete?.Invoke();
yield return DisplayGameObjectStructureCoroutineImpl(targetObject, depth);
}
private string GetIndentedName(string name, int depth)
{
var indent = "";
for (int i = 0; i < depth; i++)
{
indent += $"{i}_";
}
for (var i = 0; i < depth; i++) indent += $"{i}_";
return $"{indent}_{name}";
}
@@ -400,9 +339,7 @@ namespace SceneView
{
if (childRectTransform != null)
foreach (Transform childRectTransform in this.childRectTransform)
{
Destroy(childRectTransform.gameObject);
}
}
private void OnButtonClick(Button button, Behaviour component)
@@ -447,4 +384,4 @@ namespace SceneView
}
}
}
}
}

View File

@@ -0,0 +1,59 @@
{
"runtimeTarget": {
"name": ".NETStandard,Version=v2.1/",
"signature": ""
},
"compilationOptions": {},
"targets": {
".NETStandard,Version=v2.1": {},
".NETStandard,Version=v2.1/": {
"SceneView/1.0.0": {
"dependencies": {
"Lib.Harmony": "2.4.1"
},
"runtime": {
"SceneView.dll": {}
}
},
"Lib.Harmony/2.4.1": {
"dependencies": {
"Lib.Harmony.Ref": "2.4.1"
}
},
"Lib.Harmony.Ref/2.4.1": {
"dependencies": {
"System.Reflection.Emit": "4.7.0"
}
},
"System.Reflection.Emit/4.7.0": {}
}
},
"libraries": {
"SceneView/1.0.0": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Lib.Harmony/2.4.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-iLTZi/kKKB18jYEIwReZSx2xXyVUh4J1swReMgvYBBBn4tzA1Nd0PJlVyntY5BDdSiXSxzmvjc/3OYfFs0YwFg==",
"path": "lib.harmony/2.4.1",
"hashPath": "lib.harmony.2.4.1.nupkg.sha512"
},
"Lib.Harmony.Ref/2.4.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-+u1y2Qd6OlSUQ8JtrsrSo3adnAsrXMJ2YPYtbW+FAmdPI5yw34M9VX4bKl8ZwRuUzaGzZIz+oGMbn/yS4fWtZw==",
"path": "lib.harmony.ref/2.4.1",
"hashPath": "lib.harmony.ref.2.4.1.nupkg.sha512"
},
"System.Reflection.Emit/4.7.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VR4kk8XLKebQ4MZuKuIni/7oh+QGFmZW3qORd1GvBq/8026OpW501SzT/oypwiQl4TvT8ErnReh/NzY9u+C6wQ==",
"path": "system.reflection.emit/4.7.0",
"hashPath": "system.reflection.emit.4.7.0.nupkg.sha512"
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("SceneView")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("SceneView")]
[assembly: System.Reflection.AssemblyTitleAttribute("SceneView")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
aa136efc39beffbdc5220893902c448939a7627fda773846b8971cca38a3094b
7e4b3c1896ce345529a3ca0711584a8ab9f12be839135a3c4656f53b3d28a5be

View File

@@ -0,0 +1 @@
a2305db3c7869002bc53a6604393fdb225ceea5eb527fd1d1fb55448749af9b8

View File

@@ -0,0 +1,11 @@
D:\vs_project\DuckovMods\SceneView\bin\Debug\SceneView.deps.json
D:\vs_project\DuckovMods\SceneView\bin\Debug\SceneView.dll
D:\vs_project\DuckovMods\SceneView\bin\Debug\SceneView.pdb
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.csproj.AssemblyReference.cache
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.GeneratedMSBuildEditorConfig.editorconfig
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.AssemblyInfoInputs.cache
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.AssemblyInfo.cs
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.csproj.CoreCompileInputs.cache
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.sourcelink.json
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.dll
D:\vs_project\DuckovMods\SceneView\obj\Debug\SceneView.pdb

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
{"documents":{"D:\\vs_project\\DuckovMods\\*":"https://raw.githubusercontent.com/thisMiniBox/DuckovMods/9b9121897387fa7e2a57d76690a2a9ae848b1705/*"}}

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("SceneView")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("SceneView")]
[assembly: System.Reflection.AssemblyTitleAttribute("SceneView")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
e56036f0838e710ef74c4ebdd97d630a82ce4f293e0f56fdc74ce4c87f1ae5a4
9dcd4440d4aa7a199613e1563c8a1068a059ca6f9405861608a0463720b13e15

View File

@@ -1 +1 @@
2db483d989a5a869a86b32f19fd026cf473776d04114d97e11aed9c79ee12fd1
6169cbd5ed75cdad38ad928862fe0e8f03b1f1fbf4633591344ee6ab75a60dd5

Binary file not shown.

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Theme")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("Theme")]
[assembly: System.Reflection.AssemblyTitleAttribute("Theme")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
68f3d72038da889633db00efa4248f997c4c5eec6abc2a23beccb75352aa13bf
b705ea625fe66cf9b710de3b0b048b285053215fccc8e6ceba581ffba05eb190

View File

@@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Theme")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("Theme")]
[assembly: System.Reflection.AssemblyTitleAttribute("Theme")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
d4aae129f1e6fc18b1d2a9efecf68c3e4c2b9a7190c20b36eb059e8eaa3c965b
565a731aa7d620581c49efa1c98e11aab47b6a0d864832f0fac598d05b37c6a1

View File

@@ -1,7 +1,9 @@
using Duckov.UI;
using Duckov.Utilities;
using SodaCraft.Localizations;
using TMPro;
using UIFrame.Utilities;
using UIFrameAPI;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
@@ -13,6 +15,12 @@ namespace UIFrame
// public SpriteRenderer? title;
// public TMP_Text[]? allTexts;
public static Sprite? titleSprite=null;
// public static Vector3? titleLocalPosition=null;
public static TransformConfig titleTransform =new TransformConfig();
public static string? titleText=null;
// public static Vector3? titleTextLocalPosition=null;
public static TransformConfig titleTextTransform = new TransformConfig();
// public void Initialize()
@@ -66,5 +74,23 @@ namespace UIFrame
// title.sprite = texture;
return true;
}
public bool SetTitleLocalPosition(Vector3 position)
{
titleTransform.Position = position;
return true;
}
public bool SetTitleText(string text)
{
// titleText = text;
LocalizationManager.SetOverrideText("Title_PressToContinue", text);
return true;
}
public bool SetTitleTextPosition(Vector3 position)
{
titleTextTransform.Position = position;
return true;
}
}
}

View File

@@ -20,6 +20,7 @@ namespace UIFrame
private void Start()
{
}
protected override void OnAfterSetup()
@@ -62,14 +63,10 @@ namespace UIFrame
{
if(!UIFrameAPI.Initialize())
return;
if (UIFrameAPI.SetGameTitle(@"C:\Users\Lenovo\Pictures\异噬.png"))
{
Debug.Log("设置标题完成");
}
else
{
Debug.Log("标题设置失败");
}
UIFrameAPI.SetGameTitle(@"D:\doc\植物大战僵尸贴图\images\ad\Logo.png");
// UIFrameAPI.SetGameTitlePosition(Vector3.zero);
UIFrameAPI.SetGameTitleText("开始冒险");
}
}
}

View File

@@ -1,33 +1,43 @@
using HarmonyLib;
using SodaCraft.Localizations;
using System.Reflection;
using System.Reflection;
using UnityEngine;
namespace UIFrame.Patch
{
[HarmonyPatch(typeof(SpriteRendererLocalizor), "Refresh")]
public class PatchSpriteRendererLocalizorRefresh
public static class PatchSpriteRendererLocalizorRefresh
{
private static FieldInfo spriteRendererField = AccessTools.Field(typeof(SpriteRendererLocalizor), "spriteRenderer");
public static void Postfix(SpriteRendererLocalizor __instance)
{
if (GameOriginMainMenuUI.titleSprite != null && spriteRendererField != null)
try
{
SpriteRenderer targetSpriteRenderer = spriteRendererField.GetValue(__instance) as SpriteRenderer;
if (spriteRendererField == null)
{
Debug.LogError("Field 'spriteRenderer' not found in SpriteRendererLocalizor.");
return;
}
if (targetSpriteRenderer != null)
var targetSpriteRenderer = spriteRendererField.GetValue(__instance) as SpriteRenderer;
if (targetSpriteRenderer == null)
{
Debug.LogError("Target SpriteRenderer is null.");
return;
}
if (GameOriginMainMenuUI.titleSprite != 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?");
Utilities.ConfigApply.ApplyOverwrite(targetSpriteRenderer.transform,
GameOriginMainMenuUI.titleTransform);
}
catch (System.Exception ex)
{
Debug.LogError($"An error occurred in PatchSpriteRendererLocalizorRefresh: {ex.Message}");
}
}
}

View File

@@ -0,0 +1,48 @@
using HarmonyLib;
using SodaCraft.Localizations;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
namespace UIFrame.Patch
{
[HarmonyPatch(typeof(TextLocalizor), "RefreshTexts")]
public static class PatchTextLocalizorRefreshTexts
{
private static readonly FieldInfo tmpTextField = AccessTools.Field(typeof(TextLocalizor), "tmpText");
private static readonly FieldInfo textField = AccessTools.Field(typeof(TextLocalizor), "text");
public static void Postfix(TextLocalizor __instance)
{
try
{
var tmpText = tmpTextField.GetValue(__instance) as TMP_Text;
var text = textField.GetValue(__instance) as Text;
if (tmpText)
{
// if (GameOriginMainMenuUI.titleText != null)
// tmpText.text = GameOriginMainMenuUI.titleText;
Utilities.ConfigApply.ApplyOverwrite(tmpText.transform, GameOriginMainMenuUI.titleTextTransform);
}
if (text)
{
// if (GameOriginMainMenuUI.titleText != null)
// text.text = GameOriginMainMenuUI.titleText;
Utilities.ConfigApply.ApplyOverwrite(text.transform, GameOriginMainMenuUI.titleTextTransform);
}
}
catch (System.Exception ex)
{
Debug.LogError($"Error in PatchTextLocalizorRefreshTexts: {ex.Message}\n{ex.StackTrace}");
}
}
public static bool Prefix(TextLocalizor __instance)
{
Debug.Log($"{__instance.Key}");
return true;
}
}
}

View File

@@ -45,11 +45,26 @@ namespace UIFrame
/// 设置标题图片游戏中的启动界面Logo
/// </summary>
/// <param name="sprite">贴图</param>
/// <returns>返回false表示函数调用时设置失败之后会自动再次尝试设置</returns>
/// <returns></returns>
public static bool SetGameTitle(Sprite sprite)
{
return _apiComponent&&_apiComponent.SetTitleImage(sprite);
}
public static bool SetGameTitlePosition(Vector3 position)
{
return _apiComponent && _apiComponent.SetTitlePosition(position);
}
public static bool SetGameTitleText(string text)
{
return _apiComponent && _apiComponent.SetTitleText(text);
}
public static bool SetGameTitleTextPosition(Vector3 position)
{
return _apiComponent&&_apiComponent.SetTitleTextPosition(position);
}
/// <summary>
/// 加载图片文件为Texture2D
@@ -97,4 +112,6 @@ namespace UIFrame
}
}
}

View File

@@ -3,12 +3,21 @@ using UnityEngine;
namespace UIFrameAPI
{
public struct TransformConfig
{
public Vector3? Position;
public Quaternion? Rotation;
public Vector3? Scale;
}
public abstract class UIFrameAPIComponent:MonoBehaviour
{
// public abstract bool CreateCanvas(string name);
//设置游戏主菜单的原版标题
public abstract bool SetTitleImage(Sprite sprite);
public abstract bool SetTitleText(string text);
public abstract bool SetTitlePosition(Vector3 position);
public abstract bool SetTitleTextPosition(Vector3 position);
// //创建一个TMP字体
// public abstract TMP_FontAsset CreateFontAsset(string fontFilePath);

View File

@@ -30,6 +30,21 @@ namespace UIFrame
return gameOriginMainMenuUI.SetTitle(sprite);
}
public override bool SetTitleText(string text)
{
return gameOriginMainMenuUI.SetTitleText(text);
}
public override bool SetTitlePosition(Vector3 position)
{
return gameOriginMainMenuUI.SetTitleLocalPosition(position);
}
public override bool SetTitleTextPosition(Vector3 position)
{
return gameOriginMainMenuUI.SetTitleTextPosition(position);
}
// public override TMP_FontAsset CreateFontAsset(string fontFilePath)
// {

View File

@@ -0,0 +1,41 @@
using UIFrameAPI;
using UnityEngine;
namespace UIFrame.Utilities
{
public class ConfigApply
{
// 累积应用 TransformConfig 到 Transform
public static void ApplyCumulatively(Transform transform, TransformConfig config)
{
if (config.Position.HasValue)
{
transform.position += config.Position.Value;
}
if (config.Rotation.HasValue)
{
transform.rotation *= config.Rotation.Value;
}
if (config.Scale.HasValue)
{
transform.localScale += config.Scale.Value;
}
}
// 覆盖应用 TransformConfig 到 Transform
public static void ApplyOverwrite(Transform transform, TransformConfig config)
{
if (config.Position.HasValue)
{
transform.position = config.Position.Value;
}
if (config.Rotation.HasValue)
{
transform.rotation = config.Rotation.Value;
}
if (config.Scale.HasValue)
{
transform.localScale = config.Scale.Value;
}
}
}
}

View File

@@ -0,0 +1,799 @@
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace UIFrame.Utilities
{
[Serializable]
public struct RectTransformConfig
{
public Vector2 AnchorMin;
public Vector2 AnchorMax;
public Vector2 AnchoredPosition;
public Vector2 SizeDelta;
public Vector2 OffsetMin;
public Vector2 OffsetMax;
public Vector2 Pivot;
// 默认配置
public static readonly RectTransformConfig Default = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.up, // 锚点最大:左上角 (0, 1)
Vector2.zero,
Vector2.zero,
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f) // 默认居中轴心点
);
// 填充父级的配置
public static readonly RectTransformConfig FillParent = new RectTransformConfig(
Vector2.zero, // 锚点最小:左下角 (0, 0)
Vector2.one, // 锚点最大:右上角 (1, 1)
Vector2.zero,
Vector2.zero, // sizeDelta为零表示通过offsetMin/Max来控制尺寸
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
);
public RectTransformConfig(
Vector2 anchorMin,
Vector2 anchorMax,
Vector2 anchoredPosition,
Vector2 sizeDelta,
Vector2 offsetMin,
Vector2 offsetMax,
Vector2 pivot)
{
AnchorMin = anchorMin;
AnchorMax = anchorMax;
AnchoredPosition = anchoredPosition;
SizeDelta = sizeDelta;
OffsetMin = offsetMin;
OffsetMax = offsetMax;
Pivot = pivot;
}
}
[Serializable]
public struct ButtonConfig
{
public RectTransformConfig RectConfig;
public Color BackgroundColor;
public string Text;
public int FontSize;
public Color TextColor;
public bool RaycastTarget;
public static readonly ButtonConfig Default = new ButtonConfig(
RectTransformConfig.Default,
new Color(0.2f, 0.2f, 0.2f, 1f),
"Button",
18,
Color.white,
true
);
public ButtonConfig(
RectTransformConfig rectConfig,
Color backgroundColor,
string text,
int fontSize,
Color textColor,
bool raycastTarget = true)
{
RectConfig = rectConfig;
BackgroundColor = backgroundColor;
Text = text;
FontSize = fontSize;
TextColor = textColor;
RaycastTarget = raycastTarget;
}
}
[Serializable]
public struct TextConfig
{
public RectTransformConfig RectConfig;
public string Text;
public int FontSize;
public Color TextColor;
public TextAlignmentOptions Alignment;
public bool RaycastTarget;
public static readonly TextConfig Default = new TextConfig(
rectConfig: RectTransformConfig.Default,
text: "New Text",
fontSize: 18,
textColor: Color.white,
alignment: TextAlignmentOptions.Center,
raycastTarget: false
);
public TextConfig(
string text,
int fontSize,
Color textColor,
TextAlignmentOptions alignment,
bool raycastTarget,
RectTransformConfig rectConfig)
{
RectConfig = rectConfig;
Text = text;
FontSize = fontSize;
TextColor = textColor;
Alignment = alignment;
RaycastTarget = raycastTarget;
}
}
[Serializable]
public struct ScrollViewConfig
{
public RectTransformConfig RectConfig; // 新增ScrollView自身的RectTransform配置
public bool Vertical;
public bool Horizontal;
public Color BackgroundColor;
public Vector2 ContentPadding; // 内容区域的内边距(上下左右)
public static readonly ScrollViewConfig Default = new ScrollViewConfig
{
RectConfig = new RectTransformConfig(
new Vector2(0.5f, 0.5f), // 锚点最小:中心 (0.5, 0.5)
new Vector2(0.5f, 0.5f), // 锚点最大:中心 (0.5, 0.5)
Vector2.zero,
new Vector2(400, 300), // 默认尺寸
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
),
Vertical = true,
Horizontal = false,
BackgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.8f),
ContentPadding = new Vector2(10, 10) // (horizontal, vertical)
};
}
[Serializable]
public struct InputFieldConfig
{
public RectTransformConfig RectConfig;
public Color BackgroundColor;
public string PlaceholderText;
public int PlaceholderFontSize;
public Color PlaceholderTextColor;
public Color TextColor;
public int FontSize;
public TextAlignmentOptions TextAlignment;
public TMP_InputField.CharacterValidation CharacterValidation;
public int CharacterLimit;
public static readonly InputFieldConfig Default = new InputFieldConfig(
RectTransformConfig.Default,
new Color(0.2f, 0.2f, 0.2f, 1f),
"Enter text here",
14,
new Color(0.7f, 0.7f, 0.7f, 1f),
Color.white,
18,
TextAlignmentOptions.Left,
TMP_InputField.CharacterValidation.None,
0
);
public InputFieldConfig(
RectTransformConfig rectConfig,
Color backgroundColor,
string placeholderText,
int placeholderFontSize,
Color placeholderTextColor,
Color textColor,
int fontSize,
TextAlignmentOptions textAlignment,
TMP_InputField.CharacterValidation characterValidation = TMP_InputField.CharacterValidation.None,
int characterLimit = 0)
{
RectConfig = rectConfig;
BackgroundColor = backgroundColor;
PlaceholderText = placeholderText;
PlaceholderFontSize = placeholderFontSize;
PlaceholderTextColor = placeholderTextColor;
TextColor = textColor;
FontSize = fontSize;
TextAlignment = textAlignment;
CharacterValidation = characterValidation;
CharacterLimit = characterLimit;
}
}
[Serializable]
public struct LabeledInputFieldConfig
{
public RectTransformConfig RectConfig; // 整个控件(标签+输入框)的配置
public string LabelText;
public int LabelFontSize;
public Color LabelTextColor;
public float LabelWidth; // 标签部分的固定宽度
public float Spacing; // 标签和输入框之间的间距
public InputFieldConfig InputFieldConfig; // 复用已有的输入框配置
public static readonly LabeledInputFieldConfig Default = new LabeledInputFieldConfig
{
RectConfig = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.one, // 锚点最大:右上角 (1, 1),默认水平拉伸
Vector2.zero,
new Vector2(0, 30), // 默认高度30
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 1) // 轴心点:顶部居中
),
LabelText = "Label",
LabelFontSize = 18,
LabelTextColor = Color.white,
LabelWidth = 100f,
Spacing = 10f,
InputFieldConfig = InputFieldConfig.Default
};
}
[Serializable]
public struct DropdownConfig
{
public RectTransformConfig RectConfig;
public List<string> Options;
public Color BackgroundColor;
public int CaptionFontSize; // 下拉框当前选中项的文本大小
public Color CaptionTextColor;
public int ItemFontSize; // 下拉列表每一项的文本大小
public Color ItemTextColor;
public static readonly DropdownConfig Default = new DropdownConfig(
new RectTransformConfig(
new Vector2(0.5f, 0.5f), // 锚点最小:中心 (0.5, 0.5)
new Vector2(0.5f, 0.5f), // 锚点最大:中心 (0.5, 0.5)
Vector2.zero,
new Vector2(160, 30),
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
),
new List<string> { "Option A", "Option B", "Option C" },
new Color(0.2f, 0.2f, 0.2f, 1f),
18,
Color.white,
16,
Color.white
);
public DropdownConfig(RectTransformConfig rectConfig, List<string> options, Color backgroundColor,
int captionFontSize, Color captionTextColor, int itemFontSize, Color itemTextColor)
{
RectConfig = rectConfig;
Options = options;
BackgroundColor = backgroundColor;
CaptionFontSize = captionFontSize;
CaptionTextColor = captionTextColor;
ItemFontSize = itemFontSize;
ItemTextColor = itemTextColor;
}
}
[Serializable]
public struct LabeledDropdownConfig
{
public RectTransformConfig RectConfig;
public string LabelText;
public int LabelFontSize;
public Color LabelTextColor;
public float LabelWidth;
public float Spacing;
public DropdownConfig DropdownConfig;
public static readonly LabeledDropdownConfig Default = new LabeledDropdownConfig
{
RectConfig = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.one, // 锚点最大:右上角 (1, 1)
Vector2.zero,
new Vector2(0, 30),
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 1)
),
LabelText = "Label",
LabelFontSize = 18,
LabelTextColor = Color.white,
LabelWidth = 100f,
Spacing = 10f,
DropdownConfig = DropdownConfig.Default
};
}
[Serializable]
public struct ToggleConfig
{
public RectTransformConfig RectConfig;
public string LabelText;
public int LabelFontSize;
public Color LabelTextColor;
public Color BackgroundColor;
public Color CheckmarkColor;
public float Spacing; // 开关图形和标签之间的间距
public bool IsOnByDefault;
public static readonly ToggleConfig Default = new ToggleConfig
{
RectConfig = new RectTransformConfig(
Vector2.up, // 锚点最小:左上角 (0, 1)
Vector2.up, // 锚点最大:左上角 (0, 1)
Vector2.zero,
new Vector2(160, 20),
Vector2.zero,
Vector2.zero,
new Vector2(0.5f, 0.5f)
),
LabelText = "Toggle",
LabelFontSize = 18,
LabelTextColor = Color.white,
BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f),
CheckmarkColor = new Color(0.1f, 0.6f, 1f, 1f),
Spacing = 10f,
IsOnByDefault = false
};
}
public static class ControlUtilities
{
// 通用方法:将 RectTransformConfig 应用于 RectTransform
private static void ApplyRectTransformConfig(RectTransform rectTransform, RectTransformConfig config)
{
rectTransform.anchorMin = config.AnchorMin;
rectTransform.anchorMax = config.AnchorMax;
rectTransform.pivot = config.Pivot;
// 当sizeDelta为Vector2.zero时我们假定用户希望通过offsetMin/Max来拉伸元素
// 否则使用anchoredPosition和sizeDelta来定位和设置尺寸
if (config.SizeDelta == Vector2.zero && (config.OffsetMin != Vector2.zero ||
config.OffsetMax != Vector2.zero ||
(config.AnchorMin == Vector2.zero &&
config.AnchorMax == Vector2.one)))
{
rectTransform.offsetMin = config.OffsetMin;
rectTransform.offsetMax = config.OffsetMax;
}
else
{
rectTransform.anchoredPosition = config.AnchoredPosition;
rectTransform.sizeDelta = config.SizeDelta;
}
}
// ========================
// 矩形对象创建
// ========================
/// <summary>
/// 创建一个带有 RectTransform 组件的空 GameObject。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="name">GameObject 的名称。</param>
/// <param name="config">RectTransform 的配置。</param>
/// <returns>创建的 RectTransform 组件。</returns>
public static RectTransform CreateRect(Transform parent, string name, RectTransformConfig config)
{
var obj = new GameObject(name);
var rect = obj.AddComponent<RectTransform>();
rect.SetParent(parent, false); // false表示不保留世界坐标而是以父级为基准
ApplyRectTransformConfig(rect, config);
return rect;
}
// ========================
// 按钮创建
// ========================
public static (Button? button, TextMeshProUGUI? text) CreateButton(RectTransform? parent, ButtonConfig config,
UnityAction? onClick)
{
// 使用 CreateRect 创建按钮根对象并应用配置
var btnRect = CreateRect(parent, config.Text + "Button", config.RectConfig);
var button = btnRect.gameObject.AddComponent<Button>();
var image = btnRect.gameObject.AddComponent<Image>();
image.color = config.BackgroundColor;
button.image = image;
// 创建文本子对象,并使其填充按钮
var txtRect = CreateRect(btnRect, "Text (TMP)", RectTransformConfig.FillParent);
var tmpText = txtRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = config.Text;
tmpText.color = config.TextColor;
tmpText.alignment = TextAlignmentOptions.Center;
tmpText.fontSize = config.FontSize;
tmpText.raycastTarget = config.RaycastTarget; // 文本RaycastTarget通常为false除非文本本身需要互动
if (onClick != null)
button.onClick.AddListener(onClick);
return (button, tmpText);
}
// ========================
// 文本创建(重载)
// ========================
public static TextMeshProUGUI CreateText(Transform parent, string text)
{
var config = TextConfig.Default;
config.Text = text;
return CreateText(parent, config);
}
public static TextMeshProUGUI CreateText(Transform parent, TextConfig config)
{
// 使用 CreateRect 创建文本对象并应用配置
var textRect = CreateRect(parent, config.Text + "Text", config.RectConfig);
var tmpText = textRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = config.Text;
tmpText.color = config.TextColor;
tmpText.alignment = config.Alignment;
tmpText.fontSize = config.FontSize;
tmpText.raycastTarget = config.RaycastTarget;
return tmpText;
}
// ========================
// 滚动视图创建
// ========================
public static (ScrollRect scrollRect, RectTransform content) CreateScrollView(
Transform parent,
ScrollViewConfig config)
{
// 1. ScrollView 根对象
var scrollViewRect = CreateRect(parent, "ScrollView", config.RectConfig);
var scrollView = scrollViewRect.gameObject.AddComponent<ScrollRect>();
var scrollViewImage = scrollViewRect.gameObject.AddComponent<Image>();
scrollViewImage.color = config.BackgroundColor;
scrollViewImage.raycastTarget = true;
// 2. Viewport 子对象 (始终填充 ScrollView)
var viewportRect = CreateRect(scrollViewRect, "Viewport", RectTransformConfig.FillParent);
viewportRect.gameObject.AddComponent<RectMask2D>(); // 或 Mask但 RectMask2D 性能更好
var viewportImage = viewportRect.gameObject.AddComponent<Image>();
viewportImage.color = Color.clear; // 透明背景
// 3. Content 子对象
var contentRect =
CreateRect(viewportRect, "Content", RectTransformConfig.Default); // 初始使用Default后续会根据滚动方向调整
// 设置 Content 的锚点:根据滚动方向决定
if (config.Vertical && !config.Horizontal)
{
// 垂直滚动:宽度拉满,高度自适应
contentRect.anchorMin = new Vector2(0, 1);
contentRect.anchorMax = new Vector2(1, 1);
contentRect.pivot = new Vector2(0.5f, 1);
contentRect.anchoredPosition = new Vector2(0, -config.ContentPadding.y);
contentRect.sizeDelta = new Vector2(-2 * config.ContentPadding.x, 0); // 左右留边距
// 添加 VerticalLayoutGroup 通常是需要的,但这里只创建基础结构
}
else if (config.Horizontal && !config.Vertical)
{
// 水平滚动:高度拉满,宽度自适应
contentRect.anchorMin = new Vector2(0, 0);
contentRect.anchorMax = new Vector2(0, 1);
contentRect.pivot = new Vector2(0, 0.5f);
contentRect.anchoredPosition = new Vector2(config.ContentPadding.x, 0);
contentRect.sizeDelta = new Vector2(0, -2 * config.ContentPadding.y);
// 添加 HorizontalLayoutGroup 通常是需要的
}
else
{
// 双向滚动:自由布局,通常锚点设为左上角
contentRect.anchorMin = new Vector2(0, 1);
contentRect.anchorMax = new Vector2(0, 1);
contentRect.pivot = new Vector2(0, 1);
contentRect.anchoredPosition = new Vector2(config.ContentPadding.x, -config.ContentPadding.y);
contentRect.sizeDelta = new Vector2(0, 0); // 自适应
}
// 4. 关联 ScrollRect
scrollView.viewport = viewportRect;
scrollView.content = contentRect;
scrollView.vertical = config.Vertical;
scrollView.horizontal = config.Horizontal;
scrollView.movementType = ScrollRect.MovementType.Elastic;
scrollView.inertia = true;
scrollView.decelerationRate = 0.135f; // 默认值
return (scrollView, contentRect);
}
// ========================
// 文本编辑器创建
// ========================
public static (TMP_InputField inputField, TextMeshProUGUI text) CreateInputField(Transform parent,
InputFieldConfig config)
{
// 使用 CreateRect 创建输入框根对象并应用配置
var inputFieldRect = CreateRect(parent, "InputField", config.RectConfig);
var inputField = inputFieldRect.gameObject.AddComponent<TMP_InputField>();
// 背景图像
var backgroundImage = inputFieldRect.gameObject.AddComponent<Image>();
// 注意Resources.Load 会在运行时加载,推荐通过 Inspector 赋值或使用 Addressables
// 为了保持原有功能暂时保留如果提示找不到请确保路径正确或导入默认UI资源
backgroundImage.sprite = Resources.Load<Sprite>("UI/Skins/Background");
backgroundImage.type = Image.Type.Sliced;
backgroundImage.color = config.BackgroundColor;
inputField.image = backgroundImage; // 设置TMP_InputField的图片引用
// 输入框文本组件 (始终填充输入框)
var textRect = CreateRect(inputFieldRect, "Text (TMP)", RectTransformConfig.FillParent);
var tmpText = textRect.gameObject.AddComponent<TextMeshProUGUI>();
tmpText.text = "";
tmpText.color = config.TextColor;
tmpText.alignment = config.TextAlignment;
tmpText.fontSize = config.FontSize;
tmpText.raycastTarget = false; // 输入框内的文本通常不需要射线检测
inputField.textComponent = tmpText; // 设置TMP_InputField的文字组件引用
// 占位符文本组件 (始终填充输入框)
var placeholderRect = CreateRect(inputFieldRect, "Placeholder", RectTransformConfig.FillParent);
var placeholderText = placeholderRect.gameObject.AddComponent<TextMeshProUGUI>();
placeholderText.text = config.PlaceholderText;
placeholderText.color = config.PlaceholderTextColor;
placeholderText.alignment = config.TextAlignment;
placeholderText.fontSize = config.PlaceholderFontSize;
placeholderText.raycastTarget = false; // 占位符通常不需要射线检测
inputField.placeholder = placeholderText; // 设置TMP_InputField的占位符引用
// 配置输入字段属性
inputField.characterValidation = config.CharacterValidation;
inputField.characterLimit = config.CharacterLimit;
return (inputField, tmpText);
}
/// <summary>
/// 创建一个网格布局容器,用于自动排列子对象。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="name">GameObject 名称。</param>
/// <param name="rectConfig">容器的 RectTransform 配置。</param>
/// <param name="constraintCount">每行或每列的元素数量。</param>
/// <param name="cellSize">每个单元格的大小。</param>
/// <param name="spacing">单元格之间的间距。</param>
/// <param name="constraint">约束类型(按行数或列数)。</param>
/// <returns>创建的网格容器的 RectTransform。</returns>
public static RectTransform CreateGridLayoutContainer(
Transform parent,
string name,
RectTransformConfig rectConfig,
int constraintCount,
Vector2 cellSize,
Vector2 spacing,
GridLayoutGroup.Constraint constraint = GridLayoutGroup.Constraint.FixedColumnCount)
{
var containerRect = CreateRect(parent, name, rectConfig);
var gridLayout = containerRect.gameObject.AddComponent<GridLayoutGroup>();
gridLayout.constraint = constraint;
if (constraint == GridLayoutGroup.Constraint.FixedColumnCount)
gridLayout.constraintCount = constraintCount;
else if (constraint == GridLayoutGroup.Constraint.FixedRowCount)
gridLayout.constraintCount = constraintCount;
gridLayout.cellSize = cellSize;
gridLayout.spacing = spacing;
return containerRect;
}
/// <summary>
/// 创建一个带标签的输入框(左边文字,右边输入)。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含根对象、标签和输入框的元组。</returns>
public static (RectTransform root, TextMeshProUGUI label, TMP_InputField inputField) CreateLabeledInputField(
Transform parent, LabeledInputFieldConfig config)
{
// 1. 创建根容器并添加水平布局
var rootRect = CreateRect(parent, config.LabelText + " LabeledInput", config.RectConfig);
var layoutGroup = rootRect.gameObject.AddComponent<HorizontalLayoutGroup>();
layoutGroup.childControlWidth = true;
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandWidth = false;
layoutGroup.spacing = config.Spacing;
// 2. 创建标签
var labelConfig = new TextConfig(
config.LabelText,
config.LabelFontSize,
config.LabelTextColor,
TextAlignmentOptions.Left,
false,
RectTransformConfig.Default // RectTransform由LayoutGroup控制
);
var label = CreateText(rootRect, labelConfig);
var labelLayout = label.gameObject.AddComponent<LayoutElement>();
labelLayout.preferredWidth = config.LabelWidth;
labelLayout.flexibleWidth = 0; // 不参与弹性宽度分配
// 3. 创建输入框
var (inputField, _) = CreateInputField(rootRect, config.InputFieldConfig);
var inputLayout = inputField.gameObject.AddComponent<LayoutElement>();
inputLayout.flexibleWidth = 1; // 占据剩余所有宽度
return (rootRect, label, inputField);
}
/// <summary>
/// 创建一个下拉框控件。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含下拉框组件和其主标签的元组。</returns>
public static (TMP_Dropdown dropdown, TextMeshProUGUI captionText) CreateDropdown(Transform parent,
DropdownConfig config)
{
// Unity 从代码创建 Dropdown 比较繁琐,因为它依赖于一个预设的模板结构。
// 以下代码将手动构建这个结构。
// 1. Root Dropdown Object
var dropdownRect = CreateRect(parent, "Dropdown", config.RectConfig);
var dropdownImage = dropdownRect.gameObject.AddComponent<Image>();
dropdownImage.color = config.BackgroundColor;
var dropdown = dropdownRect.gameObject.AddComponent<TMP_Dropdown>();
// 2. Label (Caption Text)
var labelRect = CreateRect(dropdownRect, "Label", RectTransformConfig.FillParent);
labelRect.offsetMin = new Vector2(10, 0);
labelRect.offsetMax = new Vector2(-25, 0);
var labelText = labelRect.gameObject.AddComponent<TextMeshProUGUI>();
labelText.alignment = TextAlignmentOptions.Left;
labelText.color = config.CaptionTextColor;
labelText.fontSize = config.CaptionFontSize;
dropdown.captionText = labelText;
// 3. Arrow
var arrowRect = CreateRect(dropdownRect, "Arrow", new RectTransformConfig(
new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(-15, 0), new Vector2(20, 20), Vector2.zero,
Vector2.zero, new Vector2(0.5f, 0.5f)
));
var arrowImage = arrowRect.gameObject.AddComponent<Image>();
arrowImage.color = new Color(0.8f, 0.8f, 0.8f); // 默认箭头颜色
// 4. Template (Scroll View, the dropdown list) - 必须默认禁用
var templateRect = CreateRect(dropdownRect, "Template", new RectTransformConfig(
new Vector2(0, 0), new Vector2(1, 0), new Vector2(0, 2), new Vector2(0, 150), Vector2.zero,
Vector2.zero, new Vector2(0.5f, 1)
));
var templateImage = templateRect.gameObject.AddComponent<Image>();
templateImage.color = config.BackgroundColor;
var scrollRect = templateRect.gameObject.AddComponent<ScrollRect>();
scrollRect.movementType = ScrollRect.MovementType.Clamped;
templateRect.gameObject.SetActive(false);
dropdown.template = templateRect;
// 5. Viewport
var viewportRect = CreateRect(templateRect, "Viewport", RectTransformConfig.FillParent);
viewportRect.gameObject.AddComponent<RectMask2D>();
scrollRect.viewport = viewportRect;
// 6. Content
var contentRect = CreateRect(viewportRect, "Content", new RectTransformConfig(
new Vector2(0, 1), new Vector2(1, 1), Vector2.zero, new Vector2(0, 28), Vector2.zero, Vector2.zero,
new Vector2(0.5f, 1)
));
scrollRect.content = contentRect;
// 7. Item (The template for each option)
var itemRect = CreateRect(contentRect, "Item", new RectTransformConfig(
new Vector2(0, 1), new Vector2(1, 1), Vector2.zero, new Vector2(0, 20), Vector2.zero, Vector2.zero,
new Vector2(0.5f, 1)
));
var itemToggle = itemRect.gameObject.AddComponent<Toggle>();
itemToggle.targetGraphic = itemRect.gameObject.AddComponent<Image>(); // Add an image to be the background
var itemLabelRect = CreateRect(itemRect, "Item Label", RectTransformConfig.FillParent);
itemLabelRect.offsetMin = new Vector2(10, 0);
itemLabelRect.offsetMax = new Vector2(-10, 0);
var itemLabel = itemLabelRect.gameObject.AddComponent<TextMeshProUGUI>();
itemLabel.color = config.ItemTextColor;
itemLabel.fontSize = config.ItemFontSize;
dropdown.itemText = itemLabel;
// 8. Populate options
dropdown.ClearOptions();
dropdown.AddOptions(config.Options);
return (dropdown, labelText);
}
/// <summary>
/// 创建一个带标签的下拉框(左边文字,右边下拉)。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含根对象、标签和下拉框的元组。</returns>
public static (RectTransform root, TextMeshProUGUI label, TMP_Dropdown dropdown) CreateLabeledDropdown(
Transform parent, LabeledDropdownConfig config)
{
// 1. 创建根容器并添加水平布局
var rootRect = CreateRect(parent, config.LabelText + " LabeledDropdown", config.RectConfig);
var layoutGroup = rootRect.gameObject.AddComponent<HorizontalLayoutGroup>();
layoutGroup.childControlWidth = true;
layoutGroup.childControlHeight = true;
layoutGroup.childForceExpandWidth = true;
layoutGroup.spacing = config.Spacing;
// 2. 创建标签
var labelConfig = new TextConfig(
config.LabelText,
config.LabelFontSize,
config.LabelTextColor,
TextAlignmentOptions.Left,
false,
RectTransformConfig.Default
);
var label = CreateText(rootRect, labelConfig);
var labelLayout = label.gameObject.AddComponent<LayoutElement>();
labelLayout.preferredWidth = config.LabelWidth;
labelLayout.flexibleWidth = 0;
// 3. 创建下拉框
var (dropdown, _) = CreateDropdown(rootRect, config.DropdownConfig);
var dropdownLayout = dropdown.gameObject.AddComponent<LayoutElement>();
dropdownLayout.flexibleWidth = 1;
return (rootRect, label, dropdown);
}
/// <summary>
/// 创建一个切换开关控件。
/// </summary>
/// <param name="parent">父级 Transform。</param>
/// <param name="config">控件配置。</param>
/// <returns>包含Toggle组件、标签和勾选标记图像的元组。</returns>
public static (Toggle toggle, TextMeshProUGUI label, Image checkmark) CreateToggle(Transform parent,
ToggleConfig config)
{
// 1. Root Toggle Object
var toggleRect = CreateRect(parent, "Toggle", config.RectConfig);
var toggle = toggleRect.gameObject.AddComponent<Toggle>();
toggle.isOn = config.IsOnByDefault;
// 2. Background
var backgroundRect = CreateRect(toggleRect, "Background", new RectTransformConfig(
new Vector2(0, 0.5f), new Vector2(0, 0.5f), Vector2.zero, new Vector2(20, 20), Vector2.zero,
Vector2.zero, new Vector2(0, 0.5f)
));
var backgroundImage = backgroundRect.gameObject.AddComponent<Image>();
backgroundImage.color = config.BackgroundColor;
toggle.targetGraphic = backgroundImage;
// 3. Checkmark
var checkmarkRect = CreateRect(backgroundRect, "Checkmark", RectTransformConfig.FillParent);
checkmarkRect.offsetMin = new Vector2(3, 3);
checkmarkRect.offsetMax = new Vector2(-3, -3);
var checkmarkImage = checkmarkRect.gameObject.AddComponent<Image>();
checkmarkImage.color = config.CheckmarkColor;
toggle.graphic = checkmarkImage;
// 4. Label
var labelRect = CreateRect(toggleRect, "Label", new RectTransformConfig(
new Vector2(0, 0), new Vector2(1, 1), Vector2.zero, new Vector2(-config.Spacing - 20, 0),
new Vector2(config.Spacing + 20, 0), Vector2.zero, new Vector2(0, 0.5f)
));
var label = labelRect.gameObject.AddComponent<TextMeshProUGUI>();
label.text = config.LabelText;
label.color = config.LabelTextColor;
label.fontSize = config.LabelFontSize;
label.alignment = TextAlignmentOptions.Left;
return (toggle, label, checkmarkImage);
}
}
}

View File

@@ -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+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("UIFrame")]
[assembly: System.Reflection.AssemblyTitleAttribute("UIFrame")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
911460e450d98a36d352c39840be04d55f4d5ae8227da097050ab185b491cbc7
eead11a1c35697f07220b82ac52ad2f4054a2b06624be646cc8f8e7dceec6281

View File

@@ -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+786025f720c05ae486c8c66d3a6114633ccd0dbf")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+9b9121897387fa7e2a57d76690a2a9ae848b1705")]
[assembly: System.Reflection.AssemblyProductAttribute("UIFrame")]
[assembly: System.Reflection.AssemblyTitleAttribute("UIFrame")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -1 +1 @@
d9927e767d78bd001547a17de1674f3773a1c4e78cf329975757d4b609c6bada
266dfc575dfbc47bf568b65a303d0d712ab550e53b7d58f879b06a67eb491c19

View File

@@ -1 +1 @@
0ee34f07c3de41359bb7fcfd63f21e2bd997731e7e65df6cde5e62762235bbce
b33937ce9d03978cf1a7dfad4f7e099a7e539b1feb08ebc5b4ce269ec5d58536

Binary file not shown.