Skip to content

Where synced media lands

The media path and its Resources segment, the addresses assigned, the import that must happen, and the combination that ships every file twice.

All documentation — Media
On this page

A sync writes media into your project, and three separate things then act on those files: a delta that deletes and moves inside the folder, an importer that fixes the texture type, and a postprocessor that assigns an Addressables address.

All three key off one setting. Getting it right is mostly a matter of knowing which loading mechanism you are using.

The media path

mediaPath, relative to Assets/. The default is Media/TaleShard/Resources.

Changing the default does not reach an existing install. Unity serialises the value into the settings asset, so a project keeps whatever it was created with.

The Resources segment, and why it is in the default

Resources.Load reads paths relative to any folder literally called Resources, and can see nothing outside one. So a file synced to

Assets/Media/TaleShard/Resources/portraits/kim.png

loads as portraits/kim — which is the media key itself, and exactly what the built-in fallback source asks for. That is the whole reason the segment is there: it makes ResourcesMediaSource work with no configuration at all.

Drop the segment and the fallback reads the root of Resources and finds nothing, whatever it is asked.

The combination that ships everything twice

Media under a Resources folder and marked Addressable. Both mechanisms then hold the same files, so every synced file is in the build twice — once in the Resources blob, once in an Addressables bundle.

The sync window reports it as a warning rather than an error, because it is a cost rather than a fault. The fix is to drop the Resources segment from the path.

How the path is read

MediaPathPlacement is where that decision lives, and its rules are exact:

IsUnderResources(path)True when any segment is exactly Resources
ResourcesPrefixOf(path)Everything after the last Resources segment, or null when there is none
DuplicateInclusionWarning(path, autoMarkAddressable)The sentence above, or null

ResourcesPrefixOf answering the empty string is a real answer, and is not null: it means the media sits at the root of a Resources folder, which is what the automatic fallback already reads. The default path is exactly that case. A non-empty prefix is what you pass to new ResourcesMediaSource("…").

Addressables

autoMarkAddressable is on by default. When the package is present, the postprocessor marks what the sync imports.

WhatAddressGroup
MediaThe relative path from the media root, without the extension — portraits/ryn_zhaoTaleShard Media
Entity prefabsThe filename without the extension — ryn_zhaoTaleShard Entities

Entity prefabs come from entityPrefabsPath, default Prefabs/Entities. Leave it empty to disable that half.

Because the address a media file gets is the key a MediaAddress carries, the Addressables source needs no configuration either — see loading media.

Whether the package is present

The Addressables integration lives in its own assembly, so a project without the package is never forced to resolve it — an assembly definition resolves its references before compiling, so a conditional inside a file cannot save an assembly that lists an absent reference.

The dependency is therefore inverted: the optional assembly registers itself on load, and the core assembly invokes through a delegate without ever naming Addressables.

The import that has to happen

Synced media is imported as a Sprite, on the first import of each file and never again.

Setting the type to Sprite does not break Texture2D readers. With single sprite import mode the main asset is still the Texture2D and the Sprite is a sub-asset, so an existing LoadAssetAsync<Texture2D> keeps resolving. The assignability is one-way.

The importer lives in the core editor assembly rather than beside the postprocessor in the optional one, and must stay there: that assembly is excluded from compilation in a project without the Addressables package, nothing in the importer touches the Addressables API, and a project loading synced media by any other means needs the same fix.

What always goes through Resources

Media is the part you choose a mechanism for. The project’s data is not.

The generated loaders read boards, entity data and localization through Resources.Load, and the generated bootstrapper’s default loader does the same. So a project that moves all of its media to Addressables still ships its JSON in the Resources blob.

That is not a leak to plug: those files are small, they are needed on the first frame, and the bootstrapper’s loader is a seam — pass your own loadJson if you want them somewhere else.

Written for
Unity developers · Advanced integrators
Last updated