This means that any time you rename a class, move the class to a new namespace, move the code to a new assembly, or rename the assembly it is in, you will need to rebuild your asset bundles.
We encountered problems like this today! For us it was not upgrading unity that fixed it (this seems to have no effect), but performing a clean build of our asset bundles (deleting the ‘library’ folder et cetera and having unity regenerate everything).
Some probing into our bundles revealed that m_AssemblyName was getting stuck on the old value even after we rebuilt them! I would therefore speculate that it’s necessary to reimport the bundled prefabs (or just nuke the library) after changing your MonoBehaviours’ assemblies around.
That may actually be due to the incremental build process of the build pipeline is not detecting the rename. You could try using “BuildAssetBundleOptions.ForceRebuildAssetBundle” to force it to rebuild and see if that works instead.
I have same problem, My scenes in project is loaded from assetbunle and scripts can’t find.
I rebuild with “BuildAssetBundleOptions.ForceRebuildAssetBundle” option but not working
Are you planning to fix it so that can detect changes in AssemblyName when build AssetBundle?
Or, if you have a way to get an AssemblyName from AssetBundle with Editor script, please let me know as I can create the validator on my own.
I would like to add a namespace for some scripts. Is there any way to update/fix/relink an asset bundle through code without rebuilding the bundles? Also, just curious, but why not use the guid of the script? why use the name?
@Ryanc_unity
That is exactly my question. Why not use only the GUID for that, when its main purpose is to allow us renaming and moving stuff around our project without losing the references?
Also, with more and more people making use of AssembyDefinitions and Unity Package Manager to create reusable modules whenever we can, I feel that this kind of renaming would start being a very “hidden” problematic issue.
I found this thread searching for some clarity as to how Assembly Definitions are referenced. We were experiencing an issue where after unpacking Asset Bundles, our scripts on prefabs were appearing as missing, despite those same scripts definitely being present in the project. We presumed we were having some issues with our ADs, as this was our first use of them. I was initially confused as to why Unity would choose string references too, but now I’m actually pretty glad they did.
Our pipeline features a separate Unity project that handles building Asset Bundles. However, this project hadn’t been set up with Assembly Definitions just yet, so the scripts were considered part of “Assembly-Csharp.dll”. If Unity chose to reference ADs by GUID, I believe that would mean that we couldn’t use the system, as assets have different GUIDs across different projects, even if they’re essentially duplicates.
I don’t know enough to say that it’s definitely Unity’s reason for going that route though.
Thanks for sharing your experience, it really helps me/us to understand the different ways of using Unity.
I have two notes about your workflow:
Yes, if you just recreate the AssemblyDefinition on a separate project, it will for sure take a GUID different from the one in your main project. I would say you should not re-create it, but really have a copy of it with its meta file, the same way you probably have done with the scripts. (of course, it is better if you have a way of sharing everything between both projects (via Unity Package Manager for instance), so that you just import them, instead of manually copying from one to another).
I don’t understand why your assets would work since in the separate project the scripts are part of “Assembly-Csharp.dll” and in the other project, the scripts are part of an AssemblyDefinition. According to that post, it should be a problem:
I actually did do this (manually copied our AssemblyDefinitions and their respective meta files), but I noticed that the referenced definitions were broken, which I believe means that the copied ADs were essentially different because they were in a different project.
Apologies if I was not clear initially, here’s a breakdown of what (I think) happened:
Asset Bundling project did not contain AssemblyDefinitions (i.e. all scripts were a part of “Assembly-CSharp.dll”), project that unpacks Asset Bundles did have AssemblyDefinitions
When unpacking Asset Bundles, scripts were appearing as missing
ADs were copied into Asset Bundling project
AD references were broken, indicating that despite being copied from the other project into the Asset Bundling project, the ADs were effectively different, with different GUIDs
References were fixed
A test was done where the Asset Bundle was rebundled and re-unpacked by the other project
(I assume that when rebundled, “m_assemblyName” was set to the name of the respective AssemblyDefinitions, since it is just a string)
When unpacked, scripts were found and linked successfully in the unpacking project
I found this thread due to a similar issue where any scenes I have which live in asset bundles were unable to find references to scripts which live in an assembly definition… but… any of the suggestions listed here were not helping my case. I have however narrowed down the source of the issue which you all might find interesting because it could explain why some of you are having issues. I’m in the process of submitting a reproduction project. Here’s the bug report write up:
1. What happened?
We get a heap of logs that scripts are missing when our scripts are added to assembly defintions and referenced in a scene which lives inside of an asset bundle:
The referenced script on this Behaviour (Game Object ‘SomeObject’) is missing!
What I’ve found is that if scripts are located in a package with an assembly definition, any scene that is bundled inside of an asset bundle can not find a reference to any scripts in that package, if:
IL2CPP is the active scripting backend, which we must use for platforms like Switch
the app is built manually using the BuildPipeline.BuildPlayer method which we must use for our very extensive compiler pipeline
It’s as though under these circumstances that the script address (class, namespace and assembly name) is not being stored in asset bundles.
2. How to reproduce:
create a project that has two scenes, a scene called LaunchScene which has one job, to load a second scene BundledScene, which is a scene that we’ll store in an asset bundle, code example to load the second scene:
add a monobehaviour test script to a local embedded package with an assembly defintion, and then add this script as a component to an empty game object in the scene called BundledScene
set BundledScene to have an asset bundle name: bundledscene, the example compiler code below has a line to build this out to an asset bundle stored in the StreamingAssets folder,
note: only add the LaunchScene to BuildSettings, don’t add the BundledScene to the list because it’ll be loaded from an asset bundle instead
set the standalone platform as the active platform, it doesn’t matter if it’s windows or mac, make sure IL2CPP is the active scripting backend (Mono doesn’t have this issue)
then compile out the app using the BuildPipeline method, example code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class BuildTools {
[MenuItem( "Tools/Build App" )]
static void BuildApp () {
// force build asset bundles, which for this test should only build one bundle for the scene called 'BundledScene'
var assetBundleOptions = BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.ForceRebuildAssetBundle;
BuildPipeline.BuildAssetBundles( Application.streamingAssetsPath, assetBundleOptions, EditorUserBuildSettings.activeBuildTarget );
// compile out app using BuildPipeline
var directlyIncludedScenes = new List<string>();
foreach ( var s in EditorBuildSettings.scenes ) {
directlyIncludedScenes.Add( s.path );
}
var buildOptions = BuildOptions.ShowBuiltPlayer;
if ( EditorUserBuildSettings.development ) {
buildOptions |= BuildOptions.Development;
}
BuildPipeline.BuildPlayer( directlyIncludedScenes.ToArray(), $"{Application.dataPath}/../Builds/Test", EditorUserBuildSettings.activeBuildTarget, buildOptions );
}
}
When you run the app check the player.log to find logs saying the referenced script is missing!
If you change to Mono this issue goes away, the script references are not missing. If you build using the manual Build button in Build Settings the problem also doesn’t occur. But none of these workarounds are an option for us in our production pipeline. The script references should not be missing.
note: I’ve used several revisions of 2021.2.x, currently on the latest at time of writing 2021.2.13 and the issue remains.
I’m not sure if ChunkBasedCompression for asset bundles was also needed or not to replicate the issue, but is what we need to use for most of our platforms so I just left that there when setting up the reproduction project. The bug report issue number is: 1407312
So how obscure is that, scripts are missing if the build is: IL2CPP, the scripts live in a package (with assembly defintion) that are used by a scene which lives in an asset bundle when the app is built using the manual BuildPipeline method.
Note that if a reference to at least ‘one’ script from the assembly definition is referenced or used in a scene which is ‘not’ added to an asset bundle, then all of a sudden the references to ‘all’ scripts start working. This workaround allows the build pipeline to start working properly and adds the script references to asset bundles. But if the only reference to scripts is within asset bundles then they’re not compiled properly and can’t be found. ONLY when using IL2CPP, and ONLY when building with the BuildPipeline method…
Hi @Ryanc_unity just wondering if anyone is looking at this bug report, I’ve submitted a super simple project that reproduces this script missing error consistently, it’s been three weeks since submitted, it’d be great to know if this is being looked at, thanks.