Файловая система
UNIGINE has its own file system module used to access files and folders. It has a few peculiarities you should be aware of, when loading resources or organizing the structure of your UNIGINE-based project. UNIGINE имеет собственный модуль файловой системы, используемый для доступа к файлам и папкам. У него есть несколько особенностей, о которых вы должны знать при загрузке ресурсов или организации структуры вашего проекта на основе UNIGINE.
GUIDsGUID#
In UNIGINE's file system, each file has a GUID (Globally Unique Identifier), which defines a virtual path to this file (not a file on a disk). Using GUIDs provides more flexible file management: you can abstract from file names (which can be the same in different folders of the project). For example, you can change a path to the file while keeping the same GUID. В файловой системе UNIGINE каждый файл имеет GUID (глобальный уникальный идентификатор), который определяет виртуальный путь к этому файлу (а не к файлу на диске). Использование GUID обеспечивает более гибкое управление файлами: вы можете абстрагироваться от имен файлов (которые могут быть одинаковыми в разных папках проекта). Например, вы можете изменить путь к файлу, сохранив тот же идентификатор GUID.
The Engine generates GUIDs for all files of the virtual file system. Движок генерирует GUID для всех файлов виртуальной файловой системы .
Files of UNIGINE's file system can be accessed by using both names or GUIDs: you can obtain a GUID for the specific file, change the file GUID, add/remove the file with the certain name or GUID to/from a blob or a cached file, and so on.К файлам файловой системы UNIGINE можно получить доступ, используя как имена, так и идентификаторы GUIDs: вы можете получить GUID для конкретного файла, изменить GUID файла, добавить / удалить файл с определенным именем или GUID из BLOB-объекта или кешированного файла и так далее.
If UnigineEditor is loaded, it saves generated GUIDs to the data/guids.db file automatically. Otherwise, you can implement the logic of updating guids.db via code. The guids.db file stores a pair: a GUID of a file and a path to this file relative to the data folder. Если UnigineEditor загружен, он автоматически сохраняет сгенерированные идентификаторы GUID в файл data/guids.db. В противном случае вы можете реализовать логику обновления guids.db с помощью кода. В файле guids.db хранится пара: GUID файла и путь к нему относительно папки data.
As UNIGINE's file system provides mount points to extend the project, there can be several guids.db files within a single project. Each mount point can store its own guids.db: GUIDs for external files aren't written to data/guids.db. Поскольку файловая система UNIGINE предоставляет точки монтирования для расширения проекта, в одном проекте может быть несколько файлов guids.db. Каждая точка монтирования может хранить свой собственный guids.db: GUID для внешних файлов не записываются в data/guids.db.
Deleting the guids.db file won't cause any issues: if there is no guids.db file, the Engine will search among .meta files. However, guids.db might be necessary for the final release build of the project, if you aren't going to include the .meta files. Удаление файла guids.db не вызовет никаких проблем: если файла guids.db нет, движок будет искать среди файлов .meta. Однако guids.db может потребоваться для окончательной сборки проекта, если вы не собираетесь включать файлы .meta.
Ignore Option for guids.dbПараметр Ignore для guids.db#
Sometimes in case of teamwork development, an invalid guids.db file may be committed to the repository (due to an incorrect merge or otherwise) causing errors when working with UnigineEditor. You can make the Engine ignore the guids.db file via the -skip_guidsdb startup command line option. In this case, the Engine searches for GUIDs among all .meta files inside the data folder and all mounted external directories and packages. UnigineEditor uses this argument by default to avoid errors, and always re-generates the guids.db file to ensure its validity. Иногда в случае совместной разработки недопустимый файл guids.db может быть зафиксирован в репозитории (из-за неправильного слияния или иным образом), что приведет к ошибкам при работе с UnigineEditor . Вы можете заставить движок игнорировать файл guids.db с помощью параметра командной строки запуска -skip_guidsdb . В этом случае движок ищет идентификаторы GUID среди всех файлов .meta внутри папки data и всех смонтированных внешних каталогов и пакетов. UnigineEditor использует этот аргумент по умолчанию, чтобы избежать ошибок, и всегда повторно генерирует файл guids.db, чтобы гарантировать его достоверность.
File System UpdateОбновление файловой системы#
Dynamic ScanningДинамическое сканирование#
Dynamic scanning allows the Engine to form a virtual file system for all files within the data folder (including the ones inside mount points). Dynamic scanning is performed on the Engine start-up. For files physically stored inside the data folder, file changes tracking is enabled in real time using relative paths to address files. Динамическое сканирование позволяет движку формировать виртуальную файловую систему для всех файлов в папке data (включая те, которые находятся внутри точек монтирования ). Динамическое сканирование выполняется при запуске двигателя. Для файлов, физически хранящихся в папке data, отслеживание изменений файлов включено в реальном времени с использованием относительных путей для адресации файлов.
If changes to the file system are made not by means of UnigineScript, you may need to call the filesystem_reload console command. Если изменения в файловой системе вносятся не с помощью UnigineScript, вам может потребоваться вызвать консольную команду filesystem_reload .
Automatic Resource ReloadingАвтоматическая перезагрузка ресурсов#
When UnigineEditor is loaded, the Engine tracks changes made in files at run time: it checks the time of the last modification of such files and updates them in the memory. If UnigineEditor isn't loaded, the changed files are reloaded after reloading the world. Когда UnigineEditor загружен, Engine отслеживает изменения, внесенные в файлы во время выполнения: он проверяет время последней модификации таких файлов и обновляет их в памяти. Если UnigineEditor не загружен, измененные файлы перезагружаются после перезагрузки мира .
When UnigineEditor is loaded, automatic tracking of changes isn't available for the mount points. Each mount point is updated manually on demand. Когда загружен UnigineEditor, автоматическое отслеживание изменений недоступно для точек монтирования . Каждая точка монтирования обновляется вручную по запросу.
Known vs Unknown FilesИзвестные и неизвестные файлы#
If you add new files at run time, the Engine won't know anything about such files (as the virtual file system has been formed on the start-up). Re-scanning the file system is resource-consuming, therefore, you can add new files to the virtual file system via API by using addVirtualFile(). Если вы добавляете новые файлы во время выполнения, движок ничего не будет знать о таких файлах (поскольку виртуальная файловая система была сформирована при запуске). Повторное сканирование файловой системы требует значительных ресурсов, поэтому вы можете добавлять новые файлы в виртуальную файловую систему через API с помощью addVirtualFile() .
Data DirectoryКаталог данных#
All files used by the Engine at run time are stored in the data folder specified via the -data_path start-up option. By default, this is the data folder created automatically on project creation via UNIGINE SDK Browser. Все файлы, используемые движком во время выполнения, хранятся в папке data, указанной с помощью параметра запуска -data_path . По умолчанию это папка data, автоматически создаваемая при создании проекта с помощью UNIGINE SDK Browser .
When the file system resolves paths, it tries to concatenate data paths with the specified path and perform a lookup. In case of absolute paths, the file system will use them "as is" without any checks. Когда файловая система определяет пути, она пытается связать пути данных с указанным путем и выполнить поиск. В случае абсолютных путей файловая система будет использовать их «как есть» без каких-либо проверок.
For example, if the project folder has the following structure: Например, если папка проекта имеет следующую структуру:
-
unigine_project
- assets
- bin
- data
The data path will be unigine_project/data after the application start-up: После запуска приложения путь к данным будет равен unigine_project/data:
bin\main_x64d.exe -data_path "../"
Current DirectoryТекущий каталог#
When the specified -data_path is absolute, the current working directory may differ from the directory with the binary executable. However, when the path to the data directory is relative, the Engine switches the current directory to the one with the binary executable. Если указанный -data_path является абсолютным, текущий рабочий каталог может отличаться от каталога с исполняемым двоичным файлом. Однако, когда путь к каталогу данных является относительным, Engine переключает текущий каталог на каталог с исполняемым двоичным файлом.
When accessing a file outside the data directory via API, the path to such file should be specified relative to the current directory. For example: При доступе к файлу вне каталога data через API, путь к такому файлу должен быть указан относительно текущего каталога. Например:
// cbox.mesh is stored outside the data directory, so the path is specified relative to the current directory
ObjectMeshStatic cbox = new ObjectMeshStatic("../../data/cbox.mesh");
Root Mount FileКорневой файл монтирования#
The building block of the virtual file system is a mount: the file system is created as a root mount and can be easily extended by using additional mount points. This approach allows extending the virtual file system of your project by adding any external folders and packages to the data directory. Строительным блоком виртуальной файловой системы является монтирование : файловая система создается как корневое монтирование и может быть легко расширена с помощью дополнительных точек монтирования . Этот подход позволяет расширить виртуальную файловую систему вашего проекта, добавляя любые внешние папки и пакеты в каталог данных.
At project creation, the root_mount.umount file is created in the data folder. This is a file in the JSON format that represents the root mount point. It stores the version of UNIGINE SDK, in which the root mount has been created, and ignore filters (i.e., indication to folders that should be ignored): При создании проекта файл root_mount.umount создается в папке data. Это файл в формате JSON, представляющий корневую точку монтирования. Он хранит версию UNIGINE SDK, в которой было создано корневое монтирование, и игнорирует фильтры (т.е. указание на папки , которые следует игнорировать):
{
"version": "2.9.0.0"
"ignore_filters": [
".svn",
".git",
".teamcity",
".thumbnails"
]
}
The root_mount.umount file already contains default ignore filters and the list can be extended as necessary using wildcards. Файл root_mount.umount уже содержит фильтры игнорирования по умолчанию, и при необходимости список может быть расширен с помощью подстановочных знаков.
The path is set relative to the data folder. If a folder that should be ignored is located inside any other folder (for example data/folder_1/.svn), the relative path to that folder should be set as an ignore filter (folder_1/.svn). Путь задается относительно папки data. Если папка, которую следует игнорировать, находится внутри любой другой папки (например, data/folder_1/.svn), относительный путь к этой папке должен быть установлен как фильтр игнорирования (folder_1/.svn).
If a project does not contain the root_mount.umount file (the project was created with a previous version of UNIGINE SDK or the file has been deleted), the project would run without ignoring any folders in data. Если проект не содержит файла root_mount.umount (проект был создан с помощью предыдущей версии UNIGINE SDK или файл был удален), проект будет запущен без игнорирования папок в data.
The root_mount.umount file can be created manually or via code using API. Файл root_mount.umount можно создать вручную или с помощью кода с использованием API .
File PackagesФайловые пакеты#
TypesТипы#
UNIGINE supports the following types of file archives to save space or pack the production version of resources: UNIGINE поддерживает следующие типы файловых архивов для экономии места или упаковки производственной версии ресурсов:
- UNG (a UNIGINE-native format for archives created with Archiver tool)
The maximum size for a file inside a UNG archive is limited to 2 GB. UNG (собственный формат UNIGINE для архивов, созданных с помощью инструмента Archiver)The maximum size for a file inside a UNG archive is limited to 2 GB.The maximum size for a file inside a UNG archive is limited to 2 GB.The maximum size for a file inside a UNG archive is limited to 2 GB. Максимальный размер файла внутри архива UNG ограничен 2 GB.
- ZIPZIP
- Custom C++ packages created via UNIGINE API Пользовательские пакеты C ++ , созданные с помощью UNIGINE API
Besides saving space, archives also speed up resource loading, as files in an archive are read linearly. Помимо экономии места, архивы также ускоряют загрузку ресурсов, поскольку файлы в архиве читаются линейно.
UNG and ZIP archives are loaded automatically if they are located within the data folder. Files are added to the virtual file system the same way as non-archived files. Архивы UNG и ZIP загружаются автоматически, если они находятся в папке data. Файлы добавляются в виртуальную файловую систему так же, как и неархивированные файлы.
Content AccessДоступ к контенту#
Archives are completely transparent to the Engine. There is no need to explicitly unpack the archives, as their content is automatically handled as not packed. Archived files are addressed as if they are non-archived. For example, if you have data/project/archive.ung and want to address directory/file.txt within it, simply specify the following path: project/directory/file.txt. Архивы полностью прозрачны для Engine. Нет необходимости явно распаковывать архивы, поскольку их содержимое автоматически обрабатывается как незапакованное. К архивным файлам обращаются как к неархивированным. Например, если у вас есть data/project/archive.ung и вы хотите адресовать в нем directory/file.txt, просто укажите следующий путь: project/directory/file.txt.
Inside the archive, files can be organized in any way. However, in the root of the archive only files with unique names should be placed. Otherwise, the file search will return incorrect results. Внутри архива файлы могут быть организованы любым способом. Однако в корень архива следует помещать только файлы с уникальными именами. В противном случае поиск файлов даст неверные результаты.
Here is an example of an incorrect file tree for an archive: Вот пример неверного дерева файлов для архива:
-
my_archive.ung
-
my_folder
- file_2.txt
- file_1.txt
- file_2.txt
-
my_folder
In this case, there is no problem with file_1.txt, since its name is unique. file_2.txt, on the other hand, will cause problems: it does not guarantee that a non-root file will be returned. В этом случае проблем с file_1.txt нет, так как его имя уникально. file_2.txt, с другой стороны, вызовет проблемы: он не гарантирует, что будет возвращен некорневой файл.
The correct archive structure can be specified as follows: Правильная структура архива может быть указана следующим образом:
-
my_archive.ung
-
my_folder
- file_2.txt
-
another_folder
- file_2.txt
- file_1.txt
-
my_folder
In this case, the files with the same names are stored in different directories, so the file search will be perfectly correct. В этом случае файлы с одинаковыми именами хранятся в разных каталогах, поэтому поиск файлов будет совершенно правильным.
If there is a name collision between an archived file and a non-archived one, the first matching file is returned. The search is performed in the following order: Если существует конфликт имен между заархивированным и неархивированным файлом, возвращается первый соответствующий файл. Поиск производится в следующем порядке:
- Non-archived files Неархивированные файлы
- Files in UNG archives Файлы в UNG-архивах
- Files in ZIP archives Файлы в in ZIP-архивах
From UNIGINE API, archives are handled using the FileSystem functions as well. Из UNIGINE API архивы также обрабатываются с помощью функций FileSystem.
Extending File SystemРасширение файловой системы#
The virtual file system can be easily extended by using the mount point feature. It allows you to extend the virtual file system of your project by adding any external folders and packages to the data directory. Виртуальную файловую систему можно легко расширить с помощью функции точки монтирования . Это позволяет вам расширять виртуальную файловую систему вашего проекта, добавляя любые внешние папки и пакеты в каталог данных.
Using the mount points in your project allows you to use content stored: Использование точек монтирования в вашем проекте позволяет вам использовать сохраненный контент:
- In a single folder or repository for several projects. В одной папке или репозитории для нескольких проектов.
- In several folders for one project. You can create as many mount points as required for the project. В нескольких папках для одного проекта. Вы можете создать столько точек монтирования, сколько требуется для проекта.
A UNIGINE-based project has a single data directory. Here all project assets and runtime files are stored. In addition, the data folder can store mount points created via the Asset Browser (Create -> Create Mount Point) or API. Проект на основе UNIGINE имеет единственный каталог data. Здесь хранятся все активы проекта и файлы времени выполнения. Кроме того, папка data может хранить точки монтирования, созданные с помощью Asset Browser (Create -> Create Mount Point) или API .
A mount point is represented on the disk as a *.umount file: a file in the JSON format that stores a reference to an external directory or package as an absolute path or a path relative to the current directory. Also the *.umount file stores version of UNIGINE SDK, in which the mount has been created, and information on whether the mount is read-only or not. You can also specify exclusive_filters (whitelist) or ignore_filters (blacklist) as a list of wildcards (e.g., "*.jpg", "some_folder_*") to selectively add files of certain types or contents of folders with certain names, or on the contrary, to ignore the ones specified). For example: Точка монтирования представлена на диске как файл *.umount: файл в формате JSON, в котором хранится ссылка на внешний каталог или пакет как абсолютный путь или путь относительно текущего каталога. Также файл *.umount хранит версию UNIGINE SDK, в которой было создано монтирование, и информацию о том, доступно ли монтирование только для чтения или нет. Вы также можете указать exclusive_filters (белый список) или ignore_filters (черный список) в качестве списка подстановочных знаков (например, "*.jpg", "some_folder_*"), чтобы выборочно добавлять файлы определенных типов или содержимое папок с определенными именами или, наоборот, игнорировать указанные). Например:
{
"data_path": "D:/mount_test",
"readonly": false,
"ignore_filters": ["*.jpg","*.prop"],
"version": "2.9.0.0"
}
All folders inside the mount point are treated by the file system as usual folders with assets inside the data directory. Все папки внутри точки монтирования обрабатываются файловой системой как обычные папки с активами внутри каталога data.
Inside each mount point, there is a .runtimes folder that stores runtime files generated for assets of the external directory. Note that they aren’t added to the runtimes stored inside the data/.runtimes folder. If you move an asset from one mount point to another, its runtime will be moved as well. Внутри каждой точки монтирования есть папка .runtimes, в которой хранятся файлы времени выполнения, созданные для ресурсов внешнего каталога. Обратите внимание, что они не добавляются к средам выполнения, хранящимся в папке data/.runtimes. Если вы переместите актив из одной точки монтирования в другую, его среда выполнения также будет перемещена.
As well as runtime files are stored per mount point, the guids.db file is also generated and stored per mount point by default: GUIDs for external files aren't written to data/guids.db. Помимо файлов среды выполнения, хранящихся для каждой точки монтирования , файл guids.db также создается и сохраняется для каждой точки монтирования по умолчанию: GUID для внешних файлов не записываются в data/guids.db.
If several team members work with a single mount point, it should be read-only to avoid issues. Если несколько членов команды работают с одной точкой монтирования, она должна быть только для чтения , чтобы избежать проблем.
The read-only mount point doesn’t allow any changes in the folder or package it is referenced to. It means that such folder must store assets with already generated .meta files and runtimes. Otherwise, they won’t be available in the Asset Browser. The workflow here should be as follows: Точка подключения только для чтения не позволяет вносить изменения в папку или пакет, на которые она ссылается. Это означает, что в такой папке должны храниться активы с уже созданными файлами .meta и средами выполнения. В противном случае они не будут доступны в браузере объектов. Рабочий процесс здесь должен быть следующим:
- The .meta and runtime files for assets are generated once and saved/committed to the folder/repository (if any). .meta и файлы времени выполнения для ресурсов создаются один раз и сохраняются / фиксируются в папке / репозитории (если есть).
- In each project that uses the assets from this folder/repository, the read-only mount point is created. The assets are used "as is", without opportunity to somehow modify them. В каждом проекте, в котором используются ресурсы из этой папки / репозитория, создается точка монтирования только для чтения. Ресурсы используются "как есть", без возможности их каким-либо образом изменить.
When working with mount points, there are rules to be followed: При работе с точками монтирования следует соблюдать следующие правила:
- Mount points can be embedded: a folder referenced by a *.umount file can store another *.umount file, etc. However, looped mount points are not allowed: you cannot create the 2.umount inside the 1.umount that refers to 1.umount. Точки монтирования могут быть встроены: папка, на которую ссылается файл *.umount, может хранить другой файл *.umount и т. д. Однако зацикленные точки монтирования не допускаются: вы не можете создать 2.umount внутри 1.umount, который ссылается на 1.umount.
- *.umount files cannot be packed, as well as packages cannot store another packages. However, the *.umount file can refer to a package. Файлы *.umount не могут быть упакованы, а также пакеты не могут хранить другие пакеты. Однако файл *.umount может относиться к пакету.
- *.umount file should have a unique name. If the data folder contains a folder with the same name as the mount point, this mount point will be ignored. Файл *.umount должен иметь уникальное имя. Если папка data содержит папку с тем же именем, что и точка монтирования, эта точка монтирования будет проигнорирована.
When UnigineEditor is loaded, automatic resource reloading isn’t available for mount points. Each mount point is updated manually on demand: in the Asset Browser, right-click the mount point and choose Refresh Mount Point. When UnigineEditor isn't loaded, the Engine reloads all resources, including mount points, after reloading the world if resources are added to the virtual file system. Когда загружен UnigineEditor, автоматическая перезагрузка ресурсов недоступна для точек монтирования. Каждая точка монтирования обновляется вручную по запросу: в Asset Browser щелкните правой кнопкой мыши точку монтирования и выберите Refresh Mount Point. Когда UnigineEditor не загружен, Engine перезагружает все ресурсы, включая точки монтирования, после перезагрузки мира , если ресурсы добавлены в виртуальную файловую систему.
PathsПути#
The Engine accepts the relative, absolute, network, and virtual paths. Движок принимает относительный, абсолютный , сетевой и виртуальный пути.
Virtual PathsВиртуальные пути#
UNIGINE's file system is strict. It means that the virtual file system always checks the exact file location instead of searching somewhere inside the data directory. Such approach makes working with project files clear and transparent. Файловая система UNIGINE строгая . Это означает, что виртуальная файловая система всегда проверяет точное местоположение файла, а не ищет где-нибудь внутри каталога data. Такой подход делает работу с файлами проекта понятной и прозрачной.
The virtual file system operates with virtual paths to files. A virtual path is a path to a file inside the data folder (including files in mount points). The Engine always tries to convert any path to a virtual one. There are several types of virtual paths: Виртуальная файловая система работает с виртуальными путями к файлам. Виртуальный путь - это путь к файлу внутри папки data (включая файлы в точках монтирования ). Движок всегда пытается преобразовать любой путь в виртуальный. Есть несколько типов виртуальных путей:
- Full virtual path - a path to a file inside the data folder Полный виртуальный путь - путь к файлу внутри папки data
- Partial virtual path Частичный виртуальный путь
- Virtual path specified as an absolute one Виртуальный путь указан как абсолютный один
When specifying a virtual path to a file inside the mount point, it always includes the name of the mount point. For example, if you have a data/external_images.umount mount point, that refers to D:\external_content, you should access any file in this folder as follows: При указании виртуального пути к файлу внутри точки монтирования он всегда включает имя точки монтирования. Например, если у вас есть точка монтирования data/external_images.umount, которая относится к D:\external_content, вы должны получить доступ к любому файлу в этой папке следующим образом:
external_images/1.tga
PartialЧастичные пути#
Using partial paths means that the file system performs a non-strict file search. In this case, only a file name can be provided without a path. Partial paths are allowed for cases where the user can enter a path manually, such as: Использование частичных путей означает, что файловая система выполняет нестрогий поиск файлов. В этом случае можно указать только имя файла без пути. Частичные пути разрешены в случаях, когда пользователь может ввести путь вручную, например:
- World loading operations. You can specify only a world name and it will be found and loaded. Мировые операции по загрузке. Вы можете указать только имя мира, и оно будет найдено и загружено.
- Including paths in the source code. Включение путей в исходный код.
- Paths in UI files. Пути в файлах пользовательского интерфейса .
- Paths in manual material files. Пути в файлах материалов руководства .
- Paths to textures in base material files. Пути к текстурам в файлах базового материала .
- Paths to font files. Пути к файлам шрифтов.
It is also possible to provide a sub-path that uniquely specifies a file. For example, to load data/project/my_world/my_world.world, you can use my_world.world (if a name is unique) or my_world/my_world.world. Также можно указать вложенный путь, который однозначно определяет файл. Например, чтобы загрузить data/project/my_world/my_world.world, вы можете использовать my_world.world (если имя уникальное) или my_world/my_world.world.
Also you can refer files by GUIDs to uniquely specify a file. Также вы можете ссылаться на файлы по GUID , чтобы однозначно указать файл.
Virtual Path Specified as AbsoluteВиртуальный путь задан как абсолютный#
The Engine can resolve paths that are specified as absolute, but actually are virtual. It means that the path to a file can look like absolute, but physically there is no such file by this path. Движок может разрешать пути, которые указаны как абсолютные, но фактически являются виртуальными. Это означает, что путь к файлу может выглядеть как абсолютный, но физически такого файла по этому пути нет.
For example, there is a project stored in the D:/projects/unigine_project/ folder. In the data folder of this project, there is a test.umount that refers to a D:/content/test/ folder with the 1.tga texture. You can specify the path to this texture as absolute as follows and the Engine will be able to return a virtual path for it. Например, в папке D:/projects/unigine_project/ хранится проект. В папке данных этого проекта есть test.umount, который относится к папке D:/content/test/ с текстурой 1.tga. Вы можете указать путь к этой текстуре как абсолютный, как показано ниже, и движок сможет вернуть для нее виртуальный путь.
getVirtualPath("D:/projects/unigine_project/test/1.tga"); // returned: test/1.tga
If you try to get an absolute path, the absolute path D:/content/test/1.tga will be returned. Если вы попытаетесь получить абсолютный путь, будет возвращен абсолютный путь D:/content/test/1.tga.
getAbsolutePath("D:/projects/unigine_project/test/1.tga"); // returned D:/content/test/1.tga
To get more usage examples on the getVirtualPath() / getAbsolutePath() methods, check the article on the FileSystem class. Чтобы получить больше примеров использования методов getVirtualPath() / getAbsolutePath(), ознакомьтесь со статьей о классе FileSystem.
Network PathsСетевые пути#
A lot of heavy content used in a project is usually stored on a network drive. To access such content, a network path should be specified in the following format: Большое количество тяжелого контента, используемого в проекте, обычно хранится на сетевом диске. Для доступа к такому контенту необходимо указать сетевой путь в следующем формате:
//share/content/1.tga
The network paths are successfully resolved by the file system. Сетевые пути успешно разрешены файловой системой.
You can create a mount point that refers to a network folder. It allows you to avoid unnecessary copying of assets to a local computer and, therefore, saves the disk space. Вы можете создать точку монтирования, которая ссылается на сетевую папку. Это позволяет избежать ненужного копирования ресурсов на локальный компьютер и, следовательно, экономит место на диске.
Relative vs AbsoluteОтносительный vs Абсолютный#
A relative path is a path specified relative to the current directory. It should be used when, for example, you need to write some file in the same folder with the binary executable. If you specify a virtual path, it will be written into the data directory by default. относительный путь - это путь, указанный относительно текущего каталога. Его следует использовать, например, когда вам нужно записать какой-либо файл в ту же папку, что и исполняемый двоичный файл. Если вы укажете виртуальный путь, по умолчанию он будет записан в каталог data.
When relative paths are used, you can relocate your UNIGINE-based application or copy it onto another machine, and all resources will be properly loaded. There is no loading speed penalty as well: it is as fast as loading files by an absolute path due to the virtual file system. It is possible to use absolute paths to load resources outside the data folder, but such project will not be portable. Когда используются относительные пути, вы можете переместить приложение на основе UNIGINE или скопировать его на другой компьютер, и все ресурсы будут правильно загружены. Также нет потери скорости загрузки: это так же быстро, как загрузка файлов по абсолютному пути, благодаря виртуальной файловой системе . Можно использовать абсолютные пути для загрузки ресурсов вне папки data, но такой проект не будет переносимым.
As file names are added to the virtual file system, usually the same name and path should be used to load and remove the file when accessing from your source code by using FileSystem functions: Поскольку имена файлов добавляются в виртуальную файловую систему , обычно следует использовать то же имя и путь для загрузки и удаления файла при доступе из исходного кода с помощью FileSystem функции:
- For default resources, functions return full paths relative to the data folder. Для ресурсов по умолчанию функции возвращают полные пути относительно папки data.
- If you load a file and specify a relative path, use a relative path to delete the resource. Если вы загружаете файл и указываете относительный путь, используйте относительный путь для удаления ресурса.
- If you load a file using an absolute path, use an absolute path to delete the resource. Если вы загружаете файл с использованием абсолютного пути, используйте абсолютный путь для удаления ресурса.
You can check whether a path is absolute or relative via the isAbsolute() function. Вы можете проверить, является ли путь абсолютным или относительным, с помощью функции isAbsolute().
The file system also allows you to get a path to a file relative to the data folder by using the getVirtualPath() function. Файловая система также позволяет вам получить путь к файлу относительно папки data с помощью функции getVirtualPath().
Loading PrioritiesПриоритеты загрузки#
The Engine resolves any path as follows: Движок разрешает любой путь следующим образом:
- It tries to convert the path to a full virtual one. Он пытается преобразовать путь в полный виртуальный.
- It tries to get the current mount point by this path. Он пытается получить текущую точку монтирования по этому пути.
By using the obtained information on the path, the Engine can get a real path to the file on the disk (or blob/package/cache). Используя полученную информацию о пути, Engine может получить реальный путь к файлу на диске (или blob / package / cache).
A virtual path can represent up to four entities at the same time: it can be a file on the disk, a file stored in a package, a file added to a cache and to a blob. Виртуальный путь может представлять до четырех объектов одновременно: это может быть файл на диске, файл, хранящийся в пакете , файл, добавленный в кеш и к blob .
For example, the textures/white.dds path has only one GUID, however, it can represent the following at the same time: Например, путь textures/white.dds имеет только один GUID, однако он может одновременно представлять следующее:
- Within the project folder, you can have both core/textures/white.dds and core.ung/textures/white.dds. В папке проекта вы можете иметь как core/textures/white.dds, так и core.ung/textures/white.dds.
- In addition, in code, you can have both:
Вдобавок в коде вы можете иметь и то, и другое:
// the file loaded into a cache FileSystem::addCacheFile("core/textures/white.dds"); // the file loaded into a blob FileSystem::addBlobFile("core/textures/white.dds");
// the file loaded into a cache FileSystem::addCacheFile("core/textures/white.dds"); // the file loaded into a blob FileSystem::addBlobFile("core/textures/white.dds");
During read / write operations, the Engine will load the first found entity for such virtual path. The entities are checked in the following order: Во время операций чтения / записи Engine загрузит первый найденный объект для такого виртуального пути. Сущности проверяются в следующем порядке:
- For read operations:
- The file loaded into a blob.The file loaded into a blob.
- The file added into a cache.The file added into a cache.
- The read-only file stored on the disk.The read-only file stored on the disk.
- The file stored in a package.The file stored in a package.
- The file loaded into a blob. Файл загружен в большой двоичный объект.
- The file added into a cache. Файл добавлен в кеш.
- The read-only file stored on the disk. Файл только для чтения, хранящийся на диске.
- The file stored in a package. Файл, хранящийся в пакете.
- For write operations:
- The file loaded into a blob.The file loaded into a blob.
- The file stored on the disk.The file stored on the disk.
The file loaded into a blob.The file stored on the disk.Cached and packed files aren't checked as write operations aren't allowed for them.Для операций написать :Cached and packed files aren't checked as write operations aren't allowed for them.Cached and packed files aren't checked as write operations aren't allowed for them.- The file loaded into a blob. Файл загружен в большой двоичный объект.
- The file stored on the disk. Файл, хранящийся на диске.
Cached and packed files aren't checked as write operations aren't allowed for them. Кэшированные и упакованные файлы не проверяются, поскольку для них запрещены операции записи .
Accessing Assets and Runtime FilesДоступ к ресурсам и файлам времени выполнения#
Working with assets via UnigineEditor is clear and simple, but in order to access your project files properly you should have a clear understanding of the concept of asset and runtime files. Работа с активами через UnigineEditor проста и понятна, но для правильного доступа к файлам проекта вы должны иметь четкое представление о концепции файлов ресурсов и времени выполнения .
Generated runtime files have constant GUIDs and are named as follows:
<GUID>.<extension> (e.g., ab23be4cd7832478edaaab23be4cd7832478edaa.dds). Созданные файлы среды выполнения имеют постоянные идентификаторы GUID и имеют следующие имена:
<GUID>.<extension> (например, ab23be4cd7832478edaaab23be4cd7832478edaa.dds).
These files are stored in sub-folders of the data/.runtimes folder. The structure or this folder is optimized for the file system. Эти файлы хранятся в подпапках папки data/.runtimes . Структура этой папки оптимизирована для файловой системы.
A runtime file generated for a non-native asset with a certain GUID is placed in a folder that has a name equal to the first two bytes of this GUID. Файл среды выполнения, сгенерированный для неродного ресурса с определенным GUID , помещается в папку с именем, равным первым двум байтам этого GUID.
E.g., your non-native asset data/my_textures/1.tga will have runtime file (with a name corresponding to runtime's GUID) generated for it in a folder: ./runtimes/ae/aeb53b44cdbbbbbbbbaaabccc1c1c1c1c1c1c1c1.dds Например, для вашего неродного ресурса data/my_textures/1.tga будет создан файл времени выполнения (с именем, соответствующим GUID среды выполнения) в папке: ./runtimes/ae/aeb53b44cdbbbbbbbbaaabccc1c1c1c1c1c1c1c1.dds
Therefore each runtime file has an alias - a human-readable form of a path used to refer to this file. , поэтому каждый исполняемый файл имеет псевдоним - удобочитаемую форму пути, используемого для ссылки на этот файл.
Full aliases are constructed as follows: <source_asset_path>/<runtime_alias> Полные псевдонимы строятся следующим образом: <source_asset_path>/<runtime_alias>
E.g.:
НАПРИМЕР:
- 1.tga/1.dds
- 1.fbx/material/1.mat
In order to simplify access to runtime files, we also use a concept of the primary runtime - a runtime file uniquely assoсiated with the asset. It acts like an implied reference to a runtime file: when we say "model.fbx", we actually mean "model.node". So, that we could write: Для упрощения доступа к файлам среды выполнения мы также используем концепцию основной среды выполнения - файла среды выполнения, однозначно связанного с активом. Он действует как подразумеваемая ссылка на исполняемый файл: когда мы говорим «model.fbx», мы на самом деле имеем в виду «model.node» . Итак, чтобы мы могли написать:
NodeReferencePtr node = NodeReference::create("model.fbx");
There are two ways you can access your assets and runtime files: Есть два способа получить доступ к своим ресурсам и файлам времени выполнения:
The file system includes a subsystem for managing assets and runtime files. This subsystem is implemented as a separate class named FileSystemAssets. Файловая система включает подсистему для управления активами и исполняемыми файлами. Эта подсистема реализована как отдельный класс с именем FileSystemAssets.
You can use assets_info and assets_list console commands to view information on non-native assets and runtimes generated for them. Вы можете использовать консольные команды assets_info и assets_list для просмотра информации о неродных активах и сгенерированных для них средах выполнения.
Accessing by PathДоступ по пути#
The way of accessing a certain asset by path is determined by its type: Способ доступа к определенному активу по пути определяется его типом:
-
Native assets are accessed simply by their name:
Собственные ресурсы доступны просто по их имени:
ImagePtr image = Image::create("image.dds");
ImagePtr image = Image::create("image.dds");
-
All non-native assets have a primary runtime file. So, when you refer to the asset by its name, this primary runtime file will be actually used. For example, if you specify:
ImagePtr image = Image::create("image.png");
The image.dds generated primary runtime file will actually be used.The image.dds generated primary runtime file will actually be used.
You can also directly access any asset source file (not a runtime file). For example, if you need to specify a .png texture, you should write the following:You can also directly access any asset source file (not a runtime file). For example, if you need to specify a .png texture, you should write the following:
ImagePtr image = Image::create("asset://image.png");
In this case, the runtime .dds file will be ignored, .png source file will be used.In this case, the runtime .dds file will be ignored, .png source file will be used.
The image.dds generated primary runtime file will actually be used.You can also directly access any asset source file (not a runtime file). For example, if you need to specify a .png texture, you should write the following:In this case, the runtime .dds file will be ignored, .png source file will be used. Все неродные ресурсы имеют файл основной среды выполнения . Итак, когда вы ссылаетесь на актив по его имени, фактически будет использоваться этот основной файл времени выполнения. Например, если вы укажете:ImagePtr image = Image::create("image.png");
The image.dds generated primary runtime file will actually be used. Фактически будет использоваться сгенерированный image.dds основной файл времени выполнения.
You can also directly access any asset source file (not a runtime file). For example, if you need to specify a .png texture, you should write the following: Вы также можете получить прямой доступ к любому исходному файлу ресурса (не к файлу времени выполнения). Например, если вам нужно указать текстуру .png, вы должны написать следующее:
ImagePtr image = Image::create("asset://image.png");
In this case, the runtime .dds file will be ignored, .png source file will be used. В этом случае исполняемый файл .dds будет проигнорирован, будет использован исходный файл .png.
-
Each container asset also has a primary runtime, in case of an FBX asset it is a generated .node file. So, you can use the following reference:
NodeReferencePtr node = NodeReference::create("teapot.fbx");
The teapot.node generated runtime file will be used in this case.
The teapot.node generated runtime file will be used in this case.You can access each runtime file of a container asset. For example, an FBX file has .node and .mesh runtime files generated for it. You can access the generated .mesh file in the following way:You can access each runtime file of a container asset. For example, an FBX file has .node and .mesh runtime files generated for it. You can access the generated .mesh file in the following way:
The teapot.node generated runtime file will be used in this case.MeshPtr mesh = Mesh::create("teapot.fbx/teapot.mesh");
You can access each runtime file of a container asset. For example, an FBX file has .node and .mesh runtime files generated for it. You can access the generated .mesh file in the following way: Каждый ресурс контейнера также имеет основную среду выполнения, в случае актива FBX это сгенерированный файл .node. Итак, вы можете использовать следующую ссылку:NodeReferencePtr node = NodeReference::create("teapot.fbx");
The teapot.node generated runtime file will be used in this case.
В этом случае будет использоваться сгенерированный файл времени выполнения teapot.node.
You can access each runtime file of a container asset. For example, an FBX file has .node and .mesh runtime files generated for it. You can access the generated .mesh file in the following way: Вы можете получить доступ к каждому исполняющему файлу ресурса контейнера. Например, для файла FBX созданы файлы времени выполнения .node и .mesh. Вы можете получить доступ к сгенерированному файлу .mesh следующим образом:
MeshPtr mesh = Mesh::create("teapot.fbx/teapot.mesh");
Accessing by GUIDДоступ по GUID#
You can also access any runtime or asset in your project using GUIDs. If a GUID of a file is specified, the exact path corresponding to this GUID is used: Вы также можете получить доступ к любой среде выполнения или активу в своем проекте, используя GUID . Если указан GUID файла, используется точный путь, соответствующий этому GUID:
UGUID asset_guid; // GUID of the asset named "1.tga"
const char *asset_path = "1.tga";
ImagePtr image = Image::create(asset_guid); // -> 1.tga
ImagePtr image = Image::create(asset_path); // -> 1.dds
ModifiersМодификаторы#
File modifiers serve to automatically choose which resources to load when a UNIGINE project is run on different platforms or with different localizations. Instead of keeping multiple versions of the same project and copying shared data between them, you can add a custom postfix to file or folder names, and load only required resources on demand. Модификаторы файла служат для автоматического выбора ресурсов для загрузки, когда проект UNIGINE выполняется на разных платформах или с разными локализациями. Вместо того, чтобы хранить несколько версий одного и того же проекта и копировать общие данные между ними, вы можете добавить собственный постфикс к именам файлов или папок и загружать только необходимые ресурсы по запросу.
Modifiers are added to file or folder names as a postfix (only one can be specified). Any custom postfix can be used. For example, it could be: Модификаторы добавляются к именам файлов или папок в виде постфикса (можно указать только один). Можно использовать любой собственный постфикс. Например, это может быть:
- File name modifier: file.small.node or texture.eng.dds File name modifier: file.small.node or texture.eng.dds
- Folder name modifier: textures.lowres
If a folder has a modifier, files inside it should not have their own modifiers. Otherwise, file modifiers will be ignored.Модификатор имени папки: textures.lowresIf a folder has a modifier, files inside it should not have their own modifiers. Otherwise, file modifiers will be ignored.If a folder has a modifier, files inside it should not have their own modifiers. Otherwise, file modifiers will be ignored.If a folder has a modifier, files inside it should not have their own modifiers. Otherwise, file modifiers will be ignored. Если у папки есть модификатор, файлы внутри нее не должны иметь собственных модификаторов. В противном случае модификаторы файлов будут проигнорированы.
Register necessary modifiers in code via addModifier(). When the project is running, resources with the registered modifiers are loaded automatically. Files without modifiers have the lowest priority (can be used for default resources). Зарегистрируйте необходимые модификаторы в коде через addModifier() . Когда проект запущен, ресурсы с зарегистрированными модификаторами загружаются автоматически. Файлы без модификаторов имеют самый низкий приоритет (могут использоваться для ресурсов по умолчанию).
Usage ExampleПример использования#
For example, three localization languages are supported in the project: English (by default), German and French. Depending on the language, different splash textures should be loaded on the start-up. Например, в проекте поддерживаются три языка локализации: английский (по умолчанию), немецкий и французский. В зависимости от языка при запуске должны быть загружены разные текстуры заставки.
To organize your resources, name them using the following file modifiers: Чтобы организовать свои ресурсы, назовите их, используя следующие модификаторы файлов:
-
data
-
splashes
- splash.png (this is a default version of the texture. In our case, a texture with an English title)
- splash.de.png (a German title)
- splash.fr.png (a French title)
-
splashes
After that, you need to specify in code which modifier to use via addModifier(). This function is called in the system script since a modifier needs to be registered before the world and its resources start to be loaded. For example, to load a German splash screen and the low resolution textures interface: После этого нужно указать в коде, какой модификатор использовать через addModifier(). Эта функция вызывается в системном скрипте , поскольку модификатор должен быть зарегистрирован до того, как мир и его ресурсы начнут загружаться. Например, чтобы загрузить немецкий заставку и интерфейс текстур с низким разрешением:
// unigine.cpp
int init() {
...
// Register modifier
engine.filesystem.addModifier("de");
// Set a splash texture
engine.splash.setWorld("textures/splash.png"); // splash.de.png will be automatically used
...
return 1;
}
Also you can use -extern_define CLI option to pass the language (for example, if a user chooses a language in the launcher). bin\main_x64d.exe -extern_define "LANG_DE"
bin\main_x64d.exe -extern_define "LANG_DE"
And here is how passed defines can be handled in the code. А вот как переданные определения могут быть обработаны в коде.
// unigine.cpp
string lang = "";
int init() {
...
// Parse EXTERN_DEFINE
#ifdef LANG_DE
lang = "de";
#elif LANG_FR
lang = "fr";
#endif
if(lang != "") {
engine.filesystem.addModifier(lang);
}
// Set a splash texture: splash.de.png or splash.fr.png will be used if the language is passed
engine.splash.setWorld("textures/splash.png"); // otherwise, splash.png
...
return 1;
}
Asynchronous LoadingАсинхронная загрузка#
UNIGINE Engine allows you to control asynchronous loading of files by means of the AsyncQueue class. All file-related methods of this class will load a file and add it to the file system as a cached one. UNIGINE Engine позволяет управлять асинхронной загрузкой файлов с помощью класса AsyncQueue. Все методы этого класса, связанные с файлами, загружают файл и добавляют его в файловую систему как кэшированный.