Анимация корутиной РЕШЕНО

Графический интерфейс пользователя

Анимация корутиной РЕШЕНО

Сообщение pesiik 03 апр 2017, 20:43

Изображение

У меня просто панель с цифрами и индикатор этажей лифта. Нажимаешь кнопку - лифт едет на выбранный этаж. Плавное перемещение головки реализовывал с помощью корутины. Но при ее запуске юнити виснет. Следствие бесконечного цикла. Корутина внизу кода. Подскажите что я не так сделал

Синтаксис:
Используется csharp
public class Initializator : MonoBehaviour
{
 
    private byte choisesFloor = 1;
    private byte currentFloot = 1;
    private const byte maxFloor = 9;
    private float divisionOfFloor;
 
    private List<Button> panelOfButtons;
    public List<Button> PanelOfButtons { get { return panelOfButtons; } set { panelOfButtons = value; } }
    private GameObject floorIndicator;
    public GameObject FloorIndicator { get { return floorIndicator; } set { floorIndicator = value; } }
    private RectTransform lineFloorRectTransform;
 
    private static Initializator instance;
    public static Initializator Instance { get { return instance; } }
 
    void Awake()
    {
        instance = this;
        panelOfButtons = transform.FindChild("ButtonsOfElevator").GetComponentsInChildren<Button>().ToList();
        foreach (Button buttonOfFloor in panelOfButtons)
        {
            byte floor = byte.Parse(buttonOfFloor.GetComponentInChildren<Text>().text);
            buttonOfFloor.onClick.AddListener(()=>SetNumberOfFloor(floor));
            buttonOfFloor.onClick.AddListener(StartCoroutineProgressForFloor);
        }
        floorIndicator = transform.FindChild("FloorIndicator").gameObject;
        lineFloorRectTransform = floorIndicator.transform.FindChild("ProgressLine").GetComponent<RectTransform>();
        CalculateRectForFloorIndicator();
    }
 
 
    public void SetNumberOfFloor(byte _number)
    {
        choisesFloor = _number;
    }
 
 
 
    void CalculateRectForFloorIndicator()
    {
        RectTransform rectTransform = floorIndicator.GetComponent<RectTransform>();
        divisionOfFloor = Mathf.Abs(rectTransform.sizeDelta.x / panelOfButtons.Count);
       
    }
 
    void StartCoroutineProgressForFloor()
    {
        lineFloorRectTransform.gameObject.SetActive(true);
        StartCoroutine(ProgressForFloorIndicator());
    }
 
    IEnumerator ProgressForFloorIndicator()
    {
        float selectedFloor = Mathf.Abs( divisionOfFloor * (currentFloot - choisesFloor));
        Vector3 v3 = lineFloorRectTransform.transform.localPosition;
        Debug.Log(lineFloorRectTransform.transform.localPosition.x + " begin");
 
        if (choisesFloor >= currentFloot)
            while (lineFloorRectTransform.transform.localPosition.x < v3.x + selectedFloor)
            {
                lineFloorRectTransform.transform.localPosition = new Vector3(v3.x + 1f, v3.y);
            }
        else
        {
            while (lineFloorRectTransform.transform.localPosition.x > v3.x + selectedFloor)
            {
                lineFloorRectTransform.transform.localPosition = new Vector3(v3.x - selectedFloor*0.1f, v3.y);
            }
        }
        Debug.Log(lineFloorRectTransform.transform.localPosition.x + " end");
 
        currentFloot = choisesFloor;
        yield return null;
    }
 
    void CheckForCurrentFloor()
    {
       
    }
 
}
Последний раз редактировалось pesiik 03 апр 2017, 23:42, всего редактировалось 1 раз.
pesiik
UNITрон
 
Сообщения: 223
Зарегистрирован: 01 авг 2015, 11:46

Re: Анимация корутиной

Сообщение samana 03 апр 2017, 20:53

Я не очень тщательно вник в код, возможно что-то и пропустил, но меня очень смутил единственный yield в самом конце, который там и не нужен, ведь корутина и так завершится. А ведь вы пытаетесь в цикле while перемещать объект, поэтому в каждом while должен быть свой yield, что-то вроде
Синтаксис:
Используется csharp
while (lineFloorRectTransform.transform.localPosition.x < v3.x + selectedFloor)
            {
                lineFloorRectTransform.transform.localPosition = new Vector3(v3.x + 1f, v3.y);
                yield return null;
            }


