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
Start here
Concepts
Authoring for a game
Playing a story
The generated code
The plugin and sync
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.pngloads 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.
| What | Address | Group |
|---|---|---|
| Media | The relative path from the media root, without the extension — portraits/ryn_zhao | TaleShard Media |
| Entity prefabs | The filename without the extension — ryn_zhao | TaleShard 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.