【问题标题】:Godot C# setScript() with derived classGodot C# setScript() 与派生类
【发布时间】:2021-04-30 08:43:01
【问题描述】:

我有一个 Paddle 场景(就像 PONG 游戏中的场景)。但是我的桨可以是水平的也可以是垂直的。

所以我创建了一个父抽象类包含通用逻辑的“Paddle”,以及扩展Paddle“PaddleHorizo​​ntal”和“PaddleVertical”的两个派生类是不同的(一个上下,另一个左右)。

一开始,我想创建我的桨并将正确的脚本附加到每个桨上,但 我收到了这个错误

" 脚本继承自原生类型 'KinematicBody2D',因此不能在类型对象中实例化:'PackedScene'"

我的Main.cs是这样的:

using Godot;

public class Main : Node2D
{

    private PackedScene _paddleScene;
    
    public override void _Ready()
    {
        base._Ready();
        _paddleScene = GD.Load<PackedScene>("res://src/scenes/entities/paddle/Paddle.tscn");
        var script = GD.Load<Reference>("res://src/scenes/entities/paddle/PaddleHorizontal.cs");
        _paddleScene.SetScript(script);
        this.InitPaddles();
    }


    private void InitPaddles()
    {
        this.AddPaddle(new Vector2(PaddlePositions.Top.x, PaddlePositions.Top.y));
        this.AddPaddle(new Vector2(PaddlePositions.Bottom.x, PaddlePositions.Bottom.y));
    }

    private void AddPaddle(Vector2 paddlePosition)
    {
        KinematicBody2D paddleInstance = (KinematicBody2D)_paddleScene.Instance();
        paddleInstance.Position = paddlePosition;
        AddChild(paddleInstance);
    }
}
// -- Paddle.cs --
using Godot;

public abstract class Paddle : KinematicBody2D
{
    // common methods & properties

    // the one method that is different and should be override
    public abstract Vector2 GetMovement();
}

// -- PaddleHorizontal.cs --
using Godot;

public class PaddleHorizontal : Paddle
{
    public override Vector2 GetMovement()
    {
        // different from PaddleVertical
    }

}

我猜错误来自这样一个事实,即 PaddleHorizo​​ntal 不直接扩展 KinematicBody2D 但两种类型的 Paddle 之间有很多共同的逻辑......如果你们有解决方案或解决方法...

编辑: mxmissile 在 cmets 中找到了解决方法。他建议不设置 PackedScene 的脚本,而是设置在 Instance 上。它有效。查看https://github.com/godotengine/godot/issues/31994 了解更多详情,并阅读第一条评论以避免其他问题。

【问题讨论】:

  • 我对 godot 一无所知,但在我看来,您似乎正在尝试“设置”PackedScene 的脚本,该脚本必须派生自 PackedScene。我在这里猜,但是paddleInstance 有 SetScript 方法吗?
  • @mxmissile 你可能不知道 Godot,但多亏了你,我改变了我的想法并......找到了解决方法! :P 我在 Instance 而不是 PackedScene 上搜索了 setScript 并发现了这一点:github.com/godotengine/godot/issues/31994 他在他的实例上设置了脚本,但他也有一个问题可以通过第一条评论来解决。 (该问题自 14 天后开放,所以...)
  • @mxmissile 在我看来,这是一种解决方法而不是解决方案。至少它可以工作,但我更愿意解释为什么它不工作,所以我会保持这个线程打开。
  • 我同意,希望 godot 专家能加入进来。
  • @mxmissile 还是非常感谢你,我在编辑帖子时提到了你的名字

标签: c# derived-class godot


【解决方案1】:

@mxmissile 建议的解决方案如下:

private void AddPaddle(Vector2 paddlePosition)
    {
        KinematicBody2D paddleInstance = (KinematicBody2D)_paddleScene.Instance();
        ulong paddleInstanceId = paddleInstance.GetInstanceId();

        Resource script = GD.Load("res://src/scenes/entities/paddle/PaddleHorizontal.cs");
        paddleInstance.SetScript(script);

        paddleInstance = (KinematicBody2D)GD.InstanceFromId(paddleInstanceId);

        paddleInstance.Position = paddlePosition;
        AddChild(paddleInstance);
    }

【讨论】:

    【解决方案2】:

    错误

    脚本继承自原生类型“KinematicBody2D”,因此无法实例化 在对象类型中:'PackedScene'

    此错误是由于将 Object 的脚本设置为 不同的对象层次结构。

    如果您设置控制节点的脚本,也会出现同样的错误 到从 Node2D 继承的脚本。

    解决方案

    而不是set_script()_paddleScene 你应该set_script()paddleInstanceKinematicBody2D 的实例。

    KinematicBody2D paddleInstance = (KinematicBody2D)_paddleScene.Instance();
    paddleInstance.SetScript(thePaddleScript);
    

    【讨论】:

    • 感谢您的回复,但您可能没有完全阅读该帖子...我进行了编辑以添加 @mxmissile 解决方案,该解决方案发现我必须在添加脚本之前实例化。但仍然感谢您让我了解问题的根源:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2011-06-10
    相关资源
    最近更新 更多