Pull to refresh
20
0

Программист Unity3D, C#

Send message

Начал читать, думал что это про Техникал Дизайн Документ, думаю нифига, кто-то их еще пишет и делает по ним код, но статья оказалось про другое ))) надо бы в заголовке указать, чтобы не путалось. Палец вверх за ремарку про SOLID/KISS. В остальном статья полезна. В одной игре можно применять разные подходы, надо просто уметь варить из них кашу. Положил себе в копилку еще один.

Причем тут WPF? У человека в статье конкретика применения MVVM в рамках геймдева через движок Unity3d. Тот факт что MVVM для клиентского кода в рамках Unity слабо подходит, это другой разговор, но тем не менее.

Сделайте доступ по подписке как в МС для версии: доки, таблицы, почта, презентация. Перейду сразу же)

Статья про минусы, это хорошо, но однополярно, надо бы такую же, но про плюсы. Например то, что Unity позволяет построить архитектуру вообще исключив MonoBehaviour (оставив, его только для запуска всей логики Awake или Start). Бизнес-логика вообще не требует MonoBehaviour. Например, есть возможность строить все на ScriptableObject, который почему-то все игнорируют или юзают для создания Asset'ов данных.

В целом Unity это такой механизм, который позволяет творить многое, если что-то не устраивает. Для меня лично единственный минус движка - это его однопоточность. Т.е. можно было бы не юзать MonoBehavoiur вовсе, но ты не можешь получить доступ к UnityObject вне основного потока, точнее доступ получишь, но ничего сделать с этим объектом не можешь и это проблема конечно, из которой вытекают проблемы с UI, Input'ом и т.п.

Благо что бизнес-логику все таки можно спокойно распаралелливать и выносить вообще туда, куда тебе надо, а проблемы View оставить на Unity.

Именно последний вывод и заставляет отметать любые мысли о переходе на Addressables. Вроде бы удобно, вроде бы экономит трафик и место и память главное. Но... пока что переход с классических AssetBundle нецелесообразен, если не начинается проект с нуля и в нем огромное количество внешнего контента.

1. С чего вы это решили, что я не понимаю, когда как в статье четко указано, про то как работают Coroutine и почему в других потоках нельзя использовать доступ UnityEngine.Object?
2. UniRx способен запускать, но не способен в этих потоках оперировать с объектами Unity, к чему вообще комментарий я не понял.
3. Очень интересно, теперь я буду знать, зачем я затеял это, спасибо.
Спасибо за отзыв!
uViLEd это просто Unity Visual Logic Editor )))

1. Bolt очень хорош, как копия Blueprint. Но это именно кодогенерация, человеку который не знает программирования, все равно будет сложно с ним разбираться. Ибо даже если это визуальность, необходимо знать API движка.

2. Дело не в самом компиляторе, а в языке C# 7+ (паттерн матчинг, кортежи, локальные функции, out переменные), только Roslyn поддерживает в Unity его. Ну и старые версии поддерживаются в Panthea VS, который предшествовал uViLEd.

3. В целом всё довольно неплохо, как мне кажется) Об этом будет во второй части, писать много. Но на самом деле рефлексии там почти нет))
Такие вещи сложно найти прямо вот, чтобы на 100% устраивали, почти всегда это пишется под проект, либо под серию проектов. В целом конечно унифицировать можно)
Типа того) я потому и написал, что перешел на async/await.
Главное понимать, в просто виде без Task.Run это все работает в основном потоке Unity, т.е. также как Coroutine.
И да как выше писали, асинхронные операции не остановятся при выгрузке сцены, особенно это касается While(true) {await}. В этом случае надо использовать (да собственно и в других тоже) механизм CancellationTokenSource
Я это делал так habr.com/ru/post/352296

Сейчас я полностью перешел на acyns/await

начало хорошее, но есть и более эффективные способы работы с Coroutine
Можно, но это касается переменных, которые не меняют дизайнеры, ваш варианет не исключает, а дополняет описанный в статье.
Представьте, если все такие данные в коде, их настройка превратиться в кошмар, изменил, перекомпилировал, запустил, посмотрел, повторил.
В случае со ScriptableObject перекомпиляции не нужно — изменил, запустил.
var audioClip = bundle.LoadAssetAsync(bundle.GetAllAssetNames()[0]); Не очень понятная строчка, поскольку в таком виде вы получите не audioClip, а AssetBundleRequest, который явялется асинхронной операцией и в этом случае получить из него данно можно через yield return, соотвественно через запуск Coroutine.
Выше в статье есть пример кода:
public void LoadAssetAsync<T>(string name, Action<T> result) where T : UnityEngine.Object
    {
        var request = _assetBundle.LoadAssetAsync<T>(name);

        TaskManager.Task.Create(request)
                        .Subscribe(() =>
                        {
                            result(request.asset as T);

                            Unload(false);
                        })
                        .Start();
    }
да спасибо, исправил в статье
Спасибо). Про async/await, тут нужно понимать, что если их использовать в чистом виде, то работать все будет в том же потоке, именно переход с Coroutine на них простой, однако если хочется именно многопоточности, нужно использовать Task.Run и тут возникает сложность с невозможностью доступа к всем наследникам UnityEginge.Object в таких задачах. Вот так приблизительно будет выглядеть основная функция для сетевого запросе через async/await, в данном случае она в основном потоке выполняется
private async Task<UnityWebRequest> WebRequest(CancellationTokenSource cancelationToken, UnityWebRequest request, Action<float> progress)
    {
        while (!Caching.ready)
        {
            if (cancelationToken.IsCancellationRequested)
            {                             
                return null;
            }

            await new WaitForUpdate();
        }

#pragma warning disable CS4014
        request.SendWebRequest();
#pragma warning restore CS4014

        while (!request.isDone)
        {
            if (cancelationToken.IsCancellationRequested)
            {                
                request.Abort();
                request.Dispose();

                return null;                
            }
            else
            {
                progress?.Invoke(request.downloadProgress);

                await new WaitForUpdate();
            }
        }

        progress?.Invoke(1f);
           
        return request;        
    }

Исследование конечно полезное, но давайте посмотрим правде в глаза, детский рынок, очень сильно нерентабельный. Кое-как может жить брендированный контент и чем мощнее бренд тем лучше (хотя конечно маржа у них дикая, до 50% от цены приложения). И вот вопрос, ну ок ребята уберем рекламу, а жить на что? Fixed price не работает в принципе (исключения есть, но это скорее исключение), разработка не такая уж дешевая в детском сегменте, да, она меньше, чем везде, но тем не менее. f2p тоже не для всякого приложения применимо. И как жить спросите вы? Родители не охотно тратят деньги на своих чад. Реклама в своем большинстве это мешающий фактор, который отключается путем покупки внутри игры. Но вот у нас статистика показывает, что родители осознанно не покупают отключение, их все устраивает. Так к чему я, к тому, что рынок диктует то как выживать разработчикам, и реклама вводится в игры не от жуткого желания оных навредить детям. Работал бы fixed price — проблем бы не было, но увы, даже 50 рублей цена уже пугает всех.
Присоединяюсь про листенеры, ужаснуло просто
Мысли здравые, в целом, особенно про строки, там надо на уровне редактора просто сделать привязку к индексам. Просто для текущих моих проектов нет смысла, поскольку боли такой нет.
Что касается строк и тэгов, ну можно загнаться и текст написать через 1000 символов) вопрос зачем).
А насчет памяти ассет чем хорош, его не надо хранить сразу в виде ссылку внутри сцены — хотя и можно. Сейчас например все языки сделаны загружаемыми, после загрузки и установки языка делаешь Unload бандлу с галкой true и память кушаться не будет (я надеюсь).
А в целом идеи хорошие можно рассмотреть.
PS: 400 мб данных локализации тут все на бандлах надо делать, в моем сегменте такого нет слава богу) даже с текстурами звуками и т.п.).
Да, это пришло с 2018 версию (2017 это еще было экспериментальным), а статья писалась когда еще Unity 5 был актуален
В этой статье описаны методы, но не конечные реализации, прочитайте про способы ускорения вызова методов, полученных через рефлексию в обход MethodInvoke (который и является самым тормозным способом). Рефлексия bad practiсe, для тех кто не понимает когда, как и зачем.
А в приведенной статье, про сравнение сокростей, как раз таки рефлексия даже не используется.

Information

Rating
Does not participate
Location
Воронеж, Воронежская обл., Россия
Registered
Activity

Specialization

Game Developer
Lead
C#
Object-oriented design
C++
Software development
Game Development
Unity3d
Visual Studio
Git
OOP