Проблемы разработки от EvilOkta
Всем привет, не уверен что меня помнят ибо почти 4 (или больше?) года отсутствовал на форуме, возможно что-то поменялось.
Решил воскресить свой заброшенный на Blitz 3d проект и как площадку для реализации выбрал Unity, изучаю сейчас C#. Такой вопрос, предположим в скрипте есть метод, в процессе выполнения которого анализируется некоторая ситуация и по результатам анализа выбирается одна из некоторых переменных, назовем их условно intA, intB, intC, intD. Пусть на момент окончания анализа они имеют значения 10, 20, 30, 40 соответственно. Задача передать одну выбранную анализатором переменную в другой метод (предположим анализатор выбрал для обработки переменную intB ) и по выполнению другого метода вернуть значение выбранной переменной увеличенное на 5 (для примера). Идея в том, чтобы разработать универсальное решение для разного количества переменных. Есть подозрение что копать надо в делегатах, но если честно до сих пор не понимаю как они взаимодействуют (при универсальной сигнатуре метода). И есть подозрение что нужно использовать оператор return но не понимаю до конца как он работает при передаче в метод нескольких переменных (кстати тоже важно, как передавать в метод несколько выбранных переменных и возвращать их выборочно?) Надеюсь пнете в нужном направлении )) |
Ответ: Передача переменной в метод
Так? Или я не понял что ты хочешь?
PHP код:
|
Ответ: Передача переменной в метод
Да, это как раз и интересовало, а как одновременно передавать в метод несколько таких параметров, есть способ?
т.е. пеердавать, скажем, intA для одной цели, а IntB для другой но ествественно за один вызов. С помощью ref есть возможность? Я правильно понял логику: PHP код:
|
Ответ: Передача переменной в метод
Так не будет работать потому что ты значение переменных копируешь в другие переменные и передаешь уже для изменения их.
|
Ответ: Передача переменной в метод
точно, я не учел что передаются другие переменные. Но сам синтаксис передачи - правильный?
или надо: PHP код:
задача с возвратом переменных уже есть идеи как решить, надо просто обмозговать |
Ответ: Передача переменной в метод
про ref можно почитать тут
|
Ответ: Передача переменной в метод
спасибо, сегодня попробую поэксперементировать, как я понял из справки с помощью ref можно передавать не только переменную но и класс? или конкретный экземпляр класса?
|
Ответ: Передача переменной в метод
экземпляр, класс можно передавать через шаблон http://msdn.microsoft.com/ru-ru/library/512aeb7t.aspx
|
Ответ: Передача переменной в метод
здорово, мне кажется как раз то что нужно для реализации моей задачи, еще раз спасибо. Универсальный шаблон мне пока рановато, а передача экземпляра класса в связке с ref решит мою проблему.
p.s. надеюсь дело пойдет, а то пока не могу абстрагироваться от модели разработки блитца к модели ООП |
Ответ: Передача переменной в метод
Собственно если передать экземпляр класса, то можно его поля менять. Т.к. это ссылочный тип. Нельзя менять поля у структур (типов значений - ValueType), их надо передавать с помощью ref.
|
Ответ: Передача переменной в метод
значит я для передачи параметров в метод могу сделать класс в котором перечислю все возможные параметры, которые можно передавать в метод (они после этого станут полями класса, правильно?). После блока-анализатора я создаю экземпляр класса в котором заполняю поля необходимыми для передачи параметрами, остальным например проставляю метки "без изменения" (образно выражаясь), в методе обработчике обрабатываю экземпляр класса - возвращаю в исходный метод и там выполняю замещение тех параметров которые требуются используя как донор измененный экземпляр класса (игнорируя параметры с метками), после этого уничтожаю экземпляр класса и скрипт возвращается к исходной точке. Верно мыслю?
|
Ответ: Передача переменной в метод
Ну я бы не стал создавать экземпляры каждый раз, иначе будет работать сборщик мусора. Можно сделать один такой объект и его переиспользовать.
Вообще я не смог представить задачу, в которой это все необходимо в такой форме) Вероятно есть решение проще... |
Ответ: Передача переменной в метод
хочу просто оптимизировать управление юнитом, у меня в зависимости от команды (управление нестандартное, стратегически ориентированное, поэтому передвижением юнита будет управлять скрипт а не банальные WSAD) передаются (разными способами) параметры "маршрута" и "действий" по которым должен передвигаться юнит. Сам скрипт передвижение унифицирован и в зависимости от поступающих команд двигает юнит определенным образом.
Я понимаю что это все прекрасно реализуется огородом if..else но не хочу, понимаю что можно сделать оптимизацию и хочу ее натйти чтобы в перспективе использовать полученный опыт для других скриптов. |
Ответ: Передача переменной в метод
Может для этого просто юнита унаследовать от некоего интерфейса, а скрипт передвижения будет пользоваться интерфейсом для перемещения юнита.
|
Ответ: Передача переменной в метод
Цитата:
Код:
public int Check(params int[] inp) Цитата:
Код:
a = 2 |
Ответ: Передача переменной в метод
seaman ты передаешь числа, а надо передавать переменные и их менять. В params по ref не передать. И так как надо делать это для разного количества - достаточно простого массива, а не params, потому что не будешь же ты для каждого случая вызывать свою версию метода - то от чего хочет отказаться EvilOkta
|
Ответ: Передача переменной в метод
А вернуть IEnumerable можно. Типа:
Код:
int[]Check(params int[] inp) int[] bA = Check(b, c); |
Ответ: Передача переменной в метод
Проблема не в этом. Проблема в том, что ему надо будет вызывать метод различными способами (с различным числом параметров), а это не нужно.
Я вообще его не очень понял, почему например для каждого найденного значения не вызвать функцию один раз, зачем в нее передавать все что надо обработать... |
Ответ: Передача переменной в метод
Ну я тоже не очень понял обсуждения. Просто привел пример как передавать разное число параметров в одну функцию.
|
Ответ: Передача переменной в метод
наверное слишком сумбурно объяснил, задача так поставлена потому что юнитом через этот скрипт планируется управлять как игроком так и ИИ.
Вообще при малом количестве параметров действительно подойдет switch/case. Сейчас попробую поподробнее объяснить, возможно и правда проблема в том что я слишком все осложняю. Игра пошаговая (типа incubation) юнит передвигается по квадратному полю с помощью одного и того же метода. Команда на направление движения устанавливает центр привязки юнита, вокруг которого он "перекатывается" на соседнее поле. Есть две переменные отвечающие за его текущий поворот, имеется ввиду не физический поворот, а некоторые значения которые меняются при перемещении (это краеугольная концепция игры). При перемещении в одну сторону меняется одна переменная, в другую вторая и т.п. Задача при инициализации движения передавать в метод именно ту переменную которую требуется обработать и вернуть ее измененное значение. При расширении скрипта (и написании ИИ) возникнет необходимость передавать и другие параметры для изменения. Так как игра тактического характера то при разном расположении и повороте юнита он будет иметь разные тактические параметры - это я и хотел реализовать в обработчике движения. Если управляет игрок то довольно просто - он мышкой прокладывает маршрут по полю, анализатор запаковывает маршрут в команду, понятную методу перемещения и метод начинает перемещать юнит по маршруту, попутно изменяя его текущие параметры. Если юнитом управляет ИИ, то до прокладки маршрута в действие вступате блок логики, анализирующий текущую ситуацию на поле, параметры и расположение юнитов и т.п. (тут кстати в этом блоке мне тоже бы пригодилась методика передачи/приема переменных или аналоги), и этот блок логики по результатам анализа так же формирует маршрут и отдает его методу перемещения. Еще один момент, помимо перемещения юнита метод так же управляет его активными действиями, т.е. например "атака", "защита" и т.п. (образно говорю), поэтому и стоит задача унификация метода и отделение его от метода прокладки маршрута/действий. Кстати насчет интерфейсов, немного не понял идею, это как? |
Ответ: Передача переменной в метод
PHP код:
UPD: поправил немного код, забыл class написать и в интерфейсе была ошибка |
Ответ: Передача переменной в метод
Цитата:
|
Ответ: Передача переменной в метод
Цитата:
|
Ответ: Передача переменной в метод
Цитата:
|
Ответ: Передача переменной в метод
Как и в жизни - одна мать может родить кучу детей у которых будет ее наследственность. А учителя (интерфейсы) могут придать любому ребенку новые черты, не унаследованные от матери. Интерфейс может придать эти новые черты любому числу классов. Все они будут обладать неким общим набором свойств. И родители у этих классов могут быть разные.
|
Ответ: Передача переменной в метод
Цитата:
А вот такой вопрос - при наследовании класса, его свойства наследует класс-потомок или конкретный экземпляр класса-потомка при создании? Т.е. описывая класс-конструктор уже можно пользоваться свойствами базового класса? |
Ответ: Передача переменной в метод
Не понял про класс конструктор, все экземпляры наследника имеют доступ к публичными и защищенным членам базового класса. Причем могут их переопределять, если они объявлены как виртуальные или абстрактные.
|
Ответ: Передача переменной в метод
да, порылся в справке, понял что задал глупый вопрос.
Попробую реализовать интерфейсами, мне кажется это будет более гибкая структура.. а get и set что определяет? сигнатуру метода переданного интерфейсу? |
Ответ: Передача переменной в метод
Полезно будет почитать про свойства http://msdn.microsoft.com/ru-ru/library/x9fsa0sw.aspx
|
Ответ: Передача переменной в метод
Хотел узнать еще вот что (конечно понимаю что мои вопросы звучат совсем по ламерски но я видимо упускаю какие-то концепциии ООП, а точнее их реализации в Unity)
На старом примере немного непонятно взаимодействие классов и интерфейсов: Если классы объявляются в разных скриптах, на разных GameObject (например на объекте игрока один скрипт, на враге другой) в одном соответственно объявляю класс User в другом AI, оба являются наследниками класса Unit - вот где этот базовый класс должен быть объявлен, чтобы оба класса наследника до него дотянулись? или без разницы? Как в таком случае проектировать архитектуру программы - в какой момент инициализируется связи между классами? Я понимаю так, что при запуске программы должен запуститься какой-то базовый скрипт, в котором и будет объявлены все наследуемые классы и интерфейсы, но не могу понять как это происходит в отдельных независимых скриптах. Или концепция ООП позволяет при запуске одного из скриптов получить все связи наследования из других. Логику построения проекта на простом примере понимаю - взаимодействие скриптов происходит в момент наступление какого-то событие (пересечение с лучом, попадание в коллайдер и т. п.), а вот как быть с такими межскриптовыми связями наследования так и не понял, ведь каждый скрипт наследуется от monobehaviour а значит из за линейного наследования классы наследуются в пределах одного скрипта. Тогда как определить общий интерфейс который действует из разных скриптов с общим методом одного из классов конкретного скрипта? |
Ответ: Передача переменной в метод
1. Все скрипты проекта компилируются одновремено. Так что наследники получат все что имеет класс Unit в не зависимости в каком файле или папке проекта ты его создашь. Главное чтобы скрипты User и AI были в файлах с соответствующим именем (потому что их надо вешать на объекты как скрипты).
2. В функцию MoveUnit(Unit unit) можно будет передать и экземпляр AI и User т.к. они оба будут наследниками Unit. |
Ответ: Передача переменной в метод
Цитата:
Цитата:
Цитата:
Цитата:
Последний вопрос не понял. |
Ответ: Передача переменной в метод
Хм, пробую передать в метод переменную через интерфейс, компилятор ругается что я пытаюсь передать field как property, понимаю что несоответствие типов, тогда мне либо поле нужно объявить как свойство, либо научиться их передавать. Ниже скрипт (понимаю что много огорода). Задача передать интерфейсом поле UnitAngleNS и увеличить на 1. Для теста само собой.
PHP код:
|
Ответ: Передача переменной в метод
Direction в твоем случае свойство типа int (как поле), а не тип переменной который можно передавать в функицю. Правильно
вот так: PHP код:
PHP код:
|
Ответ: Передача переменной в метод
Хм, а как быть с переменной UnitAngleNS которую я хотел передать или я интерфейс вообще не в ту степь повел? получается передаем свойство, но оно пустое и самодостаточное, как в него положить нужную мне переменную?
|
Ответ: Передача переменной в метод
Ты все еще привязываешь себя к переменным. Но теперь ты можешь передать объекты, обладающие одинаковыми свойствами в функцию обработки. Пусть функция меняет эти свойства объектов, а не непонятные переменные.
И на сколько я понял ты немного не так применил интерфейс. PHP код:
PHP код:
вот так: PHP код:
PHP код:
|
Ответ: Передача переменной в метод
фух, разобрался с реализацией интерфейса при передаче в него одного свойства. Действительно зациклился на переменных, использование свойств более удобно (ура! +1 к опыту программирования).
Но теперь возник вопрос, а как быть если у объекта (this) есть два свойства и надо выборочно передать в метод лишь одно из них, ну или изменить одно из них? Создал свойства DirectionNS и DirectionEW у объекта, изначально равны нулю. При передаче в метод RotatePlayerUnit надо увеличить либо одно из них, либо второе в зависимости от значения переменной UnitDirection. Есть способ? PHP код:
|
Ответ: Передача переменной в метод
Я вероятно все еще не понимаю что за система у тебя, что она просто меняет переменные не зная что она меняет и все счастливы) Ты все еще держишься за изменение переменных и интерфейс не применяешь как таковой.
По коду PHP код:
PHP код:
И тут в коде нет того, что ты хочешь избежать - исключения конструкций if или case. Они есть и довольно сложные. На мой взгляд твоя задача сводится к следующему: PHP код:
PHP код:
|
Ответ: Передача переменной в метод
действительно, я все по ходу усложнил, положившись на понимание интерфейсов. Предложенное решение с передачей и обработкой функции - то, что надо.
Наверное еще не дорос я до оптимизации реализации кода, ну да ладно, буду стремиться. Огромное спасибо за разъяснения, вынес из топика очень много нового! |
Ответ: Передача переменной в метод
Еще один вопрос для понимания алгоритмов, как я понял при организации классов в Unity переменные следует использовать для расчетов, а свойства для хранения параметров игровх объектов.
А моей ошибкой было то, что я хранил значения параметров в переменных так? Т.е. если я переведу все необходимые параметры в свойства то смогу гораздо проще обрабатывать взаимодействия объектов? и еще пара вопросов: - что еще может содержать в себе свойство кроме значений? (или только значения?) - может ли одно свойство содержать в себе несколько значений? Понимаю что вопросов много, но они неизбежно возникают при изучении нового материала. Зато интересно! :) |
Ответ: Передача переменной в метод
Цитата:
Подробнее о свойствах http://msdn.microsoft.com/ru-ru/library/w86s7x04.aspx И поле и свойство может содержать в себе экземпляр класса или структуры, который может иметь N полей. А еще они могут содержать ссылки на методы - делегаты. |
Ответ: Передача переменной в метод
но чтобы вывести значение элемента свойства в инспектор в принципе можно в скрипте присвоить их значения какому-то полю, например хранилищу значения свойства? - ну для тестирования кода например
и еще разница в доступе к полям и свойствам конкретного объекта, хотел узнать так правильно? : GameObject.Property++; //изменение свойства GameField++; // изменение поля А при доступе к объекту из других классов, как правильно делать подобное? |
Ответ: Передача переменной в метод
По обращению свойство и поле не отличаются. Т.е. объект.свойство++ и объект.поле++ в коде записываются одинаково. Отличие в том, что в свойстве при этом сработает сначала метод get для взятия значения, а потом метод set для установки нового инкрементированного значения.
Я как-то писал маленькую статейку на тему обмена данными между скриптами |
Ответ: Передача переменной в метод
полезная статья, спасибо!
|
Ответ: Передача переменной в метод
Цитата:
И для чего можно использовать подобное,хотя бы простенький пример? Заранее спасибо ) Цитата:
PHP код:
|
Ответ: Передача переменной в метод
PHP код:
|
Ответ: Передача переменной в метод
Вопрос про перечисление.
Есть у меня перечисление следующего вида: PHP код:
PHP код:
Я хочу достигнуть циклического параметра, т.е. при текущем значении пересечения SectorI он превращался в SectorII а из него в SectorIII и затем снова в SectorI. В справке не нашел способа как менять значение на следующее в списке перечисление (аналогично на предыдущее). Пробую так: PHP код:
|
Ответ: Передача переменной в метод
это как самое простое и по хардкору
PHP код:
|
Ответ: Передача переменной в метод
Цитата:
PHP код:
|
Ответ: Передача переменной в метод
новая беда, где то туплю видимо.
выделил увеличение перечисления в отдельный метод, но он перестал из-за этого работать. Не могу понять что за фигня. Цель одним и тем же методом вертеть три перечисления: PHP код:
|
Ответ: Передача переменной в метод
вопрос снят, был дураком, разобрался сам. Неправильно выполнял метод
PHP код:
|
Ответ: Передача переменной в метод
Хм, опять застрял в тупике. Объявляю массив:
PHP код:
почему? |
Ответ: Передача переменной в метод
Максимум для твоего масива - [2,1].
Я думаю тебе стоит почитать про основы языка, чтобы не спрашивать каждый час на форуме о банальной проблеме |
Ответ: Передача переменной в метод
читаю основы, но сказывается то, что раньше изучал blitz 3d, сложно сразу отвязаться от него
непонятно почему максимум [2,1] - в С# по другому задаются пределы массива? в mdsn написано что "Индексация массивов начинается с нуля: массив с элементами n индексируется от 0 до n-1." у меня размерность массива 4 элемента на 3 или при индексации с 0 - 3х2. или я не так понял синтаксис? upd: все разобрался, оказывается при объявлении массива нумерация начинается с 1, а при доступе к элементам с 0. Не такой очевидный ньюанс, ибо в blitz объявление тоже было с 0. |
Ответ: Передача переменной в метод
При обьявлении ты указываешь размер, и от нуля до 2 какраз поучается те твои 3 элемента. протсо нужно привыкнуть. Всётаки читай msdn. Меньше вопросов будет.
|
Ответ: Передача переменной в метод
и снова нубский вопрос (да-да, только что из справки и тестирования скрипта)
Я научился поворачивать объект с помощью rotatearound и с помощью quaternion.slerp а теперь вопрос - как объединить эти два способа в один? Мне нужно вращать объект вокруг определенной точки в пространстве используя кватернионы (ибо с помощью углов эйлера получаю шарнирный замок в одном из положений) вращать вокруг центра объекта - понятно как, а вот как это сделать с помощью transform.RotateAround неясно, ибо оно хочет в качестве параметров два вектора а не кватернионы. рассматриваю вариант вращения через дочерние пивоты но мне этот метод кажется черезчур проблемным, ибо количество таких пивотов и их настройка слишком суровая заявка для простого поворота объекта на заданный угол вокруг определенной точки. Вот если бы как то в transform.RotateAround передать кватернион либо решить проблему шарнирного замка (читал про обход проблемы через вращение матрицами, но если честно нихрена не понял). Надеюсь хотя бы пнете в нужном направлении. )) p.s. тему впору переименовать в нубские вопросы очередного новичка )) |
Ответ: Передача переменной в метод
Самое простое - поместить пустой объект в точку поворота, поместить твой объект в чайлды к пустому, повернуть пустышку как надо, вывести твой объект из чайлдов пустышки, убить пустышку.
Пустышку можно и не убивать, так будет быстрее. |
Ответ: Передача переменной в метод
Цитата:
А с привязкой/отвязкой дочерних объектов буду штудировать справку. |
Ответ: Передача переменной в метод
transform.parent = pivot.transform сделает объект дочерним к объекту pivot
transform.parent = null - сделает объект самостоятельным |
Ответ: Передача переменной в метод
Третий час бьюсь над косяком в скрипте, кто поможет?
В общем задача скрипта практически завершена, но периодически появляются глюки. Скрипт по команде кнопок WSAD (это пока-что) перекатывает юнит на соседнее поле. RotationPivot - объект который используется как точка через которую идет перекатывание. Скрипт работает как часы, но в некоторых позициях (например при последовательности W-A-W) юнит начинает перекатываться через другую ось (а именно ось Y, хотя скрипт однозначно вращает только по X и Z) - как можно вылечить? PHP код:
|
Ответ: Передача переменной в метод
Скорее всего это из-за использования углов Эйлера для поворота.
Использование углов Эйлера может завести в тупик |
Ответ: Передача переменной в метод
Цитата:
запутался, как раз переделал скрипт чтобы в такую ловушку не попасться, и все равно :-D |
Ответ: Передача переменной в метод
Вращай последовательно. По введенным направлениям. А не сразу на весь поворот.
|
Ответ: Передача переменной в метод
Цитата:
|
Часовой пояс GMT +4, время: 18:33. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot