forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Общие вопросы (http://forum.boolean.name/forumdisplay.php?f=166)
-   -   Проблемы разработки от EvilOkta (http://forum.boolean.name/showthread.php?t=17911)

EvilOkta 06.05.2015 14:44

Ответ: Передача переменной в метод
 
отлично, сегодня вечером попробую применить на практике )) уже придумал как, главное что-бы сработало )

pax 06.05.2015 16:09

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от EvilOkta (Сообщение 295621)
PS. Можно тему переименовать в что-то типа "Проблемы разработки от EvilOkta"? А то название темы уже не актуально )

Переименована

EvilOkta 19.05.2015 11:25

Ответ: Передача переменной в метод
 
Цитата:

Сообщение от Nex (Сообщение 295631)

Немного запутался, сориентируйте Bounds.size родительского объекта будет изменяться если дочерний объекта выходит за его пределы? Или он описывает только размеры родительского объекта? Есть какие-то способы получить Bounds полной модели вместе с дочерними?

pax 19.05.2015 13:27

Ответ: Проблемы разработки от EvilOkta
 
Складывай боундсы всех моделей, чтобы получить общий
http://docs.unity3d.com/ScriptRefere...capsulate.html

EvilOkta 08.06.2015 13:37

Ответ: Проблемы разработки от EvilOkta
 
что можно почитать про отложенное выполнение методов? Не знаю как сформулировать, даже не знаю термин. Рылся в справках. Мне нужно что-то типа пула (очереди) выполнения методов с последовательным выполнением, т.е. при выполнении одного метода активируется очередь других методов, которые начинают исполняться один за другим.
Немного топорно объяснил, попробую на примере:
Есть условная ловушка - при попадании в нее с объектом производятся определеннные манипуляции. Задача завершить выполнение предыдущего метода (который обеспечил попадание в ловушку) при этом не начиная следующего, пока не сработает ловушка.
Ловушка срабатывает через корутину - сначала она определяет, что объект в ее зоне действия, после этого ожидает секунду (для завершения предыдущего метода) и запускает собственный механизм ловушки (объекту отправляется сообщение что он в ловушке, чтобы он заблокировал свои методы перемещения). При этом косяк в том, что во время этой секунды методы не заблокированы и объект спокойно может уйти из ловушки, а она затем сработает естественно вызвав баги в логике кода.
Если жестко зафиксировать отлов события срабатывания ловушки как только (!) объект оказывается в его зоне действия, то еще веселее: ловушка срабатывает до того, как объект попал в зону действия (на самом краю срабатывания триггера - объект не вошел целиком в триггер, это важно!) - как результат ломается логика кода, объект начинает колбасить
Как я вижу ситуацию: объект попадает в ловушку, скрипт должен дозавершить текущий метод, которым он попал в ловушку, но при этом зная, что следующим должен сработать метод ловушки, а не перемещения дальше. Своего рода предзнание.
Куда копать?

pax 08.06.2015 16:06

Ответ: Проблемы разработки от EvilOkta
 
PHP код:

// завершающий метод
void CallbackMethod(){

   
// сделать что-то при завершении
}

