Не очень понимаю как работает Inheritance вообще в Unity, но например в Game Maker я легко разобрался, потому-что там не было лишней писанины и просто нужно галочку поставить в определённом месте.
Вроде всё круто и работает в логах, НО это не объекты юнити, а как бы сами по себе объекты С#, у которых даже простого transform нет. Есть ли где (для новичков) примеры с GameObject и inheritance? Чтобы понять как работать с этим.
Я попробовал загуглить и нашёл разные примеры, или это для профессионалов, или это так и нужно, где даже есть незнакомые понятия virtual и override, стоит ли вообще с этим связываться для новичка, или лучше другие примеры поискать? https://forum.unity.com/threads.....525281
Код
class BaseClass : Monobehaviour { public virtual Start() { Debug.Log("BaseClass.Start()"); } }
class ChildClass : BaseClass { public override Start() { base.Start(); Debug.Log("ChildClass.Start()"); } }
Если честно, я долго делал игры без всяких базовых классов и мне этого хватало, потому не особо хочется сильно глубоко в дебри программирования лезть (и узнавать что такое "virtual", если только это не важное понятие в создании Базовых Классов), просто теперь мне нужна функция, чтобы во всех игровых объектах на уровне был базовый класс с Dictionary, где будут храниться переменные. Что-то типа свои встроенные переменные к которым легко обратиться через String и чтобы это было во всех объектах уровня.
Сообщение отредактировал alexsilent - Вторник, 30 Июня 2020, 18:48
Начни использовать потихоньку, а в процессе разберёшься
- Ключевым словом virtual ты помечаешь методы, свойства, которые могут быть переопределены в дочерних классах. Методы virtual могут содержать реализацию. - Ключевое слово abstract похоже на virtual, но абстракный метод, свойство не может содержать реализации. - Чтобы переопределить метод, свойство в дочернем классе, ты должен использовать ключевое слово override.
В твоём же случае с Dictionary можно не париться. Поехали:
Код
class BaseClass : MonoBehaviour { protected readonly Dictrionary<string, string> myAwesomeDictionary = new Dictionary<string, string>(); }
Давай по-чесноку. Нельзя нормально что-то использовать начиная с отрицания типа "мне вроде надо, но понимать не хочу". Наследование само по себене имеет ничего общего с юнити. Наследование это про C# и ооп. А то что ты видишь в юнити уже реализация этого самого ооп на C#.
В отличии от гейммейкера со встроенным GML языком юнити использует полноценный язык C# в качестве скриптового языка. Но это C# без всяких компромиссов во всей красе. ( любые нюансы C# на юнити связаны лишь с компиляцией и ограничением версии языка поддерживаемой юнити )
Отсюда следует что если ты потратишь немного времени на понимание как работает наследование в ооп то твой вопрос автоматически отпадет.
Виртуальные методы это методы для переопределения. Это значит что ты можешь *перезаписать* метод базового классе в наследуемом классе.
Код
public class Animal{ public virtual void Vocal(){ Debug.Log("Basic Animal Sound"); } }
public class Dog: Animal{ public override void Vocal(){ Debug.Log("Woof"); } }
В примере выше если ты создашь Dog и вызовешь Vocal то собака будет лаять. Ты спросишь а нафига тут базовый класс? Ну фишка в том что создав собаку наследуемую от животного ты можешь сделать массив животных ( не указывая что это собаки, кошки и прочая ). На уровне языка будет известно что твой Animal это собака так что когда ты из массива animals[0] дергнешь Vocal то он все равно залает ( ибо ты в animals[0] передал собаку например )
Что касается Юнитивских классов то базовый класс для игровых объектов у них условно Monobehavior, говорю условно потому что не все так просто но это как раз тебе уже пока не должно быть интересно. Так вот Monobehavior прекрасно знает о трансформе и gameobject которому принадлежит. Ровно как ты можешь и из go получить transform и наоборот из transform получить go
Следовательно любой твой класс отнаследованный от Monobehavior будет знать о трансформе тоже. ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
Сообщение отредактировал pixeye - Вторник, 30 Июня 2020, 19:10
В твоём же случае с Dictionary можно не париться. Поехали:
Vostrugin, ого спасибо!! Как просто выглядит код, кроме одного момента protected readonly пошёл гуглить, ибо первый раз встречаю звучит так как будто переменная только для чтения и нельзя изменять словарь, но в то же время мы его можем менять, странно) пошёл искать инфу.
protected - это модификатор доступа, словарь будет доступен только внутри этого класса и его наследников (так же не будет виден в инспекторе, для этого можно использовать аттрибут [SerializedField]) readonly - как следует из названия, не даст тебе создать по ошибке другой экземпляр словаря, но при этом ты волен добавлять/удалять новые элементы в словарь.
Я конечно ленивый, но если это всё-таки очень важный момент, то стоит изучить.
Добавлено (30 Июня 2020, 19:51) --------------------------------------------- pixeye, попытался создать класс на твоём примере, и получил ошибку, видимо потому-что Dog переписала Animal или другие причины, а как сделать так чтобы переменная trans была установлена в базовом скрипте при пробуждении, чтобы лишний раз её не дёргать из Child скриптов? То есть чтобы 2 Awake сработали, вначале у базы, потом у чайлда.
Код
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Animal : MonoBehaviour { public Transform trans; public virtual void Awake() { print("Awake Base!"); trans = transform; } public virtual void Vocal(){ Debug.Log("Basic Animal Sound"); } }
Код
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class Dog: Animal{ public override void Awake() { print("Awake Child!"); trans.position = new Vector3(0,0,0); } public override void Vocal(){ Debug.Log("Woof"); } }
Добавлено (30 Июня 2020, 20:00) --------------------------------------------- хотя убрав override из Awake Dog, все равно получил ошибку, похоже trans переменная не доступна для Dog или хз:
UnassignedReferenceException: The variable trans of Dog has not been assigned. You probably need to assign the trans variable of the Dog script in the inspector. UnityEngine.Transform.set_position (UnityEngine.Vector3 value) Dog.Awake () (at Assets/BaseClassTest/Dog.cs:8)
Добавлено (30 Июня 2020, 20:14) --------------------------------------------- Ещё попробовал такой вариант с базой, вместо Awake поставить Animal, как было в примере урока юнити с фруктами, но в таком случае с transform вообще нельзя работать, юнити выдаёт ошибку, что Transform тут не место:
Код
public class Animal : MonoBehaviour { public Transform trans; public Animal() { print("Awake Base!"); trans = transform; } public virtual void Vocal(){ Debug.Log("Basic Animal Sound"); } }
Сообщение отредактировал alexsilent - Вторник, 30 Июня 2020, 20:26
Ты используешь конструкторы класса - с монобехейверами этого делать не надо. Более того я уверен что тебя юнити предупреждает о том что ты делаешь в консоле закидывая Warning что конструкторы в монобехейвере запрещены.
у тебя есть для этого методы Awake и Start ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
лол, у меня в первом сообщении есть ответ, просто я вначале не понимал как оно работает, а сейчас перечитал и нашёл
Код
base.Awake();
хотя ещё не тестировал)
Добавлено (30 Июня 2020, 20:22) --------------------------------------------- pixeye, спасибо ещё раз!Мне C# теперь нравится больше JS (Unity Script), хотя бы потому-что даже если там тоже это было, то я раньше не знал, а теперь понимаю как упростить код в юнити. :3
Сообщение отредактировал alexsilent - Вторник, 30 Июня 2020, 20:23
Если потратишь свое время и усердно поучишь C# то он тебе еще больше понравится : ) ACTORS - мой фреймворк на Unity Until We Die - игра над которой работаю
Vostrugin, Спасибо Большое! Прикрутил словарь) всё работает, кроме [SerializedField], компилятор ругается из-за того что рядом стоит словарь, видимо его нельзя показать, ну неважно, можно и обычным кодом переменные словарю добавлять, как я вначале и планировал.
можно и обычным кодом переменные словарю добавлять, как я вначале и планировал.
Упс, да, погорячился, по дефолту юнити не отрисует словарь. Есть пара способов, но думаю не стоит пока тебя пугать Если вдруг нужно будет реализовать управление через инспектор, то проще будет свою реализацию коллекции ключ-значение сделать
Прямо удивительно как можно изучать C# более года и до сих пор не знать про наследование и бояться virtual и override alexsilent, дело конечно твое, но что-то мне подсказывает, что если ты работаешь один с таким уровнем знанием, то все что ты делаешь, ты делаешь крайне неэффективно и криво Отложить проект в сторону на месяц и заняться изучением основ могло бы сэкономить тебе кучу времени в будущем
drcrack, ну я согласен с тем что я делаю не эффективно и криво) я больше художник, чем программист , и очень долго простые вещи программирую, сейчас буду в третий раз переписывать ядро на юнити, на основе новых знаний.)
>>и заняться изучением основ Есть конечно ещё учебники и уроки, но по учебникам и урокам я вообще не могу учиться, я будто "смотрю в книгу и вижу фигу", ну реально пока я не пойму для чего это мне нужно, то не пойму урок, например в школе нам преподавали синусы, я их вообще не понимал, а через лет 10-15 после школы, когда понял что они нужны для кручения,вращения, волнообразного качания и поворота угла пули/врага для игр, то методом тыка изучил быстро, ибо было понимание зачем я это учу. Также по базовым классам, пока я не попробовал в Game Maker их, то не думал что они такие полезные, до этого я не понимал зачем мне это нужно, и только после захотелось узнать как в юнити с этим работать. Например в юнити есть Entity, многие говорят что это крутая вещь, но если я начну это учить, то я не понимаю зачем мне это нужно и не отнимет ли это просто так время, потому-что это другой альтернативный метод программирования. И ещё разные методы есть, на которые могу потратить много времени, ибо программирование даётся мне только методом тыка/проб и ошибок, пока не пойму зачем это нужно и сам не получу ошибки в коде, то не пойму как оно работает, а теорию читать совсем бесполезно для меня.
Добавлено (01 Июля 2020, 10:50) --------------------------------------------- Вот кстати, если в уроке доходчиво на примерах объясняют зачем нужен этот функционал, то такие уроки я могу ещё осилить, а если ещё и пример очень интересный и очень короткий (чтобы с ходу понять), то вообще круто, но такие учителя/уроки редкость, чаще урок просто выглядит так: "Вот вам базовое знание потому-что это надо знать." Ну как-то так, совсем не понятно, где я буду это применять и буду ли вообще, не очень мотивирует.
Сообщение отредактировал alexsilent - Среда, 01 Июля 2020, 10:53