Godot C# setScript() 与派生类

问题描述

我有一个 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评论中找到了一种解决方法。他没有设置PackedScene的脚本,而是建议在Instance上设置。它有效。检查 https://github.com/godotengine/godot/issues/31994 以了解更多详细信息并阅读第一条评论以避免另一个问题。

解决方法

@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);
    }
,

错误

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

这个错误是由于将一个对象的脚本设置为一个对象的脚本引起的 不同的对象层次结构。

如果你设置一个Control节点的脚本也会出现同样的错误 到从 Node2D 继承的脚本。

解决方案

您应该将 set_script()_paddleScene 替换为 set_script() paddleInstanceKinematicBody2D 的实例。

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