feat(godot): 添加 Godot 场景管理和路径扩展功能

- 新增 Godot 场景行为基类和具体实现(Node2D、Node3D、Control、通用场景行为)
- 添加场景行为工厂类,支持根据节点类型自动创建合适的行为实例
- 实现 Godot 场景工厂类,用于创建场景实例并集成场景注册表
- 添加 Godot 路径扩展方法,支持判断用户数据路径和资源路径
- 优化数据仓库和设置事件类的初始化方法,添加 XML 文档注释
- 修改场景切换管道中的日志记录逻辑,避免空引用异常
- 更新 Godot 日志记录器和日志工厂的文档注释
- 为设置相关类添加数据对象和类型属性的文档说明
- 移除加载进度处理器类,精简场景切换流程
This commit is contained in:
GeWuYou 2026-02-15 16:53:39 +08:00 committed by gewuyou
parent 628a39b9f8
commit 899fbd76c3
22 changed files with 536 additions and 76 deletions

View File

@ -21,7 +21,7 @@ namespace GFramework.Game.Abstractions.scene;
/// </summary>
public sealed class SceneTransitionEvent
{
private readonly Dictionary<string, object> _context = new();
private readonly Dictionary<string, object> _context = new(StringComparer.Ordinal);
/// <summary>
/// 获取或初始化源场景的唯一标识符。

View File

@ -120,6 +120,9 @@ public class DataRepository(IStorage? storage, DataRepositoryOptions? options =
this.SendEvent(new DataBatchSavedEvent(valueTuples));
}
/// <summary>
/// 初始化
/// </summary>
protected override void OnInit()
{
_storage ??= this.GetUtility<IStorage>()!;

View File

@ -184,6 +184,9 @@ public class UnifiedSettingsDataRepository(
_typeRegistry[location.Key] = type;
}
/// <summary>
/// 初始化
/// </summary>
protected override void OnInit()
{
_storage ??= this.GetUtility<IStorage>()!;

View File

@ -122,14 +122,15 @@ public class SceneTransitionPipeline
{
@event.Set("Phases", phases.ToString());
Log.Debug(
"Execute pipeline: Phases={0}, From={1}, To={2}, Type={3}, HandlerCount={4}",
phases,
@event.FromSceneKey,
@event.ToSceneKey ?? "None",
@event.TransitionType,
_handlers.Count
);
if (@event.FromSceneKey != null)
Log.Debug(
"Execute pipeline: Phases={0}, From={1}, To={2}, Type={3}, HandlerCount={4}",
phases,
@event.FromSceneKey,
@event.ToSceneKey ?? "None",
@event.TransitionType,
_handlers.Count
);
var sortedHandlers = FilterAndSortHandlers(@event, phases);

View File

@ -1,61 +0,0 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using GFramework.Core.Abstractions.logging;
using GFramework.Core.logging;
using GFramework.Game.Abstractions.enums;
using GFramework.Game.Abstractions.scene;
namespace GFramework.Game.scene.handler;
/// <summary>
/// 加载进度处理器,用于在场景加载前显示加载界面和进度反馈。
/// </summary>
public sealed class LoadingProgressHandler : SceneTransitionHandlerBase
{
private static readonly ILogger Log = LoggerFactoryResolver.Provider.CreateLogger(nameof(LoadingProgressHandler));
/// <summary>
/// 获取处理器优先级,数值越小优先级越高(优先执行)。
/// </summary>
public override int Priority => -100;
/// <summary>
/// 获取处理器处理的场景切换阶段,只处理 BeforeChange 阶段。
/// </summary>
public override SceneTransitionPhases Phases => SceneTransitionPhases.BeforeChange;
/// <summary>
/// 处理场景切换事件的异步方法。
/// </summary>
/// <param name="event">场景切换事件对象,包含切换的相关信息。</param>
/// <param name="cancellationToken">取消令牌,用于控制异步操作的取消。</param>
/// <returns>表示异步操作的任务。</returns>
public override async Task HandleAsync(SceneTransitionEvent @event, CancellationToken cancellationToken)
{
// 只处理 Push 和 Replace 操作(需要加载场景)
if (@event.TransitionType != SceneTransitionType.Push &&
@event.TransitionType != SceneTransitionType.Replace)
return;
// 显示加载界面
// TODO: 调用 UI 系统显示加载界面
Log.Info("Loading scene: {0}", @event.ToSceneKey);
// 监听加载进度(如果需要)
// 这里可以通过事件上下文传递进度信息
// 例如:@event.Set("LoadingProgress", progressValue);
await Task.CompletedTask;
}
}

View File

@ -13,4 +13,8 @@
namespace GFramework.Game.setting.events;
/// <summary>
/// 表示所有设置已应用的事件。
/// 此事件通常用于通知系统或组件,所有的设置配置已经完成并生效。
/// </summary>
public sealed class SettingsAppliedAllEvent;

View File

@ -13,4 +13,8 @@
namespace GFramework.Game.setting.events;
/// <summary>
/// 表示设置已初始化的事件。
/// 此事件用于通知系统或组件,所有设置已完成初始化。
/// </summary>
public sealed class SettingsInitializedEvent;

View File

@ -13,4 +13,8 @@
namespace GFramework.Game.setting.events;
/// <summary>
/// 表示所有设置已保存的事件。
/// 此事件用于通知系统或组件,所有设置数据已成功保存。
/// </summary>
public sealed class SettingsSavedAllEvent;

View File

@ -1,26 +1,36 @@
namespace GFramework.Godot.extensions;
/// <summary>
/// 提供对 Godot 路径相关操作的扩展方法。
/// 包含判断路径类型的功能例如用户数据路径user://和资源路径res://)。
/// </summary>
public static class GodotPathExtensions
{
/// <summary>
/// 判断是否是 Godot 用户数据路径user://
/// 判断指定路径是否为 Godot 用户数据路径user://)。
/// </summary>
/// <param name="path">待检查的路径字符串。</param>
/// <returns>如果路径以 "user://" 开头且不为空,则返回 true否则返回 false。</returns>
public static bool IsUserPath(this string path)
{
return !string.IsNullOrEmpty(path) && path.StartsWith("user://");
}
/// <summary>
/// 判断是否是 Godot 资源路径res://
/// 判断指定路径是否为 Godot 资源路径res://)。
/// </summary>
/// <param name="path">待检查的路径字符串。</param>
/// <returns>如果路径以 "res://" 开头且不为空,则返回 true否则返回 false。</returns>
public static bool IsResPath(this string path)
{
return !string.IsNullOrEmpty(path) && path.StartsWith("res://");
}
/// <summary>
/// 判断是否是 Godot 特殊路径user:// 或 res://
/// 判断指定路径是否为 Godot 特殊路径user:// 或 res://)。
/// </summary>
/// <param name="path">待检查的路径字符串。</param>
/// <returns>如果路径是用户数据路径或资源路径,则返回 true否则返回 false。</returns>
public static bool IsGodotPath(this string path)
{
return path.IsUserPath() || path.IsResPath();

View File

@ -5,19 +5,31 @@ using Godot;
namespace GFramework.Godot.logging;
/// <summary>
/// Godot平台的日志记录器实现
/// Godot平台的日志记录器实现。
/// 该类继承自 <see cref="AbstractLogger"/>,用于在 Godot 引擎中输出日志信息。
/// 支持不同日志级别的输出,并根据级别调用 Godot 的相应方法。
/// </summary>
/// <param name="name">日志记录器的名称,默认为根日志记录器名称。</param>
/// <param name="minLevel">最低日志级别,默认为 <see cref="LogLevel.Info"/>。</param>
public sealed class GodotLogger(
string? name = null,
LogLevel minLevel = LogLevel.Info) : AbstractLogger(name ?? RootLoggerName, minLevel)
{
/// <summary>
/// 写入日志的核心方法。
/// 格式化日志消息并根据日志级别调用 Godot 的输出方法。
/// </summary>
/// <param name="level">日志级别。</param>
/// <param name="message">日志消息内容。</param>
/// <param name="exception">可选的异常信息。</param>
protected override void Write(LogLevel level, string message, Exception? exception)
{
// 构造时间戳和日志前缀
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
var levelStr = level.ToString().ToUpper().PadRight(7);
var logPrefix = $"[{timestamp}] {levelStr} [{Name()}]";
// 添加异常信息
// 添加异常信息到日志消息中
if (exception != null) message += "\n" + exception;
var logMessage = $"{logPrefix} {message}";

View File

@ -11,6 +11,7 @@ public class GodotLoggerFactory : ILoggerFactory
/// 获取指定名称的日志记录器实例
/// </summary>
/// <param name="name">日志记录器的名称</param>
/// <param name="minLevel">日志记录器的最小日志级别</param>
/// <returns>返回GodotLogger类型的日志记录器实例</returns>
public ILogger GetLogger(string name, LogLevel minLevel = LogLevel.Info)
{

View File

@ -0,0 +1,33 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Godot;
namespace GFramework.Godot.scene;
/// <summary>
/// Control 场景行为类,用于管理 UI 场景节点的生命周期。
/// 适用于基于 Control 的 UI 场景元素。
/// </summary>
public sealed class ControlSceneBehavior : SceneBehaviorBase<Control>
{
/// <summary>
/// 初始化 ControlSceneBehavior 实例。
/// </summary>
/// <param name="owner">UI 场景节点的所有者实例。</param>
/// <param name="key">场景的唯一标识键。</param>
public ControlSceneBehavior(Control owner, string key)
: base(owner, key)
{
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Godot;
namespace GFramework.Godot.scene;
/// <summary>
/// 通用场景行为类,用于管理任意 Node 类型场景节点的生命周期。
/// 当场景节点不属于 Node2D、Node3D 或 Control 时使用此类。
/// </summary>
public sealed class GenericSceneBehavior : SceneBehaviorBase<Node>
{
/// <summary>
/// 初始化 GenericSceneBehavior 实例。
/// </summary>
/// <param name="owner">场景节点的所有者实例。</param>
/// <param name="key">场景的唯一标识键。</param>
public GenericSceneBehavior(Node owner, string key)
: base(owner, key)
{
}
}

View File

@ -0,0 +1,74 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using GFramework.Core.Abstractions.logging;
using GFramework.Core.extensions;
using GFramework.Core.logging;
using GFramework.Core.utility;
using GFramework.Game.Abstractions.scene;
namespace GFramework.Godot.scene;
/// <summary>
/// Godot 场景工厂类,用于创建场景实例。
/// 继承自 AbstractContextUtility 并实现 ISceneFactory 接口。
/// </summary>
public class GodotSceneFactory : AbstractContextUtility, ISceneFactory
{
/// <summary>
/// 日志记录器,用于记录调试信息。
/// </summary>
private static readonly ILogger Log =
LoggerFactoryResolver.Provider.CreateLogger(nameof(GodotSceneFactory));
/// <summary>
/// 场景注册表,用于管理场景资源。
/// </summary>
private IGodotSceneRegistry _registry = null!;
/// <summary>
/// 根据指定的场景键创建场景行为实例。
/// </summary>
/// <param name="sceneKey">场景的唯一标识符。</param>
/// <returns>返回创建的场景行为实例。</returns>
public ISceneBehavior Create(string sceneKey)
{
// 从注册表中获取指定场景键对应的 PackedScene
var scene = _registry.Get(sceneKey);
// 实例化场景节点
var node = scene.Instantiate();
// 检查节点是否实现了 ISceneBehaviorProvider 接口
if (node is ISceneBehaviorProvider provider)
{
var behavior = provider.GetScene();
Log.Debug("Created scene instance from provider: {0}", sceneKey);
return behavior;
}
// 否则使用工厂自动创建
var autoBehavior = SceneBehaviorFactory.Create(node, sceneKey);
Log.Debug("Created scene instance with auto factory: {0}", sceneKey);
return autoBehavior;
}
/// <summary>
/// 初始化方法,在对象初始化时调用。
/// 获取并设置场景注册表实例。
/// </summary>
protected override void OnInit()
{
_registry = this.GetUtility<IGodotSceneRegistry>()!;
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Godot;
namespace GFramework.Godot.scene;
/// <summary>
/// Node2D 场景行为类,用于管理 2D 场景节点的生命周期。
/// 适用于 Sprite2D、TileMap 等 2D 场景元素。
/// </summary>
public sealed class Node2DSceneBehavior : SceneBehaviorBase<Node2D>
{
/// <summary>
/// 初始化 Node2DSceneBehavior 实例。
/// </summary>
/// <param name="owner">2D 场景节点的所有者实例。</param>
/// <param name="key">场景的唯一标识键。</param>
public Node2DSceneBehavior(Node2D owner, string key)
: base(owner, key)
{
}
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using Godot;
namespace GFramework.Godot.scene;
/// <summary>
/// Node3D 场景行为类,用于管理 3D 场景节点的生命周期。
/// 适用于 MeshInstance3D、Camera3D 等 3D 场景元素。
/// </summary>
public sealed class Node3DSceneBehavior : SceneBehaviorBase<Node3D>
{
/// <summary>
/// 初始化 Node3DSceneBehavior 实例。
/// </summary>
/// <param name="owner">3D 场景节点的所有者实例。</param>
/// <param name="key">场景的唯一标识键。</param>
public Node3DSceneBehavior(Node3D owner, string key)
: base(owner, key)
{
}
}

View File

@ -0,0 +1,203 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using GFramework.Game.Abstractions.scene;
using GFramework.Godot.extensions;
using Godot;
namespace GFramework.Godot.scene;
/// <summary>
/// 场景行为基类,封装通用的场景生命周期管理逻辑。
/// 提供对 Node 类型场景节点的统一管理,包括加载、进入、暂停、恢复、退出、卸载等操作。
/// </summary>
/// <typeparam name="T">Node 类型的场景节点。</typeparam>
public abstract class SceneBehaviorBase<T> : ISceneBehavior
where T : Node
{
/// <summary>
/// 场景的唯一标识键。
/// </summary>
private readonly string _key;
/// <summary>
/// IScene 接口引用(如果节点实现了该接口)。
/// </summary>
private readonly IScene? _scene;
/// <summary>
/// 场景节点的所有者实例。
/// </summary>
protected readonly T Owner;
/// <summary>
/// 场景是否处于活跃状态。
/// </summary>
private bool _isActive;
/// <summary>
/// 场景是否已加载。
/// </summary>
private bool _isLoaded;
/// <summary>
/// 场景是否正在过渡中。
/// </summary>
private bool _isTransitioning;
/// <summary>
/// 初始化 SceneBehaviorBase 实例。
/// </summary>
/// <param name="owner">场景节点的所有者实例。</param>
/// <param name="key">场景的唯一标识键。</param>
protected SceneBehaviorBase(T owner, string key)
{
Owner = owner;
_key = key;
_scene = owner as IScene;
}
#region ISceneBehavior
/// <summary>
/// 获取场景的唯一标识键。
/// </summary>
public string Key => _key;
/// <summary>
/// 获取场景是否已加载完成的状态。
/// </summary>
public bool IsLoaded => _isLoaded;
/// <summary>
/// 获取场景是否处于活跃运行状态。
/// </summary>
public bool IsActive => _isActive;
/// <summary>
/// 获取场景是否正在进行切换操作。
/// </summary>
public bool IsTransitioning => _isTransitioning;
/// <summary>
/// 获取场景节点是否有效。
/// </summary>
public bool IsAlive => Owner.IsValidNode();
/// <summary>
/// 异步加载场景所需资源。
/// 在场景正式进入前调用,负责预加载场景所需的各类资源。
/// </summary>
/// <param name="param">场景进入参数,可能包含初始化数据或上下文信息。</param>
/// <returns>表示加载操作完成的ValueTask。</returns>
public virtual async ValueTask OnLoadAsync(ISceneEnterParam? param)
{
_isTransitioning = true;
// 调用可选接口
if (_scene != null)
await _scene.OnLoadAsync(param);
_isLoaded = true;
_isTransitioning = false;
}
/// <summary>
/// 异步处理场景正式进入逻辑。
/// 在资源加载完成后调用,启动场景的主要运行逻辑。
/// </summary>
/// <returns>表示进入操作完成的ValueTask。</returns>
public virtual async ValueTask OnEnterAsync()
{
_isTransitioning = true;
if (_scene != null)
await _scene.OnEnterAsync();
_isActive = true;
_isTransitioning = false;
}
/// <summary>
/// 异步处理场景暂停逻辑。
/// 当场景被其他场景覆盖或失去焦点时调用。
/// </summary>
/// <returns>表示暂停操作完成的ValueTask。</returns>
public virtual async ValueTask OnPauseAsync()
{
if (_scene != null)
await _scene.OnPauseAsync();
// 暂停处理
Owner.SetProcess(false);
Owner.SetPhysicsProcess(false);
Owner.SetProcessInput(false);
_isActive = false;
}
/// <summary>
/// 异步处理场景恢复逻辑。
/// 当场景重新获得焦点或从暂停状态恢复时调用。
/// </summary>
/// <returns>表示恢复操作完成的ValueTask。</returns>
public virtual async ValueTask OnResumeAsync()
{
if (Owner.IsInvalidNode())
return;
if (_scene != null)
await _scene.OnResumeAsync();
// 恢复处理
Owner.SetProcess(true);
Owner.SetPhysicsProcess(true);
Owner.SetProcessInput(true);
_isActive = true;
}
/// <summary>
/// 异步处理场景退出逻辑。
/// 在场景即将被替换或关闭时调用,执行清理工作。
/// </summary>
/// <returns>表示退出操作完成的ValueTask。</returns>
public virtual async ValueTask OnExitAsync()
{
_isTransitioning = true;
if (_scene != null)
await _scene.OnExitAsync();
_isActive = false;
}
/// <summary>
/// 异步卸载场景资源。
/// 在场景完全退出后调用,释放占用的内存和资源。
/// </summary>
/// <returns>表示卸载操作完成的ValueTask。</returns>
public virtual async ValueTask OnUnloadAsync()
{
if (_scene != null)
await _scene.OnUnloadAsync();
// 释放节点
Owner.QueueFreeX();
_isLoaded = false;
_isTransitioning = false;
}
#endregion
}

View File

@ -0,0 +1,43 @@
// Copyright (c) 2026 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using GFramework.Game.Abstractions.scene;
using Godot;
namespace GFramework.Godot.scene;
/// <summary>
/// 场景行为工厂类,根据节点类型自动创建合适的场景行为实例。
/// 使用模式匹配选择最适合的行为类型。
/// </summary>
public static class SceneBehaviorFactory
{
/// <summary>
/// 根据节点类型创建对应的场景行为实例。
/// </summary>
/// <typeparam name="T">节点类型,必须继承自 Node。</typeparam>
/// <param name="owner">场景节点的所有者实例。</param>
/// <param name="key">场景的唯一标识键。</param>
/// <returns>创建的场景行为实例。</returns>
public static ISceneBehavior Create<T>(T owner, string key)
where T : Node
{
return owner switch
{
Node2D node2D => new Node2DSceneBehavior(node2D, key),
Node3D node3D => new Node3DSceneBehavior(node3D, key),
Control control => new ControlSceneBehavior(control, key),
_ => new GenericSceneBehavior(owner, key)
};
}
}

View File

@ -34,7 +34,16 @@ public class GodotAudioSettings(ISettingsModel model, AudioBusMap audioBusMap)
model.GetData<AudioSettings>().Reset();
}
/// <summary>
/// 获取音频设置的数据对象。
/// 该属性提供对音频设置数据的只读访问。
/// </summary>
public ISettingsData Data { get; } = model.GetData<AudioSettings>();
/// <summary>
/// 获取音频设置数据的类型。
/// 该属性返回音频设置数据的具体类型信息。
/// </summary>
public Type DataType { get; } = typeof(AudioSettings);
/// <summary>

View File

@ -51,6 +51,15 @@ public class GodotGraphicsSettings(ISettingsModel model) : IResetApplyAbleSettin
model.GetData<GraphicsSettings>().Reset();
}
/// <summary>
/// 获取图形设置的数据对象。
/// 该属性提供对图形设置数据的只读访问。
/// </summary>
public ISettingsData Data { get; } = model.GetData<GraphicsSettings>();
/// <summary>
/// 获取图形设置数据的类型。
/// 该属性返回图形设置数据的具体类型信息。
/// </summary>
public Type DataType { get; } = typeof(GraphicsSettings);
}

View File

@ -48,6 +48,15 @@ public class GodotLocalizationSettings(ISettingsModel model, LocalizationMap loc
model.GetData<LocalizationSettings>().Reset();
}
/// <summary>
/// 获取本地化设置的数据对象。
/// 该属性提供对本地化设置数据的只读访问。
/// </summary>
public ISettingsData Data { get; } = model.GetData<LocalizationSettings>();
/// <summary>
/// 获取本地化设置数据的类型。
/// 该属性返回本地化设置数据的具体类型信息。
/// </summary>
public Type DataType { get; } = typeof(LocalizationSettings);
}

View File

@ -16,7 +16,7 @@ public class GodotUiFactory : AbstractContextUtility, IUiFactory
/// 日志记录器,用于记录调试信息。
/// </summary>
private static readonly ILogger Log =
LoggerFactoryResolver.Provider.CreateLogger("GodotUiFactory");
LoggerFactoryResolver.Provider.CreateLogger(nameof(GodotUiFactory));
/// <summary>
/// UI注册表用于管理UI场景资源。