Godot C # setScript() с производным классом

#c# #derived-class #godot

#c# #производный класс #godot

Вопрос:

У меня есть сцена, которая представляет собой весло (как в игре в ПОНГ). Но мои весла могут быть как горизонтальными, так и вертикальными.

Итак, я создал один родительский абстрактный класс «Paddle», который содержит общую логику, и два производных класса, которые расширяют Paddle «PaddleHorizontal» и «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 amp; 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
    }

}
 

Я предполагаю, что ошибка связана с тем фактом, что PaddleHorizontal не расширяет KinematicBody2D напрямую, но есть много логики, которая будет общей между 2 типами весел … .. Если у вас, ребята, есть решение или обходной путь…

РЕДАКТИРОВАТЬ: обходной путь был найден mxmissile в комментариях. Вместо установки скрипта PackedScene он предложил установить его в экземпляре. И это работает. Проверьте https://github.com/godotengine/godot/issues/31994 для получения более подробной информации ПРОЧТИТЕ первый комментарий, чтобы избежать еще одной проблемы.

Комментарии:

1. Я ничего не знаю о godot, но мне кажется, что вы пытаетесь «установить» сценарий PackedScene , из которого должен быть получен PackedScene . Я предполагаю здесь, но paddleInstance есть ли метод SetScript?

2. @mxmissile Возможно, вы не знаете Годо, но благодаря вам я изменил свою идею и … нашел обходной путь! 😛 Я использовал Google setScript для экземпляра вместо PackedScene и нашел это: github.com/godotengine/godot/issues/31994 Он установил свои скрипты на своих экземплярах, но у него также есть проблема, которую можно исправить с помощью первого комментария. (Проблема открыта с 14 дней, так что …)

3. @mxmissile На мой взгляд, это обходной путь, а не решение. По крайней мере, это работает, но я предпочту получить объяснения, почему это не работает, поэтому я оставлю эту тему открытой.

4. Я согласен, надеюсь, некоторые эксперты godot подключатся.

5. @mxmissile все еще большое спасибо вам, я упомянул ваше имя, когда редактировал свой пост

Ответ №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’

Эта ошибка вызвана установкой сценария объекта в сценарий другой иерархии объектов.

Та же ошибка возникнет, если вы, например, установите для сценария управляющего узла сценарий, который наследуется от Node2D.

Решение

Вместо set_script() _paddleScene того, что вы должны set_script() из paddleInstance того, который является экземпляром KinematicBody2D .

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

Комментарии:

1. Спасибо за ваш ответ, но вы, возможно, не прочитали сообщение полностью… Я внес правку, чтобы добавить решение @mxmissile, которое обнаружило, что я должен создать экземпляр перед добавлением скрипта. Но все же спасибо, что сообщили мне о происхождении проблемы 🙂