feat:场景视图添加属性编辑,添加轮廓显示
This commit is contained in:
32
CharacterPreview/CharacterPreview.csproj
Normal file
32
CharacterPreview/CharacterPreview.csproj
Normal 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>
|
||||
134
CharacterPreview/ModBehaviour.cs
Normal file
134
CharacterPreview/ModBehaviour.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
53
CharacterPreview/ModelMove.cs
Normal file
53
CharacterPreview/ModelMove.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
13
CharacterPreview/PatchSceneLoaderNotifyPointerClick.cs
Normal file
13
CharacterPreview/PatchSceneLoaderNotifyPointerClick.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
// using HarmonyLib;
|
||||
//
|
||||
// namespace CharacterPreview
|
||||
// {
|
||||
// [HarmonyPatch(typeof(SceneLoader), "NotifyPointerClick")]
|
||||
// public class PatchSceneLoaderNotifyPointerClick
|
||||
// {
|
||||
// public static void Postfix(SceneLoader __instance)
|
||||
// {
|
||||
// ModBehaviour.CreateCharacterModel();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
CharacterPreview/obj/CharacterPreview.csproj.nuget.g.props
Normal file
16
CharacterPreview/obj/CharacterPreview.csproj.nuget.g.props
Normal 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>
|
||||
@@ -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" />
|
||||
@@ -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")]
|
||||
22
CharacterPreview/obj/Debug/CharacterPreview.AssemblyInfo.cs
Normal file
22
CharacterPreview/obj/Debug/CharacterPreview.AssemblyInfo.cs
Normal 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 类生成。
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
3bcd831ea4f29882c4ad0e74553f21cd67857c5ac8ecf673bf0a5c0e6b28519c
|
||||
@@ -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 =
|
||||
BIN
CharacterPreview/obj/Debug/CharacterPreview.assets.cache
Normal file
BIN
CharacterPreview/obj/Debug/CharacterPreview.assets.cache
Normal file
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
c29902ba5d072858998bd0700a0022b61d2b982553e1d41c36961a930ba99211
|
||||
@@ -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
|
||||
BIN
CharacterPreview/obj/Debug/CharacterPreview.dll
Normal file
BIN
CharacterPreview/obj/Debug/CharacterPreview.dll
Normal file
Binary file not shown.
@@ -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")]
|
||||
@@ -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 类生成。
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
cdbee0654e5bd2c9896d77407e3d7ce5ae6183e3f37c36106e534970cbdd063c
|
||||
@@ -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 =
|
||||
BIN
CharacterPreview/obj/Release/CharacterPreview.assets.cache
Normal file
BIN
CharacterPreview/obj/Release/CharacterPreview.assets.cache
Normal file
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
356db5ad935a1120367a47fbf381e8f0de76f293776515bb91fa0b0cadad25c7
|
||||
@@ -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
|
||||
BIN
CharacterPreview/obj/Release/CharacterPreview.dll
Normal file
BIN
CharacterPreview/obj/Release/CharacterPreview.dll
Normal file
Binary file not shown.
@@ -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")]
|
||||
@@ -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 类生成。
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
cdbee0654e5bd2c9896d77407e3d7ce5ae6183e3f37c36106e534970cbdd063c
|
||||
@@ -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 =
|
||||
Binary file not shown.
239
CharacterPreview/obj/project.assets.json
Normal file
239
CharacterPreview/obj/project.assets.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
CharacterPreview/obj/project.nuget.cache
Normal file
12
CharacterPreview/obj/project.nuget.cache
Normal 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": []
|
||||
}
|
||||
1
CharacterPreview/obj/project.packagespec.json
Normal file
1
CharacterPreview/obj/project.packagespec.json
Normal 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"}}
|
||||
1
CharacterPreview/obj/rider.project.model.nuget.info
Normal file
1
CharacterPreview/obj/rider.project.model.nuget.info
Normal file
@@ -0,0 +1 @@
|
||||
17627872868371582
|
||||
1
CharacterPreview/obj/rider.project.restore.info
Normal file
1
CharacterPreview/obj/rider.project.restore.info
Normal file
@@ -0,0 +1 @@
|
||||
17627872868371582
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
5da31913e91a183301e6883819f7ba57fc0b3e4eba9910ae6ee0eafc05d2af54
|
||||
dc9e2512ec7accc32370dea781198b720358eb9814b7c9c591d009607f13a5e8
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
12b8810f5c5efba722348e9a42589fd931584289646df256a80c8a5aac0c67b6
|
||||
71229c5bb112e72727f560fc4c2dcb61c8790b85769f99a1131c10e137989a56
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
011b05448cb33a5df382363baa29281f37b1217de1b772941e072e5e1e318697
|
||||
368a9f7418aefa097e80abe04f0e70d25ca97877e818b633d54a07496a4eb4d6
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
d5e421014b0d794da78442d8a65960e244ed2b8a5d6b7b2541d1354650cfeae5
|
||||
11eb56433e596da88b772bc3383f597712eafe48622740bf0786e8030e13d6e9
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
d0b14bb5a2fe44e4165960f86b2001d300338f5655dddb8b391c1544fb8fcca4
|
||||
993bfd6f35451c9a8b17b20fe9cf49f2468dd9f29516d3ea773a01d0f4d44c33
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
0377007546f92d23941a0c0e6a0cef8c6022db4ce07a6a7b98556714f9c594f1
|
||||
ca1555b48da049a281894ed9d271c1d8ac9ceef6558c6d583a8608bf7fa55818
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
340
SceneView/ParametersPanel.cs
Normal file
340
SceneView/ParametersPanel.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}初始化了");
|
||||
// }
|
||||
// }
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
SceneView/bin/Debug/SceneView.deps.json
Normal file
59
SceneView/bin/Debug/SceneView.deps.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
SceneView/bin/Debug/SceneView.dll
Normal file
BIN
SceneView/bin/Debug/SceneView.dll
Normal file
Binary file not shown.
BIN
SceneView/bin/Debug/SceneView.pdb
Normal file
BIN
SceneView/bin/Debug/SceneView.pdb
Normal file
Binary file not shown.
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
aa136efc39beffbdc5220893902c448939a7627fda773846b8971cca38a3094b
|
||||
7e4b3c1896ce345529a3ca0711584a8ab9f12be839135a3c4656f53b3d28a5be
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
a2305db3c7869002bc53a6604393fdb225ceea5eb527fd1d1fb55448749af9b8
|
||||
11
SceneView/obj/Debug/SceneView.csproj.FileListAbsolute.txt
Normal file
11
SceneView/obj/Debug/SceneView.csproj.FileListAbsolute.txt
Normal 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
|
||||
BIN
SceneView/obj/Debug/SceneView.dll
Normal file
BIN
SceneView/obj/Debug/SceneView.dll
Normal file
Binary file not shown.
BIN
SceneView/obj/Debug/SceneView.pdb
Normal file
BIN
SceneView/obj/Debug/SceneView.pdb
Normal file
Binary file not shown.
1
SceneView/obj/Debug/SceneView.sourcelink.json
Normal file
1
SceneView/obj/Debug/SceneView.sourcelink.json
Normal file
@@ -0,0 +1 @@
|
||||
{"documents":{"D:\\vs_project\\DuckovMods\\*":"https://raw.githubusercontent.com/thisMiniBox/DuckovMods/9b9121897387fa7e2a57d76690a2a9ae848b1705/*"}}
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
e56036f0838e710ef74c4ebdd97d630a82ce4f293e0f56fdc74ce4c87f1ae5a4
|
||||
9dcd4440d4aa7a199613e1563c8a1068a059ca6f9405861608a0463720b13e15
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
2db483d989a5a869a86b32f19fd026cf473776d04114d97e11aed9c79ee12fd1
|
||||
6169cbd5ed75cdad38ad928862fe0e8f03b1f1fbf4633591344ee6ab75a60dd5
|
||||
|
||||
Binary file not shown.
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
68f3d72038da889633db00efa4248f997c4c5eec6abc2a23beccb75352aa13bf
|
||||
b705ea625fe66cf9b710de3b0b048b285053215fccc8e6ceba581ffba05eb190
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
d4aae129f1e6fc18b1d2a9efecf68c3e4c2b9a7190c20b36eb059e8eaa3c965b
|
||||
565a731aa7d620581c49efa1c98e11aab47b6a0d864832f0fac598d05b37c6a1
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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("开始冒险");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
48
UIFrame/Patch/PatchTextLocalizorRefreshTexts.cs
Normal file
48
UIFrame/Patch/PatchTextLocalizorRefreshTexts.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
// {
|
||||
|
||||
41
UIFrame/Utilities/ConfigApply.cs
Normal file
41
UIFrame/Utilities/ConfigApply.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
799
UIFrame/Utilities/ControlUtilities.cs
Normal file
799
UIFrame/Utilities/ControlUtilities.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
911460e450d98a36d352c39840be04d55f4d5ae8227da097050ab185b491cbc7
|
||||
eead11a1c35697f07220b82ac52ad2f4054a2b06624be646cc8f8e7dceec6281
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
d9927e767d78bd001547a17de1674f3773a1c4e78cf329975757d4b609c6bada
|
||||
266dfc575dfbc47bf568b65a303d0d712ab550e53b7d58f879b06a67eb491c19
|
||||
|
||||
@@ -1 +1 @@
|
||||
0ee34f07c3de41359bb7fcfd63f21e2bd997731e7e65df6cde5e62762235bbce
|
||||
b33937ce9d03978cf1a7dfad4f7e099a7e539b1feb08ebc5b4ce269ec5d58536
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user