Хотя возможно ошибка и в расчётах и какое-то условие просто никогда не возвращает true, но это надо проверять.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Анимация корутиной

Сообщение Paul Siberdt 03 апр 2017, 21:12

samana, энумератор профайрит ошибку, если внутри его тела не будет гарантированно исполняемого yield.
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Анимация корутиной

Сообщение samana 03 апр 2017, 21:13

Paul Siberdt писал(а):samana, энумератор профайрит ошибку, если внутри его тела не будет гарантированно исполняемого yield.

Вы правы, об этом я вспомнил, но было слишком поздно.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Анимация корутиной

Сообщение pesiik 03 апр 2017, 21:16

Paul Siberdt писал(а):энумератор профайрит ошибку, если внутри его тела не будет гарантированно исполняемого yield.


Этого не произошло. Корутина просто выполнилась на одну итерацию в блоке while и все. Но зато не зависло
pesiik
UNITрон
 
Сообщения: 223
Зарегистрирован: 01 авг 2015, 11:46

Re: Анимация корутиной

Сообщение Paul Siberdt 03 апр 2017, 21:17

samana писал(а):
Paul Siberdt писал(а):samana, энумератор профайрит ошибку, если внутри его тела не будет гарантированно исполняемого yield.

Вы правы, об этом я вспомнил, но было слишком поздно.

С другой стороны, я подумал, что Вы разместите в каждом лупе по елде, но было тоже поздно. :D
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Анимация корутиной

Сообщение pesiik 03 апр 2017, 21:17

samana писал(а): А ведь вы пытаетесь в цикле while перемещать объект, поэтому в каждом while должен быть свой yield.


разве тогда корутина после одной итерации не закончит свою работу?
pesiik
UNITрон
 
Сообщения: 223
Зарегистрирован: 01 авг 2015, 11:46

Re: Анимация корутиной

Сообщение Paul Siberdt 03 апр 2017, 21:19

Для симпатишности и читабельности кода посоветовал бы в ифах и прочей двусмысленной логике лишь получать значение дельты или новой позиции, а навешивать это значение уже под развилками.

Коротинка закончит работу, если вы ее не перезапускаете. Так что, заводите луп с условием выхода и обязательно обезопасьте свои нервы и проц компьютера наличием внутри лупа елды.
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Анимация корутиной

Сообщение samana 03 апр 2017, 21:21

pesiik писал(а):разве тогда корутина после одной итерации не закончит свою работу?

Конечно нет, на то она и корутина, чтобы выполнятся столько, сколько нужно. То-есть каждый кадр будет происходить только один цикл из while, до тех пор, пока условие не вернёт false.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Анимация корутиной

Сообщение Paul Siberdt 03 апр 2017, 21:25

samana писал(а):Конечно нет, на то она и корутина, чтобы выполнятся столько, сколько нужно.

Собственно, тоже самое можно сказать и про функцию ;)
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Анимация корутиной

Сообщение samana 03 апр 2017, 21:31

Paul Siberdt писал(а):Собственно, тоже самое можно сказать и про функцию

Согласен, это моё объяснение получилось не очень. :-ss
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Анимация корутиной

Сообщение pesiik 03 апр 2017, 21:38

Paul Siberdt писал(а):Для симпатишности и читабельности кода посоветовал бы в ифах и прочей двусмысленной логике лишь получать значение дельты или новой позиции, а навешивать это значение уже под развилками.

Коротинка закончит работу, если вы ее не перезапускаете. Так что, заводите луп с условием выхода и обязательно обезопасьте свои нервы и проц компьютера наличием внутри лупа елды.


А какое же условие тогда в блоке while? у меня же там если лифт выше выбранного этажа то условие одно, если ниже условие другое. Я же не могу просто написать "пока
!(lineFloorRectTransform.transform.localPosition.x == currentFloorRectTransform.x)