// Action  это делегат (ссылка на метод)
IEnumerator MyCoroutine(Action callback){

yield... yield... yield; 
// выполнение долгого действия

// вызов делегата по завершении
if(callback!= nullcallback();

}

// использование

// передача делегата
StartCoroutine(MyCoroutine(CallbackMethod));

или 

// передача лямбда функции
StartCoroutine(MyCoroutine(() =>{
    
// сделать что-то при завершении
})); 


EvilOkta 08.06.2015 17:03

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от pax (Сообщение 296486)
PHP код:

// завершающий метод
void CallbackMethod(){
   
// сделать что-то при завершении
}
// Action  это делегат (ссылка на метод)
IEnumerator MyCoroutine(Action callback){
yield... yield... yield; 
// выполнение долгого действия
// вызов делегата по завершении
if(callback!= nullcallback();
}
// использование
// передача делегата
StartCoroutine(MyCoroutine(CallbackMethod));
или 
// передача лямбда функции
StartCoroutine(MyCoroutine(() =>{
    
// сделать что-то при завершении
})); 


Спасибо интересно, правда немного непонятно как правильно использовать Yield - что именно здесь описать для моей реализации? Условие выполнение первого метода (перемещение в ловушку) или условие когда начать метод ловушки?

и еще - Action - это делегат, который не нужно явно объявлять, он как бы доступен по умолчанию, я правильно понял - это он? https://msdn.microsoft.com/ru-ru/lib...v=vs.110).aspx

pax 08.06.2015 17:44

Ответ: Проблемы разработки от EvilOkta
 
yield это твои действия любые, которые делают задержку.

Action и его вариации находятся в System да. Шаблонные вариации Action можно использовать как методы с параметрами (например при вызове метода надо передать что за ловушка сработала). Есть еще готовый делегат Func, который возвращает значение TResult.

Если тебе надо выполнить цепочку действий, то можешь сделать список экшенов для выполнения List<Action<T>> к примеру, которые принимают для обработки объект типа T.

EvilOkta 09.06.2015 10:12

Ответ: Проблемы разработки от EvilOkta
 
вроде работает, единственное вместо делегата Action поставил запуск анимации с навешанными событиями, которые делают все остальное, надеюсь такой алгоритм будет стабильным в дальнейшем )

EvilOkta 09.06.2015 22:09

Ответ: Проблемы разработки от EvilOkta
 
Такой вопрос, может подскажете - есть у меня статический класс который управляет привязкой камеры. Все работает, но в методах в каждой строчке у меня происходит Getcomponent. Визуально видно, что проще один раз инициализировать объект, который используется для поиска элементов, а потом использовать в методах.

Встала проблема - как инициализировать статический класс? Опять могу путать терминологию, но в обычном классе наследнике от Моно есть возможность использовать Start(). Можно что-то подобное сделать в статическом классе, чтобы перед исполнением методов инициализировать поле скрипта ссылкой на объект?

PHP код:

using UnityEngine;
using System.Collections;

public static class 
StaticCameraMagnit {

    public static 
bool MagnitCapturebeMagnit;
    public static 
GameObject FromMagnited;
    private static 
CameraNavigation CameraNav;

    
CameraNav GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>();
    
// вот это действие где нужно прописать для выполнения? Потом методы будут использовать эту ссылку вместо постоянного GetComponent

    
public static void MagnitedCamera(GameObject FocusTarget) {
        if (!
MagnitCapture) {
            if (
GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().Magnit_Unit!=null) {
                if (
GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().Magnit_Unit.tag=="Unit Player") {
                    
FromMagnited GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().Magnit_Unit;
                }
            }
            
GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().Magnit_Unit FocusTarget;
            
beMagnit GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().isMagnit;
            if (!
beMagnitGameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().isMagnit true;
        }
        
MagnitCapture true;
    }
    
    public static 
void UnMagnitedCamera() {
        
GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().Magnit_Unit FromMagnited;
        
GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>().isMagnit beMagnit;
        
MagnitCapture false;
    }



pax 09.06.2015 22:41

Ответ: Проблемы разработки от EvilOkta
 
Тебе поможет синглтон
PHP код:

public class MyClass
{

    private static 
MyClass _instance;
    public static 
MyClass instance
    
{
        
get
        
{
            if(
_instance == null)
            {
                    
_instance = new MyClass();
            }
            return 
_instance;
        }
    }


    private 
MyClass()
    {
           
// инициализация 

    
}


Использование: MyClass.instance.MethodOrProperty

PS: у тебя проблема не в GetComponent, а в Find. Вот самая медленная операция, а особенно несколько раз подряд искать одно и то же.

h1dd3n 12.06.2015 18:49

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от pax (Сообщение 296539)
Тебе поможет синглтон
PHP код:

public class MyClass
{

    private static 
MyClass _instance;
    public static 
MyClass instance
    
{
        
get
        
{
            if(
_instance == null)
            {
                    
_instance = new MyClass();
            }
            return 
_instance;
        }
    }


    private 
MyClass()
    {
           
// инициализация 

    
}


Использование: MyClass.instance.MethodOrProperty

PS: у тебя проблема не в GetComponent, а в Find. Вот самая медленная операция, а особенно несколько раз подряд искать одно и то же.

Нахрена ему синглтон ?

Почему нельзя просто сделать property CameraNav ?
Код:

public static CameraNavigation CameraNav
    {
        get
        {
            if(_cameraNav == null)
            {
                    _cameraNav = GameObject.Find("CameraNavigate").GetComponent<CameraNavigation>();
            }
            return _instance;
        }
    }

И оставить статический класс при этом.

pax 12.06.2015 19:19

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от h1dd3n (Сообщение 296585)
Нахрена ему синглтон ?

Почему нельзя просто сделать property CameraNav ?

И оставить статический класс при этом.

Вероятно что бы освоить очередной паттерн программирования? В общем любой вариант подойдет. И проперти этот тот же метод. Просто обращение к нему без скобочек.

EvilOkta 11.07.2015 13:25

Ответ: Проблемы разработки от EvilOkta
 
Читаю в mdsn описание Array. Вопрос такой. Есть ли методы, которые позволят из одномерного массива получить минимальное значение (максимальное тоже) и номер элемента этих значений? Сейчас реализовано через foreach но получается приходится вызывать в методе foreach аж 6 раз для разных исходных данных.
Метод делает на самом деле простую вещь - определяет, какие значения на каких гранях кубика
NumberChild - коллекция значений на гранях кубика (от 1 до 6)

PHP код:

public int Unit_Up_FieldUnit_Down_FieldUnit_W_FieldUnit_S_FieldUnit_A_FieldUnit_D_Field// значения на гранях кубика - это будет преобразовано в массив для разработки дальнейшего кода

public void Analize_Dice_Orientation () {
    
// анализ значений кубика
    
MaxCordInField 0f;
        foreach(
GameObject UnitChild in NumberChild) {
            if (
UnitChild.transform.position.MaxCordInField) {
                
MaxCordInField UnitChild.transform.position.y;
                
Unit_Up_Field = (int)NumberChild.IndexOf(UnitChild);
            }
        }
        
MaxCordInField 2f;
        foreach(
GameObject UnitChild in NumberChild) {
            if (
UnitChild.transform.position.MaxCordInField) {
                
MaxCordInField UnitChild.transform.position.y;
                
Unit_Down_Field = (int)NumberChild.IndexOf(UnitChild);
            }
        }
        
MaxCordInField this.transform.position.x-2f;
        foreach(
GameObject UnitChild in NumberChild) {
            if (
UnitChild.transform.position.MaxCordInField) {
                
MaxCordInField UnitChild.transform.position.x;
                
Unit_W_Field = (int)NumberChild.IndexOf(UnitChild);
            }
        }
        
MaxCordInField this.transform.position.x+2f;
        foreach(
GameObject UnitChild in NumberChild) {
            if (
UnitChild.transform.position.MaxCordInField) {
                
MaxCordInField UnitChild.transform.position.x;
                
Unit_S_Field = (int)NumberChild.IndexOf(UnitChild);
            }
        }
        
MaxCordInField this.transform.position.z-2f;
        foreach(
GameObject UnitChild in NumberChild) {
            if (
UnitChild.transform.position.MaxCordInField) {
                
MaxCordInField UnitChild.transform.position.z;
                
Unit_A_Field = (int)NumberChild.IndexOf(UnitChild);
            }
        }
        
MaxCordInField this.transform.position.z+2f;
        foreach(
GameObject UnitChild in NumberChild) {
            if (
UnitChild.transform.position.MaxCordInField) {
                
MaxCordInField UnitChild.transform.position.z;
                
Unit_D_Field = (int)NumberChild.IndexOf(UnitChild);
            }
        }
         } 

Печенкой чую, что можно оптимизировать но именно для случая с массивом, 6 параметров не оптимально

pax 11.07.2015 17:49

Ответ: Проблемы разработки от EvilOkta
 
Ну на ум пришло не очень быстрое решение в две строчки
PHP код:

using System.Linq;

// Вариант с сортировкой
var minByZ NumberChild.OrderBy(t=>t.transform.position.z).First();
var 
index NumberChild.IndexOf(minByZ); 


Igor 11.07.2015 19:21

Ответ: Проблемы разработки от EvilOkta
 
Pax, а разве в C# нельзя понадеяться на ленивую загрузку классов и реализовать синглтон в виде: private static MyClass _instance = new MyClass();
public static MyClass intance {get{return _instance}} ?

Например, если в java писать public static final MyClass instance = new MyClass(),
то во время первого обращения к этому классу извне (т.е., только когда он понадобится, и не раньше), будет выполнена инициализация и всё ок.

pax 11.07.2015 19:51

Ответ: Проблемы разработки от EvilOkta
 
Почему нельзя? Можно.

Igor 11.07.2015 19:58

Ответ: Проблемы разработки от EvilOkta
 
А зачем тогда пример синглтона с кучей кода в блоке get{}?

pax 11.07.2015 20:23

Ответ: Проблемы разработки от EvilOkta
 
Подобным образом можно сделать синглтоном скрипты (new GameObject().AddComponent())

seaman 11.07.2015 22:08

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от Igor (Сообщение 297659)
А зачем тогда пример синглтона с кучей кода в блоке get{}?

Не забывайте, что MonoBehaviour - специфический класс. Его экземпляр нельзя делать new MonoBehaviour(). Нужно AddComponent<MonoBehaviour>() и все что Вы делали в конструкторе - делать в Start.
Поэтому для скриптов, которые Вы хотите повесить на объект не пойдет
Код:

private static MyClass _instance = new MyClass();
public static MyClass intance {get{return _instance}}

Нужно в get проверить есть ли такой скрипт в сцене. Если нет создать обхект, на который затем повесить скрипт.

EvilOkta 12.07.2015 12:37

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от pax (Сообщение 297644)
Ну на ум пришло не очень быстрое решение в две строчки
PHP код:

using System.Linq;

// Вариант с сортировкой
var minByZ NumberChild.OrderBy(t=>t.transform.position.z).First();
var 
index NumberChild.IndexOf(minByZ); 


получается что linq выражение хоть и выглядит короче будет работать медленнее чем вызов foreach?

seaman 12.07.2015 12:57

Ответ: Проблемы разработки от EvilOkta
 
Не знаю как эквивалентное выражение Линк работало бы. Но тут же не просто перебор - тут сортировка. Сортировка по идее медленней чем просто перебор массива.
PS: нашел статью по сравнению for foreach и ForEach(из Linq). Что быстрее? foreach vs. List.ForEach vs. for-loop

EvilOkta 14.07.2015 14:33

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от seaman (Сообщение 297710)
Не знаю как эквивалентное выражение Линк работало бы. Но тут же не просто перебор - тут сортировка. Сортировка по идее медленней чем просто перебор массива.
PS: нашел статью по сравнению for foreach и ForEach(из Linq). Что быстрее? foreach vs. List.ForEach vs. for-loop

доберусь до скрипта попробую сравнить какой вариант будет быстрее в моем случае, если что результаты выложу для интереса )

EvilOkta 16.07.2015 00:18

Ответ: Проблемы разработки от EvilOkta
 
при 100000 вызовах что foreach, что linq выражение даст такой же эффект, зато строк стало поменьше

EvilOkta 31.10.2015 13:49

Ответ: Проблемы разработки от EvilOkta
 
подскажите по использованию UI системы. В общем какая проблема возникла:
Меню может появляться/исчезать по щелчку мыши на игровом поле. Управляется это так
PHP код:

UI_Menu.SetActive(true/false); 

В игровой логике присутствует проверка на пересечение курсора мыши UI c помощью:
PHP код:

if (EventSystem.current.IsPointerOverGameObject()) {...} 

Проблема в том, что если меню не активно (по умолчанию) то проверка пересечения выдает ошибку, т.к. объект не присутствует в сцене. Но при принудительном отображении меню проверка работает. Если меню снова скрыть - снова ошибки. В чем может быть беда и как исхитриться избежать таких ситуаций.

Планируемый алгоритм:
- Меню появляется при щелчке мыши по игровому объекту
- Меню пропадает при щелчке мыши по игровому полю
- Когда меню активно в логике кода должна происходить проверка на пересечение курсора мыши области UI.

Где копать?

pax 31.10.2015 14:46

Ответ: Проблемы разработки от EvilOkta
 
А если так?
PHP код:

if (EventSystem.current && EventSystem.current.IsPointerOverGameObject()) {...} 


EvilOkta 20.01.2016 00:00

Ответ: Проблемы разработки от EvilOkta
 
Подскажите, в новой системе UI каким образом можно снять выделение "Highlighted" с кнопки с помощью кода? Не могу найти какое свойство за это отвечает...

Антихрист 20.01.2016 00:19

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 303412)
Подскажите, в новой системе UI каким образом можно снять выделение "Highlighted" с кнопки с помощью кода? Не могу найти какое свойство за это отвечает...

Или полностью снять переходы:
GetComponent<Button>().transition = Selectable.Transition.None;
Или руками настроить цвет для хайлаита:
Создать ColorBlock. Настроить у него highlightedColor и присвоить его к button.colors.

EvilOkta 24.10.2019 20:20

Ответ: Проблемы разработки от EvilOkta
 
Возник вопрос, для понимания ситуации.
Есть субклассы, наследуемые от базового класса. Если создан экземпляр одного субкласса, может он каким-то образом превратиться в экземпляр другого субкласса? Паттерн состояние - это то?
Мне пока на ум пришло только уничтожение экземпляра субкласса и создание нового другого субкласса с переносом необходимых данных - так вообще делают или это плохая практика?

Антихрист 24.10.2019 21:06

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 316739)
Возник вопрос, для понимания ситуации.
Есть субклассы, наследуемые от базового класса. Если создан экземпляр одного субкласса, может он каким-то образом превратиться в экземпляр другого субкласса? Паттерн состояние - это то?
Мне пока на ум пришло только уничтожение экземпляра субкласса и создание нового другого субкласса с переносом необходимых данных - так вообще делают или это плохая практика?

Нельзя. Если у тебя есть 'треугольник' и 'квадрат' которые оба наследуются от 'фигуры', то сомневаюсь, что можно превратить одно в другое.
Паттерн состояние не превращает один класс в другой.
Данные можно перетащить из треугольника в квадрат через reflection в рамках родительского класса (фигуры).

EvilOkta 24.10.2019 21:19

Ответ: Проблемы разработки от EvilOkta
 
Ясно, спасибо! А как тогда лучше всего проектировать? Про треугольники и квадраты аналогия понятна.
Допустим базовый класс "работник"; субклассы "электрик", "менеджер", "ремонтник". Экземпляр класса "электрик" сменил работу и стал "менеджер" и должен теперь реализовывать другой набор функций.
Upcasting и Downcasting тоже не помогут?

Антихрист 25.10.2019 00:23

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 316741)
Ясно, спасибо! А как тогда лучше всего проектировать? Про треугольники и квадраты аналогия понятна.
Допустим базовый класс "работник"; субклассы "электрик", "менеджер", "ремонтник". Экземпляр класса "электрик" сменил работу и стал "менеджер" и должен теперь реализовывать другой набор функций.
Upcasting и Downcasting тоже не помогут?

Имхо, паттерн стратегия. Работа как интерфейс, конкретные профессии - его реализации. Работник ссылается на стратегию(его текущую работу). При смене профессии, меняем стратегию.

EvilOkta 30.10.2019 13:28

Ответ: Проблемы разработки от EvilOkta
 
Еще вопрос. Как вести документацию по составу класса? Для описания методов есть XML комментарии - это понятно, но интересует другое. Когда кол-во классов становится большим становится сложно в голове удерживать какие методы они реализуют, интерфейсы наследуют и какими свойствами обладают.
Может есть какие-то инструменты для создания базы данных о классах, их взаимодействии и структуре? Интересно для общего развития.
Или все банально сводится к тому, что в коде открываешь сам класс и вспоминаешь?)

