Доступ к скрипту объекта (полиморфизм)

Форум для самых маленьких, а так же тех, кому недосуг читать справку самостоятельно.

Доступ к скрипту объекта (полиморфизм)

Сообщение Dimetr 25 апр 2023, 13:09

Сделал тестовую сцену. Здесь имеется два игровых объекта.
1) playerObject с прикрепленным скриптом sc_player(наследуется от Монобихевиор)
2) enemyObject с прикрепленным скриптом sc_enemy_skeleton (наследуется от sc_enemy)
3) sc_enemy - базовый скрипт для всех врагов.

На объекты добавлены триггеры. Поэтому можем отслеживать столкновение игрока с противником
Код внутри sc_player.

Синтаксис:
Используется csharp
viod OnTriggerEnter(Collider col){

//Кешируем ссылку на скрипт sc_enemy_skeleton, используя полиморфизм
sc_enemy scEnemy = col.gameObject.GetComponent<sc_enemy>();

//Здесь затруднение. Пытаемся получить доступ к данным из sc_enemy_skeleton
scEnemy.

//Но никаких переменных и методов не видно
//Видны только данные базового скрипта sc_enemy

}
 


В чем тут ошибка? Вывел принтом переменную scEnemy в консоль - пишет что это sc_enemy_skeleton. Т.е. нужный скрипт. Но к данным доступа нет. Данные публичные.
Dimetr
UNец
 
Сообщения: 38
Зарегистрирован: 31 авг 2017, 22:30

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение Saltant 25 апр 2023, 13:24

Приведи к типу
Синтаксис:
Используется csharp
sc_enemy_skeleton scEnemy = (sc_enemy_skeleton)col.gameObject.GetComponent<sc_enemy>();

Если ты берешь базовый класс то у тебя и будет этот базовый класс.
Я на Google Play _https://play.google.com/store/apps/developer?id=Saltant
Аватара пользователя
Saltant
Адепт
 
Сообщения: 2236
Зарегистрирован: 09 окт 2018, 16:40
Откуда: Химки
  • Сайт

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение Dimetr 25 апр 2023, 13:53

Saltant писал(а):Приведи к типу
Синтаксис:
Используется csharp
sc_enemy_skeleton scEnemy = (sc_enemy_skeleton)col.gameObject.GetComponent<sc_enemy>();

Если ты берешь базовый класс то у тебя и будет этот базовый класс.


Тогда не понимаю в чем суть полиморфизма. Я мог сразу получит нужный скрипт через GetComponent<sc_enemy_skeleton>()
Проблема ведь в том, что врагов на сцене в проекте много. И когда столкнулся с одним из них - не известно какой скрипт висит конкретно на этом враге.
Разве что методом перебора узнать.
Dimetr
UNец
 
Сообщения: 38
Зарегистрирован: 31 авг 2017, 22:30

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение 1max1 25 апр 2023, 14:11

Суть полиморфизма именно в том, что ты можешь работать с базовым классом или интерфейсом, при этом не нужно знать конечный тип. А если ты думал что базовый класс будет содержать все на свете, то такого языка программирования в принципе нет в мире. Можешь написать свой, будешь первооткрывателем. Теперь отвечу как правильно использовать то что есть. Есть 3 ключевых слова virtual, override и dynamic. Первые 2 слова это из наследования, третье, это если хочется как в js.
По первым двум. В базовом классе объявляешь публичные виртуальные методы и/или свойства, которые тебе нужны будут в наследнике, типа ChangeHP(int value), Attack() и тд. После этого идешь в дочерний класс и там переопределяешь эти методы через override. Теперь достаточно вызвать метод базового типа (при этом сам экземпляр должен быть от наследника), не зная о наследнике чтобы вызвать именно метод наследника.
Если хочется роскоши и падения фпс в бездну, то можно использовать слово dynamic, это все равно что var/let у js. Переменной такого типа вообще по барабану что в ней находится, она будет пытаться вызвать абсолютно все что ее попросят.

Синтаксис:
Используется csharp
dynamic d = enemy;
d.qwerty(123, "фыв", Vector3.zero);
d.asd = 33;


Этот код не вызовет ошибки при компиляции, однако, если метода qwerty не существует в enemy или переменной asd, то ошибка будет во время выполнения. Единственная проблема, это то что оно не подсвечивает методы через подсказку, нужно знать их самому, но оно и понятно, эта переменная не знает о своем типе во время написания кода потому что она динамическая.

А если тебе прям очень нужен именно конкретный тип, то можно проверить через if или switch:

Синтаксис:
Используется csharp
        var com = GetComponent<Component>();

        if (com is Rigidbody rb)
        {
            print(rb);
        }

        switch (com)
        {
            case BoxCollider boxCollider:
                print(boxCollider);
                break;

            case SphereCollider sphereCollider:
                print(sphereCollider);
                break;
        }


Се ля ви.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение Dimetr 25 апр 2023, 15:11

Хм.. Выходит, чтобы мой пример был рабочим, переменные и методы дочернего скрипта должны быть и в скрипте базовом (далее унаследованы полностью или переопределены наследником ). А если в дочернем заявишь что-то свое, то доступа к этому в таком виде уже не будет.
Последний раз редактировалось Dimetr 25 апр 2023, 15:19, всего редактировалось 1 раз.
Dimetr
UNец
 
Сообщения: 38
Зарегистрирован: 31 авг 2017, 22:30

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение Saltant 25 апр 2023, 15:17

Dimetr писал(а):Хм.. Выходит, чтобы мой пример был рабочим, переменные и методы дочернего скрипта должны быть и в скрипте базовом. А если в дочернем заявишь что-то свое, то доступа к этому в таком виде уже не будет.

В базовом скрипте должно быть всё то что должно быть во всех скриптах которые наследуются от базового, тогда можно брать только базовый скрипт и там дергать методы или свойства. Остальная логика которая уникальна для наследуюмых классов собсна и берется только из этих классов или же реализуй интерфейс на эти классы, в котором будет эта логика - можешь тогда брать интерфейс и дергать методы и свойства.
Я на Google Play _https://play.google.com/store/apps/developer?id=Saltant
Аватара пользователя
Saltant
Адепт
 
Сообщения: 2236
Зарегистрирован: 09 окт 2018, 16:40
Откуда: Химки
  • Сайт

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение 1max1 25 апр 2023, 15:24

C# строго типизированный язык, у него конечно есть лайфхак в виде dynamic, но это для очень специфических ситуаций. Просто нужно понимать что объявляя переменную с типом базового класса, она не будет знать какой именно в ней наследник и потому можно пользоваться только базовой реализацией, а если нужно именно уникальное из наследника дернуть, то только после приведения типа. Меня это тоже напрягало в свое время))
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение Saltant 25 апр 2023, 15:29

1max1 писал(а):C# строго типизированный язык ... Меня это тоже напрягало в свое время))

Я когда познакомился с рефлексией, меня ваще все перестало напрягать, такую дичь намутить с рефлексией можно, жесть)) практически все что душе угодно. Главное понимать че мутить хочешь.
Я на Google Play _https://play.google.com/store/apps/developer?id=Saltant
Аватара пользователя
Saltant
Адепт
 
Сообщения: 2236
Зарегистрирован: 09 окт 2018, 16:40
Откуда: Химки
  • Сайт

Re: Доступ к скрипту объекта (полиморфизм)

Сообщение Dimetr 25 апр 2023, 16:04

Спасибо за ответы. Вопросов меньше не стало, но конкретно с этим все понятно.
Dimetr
UNец
 
Сообщения: 38
Зарегистрирован: 31 авг 2017, 22:30


Вернуться в Почемучка

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 24