I am hoping fresh eyes or a more experienced brain can help me here. I am testing Addressables with ECS and am running into what I think is a bug but can’t find anything on the forums. Could someone double check me on this?
I setup a fresh URP project using the latest Entities and Addressable packages for the code below.
using Unity.Entities;
using UnityEngine.AddressableAssets;
namespace UnityTemplateProjects
{
[UpdateInGroup(typeof(InitializationSystemGroup))]
[AlwaysUpdateSystem]
public class BugTestSystemGroup : ComponentSystemGroup
{}
[UpdateInGroup(typeof(BugTestSystemGroup))]
public class BugTestSystem : SystemBase
{
protected override void OnUpdate()
{
// Works
Addressables.LoadResourceLocationsAsync("Test");
// Works
Entities.ForEach((Entity entity) =>
{
var handle = Addressables.LoadResourceLocationsAsync("Test");
}).WithoutBurst().Run();
// Works
Job.WithCode(() =>
{
var handle = Addressables.LoadResourceLocationsAsync("Test");
}).WithoutBurst().Run();
// Fails
// UnityException: get_enterPlayModeOptionsEnabled can only be called from the main thread.
new JobEntityBatchTest().Run(EntityManager.UniversalQuery);
}
private struct JobEntityBatchTest : IJobEntityBatch
{
public void Execute(ArchetypeChunk batchInChunk, int batchIndex)
{
var handle = Addressables.LoadResourceLocationsAsync("Test");
}
}
}
}
It looks to me as though IJobEntityBatch.Run is using a worker thread and not the main thread. The documentation says it should be the main thread though. Anybody have any clues on this that can set me straight?
Entities.ForEach\Job.WithCode Run works differently than regular jobs Run. You’ll see that error not only in IJobEntityBatch but in any other regular job - IJob, IJobChunk etc.
The reason is regular jobs Run process still goes through the scheduler and not the thread-safe context (despite it runs on the main thread).
In the case of Entities.ForEach\Job.WithCode code will be different, as they’re just templates for codegen. ILPP eventually will generate different code for them which you can inspect through DOTS Compiler, but we are mostly interested in this thing: RunWithoutJobSystemDelegateFieldNoBurst
Which is in generated code of Entities.ForEach\Job.WithCode will be called just like a simple delegate (sort of) on the main thread without Scheduler involved in the process (as the name suggests WithoutJobSystemDelegate).
Just a fast and rough explanation of why you see an error in one case but not in another. DOTS team can correct me if I’m wrong in my explanation