seaman 02.11.2019 12:34

Ответ: Проблемы разработки от EvilOkta
 
Вложений: 1
В VS (не Community) есть средство создания диаграмм классов
Вложение 23060

pax 03.11.2019 11:53

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от seaman (Сообщение 316778)
В VS (не Community) есть средство создания диаграмм классов
Вложение 23060

Ух какой ужас, моя не смотри.

2EvilOkta: Лучше называть классы именами, описывающими функции, которые они выполняют. И организовывать в пространства имен/папки по тому же принципу. Ничего вспоминать не потребуется, все будет понятно по наименованию классов. Много ли вы диаграмм видели в справке по .net? Я часто так же использую ключевое слово partial, чтобы разделить класс на несколько частей, если часть функций можно объединить в группы. Тогда в структуре проекта это представлено несколькими файлами, имена которых так же отвечают на вопрос, что там внутри (например LevelEditor.cs и LevelEditor.LoadSave.cs).

EvilOkta 03.11.2019 12:35

Ответ: Проблемы разработки от EvilOkta
 
Спасибо ) энтерпрайз дорого (я ж не зарабатываю программированием), идея с partial интересная. Параллельно в Excel заношу публичные методы классов и их сигнатуры, на всякий случай.

Продолжаю закидывать страшными вопросами. Я наконец-то разобрался со свойствами (pax за это отдельное спасибо), но терзают сомнения, можно ли их применять вот так:

