Unity GetComponent получает базовый класс, а не производный

#unity3d

#unity3d

Вопрос:

Класс B наследует от класса A.

Я вызываю: GetComponent<A>.SomeFunction();

Класс B находится в компоненте, и он переопределяет SomeFunction() . Но SomeFunction() выполняется только через базовый класс.

Если я вызываю GetComponent<B>.SomeFunction() , то он действительно запускает производный класс.

Это ожидаемое поведение в Unity?

Редактировать:

Класс A

 public class Attacker : MonoBehaviour
{
    // The range a unit can attack in, based on where it is currently standing
    public virtual HashSet<Tile> GetAttackRangeTiles() {
        print("base invocation")
        return new HashSet<Tile>();
    }
}
 

Класс B

 public class Mage : Attacker
{
    override
    public HashSet<Tile> GetAttackRangeTiles() {
        print("derived invocation");
        return new HashSet<Tile>();
    }
}
 

Board.cs

 public class Board : MonoBehaviour {
    public void ProcessUnitAttackSelect(Unit unit) {
        foreach (Tile tile in unit.GetComponent<Attacker>().GetAttackRangeTiles()) {
            tile.SetState(Tile.State.AttackSelect);
        }
    }
}
 

Выше выводится «базовый вызов», а не «производный вызов».

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

1. Ну да. Вы запросили компонент, который является A. Поэтому он запустил версию A. Затем вы сделали это с версией B, чтобы она запускала B

2. @BugFinder предполагая, что метод находится virtual в базе и override в производном, не должна ли ссылка на class A из GameObject с компонентом script class B : A быть корректно переопределяемым методом, даже вызываемым из «базового класса производного класса»? Разве не в этом весь смысл virtual-override отношений методов?

3. Да, если метод является виртуальным, компилятор перейдет в нижнюю часть виртуальной таблицы. Вы должны показать код, поскольку он может быть чем-то вроде общей коллекции.

4. Если он виртуальный, почему вы нам не сказали?

5. Не могли бы вы опубликовать полный код?

Ответ №1:

Понял это — и класс B, и класс A были компонентами объекта. Удалив класс A (родительский класс), B запустился, как и ожидалось. Неприятная ошибка!