Синтаксис:
Используется csharp
IEnumerator ProgressForFloorIndicator()
    {
        float selectedFloor = Mathf.Abs( divisionOfFloor * (currentFloot - choisesFloor));
        Vector3 v3 = lineFloorRectTransform.transform.localPosition;
        Debug.Log(lineFloorRectTransform.transform.localPosition.x + " begin");
        Vector3 vectorСhanges;

        if (choisesFloor >= currentFloot)
            vectorСhanges = new Vector3(v3.x + 1f, v3.y);
        else
            vectorСhanges = new Vector3(v3.x - selectedFloor * 0.1f, v3.y);

        while (true)
        {
           
        }

        Debug.Log(lineFloorRectTransform.transform.localPosition.x + " end");

        currentFloot = choisesFloor;
        yield return null;
    }
pesiik
UNITрон
 
Сообщения: 223
Зарегистрирован: 01 авг 2015, 11:46

Re: Анимация корутиной

Сообщение Paul Siberdt 03 апр 2017, 22:07

Синтаксис:
Используется boo
Энумератор
{

        ВасяПупкин
        Скорость
        ЦеррозПечени
        Опьянение

        Пока не ЦеррозПечени
        {
            если(Опьянение)
            {
                Cкорость медленная
            }
            иначе
            {
                Скорость быстрая.
            }
           
            Двигаем ВасяПупкин вперед со Скорость скоростью.

            Ждем немного.
        }
       
        Объявление в газету("ВасяПупкин умер").
}
Аватара пользователя
Paul Siberdt
Адепт
 
Сообщения: 5317
Зарегистрирован: 20 июн 2009, 21:24
Откуда: Moscow, Russia
Skype: siberdt
  • Сайт

Re: Анимация корутиной

Сообщение pesiik 03 апр 2017, 22:25

Paul Siberdt писал(а):
Синтаксис:
Используется boo
Энумератор
{

        ВасяПупкин
        Скорость
        ЦеррозПечени
        Опьянение

        Пока не ЦеррозПечени
        {
            если(Опьянение)
            {
                Cкорость медленная
            }
            иначе
            {
                Скорость быстрая.
            }
           
            Двигаем ВасяПупкин вперед со Скорость скоростью.

            Ждем немного.
        }
       
        Объявление в газету("ВасяПупкин умер").
}



xD но я все равно ниче не понял. извините за то, что я туплю. но у меня там в одном случае был while(localPos.x < pointOfDestanation){ to do what tak raz raz }
в другом случае while (localPos.x > pointOfDestanation {sit down chisti raz raz} как объединить и тот случай и тот в один, до меня никак не дойдет

НИКАК НЕ ОПРЕДЕЛЮСЬ С УСЛОВИЕМ В WHILE. Ломаю голову битый час. Ведь при движении лифта вниз он должен проверять пока стрелка правее нужной цифры, а если лифт вверх движется, то пока стрелка слева от цифры. Вот и получается, что while нужно запихивать в условие
pesiik
UNITрон
 
Сообщения: 223
Зарегистрирован: 01 авг 2015, 11:46

Re: Анимация корутиной РЕШЕНО

Сообщение pesiik 03 апр 2017, 23:42

Синтаксис:
Используется csharp
IEnumerator ProgressForFloorIndicator()
    {
        float selectedFloor = Mathf.Abs(divisionOfFloor * (currentFloot - choisesFloor));
        Vector3 v3 = lineFloorRectTransform.transform.localPosition;
        Debug.Log(lineFloorRectTransform.transform.localPosition.x + " begin");
        Vector3 vectorСhanges;


        if (choisesFloor >= currentFloot)
        {
            vectorСhanges = new Vector3(v3.x, v3.y);
            while (lineFloorRectTransform.localPosition.x < v3.x + selectedFloor)
            {
                vectorСhanges = new Vector3(vectorСhanges.x+= 0.01f,vectorСhanges.y);
                lineFloorRectTransform.localPosition = vectorСhanges;
               
            }
            currentFloot = choisesFloor;
        }

        else if(choisesFloor<currentFloot)
        {
            vectorСhanges = new Vector3(v3.x, v3.y);
            while (lineFloorRectTransform.localPosition.x > v3.x - selectedFloor)
            {
                vectorСhanges = new Vector3(vectorСhanges.x -= 0.01f, vectorСhanges.y);
                lineFloorRectTransform.localPosition = vectorСhanges;
            }
            currentFloot = choisesFloor;
        }


решено таким образом. но плавности наезда нет. заведу отдельную тему
pesiik
UNITрон
 
Сообщения: 223
Зарегистрирован: 01 авг 2015, 11:46


Вернуться в uGUI

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2