Search
Write a publication
Pull to refresh
2
0
Александр Шамин @AShamin

Программист

Send message

А вы когда записываете 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, абсолютно нет.

Касательно размазано — да так и есть, поэтому я предоставил ссылки, где предоставлен весь этот код. Я просто собрал его вместе и пояснил в чем его удобство. На гениальность не претендую)
Я добавляю код, который вырос за время работы с этим паттерном. Все расписал в подпунктах, создания, инициализации и уничтожения объектов — я не находил на хабре статей в которых освещались эти моменты.
Я сильно ориентируюсь по этой статье www.skipy.ru/architecture/module_design.html

Применительно к 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() { }
}

Information

Rating
Does not participate
Location
Таганрог, Ростовская обл., Россия
Date of birth
Registered
Activity