Godot 4 字典与 PhysicasRayQueryParameters2D C# 的问题

问题描述 投票:0回答:1

这个教程(有点回到Godot 3)之后,我遇到了一些关于

PhysicasRayQueryParameters2D
的问题。这是视频中的代码:

if (ableToShoot)
{
    var spaceState = GetWorld2D().DirectSpaceState;
    Godot.Collections.Dictionary result = spaceState.IntersectRay(this.Position, player.Position, new Godot.Collections.Array {this} );

    if (result != null)
    {
        if (result.Contains("collider"))
        {
            if (result["collider"] == player)
            {
                GD.Print("Shooting");
                ableToShoot = false;
                shootTimer = shootTimerReset;
            }
        }
    }
}

这是我的代码:

if (ableToShoot)
{
    var spaceState = GetWorld2D().DirectSpaceState;
    //Change 1
    var query = PhysicsRayQueryParameters2D.Create(this.Position, player.Position);
    query.Exclude = new Godot.Collections.Array<Rid> {  };
    query.CollisionMask = 1;
    Godot.Collections.Dictionary result = spaceState.IntersectRay(query);

    if (result != null)
    {
        if (result.ContainsKey("collider")) //Change 2
        {
            if (result["collider"] == player) //Error Message
            {
                GD.Print("Shooting");
                ableToShoot = false;
                shootTimer = shootTimerReset;
            }
        }
    }

由于 Godot 3 到 4 的更改,视频中的代码明显不同。但是,我不完全确定我所做的更正/更改是否正确。我对 C# 和 Godot 都还很陌生。我把修改的两个地方都标记出来了,方便比较。然而,我的主要问题是我不断收到一条错误消息,上面写着

result["collider"] == player
。 这就是教程中的情况,我自己做了,但是当我这样做时,我收到一个错误,说我在应用于
Variant
PlayerController
(来自 a 的类)时无法使用 '==' 运算符。不同的脚本)。我尝试将结果转换为
PlayerController
,但是一旦瓷砖开始阻挡我和敌人之间,我就开始收到错误消息,指出我无法将
Godot.TileMap
转换为
Godot.PlayerController
。我该怎么办?我在翻译代码时还犯过其他错误吗?

我查看了许多 reddit 表单和 Godot 文档,但我无法克服最后一个错误。

c# raycasting godot4
1个回答
0
投票

Godot.Variant
是一个打包结构,可以保存多种类型值之一,包括原生 C# 类型(字符串、整数、基本类型数组等)和内部 Godot 类型的集合。虽然有许多不同的隐式类型转换(即编译器尝试找出您需要的类型并在
Variant
上调用适当的类型转换方法),但您通常需要在工作之前从
Variant
显式提取某些内容有了它。

(您可以在

Variant
中找到的类型的完整列表是这里。)

在这种情况下,

collider
结果字典中的
IntersectRay
值是一个
GodotObject
,一旦 C# 知道它是那种类型,您就可以对其进行相等比较。

有几种方法可以使用转换运算符或

As*()
方法(例如
AsObject()
)来实现此目的。以下是一些可能适合您的选项:

Variant.AsObject()
:

if (result["collider"].AsObject() == player)
{
}

显式演员表:

if ((GodotObject)result["collider"] == player)
{
}

隐式转换为变量:

GodotObject? collider = results["collilder"];
if (collider == player)
{
}

最后,还有

Obj
成员,它将以 c# 形式获取内部值
object?
,您可以对其进行参考比较。

Obj
参考对比:

if (ReferenceEquals(results["collider"].Obj, player))
{
}

这不是一份详尽的列表,但希望其中一个对您有用。使用

ReferenceEquals()
在大多数情况下都有效,并且在您实际上不需要除引用比较之外的任何内容的情况下绕过任何运算符重载相等性,这既更快又(通常)更容易理解。

© www.soinside.com 2019 - 2024. All rights reserved.