PHP код:

protected static string[] Mounthes = new[] { "января""февраля""марта""апреля""мая""июня""июля""августа""сентября""октября""ноября""декабря" };
protected 
string _mounth;
        protected 
byte Mounth // храним номер месяца, выдаем его string из массива по номеру элемента
        
{
            
get
            
{
                
byte count 1;
                while (
count <= Mounthes.Length)
                {
                    if (
Mounthes[count-1] == _mounth) break;
                    
count++;
                }
                return 
count;
            }
            
set
            
{
                
_mounth Mounthes[value-1];
            }
        } 

Условно закидываем номер месяца, а получаем его string название. Или это плохая практика?

Антихрист 03.11.2019 14:25

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 316781)
Спасибо ) энтерпрайз дорого (я ж не зарабатываю программированием), идея с partial интересная. Параллельно в Excel заношу публичные методы классов и их сигнатуры, на всякий случай.

Продолжаю закидывать страшными вопросами. Я наконец-то разобрался со свойствами (pax за это отдельное спасибо), но терзают сомнения, можно ли их применять вот так:

PHP код:

protected static string[] Mounthes = new[] { "января""февраля""марта""апреля""мая""июня""июля""августа""сентября""октября""ноября""декабря" };
protected 
string _mounth;
        protected 
byte Mounth // храним номер месяца, выдаем его string из массива по номеру элемента
        
{
            
get
            
{
                
byte count 1;
                while (
count <= Mounthes.Length)
                {
                    if (
Mounthes[count-1] == _mounth) break;
                    
count++;
                }
                return 
count;
            }
            
set
            
{
                
_mounth Mounthes[value-1];
            }
        } 

Условно закидываем номер месяца, а получаем его string название. Или это плохая практика?

Конкретно к этому примеру - выглядит не очень. В первую очередь за счет цикла с сравнением строк внутри гетера. Добавь одну переменную и закэшируй туда индекс.
PHP код:

protected static readonly string[] Monthes =
        {
            
"января""февраля""марта""апреля""мая""июня""июля""августа""сентября""октября""ноября",
            
"декабря"
        
};

        protected 
byte monthIndex;
        protected 
string monthName;

        protected 
byte MonthIndex
        
{
            
get => monthIndex;
            
set
            
{
                if (
value <= || value 12) return;
                
monthIndex = (byte) (value 1);
                
monthName Monthes[monthIndex];
            }
        }

        protected 
string MonthName => monthName


Randomize 03.11.2019 18:41

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 316766)
Когда кол-во классов становится большим становится сложно в голове удерживать какие методы они реализуют, интерфейсы наследуют и какими свойствами обладают.

Мне кажется, что тут скорее проблема проектирования и никакие документации не помогут. Стоит посмотреть на SOLID,
как на некий набор общепринятых практик по написанию легко поддерживаемого кода.
Естественно всё и сразу не надо пытаться исполнять, начать можно с "SRP",
а "DI" оставить до лучших времён, когда он действительно тебе будет нужен.

pax 05.11.2019 08:04

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 316781)
Спасибо ) энтерпрайз дорого (я ж не зарабатываю программированием), идея с partial интересная. Параллельно в Excel заношу публичные методы классов и их сигнатуры, на всякий случай.

Есть полезное окно, в котором всю структуру проекта можно посмотреть. Называется Обозреватель объектов (Вид => Обозреватель объектов). Там все можно подсмотреть. А если есть XML комментарии, то и их можно посмотреть в удобном формате.

Цитата:

Сообщение от Антихрист (Сообщение 316782)
Конкретно к этому примеру - выглядит не очень. В первую очередь за счет цикла с сравнением строк внутри гетера. Добавь одну переменную и закэшируй туда индекс.
PHP код:

protected static readonly string[] Monthes =
        {
            
"января""февраля""марта""апреля""мая""июня""июля""августа""сентября""октября""ноября",
            
"декабря"
        
};

        protected 
byte monthIndex;
        protected 
string monthName;

        protected 
byte MonthIndex
        
{
            
get => monthIndex;
            
set
            
{
                if (
value <= || value 12) return;
                
monthIndex = (byte) (value 1);
                
monthName Monthes[monthIndex];
            }
        }

        protected 
string MonthName => monthName


Вообще хранить название месяца в отдельной переменной не надо. Зачем память тратить. Используй свойство, если есть индекс.
PHP код:

protected string MonthName => Mounthes[monthIndex]; 

или
PHP код:

protected byte monthIndex = -1;
protected 
string MonthName => monthIndex == -null Mounthes[monthIndex]; 


Антихрист 05.11.2019 23:23

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от pax (Сообщение 316786)
Есть полезное окно, в котором всю структуру проекта можно посмотреть. Называется Обозреватель объектов (Вид => Обозреватель объектов). Там все можно подсмотреть. А если есть XML комментарии, то и их можно посмотреть в удобном формате.



Вообще хранить название месяца в отдельной переменной не надо. Зачем память тратить. Используй свойство, если есть индекс.
PHP код:

protected string MonthName => Mounthes[monthIndex]; 


Согласен, если monthIndex не может быть изменен в другом месте выйдя за рамки массива.
Цитата:

PHP код:

protected byte monthIndex = -1;
protected 
string MonthName => monthIndex == -null Mounthes[monthIndex]; 


Вроде С# не позволит впихнуть в byte отрицательное значение.
Как вариант
PHP код:

protected bytemonthIndex null


pax 07.11.2019 20:52

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от Антихрист (Сообщение 316787)
Вроде С# не позволит впихнуть в byte отрицательное значение.
Как вариант
PHP код:

protected bytemonthIndex null


Да, писал прям сюда, поэтому ошибся. Можно sbyte в данном случае использовать.

EvilOkta 07.11.2019 21:48

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от Антихрист (Сообщение 316787)
Согласен, если monthIndex не может быть изменен в другом месте выйдя за рамки массива.

Хорошая идея! Можно сделать, это действительно лучше

Цитата:

Сообщение от pax (Сообщение 316786)
Есть полезное окно, в котором всю структуру проекта можно посмотреть. Называется Обозреватель объектов (Вид => Обозреватель объектов). Там все можно подсмотреть. А если есть XML комментарии, то и их можно посмотреть в удобном формате.

Вот! Как раз таки подобное я искал, спасибо!

Цитата:

Сообщение от Randomize (Сообщение 316783)
Мне кажется, что тут скорее проблема проектирования и никакие документации не помогут. Стоит посмотреть на SOLID,
как на некий набор общепринятых практик по написанию легко поддерживаемого кода.
Естественно всё и сразу не надо пытаться исполнять, начать можно с "SRP",
а "DI" оставить до лучших времён, когда он действительно тебе будет нужен.

SOLID только начал разбираться, но мне уже не понравилось "Каждый класс должен иметь одну и только одну причину для изменений" - у меня в голове это выглядит как огромная куча классов, каждый из который использует единственный публичный метод, который делает что-то. Я больше привык когда класс описывает поведение в заданных рамках, чтобы не нарушать принципа бритвы Оккама.

Чтобы не заниматься ответом на цитаты, вопрос для понимания - в каком формате лучше использовать и хранить БД в Unity?
Или вообще без разницы?
upd конкретизирую вопрос - для проекта нужно подкачивать массивы информации в текстовом виде, в чем их лучше хранить и динамически при необходимости загружать - csv, txt, xml, xls и т.п.?

EvilOkta 31.10.2020 14:45

Ответ: Проблемы разработки от EvilOkta
 
И снова здравствуйте! Понимаю, что людей тут мало осталось, но вдруг кто поможет:
Код:

  private void ResetBoolState(params bool[] ResetState)
    {
        foreach (bool rs in ResetState)
        {
            rs = false;
        }
    }

Такая конструкция не работает, так как IEnumerable не может изменять элемент коллекции. Есть ли варианты чтобы смог?
Задача - передать несколько bool параметров в метод и сбросить их состояния.

Andvrok 31.10.2020 15:06

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 317853)
И снова здравствуйте! Понимаю, что людей тут мало осталось, но вдруг кто поможет:
Код:

  private void ResetBoolState(params bool[] ResetState)
    {
        foreach (bool rs in ResetState)
        {
            rs = false;
        }
    }

Такая конструкция не работает, так как IEnumerable не может изменять элемент коллекции. Есть ли варианты чтобы смог?
Задача - передать несколько bool параметров в метод и сбросить их состояния.

Никак, чтобы поменять значение примитивного типа вроде bool тебе надо его с ref передавать. А ref не стыкуется с params.

