Страница 2 из 2

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 10 фев 2020, 21:03
greatPretender
Susanin писал(а):Можно юзать паттерн Command

спасибо, но , увы, с ООП я на "ваше высочество" ну или мне придётся переписать весь проект)
1max1 писал(а):На всякий случай, вот пример кода с объектом в качестве параметра:

Синтаксис:
Используется csharp
class XXX : MonoBehaviour
{
    UnityAction unityAction;

    void Start()
    {
        unityAction = mth(gameObject);
        unityAction();
    }

    UnityAction mth(GameObject go)
    {
        return () =>
        {
            // тут делаешь со своим
            // объектом что хочешь
            print(go.name);
            go.name = "asd";
            // бла бла бла...
        };
    }
}

Поэтому с корректировал так и всё получилось как надо ))
Синтаксис:
Используется csharp
public List<(UnityAction<GameObject> action, int prior)> ListQueueMethods = new List<(UnityAction<GameObject>, int)>();
public UnityAction<GameObject> callDefence = (GameObject go) => { };  // для массива функций
public UnityAction<GameObject>[] CallDefences;                        // массив функций

// а вызов оформил так
callDefence = aidef.CallDefences[0];
callDefence(gameObject);
AddMethod(aidef.callDefence, 1);

// ваш вариант метода с сортировкой
public void AddMethod(UnityAction<GameObject> action, int priority) {
     methods.Add((action, priority));
     methods.Sort((l, r) => l.priority.CompareTo(r.priority));
}
 

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 11 фев 2020, 20:08
greatPretender
Не. Короч я ошибся.
В роде этот код работает, но он не выполняет то, что мне нужно. А именно не добавляет в список Метод именно с параметром.
То есть, строчка №2 должна быть написана так:
AddMethod(aidef.callDefence(gameObject), 1);
но юнити на неё ругается, cs1503.
Не может преобразовать из void в UnityEngine.Events.UnityAction<UnityEngine.GameObject>.
Можно ли это как-то обойти?
А сам метод с параметром мне вообще не нужно вызывать, как это указано в строчке №1 , но как тогда присвоить метод через Action да ещё и с параметром??((
greatPretender писал(а):
Синтаксис:
Используется csharp
public List<(UnityAction<GameObject> action, int prior)> ListQueueMethods = new List<(UnityAction<GameObject>, int)>();
public UnityAction<GameObject> callDefence = (GameObject go) => { };  // для массива функций
public UnityAction<GameObject>[] CallDefences;                        // массив функций

// а вызов оформил так
callDefence = aidef.CallDefences[0];
callDefence(gameObject); // строчка №1
AddMethod(aidef.callDefence, 1); // строчка №2

// ваш вариант метода с сортировкой
public void AddMethod(UnityAction<GameObject> action, int priority) {
     ListQueueMethods.Add((action, priority));
     ListQueueMethods.Sort((l, r) => l.priority.CompareTo(r.priority));
}
 

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 11 фев 2020, 22:45
1max1
Синтаксис:
Используется csharp
class XXX : MonoBehaviour
{
    List<(UnityAction<GameObject> action, int priority)> methods = new List<(UnityAction<GameObject>, int)>();

    void Start()
    {
        AddMethod((arg0) => print(arg0.name), 0);

        var go1 = new GameObject("GO_1");
        var go2 = new GameObject("GO_2");
        var go3 = new GameObject("GO_3");

        methods[0].action(go1); // GO_1
        methods[0].action(go2); // GO_2
        methods[0].action(go3); // GO_3
    }

    void AddMethod(UnityAction<GameObject> action, int priority)
    {
        methods.Add((action, priority));

        methods.Sort((l, r) => l.priority.CompareTo(r.priority));
    }
}

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 13 фев 2020, 21:31
greatPretender
1max1 писал(а):
Синтаксис:
Используется csharp
class XXX : MonoBehaviour
{
    List<(UnityAction<GameObject> action, int priority)> methods = new List<(UnityAction<GameObject>, int)>();

    void Start()
    {
        AddMethod((arg0) => print(arg0.name), 0);

        var go1 = new GameObject("GO_1");
        var go2 = new GameObject("GO_2");
        var go3 = new GameObject("GO_3");

        methods[0].action(go1); // GO_1
        methods[0].action(go2); // GO_2
        methods[0].action(go3); // GO_3
    }

    void AddMethod(UnityAction<GameObject> action, int priority)
    {
        methods.Add((action, priority));

        methods.Sort((l, r) => l.priority.CompareTo(r.priority));
    }
}

Короче, шаманю, шаманю, а что-то получается, но при этом другое отпадывает )))
Возможно я как-то не очень доходчиво объясняю свою цель. Поясню в кратце.
В процессе игры постоянно появляется потребность запускать методы, но предварительно проверив переменную. Как только переменная условно говоря >0, можно запустить метод. Но пока переменная <0 таких методов в очереди на запуск можно скопиться несколько десятков.
Вывод: мне нужно где-то хранить эти методы. Причём у них есть приоритет очередности запуска между собой, а не просто последовательно по времени их появления. А также, каждый метод должен взять себе параметр именно при своей генерации ,а не при запуске, т.к. потом ссылку на этот параметр можно уже не получить. Поэтому я пытаюсь где-то сохранить метод и параметр, который в него войдёт, и ждать время, когда можно будет его запустить, а не закидывать параметр в тот момент, когда можно его вызвать.
Я пробовал вместо методов использовать корутины с отложенным запуском через waitseconds и пробовал while. Но это всё или зависон игры или большие сложности.
Наверняка это требовалось многим людям и это должно быть как-то прописано в .net.
Поэтому пришёл к выводу попробовать сделать список методов. Но метод должен быть с параметром, который он берёт до попадания в список, а не при вызове, т.к. не возможно синхронизировать какой параметр к какому методу идёт, тем более после пересортировки методов внутри списка.
Поэтому тасуя ваш, свой и код из сети у меня то получается передать метод с нужным параметром в список (подтверждаю дебагом), то просто вызвать его до сортировки,а вот передать метод с нужным параметром, перетасовать его в списке и вызвать уже готовый метод, идущий первый в списке по приоритету пока не получается ))
А ваш код даёт ответы, но вписать в реалии моего скрипта не получается ))
Я не прогер по образованию, а при самостоятельном постижении не получается добиться нужного результата,
Может у вас получится что-то нашаманить?))
Вот мои исходные данные:
// список , куда добавляются методы с параметрами и тут же пересортировываются
public List<(UnityAction<GameObject> action, int priority)> methods = new List<(UnityAction<GameObject>, int)>();

// это выражение работает,
AddMethod((gameObject) => someMethod(gameObject), 1);

// ваш метод кот-ый пересортировывает список (он безотказно работает)
public void AddMethod(UnityAction<GameObject> action, int priority) {
methods.Add((action, priority));
methods.Sort((l, r) => l.prior.CompareTo(r.prior));
}

---
почему-то ругается на invoke в этой строчке
methods[0].action.Invoke(); // берём первое на очереди
мол отсутствует аргумент, соотв-щий какому-то arg0. Про arg0 тоже не понял что это , в инете лазил.
а это выражение работает: параметр gameObject передаётся в в метод в список
methods[0].action(gameObject);
// но это строчка работает только в скрипте, кот-ый лежит на этом gameObject, не могу понять как написать так, чтобы gameObject передать туда ссылкой

----
В общем, вот так. )

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 13 фев 2020, 23:24
1max1
Ну вот вызов без параметров, я уже не знаю как тебе помочь, вроде бы уже был подобный код где-то выше, или нет? Я запутался...
Синтаксис:
Используется csharp
class XXX : MonoBehaviour
{
    public List<(UnityAction action, int priority)> methods = new List<(UnityAction, int)>();

    void Start()
    {
        var go1 = new GameObject("Go_1");
        var go2 = new GameObject("Go_2");

        AddMethod(() => SomeMethod(go1), 1);
        AddMethod(() => SomeMethod(go2), 2);

        methods[0].action(); // Go_1
        methods[1].action(); // Go_2
    }

    void SomeMethod(GameObject go)
    {
        print(go.name);
    }

    public void AddMethod(UnityAction action, int priority)
    {
        methods.Add((action, priority));
        methods.Sort((l, r) => l.priority.CompareTo(r.priority));
    }
}

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 13 фев 2020, 23:31
Cr0c
Что будет, если в списке есть 5 приоритет и добавить ещё один 5?

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 14 фев 2020, 00:01
1max1
Cr0c писал(а):Что будет, если в списке есть 5 приоритет и добавить ещё один 5?

Нужно выкинуть ексепшин и закрашить игру нафиг)))

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 16 фев 2020, 08:30
greatPretender
1max1 писал(а):
Cr0c писал(а):Что будет, если в списке есть 5 приоритет и добавить ещё один 5?

Нужно выкинуть ексепшин и закрашить игру нафиг)))

Нет. Это значит должно появиться 6ое чувство.))
Когда всё сложно и много жёстких условий, это означает, что есть где-то один единственный пазл, который как никакой другой подойдёт именно в это пустое место и свяжет всю картину во едино, а значит есть пространство для расплескивания мысли а-ля гениального инженерного решения[костыля] ) и я его найду)

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 20 фев 2020, 21:00
greatPretender
1max1 писал(а):... я уже не знаю как тебе помочь, ...[/syntax]

Короче я придумал как выкрутиться. Не идеальный конечно вариант, но и не хрупкий как костыль. Зато думаю безотказный.
В момент когда в коде генерируется потребность добавить какой-то метод в очередь, у меня генерируется порядковый номер в реестр, он добавляется в словари в паре с номером экшена, и с номером параметра в свой словарь. И черед этот номер я связываю между собой номер экшена , даже после сортировки по приоритету и номер параметра, кот-ый потом нужно передать в этот экшен.
И всё ок, но наткнулся на проблему:
Мне потребовалось заменить это:
List<(UnityAction<GameObject> action, int priority)> methods = new List<(UnityAction<GameObject>, int)>();

на
List<(int numbAction, int priority)> methods = new List<(int, int)>();

т.е. теперь в списке сортируются не Экшен по int-у, а int-ы по int-у - индексы этих экшенов из массива экшенов Action<GameObject>[] CallDefences3;
Проблема такая, я не могу получить элемент их такого 2-ух столбикового списка.
Ругается на строчку:
int umbQue = methods [0];
Мол, не удаётся преобразовать тип "int numbAction, int priority" в "int".
Подскажите, пжл, а то не замечал этой проблемы, т.к. ваша строчка работала:
methods[0].action.Invoke();

Инет мне не помог ((

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 20 фев 2020, 22:37
seaman
Вы неявно используете List<Tuples<int, int>>. Я бы использовал Dictionary

Ну или явно получите нужный элемент Tuples
int umbQue = methods[0].numbAction;

Re: Как реализовать сложную очередность методов [РЕШЕНО]

СообщениеДобавлено: 23 фев 2020, 11:30
greatPretender
seaman писал(а):Вы неявно используете List<Tuples<int, int>>. Я бы использовал Dictionary

Ну или явно получите нужный элемент Tuples
int umbQue = methods[0].numbAction;

Воон оно что )
...
Очень благодарю. Всё заработало ))