MonoBehaviour Support
HybridCLR fully supports the hot update MonoBehaviour and ScriptableObject workflow, that is, you can add a hot update script on the GameObject in the code or mount it directly on the resource. Hot update script. However, due to the particularity of Unity's resource management mechanism, mounting hot update scripts on resources requires some special processing in the packaging workflow.
Used through code
AddComponent<T>()
or AddComponent(Type type)
is fully supported at all times. Just load the hot update dll into the runtime through Assembly.Load in advance
Just within.
Mount MonoBehaviour on the resource or create a ScriptableObject type resource
When the Unity resource management system deserializes hot update scripts in resources, it needs to meet the following conditions:
- The dll where the script is located has been loaded into the runtime
- It must be a resource packaged using AssetBundle (addressable and other frameworks that indirectly use ab can also)
- The dll where the script is located must be added to the assembly list file generated during packaging. This list file is loaded when Unity starts and is immutable data. The list file names and formats of different versions of Unity are different.
If no processing is done on the packaging process, since the hot update dll has been removed in the IFilterBuildAssemblies
callback, it will definitely not appear in the assembly list file.
Since condition 3 is not met, the hot update script mounted in the hot update resource cannot be restored, and a Scripting Missing
error will occur during runtime.
Therefore, we have made special processing in the Editor/BuildProcessors/PatchScriptingAssemblyList.cs
script, adding the hot update dll to the assembly list file.
You need to add the hot update assembly in the project to the HotUpdateAssemblyDefinitions or HotUpdateAssemblies field in the HybridCLRSettings configuration.
It only restricts hot update resources to be packaged in the form of ab package, and there is no limit to the way hot update dll is packaged. You can freely choose the hot update method according to the project requirements**, you can package the dll into ab, or bare data files, or encrypted compression, etc. As long as it can be guaranteed to use Assembly.Load to load the hot update resource before loading it.
assembly list file
The names and formats of the assembly list files are different in different Unity versions.
- 2019 version. It is a globalgamemanagers file when uncompressed and packaged. When compressed and packaged, it is first saved to the globalgamemanagers file, and then packaged into the data.unity3d file in BundleFile format and other files.
- 2020-2021 version. Saved in the ScriptingAssembles.json file.
Known issues
GameObject.GetComponent(string name) interface cannot get component
This is a known bug, which is related to the code implementation of unity. This problem occurs only when the hot update script is mounted on the hot update resource. The hot update script added through AddComponent in the code can be found by this method. If you encounter this problem please use GameObject.GetComponent<T>()
or GameObject.GetComponent(typeof(T))
instead
Others
Do not modify the name of the dll where the script that needs to be linked to the resource is online, because the assembly list file cannot be modified after it is packaged.
It is recommended not to disable TypeTree when typing AB, otherwise the normal AB loading method will fail. (The reason is that for scripts that disable TypeTree, Unity will verify the signature of the script in order to prevent the binary mismatch from causing process crash during the deserialization of MonoBehaviour. The content of the signature is the Hash generated by the script FullName and TypeTree data, but because we The hot update script information does not exist in the packaged installation package, so the verification will definitely fail)
If TypeTree must be disabled, a workaround is to disable the Hash verification of the script. In this case, the user must ensure that the code is consistent with the resource version when packaging, otherwise it may cause Crash, sample code
AssetBundleCreateRequest req = AssetBundle. LoadFromFileAsync(path);
req.SetEnableCompatibilityChecks(false); // Non-public, needs to be called by reflection