Randomize 31.10.2020 17:45

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 317853)
Задача - передать несколько bool параметров в метод и сбросить их состояния.

Можно собрать все булы в 1 большой инт.
Примеры тут: https://alemil.com/bitmask

EvilOkta 31.10.2020 17:58

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от Randomize (Сообщение 317855)
Можно собрать все булы в 1 большой инт.
Примеры тут: https://alemil.com/bitmask

Хорошая идея! Возьму на заметку. Я, правда, уже решил задачу, но более топорным способом. Енумы соответствуют названиям булевых переменных в аниматоре
PHP код:

foreach (AnimatorControllerParameter parameter in NPCAnimator.parameters)
        {
            
NPCAnimator.SetBool(parameter.namefalse);
        }
        
NPCAnimator.SetBool(Enum.GetName(typeof(enState), (int)CurrentAnimationState), true); 


EvilOkta 14.11.2020 23:21

Ответ: Проблемы разработки от EvilOkta
 
Созрел новый вопрос.
Есть лист объектов, который заполняется при старте игры.
PHP код:

public static List<GameObjectWorkPoints = new List<GameObject>(); 

На каждом объекте в сцене висит скрипт TableIsBusy с одним и тем же методом IAmBusy()
Есть событие на которое нужно подписать все эти методы с каждого объекта.
Делегат и событие создано, но никак не могу понять как получить имя метода с объекта в листе, для подписки. Копаю в эту сторону, но дает ошибку - явно не так.
PHP код:

foreach (GameObject WorkPlace in GameLogicInit.WorkPoints)
        {
            
PlaceIsBusy += WorkPlace.GetComponent<TableIsBusy>().GetComponent("IAmBusyNow");
        } 

Как все таки правильно такие штуки делать? Интересует, потому что такие списки могут быть сформированы в рантайме и тогда необходимо получать список методов объектов в листе на ходу.

Andvrok 15.11.2020 01:06

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 317893)
Созрел новый вопрос.
Есть лист объектов, который заполняется при старте игры.
PHP код:

public static List<GameObjectWorkPoints = new List<GameObject>(); 

На каждом объекте в сцене висит скрипт TableIsBusy с одним и тем же методом IAmBusy()
Есть событие на которое нужно подписать все эти методы с каждого объекта.
Делегат и событие создано, но никак не могу понять как получить имя метода с объекта в листе, для подписки. Копаю в эту сторону, но дает ошибку - явно не так.
PHP код:

foreach (GameObject WorkPlace in GameLogicInit.WorkPoints)
        {
            
PlaceIsBusy += WorkPlace.GetComponent<TableIsBusy>().GetComponent("IAmBusyNow");
        } 

Как все таки правильно такие штуки делать? Интересует, потому что такие списки могут быть сформированы в рантайме и тогда необходимо получать список методов объектов в листе на ходу.

Нет юнити под рукой, чтобы проверить, но чисто на сишарпе должно сработать что-то вроде:

PHP код:

PlaceIsBusy += WorkPlace.GetComponent<TableIsBusy>().IAmBusy

В подписку ты должен сам метод передать, а не вызов метода, соответственно без скобок ().
Ну и IAmBusy это же метод, а не тип, как ты его через GetComponent получать собрался?
И конечно же сигнатура метода IAmBusy должна подходить под делегат в твоём событии, но это, я думаю, ты и так понимаешь.

EvilOkta 15.11.2020 02:09

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от Andvrok (Сообщение 317894)
Нет юнити под рукой, чтобы проверить, но чисто на сишарпе должно сработать что-то вроде:

PHP код:

PlaceIsBusy += WorkPlace.GetComponent<TableIsBusy>().IAmBusy

В подписку ты должен сам метод передать, а не вызов метода, соответственно без скобок ().
Ну и IAmBusy это же метод, а не тип, как ты его через GetComponent получать собрался?
И конечно же сигнатура метода IAmBusy должна подходить под делегат в твоём событии, но это, я думаю, ты и так понимаешь.

Да, так заработало, спасибо! Сначала тупанул потому что вызываемый метод был private и соответственно был невидим для эвента.
По поводу EventSystem еще не разбирался что это за зверь такой, надо почитать. Пока тренируюсь на создании делегатов и эвентов, раньше и это было сложно - сейчас проще. Ну и как я понимаю эвенты и подписки создают слабую связность, что тоже хочется закрепить практикой )

Andvrok 15.11.2020 02:31

Ответ: Проблемы разработки от EvilOkta
 
Цитата:

Сообщение от EvilOkta (Сообщение 317896)
Да, так заработало, спасибо! Сначала тупанул потому что вызываемый метод был private и соответственно был невидим для эвента.
По поводу EventSystem еще не разбирался что это за зверь такой, надо почитать. Пока тренируюсь на создании делегатов и эвентов, раньше и это было сложно - сейчас проще. Ну и как я понимаю эвенты и подписки создают слабую связность, что тоже хочется закрепить практикой )

Покури на досуге https://habr.com/ru/post/527418/, может пару идей подкинет. Делегаты и события способ-то рабочий, но слишком «голый» и отчаянно требует сахара для удобств.

