Какой фреймворк использует unity
We evaluated and researched today’s most popular netcode frameworks for multiplayer games to inform your decision.
Updated on September 14th 2021: For the most up-to-date information on Unity’s netcode solution, please refer to our Netcode page.
Updated on 21st October to incorporate feedback from the community Changelog (blogpost & pdf):
- Removed DOTS from the comparison table to avoid confusion
- Adjusted Mirror’s ranking
- Removed the “Best in ” assessment to reduce potential bias
- Added an additional list of third-party frameworks for reference
Every multiplayer game has to account and solve for inherent network-related challenges that impact the game experience, such as latency, packet loss, and scene management, and games solve these challenges in a variety of ways. Finding the right solution depends on a game’s genre, the scale of its players and networked objects, competitiveness, and other aspects, like how much control is needed over the networking layer. Different scenarios require different netcode solutions. There’s no perfect, one-size-fits all solution for all kinds of games and experiences. For example, an FPS game running on a dedicated game server with server authority for cheat prevention, such as Apex Legends, will have completely different netcode requirements than a MOBA running on a P2P topology with deterministic rollback for cheat mitigation like Heroes Strike. Because there’s no single netcode solution for all scenarios, developers need to evaluate the options and decide which netcode solution – or combination of solutions – best suits a title’s needs. In many cases, they may also need to extend or customize existing netcode.
As you may already know, Unity has two different first-party netcode solutions. UNet solves for GameObjects and is currently in maintenance mode, while DOTS netcode solves for ECS and is in Preview. We currently support UNet’s LLAPI for customers shipping on consoles, but it isn’t a full solution for most higher-level networking needs. Luckily, Unity has a strong and very talented open source community and partner ecosystem, and their contributions provide numerous solutions that are well-suited for different scenarios.
We’ve recently reiterated our commitment to contributing to this space with a first-party Unity netcode solution in our Road to 2021 blog post. While we’re working on this solution, we want to make it easier for creators to explore and evaluate various netcode alternatives to make the right choices for their titles.
Our team has gathered feedback about some of the most widely used third-party netcode solutions, and we’ve created a decision tree to help guide you through the process of deciding which framework might work best for you.
To create these tools, we gathered and analyzed data from three sources:
- A survey of over 200 Unity users that asked for information about their experiences with specific netcode frameworks
- Over 20 in-depth interviews with users actively shipping multiplayer games with Unity
- Learnings from prototypes we built with MLAPI, DarkRift 2, Mirror, and Photon Quantum.
Customers scored and ranked the top netcode solutions across different axes based on their experience:
- Stability/support: This was evaluated along three axes – the likelihood of bugs or crashes, response time to fix issues or help debug a challenge, and the likelihood of breaking changes to the APIs.
- Ease of use: We compiled users’ evaluations of how easy it is to get started and perform common tasks, including the provision of good samples, documentation, tutorials, and the solution’s offering of simple APIs for prototyping.
- Performance: To score this, we looked for limited GC/allocations, minimal latency overhead, performant compute, and ideally the ability to multithread.
- Scalability: Similar to performance, we evaluated the solution’s ability to support a larger number of connected clients without a large sacrifice in performance.
- Feature breadth: We focused on mid-level features like object and variable replication, RPCs, scene management, and so on. We also looked for higher-level features like prediction and lag compensation.
- Cost: This consideration factored in both the cost of the libraries/solution and possible hidden costs, such as operating overhead that has to be managed separately.
Before jumping into our study’s results and recommendations, it’s important to stress two points. First, choosing a netcode solution for your game is a critical decision, and you should still perform your own evaluation. We want to make the process easier for you by sharing our summary of the most common options, but you should do your own assessment as well, based on the specifics of your game. Second, this list doesn't represent all of the alternatives, especially at the transport level, where many solid solutions exist, such as enet, litenetlib, ruffles, telepathy, and others.
The information below is a start, but we recommend that you also download the full report, where we go into greater detail about these third-party netcode solutions:
The PDF covers solutions most referenced by customers, but there are more! Some customers discussed other solutions for which we haven’t yet gathered enough customer evidence to evaluate, such as Forge, Normcore, Bolt, LL (Enet, LiteNet, and so on). We encourage you to add these to your considerations to see if they would be an option for your set-up.
Garbage collection
Unity uses the Boehm garbage collector for both the Mono and IL2CPP backends. Unity uses the Incremental mode by default. You can disable the Incremental mode to use stop-the-world garbage collection, although Unity recommends the Incremental mode.
To toggle between Incremental mode and stop-the-world, go to Edit > Project Settings > Player, open the Other Settings panel and click on the Use incremental GC checkbox. In Incremental mode, Unity’s garbage collector only runs for a limited period of time and doesn’t necessarily collect all objects in one pass. This spreads the time it takes to collect objects over multiple frames and reduces stuttering and CPU spikes. For more information, see Managed memory.
To check the number of allocations and possible CPU spikes in your application, use the Unity Profiler. You can also use the GarbageCollector API to completely disable garbage collection in Players. When the collector is disabled, be careful to avoid allocating excess memory.
Unity doesn’t support the System.Drawing library and it isn’t guaranteed to work on all platforms.
This is important to consider when you use third-party libraries, because they might have different code paths for JIT and AOT, or they might use code paths that rely on dynamically generated code. For more information on how to generate code at runtime, see Microsoft’s ModuleBuilder documentation.
Other profiles can be useful if, for example, you need to provide support for an older existing application. To change the Api Compatibility Level setting, go to Edit > Project Settings > Player. Under the Other Settings heading, set the Api Compatibility Level to the desired setting.
The performance characteristics of JIT and AOT code paths in third-party libraries might be significantly different. AOT generally reduces startup times and is suited to larger applications for this reason but increases the binary file size to accommodate the compiled code. AOT also takes longer to build during development.
JIT adjusts at runtime based on the platform it’s running on, which can increase running performance at the cost of a potentially longer application startup time. As such, you should profile your application in both the Editor, and on your target platform. For more information, see Profiler overview.
When you review a third-party library, consider the following areas:
String interpolation
Task-based Asynchronous Pattern (TAP)
Asynchronous programming allows time consuming operations to take place without causing your application to become unresponsive. This functionality also allows your code to wait for time consuming operations to finish before continuing with code that depends on the results of these operations. For example, you could wait for a file to load or a network operation to complete.
TAP is a complex subject, with Unity-specific nuances developers should consider. As a result, TAP isn't a universal replacement for coroutines in Unity; however, it is another tool to leverage. The scope of this feature is beyond this article, but some general best practices and tips are provided below.
Getting started reference for TAP with Unity
These tips can help you get started with TAP in Unity:
Differences between coroutines and TAP
There are some important differences between coroutines and TAP / async-await:
- Coroutines cannot return values, but Task can.
- You cannot put a yield in a try-catch statement, making error handling difficult with coroutines. However, try-catch works with TAP.
- Unity's coroutine feature isn't available in classes that don't derive from MonoBehaviour. TAP is great for asynchronous programming in such classes.
- At this point, Unity doesn't suggest TAP as a wholesale replacement of coroutines. Profiling is the only way to know the specific results of one approach versus the other for any given project.
As of Unity 2018.2, debugging async methods with break points isn't fully supported; however, this functionality is expected in Unity 2018.3.
Limitations of async and await tasks
The Unity API isn’t thread safe and therefore, you should only use async and await tasks from inside the UnitySynchronizationContext. Async tasks often allocate objects when invoked, which might cause performance issues if you overuse them.
Unity doesn’t automatically stop async tasks that run on managed threads when you exit Play mode. To listen for enter and exit Play mode events to stop the tasks manually, use EditorApplication.playModeStateChanged. If you take this approach, most of the Unity scripting APIs aren’t available to use unless you migrate the context back to the UnitySynchronizationContext.
In development builds A development build includes debug symbols and enables the Profiler. More info
See in Glossary , Unity displays the following error message if you try to use Unity APIs in multithreaded code:
For performance reasons, Unity doesn’t perform checks for multithreaded behavior in non-development builds and doesn’t display this error in live builds. This means that while Unity doesn’t prevent execution of multithreaded code on live builds, random crashes and other unpredictable errors are likely if you do use multiple threads. For this reason, Unity recommends that you don’t use multithreading.
Производительность! Бесплатно и без регистрации
Entity Component System - это сердце нового подхода от Unity. Но одновременно и самая нестабильная часть всего стека DOTS . Что же это такое?
Из чего состоит ECS?
Entity - это все, что вас окружает. Ваша кошка, сын маминой подруги, пицца - это все entity.
Component - это то, что делает ваш Entity особенным. У кошки есть хвост, у сына маминой подруги - мозги, у пиццы - кетчуп. Это все - компоненты.
System - логика, которая управляет всеми entity, у которых есть тот или иной набор компонентов. Хвост помогает всем кошкам балансировать в пространстве, мозги помогают всем сыновьям маминой подруги быть круче вас, а кетчуп позволяет любой пицце быть вкусной.
Если перенести аналогию на игровые объекты, то ваш персонаж в игре - это Entity. Компонент физики - Rigidbody, а система - это то, что будет управлять всей физикой на сцене, включая вашего персонажа в игре.
UnityEngine.Object special behavior
If your application tries to access a destroyed UnityEngine.Object again, Unity recreates the native counterpart object for most types. Two exceptions to this recreation behavior are MonoBehaviour and ScriptableObject: Unity never reloads them once they have been destroyed.
MonoBehaviour and ScriptableObject override the equality (==) and inequality (!=) operators. If you compare a destroyed MonoBehaviour or ScriptableObject against null , the operators return true when the managed object still exists and hasn’t yet been garbage collected.
Because you can’t overload the ?? and ?. operators, they aren’t compatible with objects that derive from UnityEngine.Object. The operators don’t return the same results as the equality and inequality operators when you use them on a destroyed MonoBehaviour or ScriptableObject while the managed object still exists.
Managed code stripping
When you build an application, Unity compiles and then searches the assemblies (.DLLs) in your project to detect and remove unused code. This process of stripping code reduces the final binary size of your build, but increases build time.
Code stripping is disabled by default when you use Mono but code stripping can’t be disabled for IL2CPP. You can control how much code Unity strips with the Managed Stripping Level property.
To change this property, go to Edit > Project Settings > Player, open the Other Settings panel, then click on the Managed Stripping Level dropdown and select a stripping level.
As you increase the Managed Stripping Level, Unity removes more code. This increases the risk that Unity might remove code that your application relies on, especially if you use reflection or generate code at runtime.
You can use annotations on certain elements of your code to prevent Unity from stripping it. For more information, see Managed Code Stripping.
Интерполяция строк
Рекомендации по IL2CPP
На обложке демо-игра Megacity. Она содержит 4,5 млн элементов Mesh Renderer, 5000 динамических транспортных средств, 200 000 уникальных строительных объектов и 100 000 уникальных аудиоисточников. Но самое удивительное, что вся эта мощь запустилась на Iphone X при 60 кадрах в секунду . Как все это возможно?
Пару лет назад компания Unity представила свой стек DOTS, на котором и построен проект Megacity. Это некий список технологий, которые в совокупности позволяют колдовать и ускорять ваш проект в десятки раз. В корне всей магии лежат 2 простых заклинания:
Если правильно управлять данными, процессору будет легче их обрабатывать, а если их легче будет обрабатывать, то игрокам будет легче жить.
Количество ядер процессора растет, но код среднестатистического программиста не использует все ядра процессора. А значит игрокам все же живется туго. Фреймрейт ведет себя как Джокер - непредсказуемо.
Для того, чтобы Unity программистам удалось осуществить вышеописанные постулаты, компания выпустила дополнительные пакеты:
Дары смерти от Unity Technologies
Job System - Пишите многопоточный код, даже если вы не знаете что такое "Race condition" или "Context switch".
Burst Compiler - Ускорьте код в 10 раз, просто добавив атрибут и отказавшись от ссылочных типов.
Unity Mathematics - Специальная математика, адаптированная под компилятор Burst.
Native Container - Обертка над неуправляемой памятью. Это такие же List, Array, Queue, но живут в мире без мусора. Мусор - это ваш код. Мусор - это то, что могут оставлять после себя мертвые ссылочные типы. Сборкой мусора в проекте занимается некий дворник - Garbage Collector, но он очень медленный и злой дядька . Да и Greenpeace советует убирать после себя трупы, не правда ли?
А сердцем DOTS является:
Entities - архитектурный паттерн Entity Component System (ECS), который ставит во главу угла данные, а не объекты, и тем самым переворачивает привычное представление о программировании среди ценителей ООП . Подобный подход развивает идею композиции над наследованием и позволяет легко адаптироваться под динамичные потребности гейм-дизайнера.
ECS стоит рассматривать в первую очередь как архитектурное решение. Скорость - это бонус.
На текущий момент DOTS выглядит скорее проклятьем Unity Technologies, чем волшебной палочкой. Стек до сих пор не вышел в официальный релиз. И неизвестно когда DOTS выйдет в официальный релиз. Сейчас это крайне нестабильная штука, которую точно не стоит использовать в Production проекте.
Поэтому, давайте попробуем применить подход Entity Component System (ECS) в своем проекте.
Expression-bodied members
You can also use expression-bodied members in read-only properties:
Вопрос-Ответ
Вы можете порождать prefab любым известным вам способом, конвертация пройдет автоматически.
В ECS всё - данные . Ивенты тоже, необходимо просто создать компонент и запустить его в нужный момент. Ну и создать систему, которая бы реагировала на этот ивент.
В ECS очень важно не нарушать порядок, при котором выполняются системы, асинхронное срабатывание может привести к большим проблемам в будущем.
Очень часто ивент-компоненты нужно очищать в конце кадра, для этого в LeoECS есть готовый механизм.
У Leo ECS есть готовая интеграция , которая позволяет запускать системы в разных потоках. Она не использует Job System и Burst Compiler , а использует стандартную библиотеку System.Threading.
Но вы вполне можете использовать и пакеты от компании Unity, они дадут намного больше производительности, но интеграция с ними не так легка.
На хабре уже существует отличный пост про Job систему. Вам необходимо вызвать ее внутри ваших Run методов в LeoECS.
Пример работы с Job System есть выше, в разделе про тестирование.
Готовой интеграции для LeoECS с популярными сетевыми библиотеками на данный момент не существует, но передача данных осуществляется через ивенты, а как работать с ивентами я уже отвечал.
В любом случается, на данный момент вам придется самостоятельно придумать как лучше всего интегрировать то или иное решение с ECS.
Да, возможно сторонние ECS решения не такие быстрые, как подход DOTS, но они позволяют существенно увеличить производительность относительно классического MonoBehavior подхода. Теперь вы знаете с чего начать свой Megacity проект!
Превращаем GameObject в Entity
Если Leo ECS по умолчанию не конвертирует игровые объекты из Unity Engine, то как интегрировать его с этим движком? Можно ли как-нибудь очень-очень легко превращать наши игровые объекты в Entity, чтобы процесс готовки был простым и понятным.
В этом нам поможет моя собственная библиотека UniLeo . Я написал ее для того, чтобы сохранить привычный flow работы с игровым движком Unity.
UniLeo автоматически конвертирует ваши игровые объекты в Entity и позволяет настраивать компоненты прямо из инспектора.
Перейдем наконец-то к коду
Подключаем пакеты через Unity Package Manager
Добавьте ссылку в Packages/manifest.json
Или Unity Editor -> Window -> Package Manager
Компонент в Leo ECS - это обычная структура, но мы, благодаря UniLeo можем управлять ее содержимым в рамках редактора Unity.
Не забываем пространство имен
То есть, если в проекте нужно управлять физикой, необходимо создать компонент с переменной RigidBody. Таким образом можно управлять абсолютно любым элементом игрового движка Unity.
Теперь нам необходимо как-нибудь прикрепить наш компонент к игровому объекту, но как это сделать? Компоненты - это структуры. А движок Unity позволяет крепить к игровым объектам только классы, которые наследуется от MonoBehavior .
Но в UniLeo можно создать класс-проводник, который должен наследоваться MonoProvider и его можно крепить к игровым объектам.
После того, как данный класс закреплен на игровом объекте, его можно предварительно настроить из редактора.
Отлично, теперь мы можем без лишних проблем настроить наш компонент прямо из редактора Unity.
Настало время написать первую систему. Для этого необходимо просто создать класс и реализовать один из готовых интерфейсов, чаще всего используются только:
IEcsInitSystem // Срабатывает 1 раз при инициализации
IEcsRunSystem // Срабтаывает на Update или Fixed Update метод
Пишем первую систему
Когда наша первая система создана, мы должны как-то запустить ее: для этого создадим стартап код ECS, это простой класс, который наследуется от MonoBehavior .
Обратите внимание, что к вашему игровому объекты автоматически добавится компонент Convert To Entity , который позволяет выбрать предпочтительный метод конвертации ваших игровых объектов.
Выбираем метод конвертации
Convert And Inject - Создаст entity на основе компонентов, повешанных на игровой объект.
Convert And Destroy - После превращения GO в Entity , объект автоматически удалится. Может быть полезно, когда необходимо просто добавить определенные компоненты в ECS мир..
После запуска игровой объект автоматически сконвертируется в Entity. Система начнет отрабатывать свои методы. Мы успешно интегрировали Leo ECS в наш проект. Поздравляю!
Наверное у вас еще остались вопросы, я попробую ответить на них.
Обязательные условия
Откройте "Параметры проигрывателя" в инспекторе Unity, выбрав параметры Правка > Параметры проигрывателя > Проигрыватель.
После переключения на эквивалентную среду выполнения сценариев .NET 4.x можно указать Уровень совместимости API с помощью раскрывающегося списка в "Параметрах проигрывателя" (Правка > Параметры проигрывателя > Проигрыватель). Существует два варианта.
Дополнительные сведения об этих вариантах см. в этой записи блога Unity.
Visual Studio создает файлы.csproj и .sln для проектов Unity каждый раз, когда они открываются. Это значит, что добавить ссылки на сборки в Visual Studio напрямую нельзя, поскольку при повторном открытии проекта они будут потеряны. Вместо этого необходимо использовать специальный текстовый файл с именем Csc. rsp :
Создайте новый текстовый файл с именем Csc. rsp в каталоге корневых ресурсов проекта Unity.
Перезапустите редактор Unity.
nameof operator
The nameof operator gets the string name of a variable, type, or member. Some cases where nameof comes in handy are logging errors, and getting the string name of an enum:
Директива using static
Директива using static позволяет использовать статические функции, не указывая имя класса. Директива using static помогает сэкономить место и время при использовании нескольких статических функций одного класса.
Рецепт ECS под соусом Leo
Поиск Гугл по рецептам приводит нас к самому вкусному результату:
Leo ECS - очень легкий и быстрый ECS фреймворк, который не требует какого-то специфичного игрового движка. Он прост, быстр и не форсирует вашу интеграцию с Unity Engine.
Помимо этого, на данный момент Leo ECS самый популярный ECS фреймворк после Entitas
Entitas - аппетитный фреймворк с самым большим комьюнити, но вся его проблема в том, что он работает на классах. Добавлять этот ингредиент сейчас не модно, повара предпочитают использовать структуры на компонентах. Классы почти в 2 раза медленней структур в синтетических тестах, т.к хранят в памяти ссылку. А данные тесты демонстрируют отставание по скорости готовки от 10 до 20 раз.
Другие ECS рецепты, которые могут вас заинтересовать
ECS.ME - потрясающий ECS фреймворк для Unity, приготовленный для сетевых игр с элементом отката (RollBack). Эдакий некоммерческий аналог Quantum от Exit Games. Рецепт очень-очень крутой и вкусный. Но чтобы rollback не дал трещину, нужно четко следовать правилам данного фреймворка.
EgoECS - ECS фреймворк с сильнейшей интеграцией в Unity. С его помощью можно готовить MonoBehavior в качестве компонентов. Если вам не важна скорость работы, EgoECS выглядит весьма хорошим рецептом. Каждая система - это всего 1 фильтр, кому-то такой подход может скручивать руки при написании кода.
Svelto ECS - очень амбициозный рецепт, с очень сложным API. Но я должен был его упомянуть. Скорее всего он не подходит новичкам, но если вы заинтересовались, то на habr существует перевод Wiki данного фреймворка.
Actors - изначально разрабатывался как набор утилит. В рецепте присутствует шина событий(глобальный ивенты), которая может нарушить порядок вызовов функций и никак не относится к ECS. Реактивщина в ECS может сбить вас с толку при поиске багов / ошибок в вашей игре.
Caller info attributes
Caller info attributes provide information about the caller of a method. You must provide a default value for each parameter you want to use with a Caller Info attribute:
Using static
Using static allows you to use static functions without typing its class name. With using static, you can save space and time if you need to use several static functions from the same class:
Оператор nameof
Оператор nameof получает строковое имя, тип или член переменной. В некоторых случаях nameof удобно использовать для регистрации ошибок и получения строкового имени перечисления.
Новые возможности синтаксиса и языка
Элементы, воплощающие выражение
Члены, заданные выражениями, теперь можно использовать также в свойствах, доступных только для чтения:
Scripting backends
Unity has two scripting backends; Mono, and IL2CPP A Unity-developed scripting back-end which you can use as an alternative to Mono when building projects for some platforms. More info
See in Glossary (Intermediate Language To C++), each of which uses a different compilation technique:
- Mono uses just-in-time (JIT) compilation and compiles code on demand at runtime.
- IL2CPP uses ahead-of-time (AOT) compilation and compiles your entire application before it runs.
The benefit of using a JIT-based scripting backend is that the compilation time is typically much faster than AOT.
Инициализаторы автосвойств
Асинхронный шаблон, основанный на задачах (TAP)
Асинхронное программирование позволяет выполнять длинные операции без зависания приложений. Кроме того, с помощью этой функции можно сделать так, чтобы код, в котором используются результаты ресурсоемких операций, выполнялся только после того, как будут выполнены эти операции, например после загрузки определенного файла или завершения сетевой операции.
TAP — это сложная тема с определенными характерными для Unity нюансами, которые разработчикам необходимо учитывать, поэтому его нельзя назвать универсальной заменой соподпрограммам в Unity. Тем не менее это полезный инструмент. Сфера применения этого компонента выходит за рамки данной статьи, но некоторые общие рекомендации и советы вы найдете ниже.
Начало работы с TAP в Unity
Эти советы помогут вам приступить к работе с TAP в Unity.
Различия между соподпрограммами и TAP
Между соподпрограммами и TAP (async-await) есть несколько важных различий.
- Соподпрограммы не могут возвращать значения, а Task может.
- Вставить yield в оператор try-catch нельзя, что затрудняет обработку ошибок при использовании соподпрограмм. При этом try-catch работает с TAP.
- Функция соподпрограмм в Unity недоступна в классах, которые не являются производными от MonoBehaviour. Для асинхронного программирования в таких классах отлично подходит TAP.
- В настоящее время Unity не предлагает TAP как полную замену соподпрограмм. Узнать результаты применения одного или другого подхода для конкретного проекта можно только путем профилирования.
В Unity 2018.2 отладка асинхронных методов с использованием точек останова не поддерживается в полном объеме; эта возможность будет реализована в Unity 2018.3.
Prerequisites
Open PlayerSettings in the Unity Inspector by selecting Edit > Project Settings > Player.
You can read more about these options in Unity's blog post.
Visual Studio regenerates .csproj and .sln files for Unity projects each time they're opened. As a result, you cannot add assembly references directly in Visual Studio because they'll be lost upon reopening the project. Instead, a special text file named csc.rsp must be used:
Create a new text file named csc.rsp in your Unity project's root Assets directory.
On the first line in the empty text file, enter: -r:System.Net.Http.dll and then save the file. You can replace "System.Net.Http.dll" with any included assembly that might be missing a reference.
Restart the Unity editor.
ОБНОВЛЕНО! Насколько увеличится скорость?
Я провел классический эксперимент, создал 100 000 GameObject и двигал их по вектору Z на 0.1 значение.
Как видно из этих тестов, переход на ECS подарил в районе 20 FPS. Однако точно такой же тест от коллеги по цеху, запущенный на моем устройстве, демонстрирует увеличение производительности в 3 раза. Мне же не удалось достичь таких результатов.
Leo ECS еще один тест
После тщательного анализа исходного кода моего коллеги, я так и не нашел причины за счёт чего ему удалось увеличить скорость работы. Есть ощущение, что пакеты от DOTS, установленные на моей сборке, как-то замедляли весь процесс тестирования.
Нагрузка Update методов из Profiler
Однако я попробовал вынести работу в многопоток через Job System и получил буст производительности в 5-6 раз. При этом добавление атрибута от Burst никак не увеличила производительность. Видимо в моем коде нет как таковой логики чтобы ее Burstить.
Leo ECS + Job System
То есть, переход на ECS позволит процессору вашего целевого устройства легче выполнять работу, а вам - писать чистый код.
IL2CPP Considerations
Информационные атрибуты вызывающего объекта
Информационные атрибуты вызывающего объекта содержат информацию о вызывающем объекте метода. Для каждого параметра, который вы хотите использовать c информационным атрибутом вызывающего объекта, необходимо указать значение по умолчанию.
Auto-property initializers
New syntax and language features
Add packages from NuGet to a Unity project
Click the Download button:
Locate the downloaded file and change the extension from .nupkg to .zip.
Within the zip file, navigate to the lib/netstandard2.0 directory and copy the Newtonsoft.Json.dll file.
In your Unity project's root Assets folder, create a new folder named Plugins. Plugins is a special folder name in Unity. See the Unity documentation for more information.
Paste the Newtonsoft.Json.dll file into your Unity project's Plugins directory.
Create a file named link.xml in your Unity project's Assets directory and add the following XML. This will ensure Unity's bytecode stripping process does not remove necessary data when exporting to an IL2CPP platform. While this step is specific to this library, you may run into problems with other libraries that use Reflection in similar ways. For more information, please see Unity's docs on this topic.
This is a simple example of using a library which has no dependencies. When NuGet packages rely on other NuGet packages, you would need to download these dependencies manually and add them to the project in the same way.
Добавление пакетов из NuGet в проект Unity
Найдите загруженный файл и измените его расширение с .nupkg на .zip.
В ZIP-файле зайдите в каталог lib/netstandard2.0 и скопируйте файл Newtonsoft.Json.dll.
В папке Assets в корневом каталоге проекта Unity создайте папку с именем Plugins (Подключаемые модули). В Unity "Plugins" — это имя специальной папки. Дополнительные сведения см. в документации по Unity.
Скопируйте файл Newtonsoft.Json.dll в каталог Plugins проекта Unity.
Создайте файл с именем link.xml в каталоге Assets проекта Unity и добавьте приведенный ниже код XML. Это нужно для того, чтобы процесс удаления байт-кода в Unity не удалял необходимые данные при экспорте в платформу IL2CPP. Несмотря на то что это действие относится только к данной библиотеке, проблемы могут возникнуть и с другими библиотеками, которые используют отражение подобным образом. Дополнительные сведения на эту тему см. в документации по Unity.
Это простой пример использования библиотеки без зависимостей. Если одни пакеты NuGet зависят от других, необходимо вручную загрузить эти зависимости и добавить их в проект таким же образом.
Читайте также: