Так, а зачем вообще тащить эти костыли в движок? Все анимации лучше всего хранить в префабах (небольшие скриптовые файлы содержащие в себе всю логику взаимодействия анимаций, эвенеты, нарезка длинных анимаций на короткие, смешивание, скорость воспроизведения, цикличность воспроизведения, ИК кости и прочие констрейнты с их настройками, и т.д.), а из кода уже просто обращаться к этому компоненту как к отдельному классу и его Стейтам.
__________________ Иван Топорышкин пошел на охоту,
С ним пудель пошел, перепрыгнув забор,
Иван, как бревно провалился в болото,
А пудель в реке утонул, как топор.
Небольшая демонстрация того, на каких тоненьких ниточках в С++ держится детектирование тех или иных конструкций. В чистом Си, напомню, таких ситуаций не могло возникнуть в принципе. Напомню также, что компилятор в первую очередь ориентируется по синтаксису и только во вторую - по типу, причём синтаксис имеет определяющее значение.
Конструкция, помеченная стрелочкой, до вчерашнего дня ошибочно трактовалась компилятором как объявление новой функции. А поскольку функция внутри функции невозможна, то естественно выпадала ошибка. Почему так происходило? Первые два токена в этом плане не могут служить чётким критерием, при условии, что первый токен - реально существующий тип, а второй - имя. Дальше у нас есть ветвление, либо это переменная (неважно в сущности, локальная или глобальная), либо действительно объявление новой функции. В чистом Си, наличие открывающей круглой скобки уже явным образом говорило - перед нами объявление новой функции. В С++ это не так, ведь это может быть вызов кастомного конструктора. То есть, даже прочитав скобку, мы всё еще не можем определить что перед нами. Надо читать то что внутри скобок. Я не знаю как это устроено в самом С++, но я лично делаю лукап на несколько токенов вперёд (обычно на один, не больше), чтобы оценить обстановку, а потом возвращаюсь на текущее место. Так вот, в моменте ветвления, когда токен ( уже прочитан, а следующий находится в памяти, на первый взгляд мы можем просто посмотреть что это за токен и сделать выводы. Если токен это целое число, дробное число, строка или же пунктуация, то это 100% вызов конструктора. Следующая проверка - на наличие модификаторов или declspec. Если они есть - значит перед нами декларация новой функции. Разумеется они быть не обязаны. Следующая проверка на то, что следующий токен не является известным компилятору типом. И тут всё и падает с ошибкой. Потому что g_vecZero выглядит вот так:
C++ Source Code:
#define g_vecZero vec3( 0.0f )
Таким образом компилятор читает слово vec3, находит такой тип и думает - это объявление функции. Ну и дальше идёт ругань про невозможность объявления функции внутри функции. И невозможность распарсить её аргументы. А потому что кроме вызова пользовательских конструкторов в С++ есть ещё r-value объекты, которые добавляют ещё хаоса. И теперь к типу дополнительно надо проверять так же наличие очередной открывающей круглой скобки, чтобы убедиться что перед нами.
А ведь в теории конструктор может быть шаблонной функцией...
Дядя Миша писал: Конструкция, помеченная стрелочкой, до вчерашнего дня ошибочно трактовалась компилятором как объявление новой функции
Но это и есть объявление новой функции. Согласно принципу MVP в плюсах, "всё, что выглядит как объявление функции, есть объявление функции".
Чтобы избежать этого, в С++11 имеется инициализация фигурными скобками. Ну или по классике:
C++ Source Code:
auto transform = xform(...);
Что абсолютно эквивалетно приведённому выше коду, но не выглядит как объявление функции.
__________________
Правдой дорожить, лжи не потакать,
Дальних не судить, ближним помогать,
С тишиной сойтись на исходе дня
Научи меня, Родина моя!
XaeroX писал: "всё, что выглядит как объявление функции, есть объявление функции".
Осталось только определиться с критериями. Потому что единственным способом отдуплить объявление функции от вызова конструктора является анализ того что между скобками.
Я пока не знаю так хорошо синтаксис, но что тут нелегального? Вызов функции, и задаёшь ей аргументы. Только мне не понятно что есть xform и зачем он тут? Тогда уж как то так myvar = xform.transform( g_vecZero, vec3( 0.0f, m_absangles.y, 0.0f ));
__________________ Иван Топорышкин пошел на охоту,
С ним пудель пошел, перепрыгнув забор,
Иван, как бревно провалился в болото,
А пудель в реке утонул, как топор.