Godot 4 Dictionary 问题与 PhysicasRayQueryParameters2D C#

Godot 4 Dictionary issues with PhysicasRayQueryParameters2D C#

提问人:Shane Amare 提问时间:10/10/2023 更新时间:10/10/2023 访问量:61

问:

按照教程(它有点回到 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 还是新手。我标记了我所做的更改的两个地方,以便于比较。但是,我的主要问题是我不断收到错误消息,其中显示. 这就是教程中的情况,我自己做了,但是当我这样做时我得到了一个错误,说当应用于and(来自不同脚本的类)时,我不能使用“==”操作符。我尝试将结果转换为 ,但是一旦瓷砖开始阻塞我和敌人之间,我就开始收到错误消息,说我无法转换为 .我该怎么办?在翻译代码时,我是否犯了其他错误?result["collider"] == playerVariantPlayerControllerPlayerControllerGodot.TileMapGodot.PlayerController

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

C# 光线投射 GODOT4

评论


答:

1赞 Corey 10/10/2023 #1

Godot.Variant是一个可以保存多种类型值之一的结构,包括本机 C# 类型(字符串、整数、基本类型的数组等)和内部 Godot 类型的集合。虽然有一堆不同的隐式类型转换(即编译器试图找出你需要什么类型并调用适当的类型转换方法),但你经常需要从中显式提取一些东西,然后才能使用它。VariantVariant

(您可以在 这里 找到的完整类型列表。Variant

在这种情况下,结果字典中的值是一个,你可以对它进行相等比较。一旦 C# 知道它是什么类型。colliderIntersectRayGodotObject

有几种方法可以使用转换运算符、诸如等方法来实现此目的。以下是可能适合您的几个选项:As*()AsObject()

Variant.AsObject()

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

显式演员表:

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

隐式转换为变量:

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

最后,还有一个成员,它将内部值作为 c# 获取,您可以对其进行引用比较。Objobject?

Obj 参考比较:

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

这不是一个详尽的列表,但希望其中一个对你有用。在大多数情况下,使用都有效,并且绕过了任何运算符对相等性的过度依赖,在这种情况下,除了引用比较之外,您确实不需要其他任何东西,这既更快,而且(通常)更容易理解。ReferenceEquals()