А вы когда записываете full-body avatar, он уникальный для каждой реальной модели? Или вы переносите на какую-нибудь унифицированную модель (SMPL и его развитие и прочие)?
Иными словами - можно ли записанной модели добавить иную анимацию?
P.S. Если переносите - так как решаете вопрос подстройки анимации в зависимости от параметров модели?
Хорошая статья (с почином), так держать! У меня небольшой pet-project на Unity, поэтому несколько комментариев: 1. Если мы коснулись Git и Unity, обязательно добавьте в отслеживание *.meta файлы. В них содержится мета-информации о данных, которые Unity применяет к каждому файлу. Без этого ваш коммит может не содержать выполненных в редакторе действий. Чтобы было удобно - зайдите в настройки редактора и установите следующие параметры:
Version Control Mode: Visible Meta File;
Assets Serialization: Force Text
2. Настройте отслеживание файлов. К сожалению, многие файлы, применяемые в Unity - это большие файлы (картинки, видео, текстуры). Для них желательно использовать Git LFS. Для этого необходимо настроить .gitattributes чтобы автоматизировать добавление файлов.
3 Самое главное! У вас непременно будут конфликты слияния (для файлов .scene, .prefab и прочих). Используйте для них UnityYAMLMerge.
В целом в сети есть множество ресурсов, где подробно описана процедура настройки Git под Unity, вы можете дополнить ваш гайд, чтобы у новичка появилось полное понимание как работать с системой контроля версий относительно Unity.
Я сам его использую более года.
Удобно, но закрывает только задачи 1 пользователя.
Поэтому рассматривать его в контексте систем знаний для командной работы — невозможно.
Честно — ждал этого ответа.
Для личной системы знаний — joplin удобен, но сделать обмен данными, общее управление достаточно сложно. Неизбежно получаем конфликты.
А с последней итерацией плагинов — Joplin просто стал великолепен!
Но только для single user
То есть у вас блендшейпы на все случаи жизни? Например мы сгибаем руку в суставе и для корректного отображения этой анимации дизайнер должен прорисовать блендшейп для модели человека, для модели одежды (для каждой модели одежды причем)? То есть добавление любой новой модели одежды или человека — огромная работа?
А вы прорабатывали собственную генерацию на подобие SMPL модели?
А можете поделится литературой по этой теме — в частности мне необходимо решить задачу скиннинга в реалтайм по данным с depth камеры.
Как производить трансформирование вершин модели я в принципе понимаю, однако возникает проблема привязки вершин к joint-ам и возникает отвратительная анимация движения.
(Если добавите источники — это 95% ответа на поставленный выше вопрос)
Да, можно добавить блокировку (как советуют в указанных ресурсах), но это бессмысленно. Однако в Unity все сложно с потоками (половина функционала unity не может быть вызвана не из основного потока), поэтому если и запускать потоки дополнительной обработки — то в Start(). К тому времени все Awake отработают.
А мой класс вывалится с ошибкой даже с блокировкой — по той причине что вызов GetComponent() не может быть совершен не из главного потока. Поэтому ни о какой потокобезопасности и не может быть и речи. Один из вариантов — разделение по времени (то что выше описал).
Смешно сказать, но очень часто индексирую (часто делают в обработке изображений для правильной обработки краев).
Логика в исключении есть — но давайте тогда подумаем, что мы за этим тянем? Дополнительная обработка исключений — кто-то должен отловить и обработать эту ошибку (а кто?). В итоге мы придем к тому же коду, только оформленному иначе.
Касательно DontDestroyOnLoad() -> он тащит за собой следующий вызов
/// /// Do not destroy the target Object when loading a new Scene.
///
/// An Object not destroyed on Scene change.
[MethodImpl(MethodImplOptions.InternalCall)]
[FreeFunction(«GetSceneManager().DontDestroyOnLoad»)]
public static extern void DontDestroyOnLoad(Object target);
Если лезть дальше, то просто помечается объект, не удалятся (KeepAlive()). И если мы накидаем несколько на сцену объектов одного класса, то когда будут уничтожены эти объекты? При выходе из приложения.
Как я это проверил — наследовал вышеуказанный синглтон и просто добавил в него счетчик созданных объектов (в конструктор и деструктор(финализатор)).
Вообще логика мне ваша понятна, но в данном случае я предпочитаю сделать так, чтобы точно держать в памяти 1 объект.
Так смысл синглтона в том, что он 1 будет на весь проект. Мы и так кинем сообщение об ошибке, но приложение останется работоспособным и не упадет. И убивать дополнительные инстансы является верным делом, так как они просто будут сидеть в памяти и все. А за счет DontDestroyOnLoad объект не будет почищен уборщиком памяти и просто будет висеть. У меня все приложении должны работать 24/7 без присмотра пользователя, если я оставлю exception, то при вызове какого-нибудь захудалого менеджера раз в 2-3 часа будет вызывать падение приложения. Или писать логику на обработчик ошибок (каждый раз разную). Такие доводы.
Вот этого не понял.
В одном случае мы проверяем, что на сцене нет объектов, которые создают ложные синглтоны (например при переходе между сценами оставили какой-то менеджер). И устраняем эти ложные объекты. Например при работе со фоновым звуком, в каждой сцене не надо иметь менеджер звука — нужно только его вызывать. И еще интересный момент — успешная замена в итоге вызовет исключение, если будет найдено более 1 объекта. То есть мы еще и поимеем обработку исключений. Адекватно ли это? FYI, абсолютно нет.
Касательно размазано — да так и есть, поэтому я предоставил ссылки, где предоставлен весь этот код. Я просто собрал его вместе и пояснил в чем его удобство. На гениальность не претендую)
Я добавляю код, который вырос за время работы с этим паттерном. Все расписал в подпунктах, создания, инициализации и уничтожения объектов — я не находил на хабре статей в которых освещались эти моменты.
Применительно к Unity — совсем немного времени на нем провел, пришел из плюсов с полгодика назад.
Отсюда вопрос — хорошая литература и проекты по Unity (Net)- не подскажешь? А то я больше занимаюсь обработкой изображений, на Unity у меня небольшой проектик по AR (в ТЦ Капитолий стоит, майки примерять) и чувствую что нагреб граблей по незнанию.
Поддерживаю
Сам синглтон еще терпим — но в крайне редких случаях. Unity позволяет обойтись без него стандартными средствами. Проблем приносит на порядок больше.
SL — просто отличный пример как не стоит делать (за редким исключением).
По факту SL хорошо смотрится вкупе с DI — когда каждый сервис является подмножеством взаимозаменяемых сервисов, но сложность этого подхода все же ставит его в антипаттерны.
Проверяли логику работы данных синглтонов при переходе между сценами?
Накидаю кейс проверки — нужно вызывать методы синглтона посредством делегатов (UnityEvent). Допустим используем синглтон для музыки, пишем обертку для дизайнера, чтобы он мог ручками накидывать необходимые ему взаимосвязи через интерфейс Unity Editor — как отработает ваш код?
Я пока данный глюк так и не поборол.
Под катом мой код сингелтона:
Singelton.cs
using UnityEngine;
/// <summary>
/// Реализация сингелтона для наследования.
/// </summary>
/// <typeparam name="T">Класс, который нужно сделать сингелтоном</typeparam>
/// <remarks>/// Если необходимо обращаться к классу во время OnDestroy или OnApplicationQuit
/// необходимо проверять наличие объекта через IsAlive. Объект может быть уже
/// уничтожен, и обращение к нему вызовет его еще раз.
///
///
/// При использовании в дочернем классе Awake, OnDestroy,
/// OnApplicationQuit необходимо вызывать базовые методы
/// base.Awake() и тд.
///
/// Добавил скрываемый метод Initialization - чтобы перегружать его и использовать
/// необходимые действия.
///
/// Создание объекта производится через unity, поэтому использовать блокировку
/// объекта нет необходимости. Однако ее можно добавить, в случае если
/// понадобится обращение к объекту из других потоков.
///
/// Из книг:
/// - Рихтер "CLR via C#"
/// - Chris Dickinson "Unity 2017 Game optimization"
///</remarks>
public class Singelton<T> : MonoBehaviour where T : Singelton<T>
{
private static T instance = null;
private bool alive = true;
public static T Instance
{
get
{
if (instance != null)
{
return instance;
}
else
{
//Find T
T[] managers = GameObject.FindObjectsOfType<T>();
if (managers != null)
{
if (managers.Length == 1)
{
instance = managers[0];
DontDestroyOnLoad(instance);
return instance;
}
else
{
if (managers.Length > 1)
{
Debug.LogError($"Have more that one {typeof(T).Name} in scene. " +
"But this is Singelton! Check project.");
for (int i = 0; i < managers.Length; ++i)
{
T manager = managers[i];
Destroy(manager.gameObject);
}
}
}
}
//create
GameObject go = new GameObject(typeof(T).Name, typeof(T));
instance = go.GetComponent<T>();
instance.Initialization();
DontDestroyOnLoad(instance.gameObject);
return instance;
}
}
//Can be initialized externally
set
{
instance = value as T;
}
}
/// <summary>
/// Check flag if need work from OnDestroy or OnApplicationExit
/// </summary>
public static bool IsAlive
{
get
{
if (instance == null)
return false;
return instance.alive;
}
}
protected void Awake()
{
if (instance == null)
{
DontDestroyOnLoad(gameObject);
instance = this as T;
Initialization();
}
else
{
Debug.LogError($"Have more that one {typeof(T).Name} in scene. " +
"But this is Singelton! Check project.");
DestroyImmediate(this);
}
}
protected void OnDestroy() { alive = false; }
protected void OnApplicationQuit() { alive = false; }
protected virtual void Initialization() { }
}
А вы когда записываете full-body avatar, он уникальный для каждой реальной модели? Или вы переносите на какую-нибудь унифицированную модель (SMPL и его развитие и прочие)?
Иными словами - можно ли записанной модели добавить иную анимацию?
P.S. Если переносите - так как решаете вопрос подстройки анимации в зависимости от параметров модели?
Хорошая статья (с почином), так держать! У меня небольшой pet-project на Unity, поэтому несколько комментариев:
1. Если мы коснулись Git и Unity, обязательно добавьте в отслеживание *.meta файлы. В них содержится мета-информации о данных, которые Unity применяет к каждому файлу. Без этого ваш коммит может не содержать выполненных в редакторе действий. Чтобы было удобно - зайдите в настройки редактора и установите следующие параметры:
Version Control Mode: Visible Meta File;
Assets Serialization: Force Text
2. Настройте отслеживание файлов. К сожалению, многие файлы, применяемые в Unity - это большие файлы (картинки, видео, текстуры). Для них желательно использовать Git LFS. Для этого необходимо настроить
.gitattributes
чтобы автоматизировать добавление файлов.3 Самое главное! У вас непременно будут конфликты слияния (для файлов .scene, .prefab и прочих). Используйте для них UnityYAMLMerge.
В целом в сети есть множество ресурсов, где подробно описана процедура настройки Git под Unity, вы можете дополнить ваш гайд, чтобы у новичка появилось полное понимание как работать с системой контроля версий относительно Unity.
discourse.joplinapp.org/t/automatic-backlinks-with-manual-insert-option/13632
или посмотрите на Graph UI
Удобно, но закрывает только задачи 1 пользователя.
Поэтому рассматривать его в контексте систем знаний для командной работы — невозможно.
Для личной системы знаний — joplin удобен, но сделать обмен данными, общее управление достаточно сложно. Неизбежно получаем конфликты.
А с последней итерацией плагинов — Joplin просто стал великолепен!
Но только для single user
А вы прорабатывали собственную генерацию на подобие SMPL модели?
Как производить трансформирование вершин модели я в принципе понимаю, однако возникает проблема привязки вершин к joint-ам и возникает отвратительная анимация движения.
(Если добавите источники — это 95% ответа на поставленный выше вопрос)
А мой класс вывалится с ошибкой даже с блокировкой — по той причине что вызов GetComponent() не может быть совершен не из главного потока. Поэтому ни о какой потокобезопасности и не может быть и речи. Один из вариантов — разделение по времени (то что выше описал).
Логика в исключении есть — но давайте тогда подумаем, что мы за этим тянем? Дополнительная обработка исключений — кто-то должен отловить и обработать эту ошибку (а кто?). В итоге мы придем к тому же коду, только оформленному иначе.
Касательно DontDestroyOnLoad() -> он тащит за собой следующий вызов
Если лезть дальше, то просто помечается объект, не удалятся (KeepAlive()). И если мы накидаем несколько на сцену объектов одного класса, то когда будут уничтожены эти объекты? При выходе из приложения.
Как я это проверил — наследовал вышеуказанный синглтон и просто добавил в него счетчик созданных объектов (в конструктор и деструктор(финализатор)).
Вообще логика мне ваша понятна, но в данном случае я предпочитаю сделать так, чтобы точно держать в памяти 1 объект.
В одном случае мы проверяем, что на сцене нет объектов, которые создают ложные синглтоны (например при переходе между сценами оставили какой-то менеджер). И устраняем эти ложные объекты. Например при работе со фоновым звуком, в каждой сцене не надо иметь менеджер звука — нужно только его вызывать. И еще интересный момент — успешная замена в итоге вызовет исключение, если будет найдено более 1 объекта. То есть мы еще и поимеем обработку исключений. Адекватно ли это? FYI, абсолютно нет.
Касательно размазано — да так и есть, поэтому я предоставил ссылки, где предоставлен весь этот код. Я просто собрал его вместе и пояснил в чем его удобство. На гениальность не претендую)
Применительно к Unity — совсем немного времени на нем провел, пришел из плюсов с полгодика назад.
Отсюда вопрос — хорошая литература и проекты по Unity (Net)- не подскажешь? А то я больше занимаюсь обработкой изображений, на Unity у меня небольшой проектик по AR (в ТЦ Капитолий стоит, майки примерять) и чувствую что нагреб граблей по незнанию.
Сам синглтон еще терпим — но в крайне редких случаях. Unity позволяет обойтись без него стандартными средствами. Проблем приносит на порядок больше.
SL — просто отличный пример как не стоит делать (за редким исключением).
По факту SL хорошо смотрится вкупе с DI — когда каждый сервис является подмножеством взаимозаменяемых сервисов, но сложность этого подхода все же ставит его в антипаттерны.
Накидаю кейс проверки — нужно вызывать методы синглтона посредством делегатов (UnityEvent). Допустим используем синглтон для музыки, пишем обертку для дизайнера, чтобы он мог ручками накидывать необходимые ему взаимосвязи через интерфейс Unity Editor — как отработает ваш код?
Я пока данный глюк так и не поборол.
Под катом мой код сингелтона: