Godot中强类型数组取值触发InvalidCastException异常求助
Godot中强类型数组元素类型转换失败问题排查
我定义了PathNode类型的数组free_doors,以及同类型变量match_door。执行语句:
match_door = free_doors[rand.RandiRange(0, free_doors.Count - 1)];
时,Godot抛出InvalidCastException异常,提示无法将Godot.Node3D类型转换为FireBrand.Entities.Navigation.PathNode类型。明明变量与数组元素类型一致,为何会出现该问题?
完整错误信息:
E 0:00:03:0669 object System.Runtime.CompilerServices.CastHelpers.ChkCastAny(System.Void*, object): System.InvalidCastException: Unable to cast object of type 'Godot.Node3D' to type 'FireBrand.Entities.Navigation.PathNode'. <C++ Error> System.InvalidCastException <C++ Source> :0 @ object System.Runtime.CompilerServices.CastHelpers.ChkCastAny(System.Void*, object) <Stack Trace> :0 @ object System.Runtime.CompilerServices.CastHelpers.ChkCastAny(System.Void*, object) VariantUtils.generic.cs:385 @ T Godot.NativeInterop.VariantUtils.ConvertTo<T>(Godot.NativeInterop.godot_variant&) Array.cs:1409 @ T Godot.Collections.Array`1.get_Item(int) DungeonMaster.cs:167 @ void FireBrand.General.DungeonMaster+<BuildDungeon>d__31.MoveNext() :0 @ void System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() :0 @ void System.Threading.Tasks.Task+<>c.<ThrowAsync>b__128_0(object) GodotSynchronizationContext.cs:51 @ void Godot.GodotSynchronizationContext.ExecutePendingContinuations() GodotTaskScheduler.cs:76 @ void Godot.GodotTaskScheduler.Activate() ScriptManagerBridge.cs:82 @ void Godot.Bridge.ScriptManagerBridge.FrameCallback()
问题原因分析
- Godot变体系统的隐式转换限制:Godot底层通过
Variant统一存储对象,当向强类型Array<PathNode>添加元素时,若元素来自场景加载或节点树查询,可能被包装为基类Node3D的变体,而非你的自定义PathNode类型。变体提取时会丢失具体子类型信息,导致强类型转换失败。 - 自定义类型未正确注册:如果
PathNode是自定义C#节点类,未添加[GlobalClass]特性或未在引擎中注册,Godot无法识别该子类型,只能以Node3D的形式存储实例。 - 数组填充逻辑错误:检查
free_doors的填充代码,是否误将纯Node3D节点(而非附加PathNode脚本的实例)加入数组。比如场景根节点未绑定PathNode脚本,加载后就会得到Node3D实例。
解决方案
显式转换并添加类型校验
在获取数组元素时显式转换,同时加入空值检查避免异常:var index = rand.RandiRange(0, free_doors.Count - 1); var candidate = free_doors[index] as PathNode; if (candidate != null) { match_door = candidate; } else { GD.PrintErr($"索引{index}处的元素不是PathNode类型,实际类型:{free_doors[index].GetType()}"); // 可添加容错逻辑,比如跳过该元素或重新选择 }确保自定义类型正确注册
给PathNode类添加[GlobalClass]特性,让Godot识别该自定义节点类型:using Godot; [GlobalClass] public partial class PathNode : Node3D { // 自定义属性与逻辑 }规范数组元素的添加逻辑
加载场景或创建实例时,显式指定PathNode类型,确保加入数组的都是正确实例:var doorScene = GD.Load<PackedScene>("res://Scenes/PathDoor.tscn"); var doorInstance = doorScene.Instantiate<PathNode>(); free_doors.Add(doorInstance);确认数组为强类型初始化
确保free_doors是强类型的Array<PathNode>,而非弱类型的Array:var free_doors = new Godot.Collections.Array<PathNode>();
内容的提问来源于stack exchange,提问作者Stephen Hyberger
相关产品推荐
相关产品推荐

