#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, которое обнаружило, что я должен создать экземпляр перед добавлением скрипта. Но все же спасибо, что сообщили мне о происхождении проблемы 🙂