EvilOkta 15.11.2020 15:23

Ответ: Проблемы разработки от EvilOkta
 
Кстати по поводу событий и прочего. Я знаю, что плохая практика в Update постоянно проверять кучу состояний для управления объектом, но возник следующий вопрос. Попробую объяснить.
Допустим есть NPC, у него есть методы, отвечающие за различные "действия" - идти, сесть, стоять и т.п. Все эти методы выведены под общую сигнатуру, для того чтобы ими можно было бы управлять через события и т.п.
Но в чем подвох. Например метод "идти" получает точку назначения и включает NavAgent типа так:
PHP код:

NPCPathFinder.SetDestination(Target.transform.position); 

NPC начинает идти к цели - все отлично, но метод Walk по факту исполнен включением SetDestination, хотя NPC продолжает идти (я так и не разобрался, получается НавАгент работает асинхронно?). Допустим следующий метод после достижения цели должен быть "Стоять", и если формировать список методов для исполнения на основе делегата или списка методов, они сработают последовательно, т.е. установка цели -> метод Walk исполнен -> метод "стоять" (хотя NPC не дошел до цели). Это естественно неправильно.
Какие есть способы управления такими последовательностями?
У меня пока в голове только идея сделать какой-то промежуточный менеджер, который в апдейте каждую итерацию (что уже заставляет задуматься) проверяет достиг ли активный метод цели и если да, то активировать следующий в цепочке метод. Это нормальная практика, или костыли?
Надеюсь правильно объяснил задачу.

pax 16.11.2020 19:53

Ответ: Проблемы разработки от EvilOkta
 
Тебе нужно копать в сторону State Machine (машина состояний). В Unity есть встроенная в Animator'е. Её иногда можно приспособить для логики. Вот пример:


Можешь найти готовую машину состояний, на ассет сторе много разного. Поищи например так: https://assetstore.unity.com/?q=Beha...rees&orderBy=1

EvilOkta 06.12.2020 00:39

Ответ: Проблемы разработки от EvilOkta
 
Машина состояний постепенно пилится на базе аниматора (спасибо pax за видео), столкнулся со следующей задачкой, видимо туплю где-то.
Есть такой кусок кода:
PHP код:

public Transform SetWalkTarget()
    {
        
System.Random rnd = new System.Random(DateTime.Now.Millisecond);
        return 
GameLogicInit.Points[rnd.Next(0GameLogicInit.Points.Count)].transform;
    }
    } 

Он находится у множества объектов и по хорошему должен случайным образом выбирать точку назначения из списка для каждого объекта, но так как он срабатывает у всех объектов одновременно рандомайзер выдает им один и тот же результат. Как его разнообразить?

seaman 06.12.2020 01:38

Ответ: Проблемы разработки от EvilOkta
 
Иметь в игре один rnd (статический), получать там где надо rnd.Next(0,1), приводить к нужному диапазону уже в объекте.

pax 06.12.2020 18:11

Ответ: Проблемы разработки от EvilOkta
 
Есть уже статический рандом в Unity
https://docs.unity3d.com/ScriptRefer...dom.Range.html

EvilOkta 14.12.2020 23:58

Ответ: Проблемы разработки от EvilOkta
 
Немного странный вопрос. Дебаггером сейчас прохожу свой код, внутри аниматора. И вижу что порядок выполнения команд такой, что аниматор как-бы находится одновременно в двух разных State. Я так подозреваю это в момент transition происходит. Как то можно отловить такой момент чтобы отфильтровать? А то получается логика в разных стейтах начинает друг друга перебивать.

pax 15.12.2020 10:30

Ответ: Проблемы разработки от EvilOkta
 
Ну тебе надо настроить транзишн так, чтобы у него Has Exit Time галка была снята и длительность (duration) была 0.

EvilOkta 02.02.2021 13:26

Ответ: Проблемы разработки от EvilOkta
 
Есть еще вопрос, как можно посмотреть через VS какие объекты остаются в памяти?
Dispose вызываю, но такое ощущение что это не помогает.

upd: вроде разобрался, выяснил, что данные файла, загруженные в оперативную память почему то остаются после уничтожения объекта в
Microsoft.IO.RecyclableMemoryStreamManager
ее как то вручную нужно чистить?
upd2: все подозрение падает на строчку
PHP код:

FileInfo XLSXFile = new FileInfo(FilePath); 

в которой загружается файл в оперативную память. Данные дергаю из Excel документа.
Как я понял FileInfo не поддерживает IDisposable и этот объем радостно улетает в LOH даже если уже не нужен и я его превращаю в null
PHP код:

XLSXFile null 

Где можно поискать решение? При множественной загрузке файлов через этот метод происходит утечка памяти, т.к. каждый предыдущий файл остается в LOH...

pax 03.02.2021 08:03

Ответ: Проблемы разработки от EvilOkta
 
Попробуй просто после использования через какое-то время вызвать сборщик мусора GC.Collect(). Память сразу обычно не очищается.


Часовой пояс GMT +4, время: 02:04.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot