Unity is a platform that has been around for a long time and is constantly evolving. However, when working with several projects at the same time, you can still face difficulties in using common sources (.cs), libraries (.dll) and other assets (images, sounds, models, prefabs). In this article, we will talk about our experience with a native solution to such a problem for Unity.
Shared Resource Distribution Methods
There is more than one way to use shared resources for different projects, but each approach has its pros and cons.
1. Duplication - βby handβ we duplicate resources between projects.
Pros:
- Suitable for all kinds of resources.
- No dependency issues.
- No problem with asset GUIDs.
Cons:
- Giant repositories.
- There is no option for versioning.
- Difficulty tracking changes to shared resources.
- Difficulty updating shared resources.
2.
Pros:
- You can work with sources.
- You can distribute assets.
- No dependency issues.
Cons:
- Git skills required.
- Git is not very friendly with binary files - you have to include LFS.
- Access control for repositories.
- Difficulty upgrading and downgrading.
- GUID collisions are possible and there is no unambiguous behavior on the part of Unity to resolve them.
3. NuGet - distribution of shared libraries through NuGet packages.
Pros:
- Convenient work with projects that do not depend on Unity.
- Convenient versioning and dependency resolution.
Cons:
- Unity does not know how to work with NuGet packages out of the box (you can find NuGet Package Manager for Unity on GitHub, which fixes this, but there are nuances).
- Difficulties in distributing other types of assets.
4. Unity Package Manager - distribution of shared resources through a native solution for Unity.
Pros:
- Native interface for working with packages.
- Protection against overwriting .meta files in packages in case of GUID conflicts.
- Versioning capability.
- Ability to distribute all kinds of resources for Unity.
Cons:
- GUID conflicts can still happen.
- There is no documentation for the implementation.
The latter method has more advantages than disadvantages. However, it is not very popular now due to the lack of documentation, and therefore we will dwell on it in detail.
Unity Package Manager
Unity Package Manager (hereinafter referred to as UPM) is a package management tool. It was added in Unity 2018.1 and was only used for packages developed by Unity Technologies. However, starting with version 2018.3, it became possible to add custom packages.
Unity Package Manager Interface
Packages do not end up in the project sources (Assets directory). They are in a separate directory. %projectFolder%/Library/PackageCache
and do not affect the project in any way, their only mention in the source code is in the file packages/manifest.json
.
Packages in the project file system
Package sources
UPM can use several package sources:
1. File system.
Pros:
- Implementation speed.
- Requires no third party tools.
Cons:
- versioning complexity.
- Shared access to the file system is required for everyone who works with the project.
2. Git repository.
Pros:
- All you need is a Git repository.
Cons:
- You cannot switch between versions through the UPM window.
- Doesn't work with all Git repositories.
3. npm repository.
Pros:
- Fully supports UPM functionality and is used to distribute official Unity packages.
Cons:
- Currently ignores all string versions of packages except "-preview".
We'll look at the UPM + npm implementation below. This bundle is convenient because it allows you to work with any kind of resources and manage package versions, and also fully supports the native UPM interface.
As an npm repository, you can use
Environment setup
First you need to install
Create a package
To create a package, you need to put the file package.json
, which will describe it, to the directory with the contents of this package. You need to do the following:
Go to the project directory that we want to make a package.
Run the npm init command and enter the required values ββduring the dialog. For name, specify the name in reverse domain format, for example, com.plarium.somepackage.
For convenient display of the package name, add the displayName property to package.json and fill it in.
Since npm is js-oriented, the file contains the main and scripts properties that we do not need, which Unity does not use. It is better to remove them so as not to clog up the description of the package. The file should look something like this:
- Go to the project directory that we want to make a package.
- Run the npm init command and enter the required values ββduring the dialog. For name, specify the name in reverse domain format, for example, com.plarium.somepackage.
- For convenient display of the package name, add the displayName property to package.json and fill it in.
- Since npm is js-oriented, the file contains the main and scripts properties that we do not need, which Unity does not use. It is better to remove them so as not to clog up the description of the package. The file should look something like this:
{ "name": "com.plarium.somepackage", "displayName": "Some Package", "version": "1.0.0", "description": "Some Package Description", "keywords": [ "Unity", "UPM" ], "author": "AUTHOR", "license": "UNLICENSED" }
- Open Unity and generate a .meta file for package.json (Unity doesn't see assets without .meta files, Unity packages open read-only).
Sending a package
To send a package, you need to run the command: npm publish --registry *Π°Π΄ΡΠ΅Ρ Π΄ΠΎ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²*
.
Installing and updating packages through the Unity Package Manager
To add a package to a Unity project, you need to:
- Write to file
manifest.json
information about the source of the packages. To do this, you need to add a propertyscopedRegistries
and indicate the scopes and the address of the source by which specific scopes will be searched."scopedRegistries": [ { "name": "Main", "url": "Π°Π΄ΡΠ΅Ρ Π΄ΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²", "scopes": [ "com.plarium" ] } ]
- Go to Unity and open the Package Manager window (working with custom packages is no different from working with built-in ones).
- Select All Packages.
- Find the required package and add it.
Working with sources and debugging
In order for the sources to be connected to the project, you need to create
The use of packages does not limit the scope for debugging. However, when working with packages in Unity, you cannot go to the IDE by clicking on an error in the console if the error occurred in the package. This is because Unity does not see the scripts as separate files, because when using the Assembly Definition, they are collected into a library and included in the project. When working with sources from a project, a click-through transition to the IDE is available.
Script in a project with a connected package:
Script from the package with a working breakpoint:
Urgent fixes to packages
Unity packages added to the project are read-only, but can be edited in the package cache. For this you need:
- Go to the package in the package cache.
- Make the necessary changes.
- Update version in file
package.json
. - send package
npm publish --registry *Π°Π΄ΡΠ΅Ρ Π΄ΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²*
. - Update the package version to the corrected version through the UPM interface.
Package import conflicts
When importing packages, the following GUID conflicts may occur:
- Package - package. If, when importing a package, it is found that already added packages contain assets with the same GUID, assets with matching GUIDs from the imported package will not be added to the project.
- Package is a project. If, when importing a package, it is found that the project has assets with matching GUIDs, then the assets from the package will not be added to the project. However, the assets that depend on them will start using the assets from the project.
Transferring assets from a project to a package
If you transfer an asset from a project to a package while Unity is open, then its functionality will be preserved, and links in dependent assets will start using the asset from the package.
It's important: When copying an asset from a project to a package, the Package-Project conflict described in the section above will occur.
Possible solutions to conflicts
- Reassigning GUIDs according to own algorithms when importing all assets to avoid collisions.
- Adding all assets to one project with their subsequent separation into packages.
- Create a database containing the GUIDs of all assets and validate when submitting packages.
Conclusion
UPM is a new solution for distributing shared resources in Unity, which can be a worthy alternative to existing methods. The recommendations described in the article arose on the basis of real cases. We hope you find them useful.
Source: habr.com