Edit: Removed TransformAccessArray from this list until we have a good alternative
Why are they being deprecated?
Usability is always at the core of Unity, and the simplicity of our APIs is a key part of that. But simplicity should never come at the cost of transparency, especially when performance is involved. We’ve recently identified some key performance problems with these APIs which are not immediately obvious from the surface. While they provide a neat and simple way to access your data, they abstract away the systems underneath them, which makes identifying bottlenecks and optimizing your code more difficult. It becomes more difficult to move to the low-level APIs when performance or control requires it.
So simply put, they make it harder to learn how to use ECS to write fast code.
IJobProcessComponentData provides a simple way to iterate through and transform component data.
You can also use ForEach in a main-thread ComponentSystem for added simplicity, but at the cost of performance and parallelization.
IJobChunk and ComponentGroup.CreateArchetypeChunkArray provide more manual control, which may be necessary to solve certain problems efficiently.
What are the recommended replacements for [Inject]
ComponentGroup injection (injecting structs) is replaced by (Job)ComponentSystem.GetComponentGroup, ForEach, IJobProcessComponentData, IJobChunk, and manual chunk iteration.
ComponentDataFromEntity injection is replaced by (Job)ComponentSystem.GetComponentDataFromEntity.
Injecting other systems is replaced by (Job)ComponentSystem.World.GetOrCreateManager.
Note: When converting the injection of a EntityCommandBufferSystem (formerly BarrierSystem), you must explicitly inform the EntityCommandBufferSystem of which JobHandle(s) to wait on before executing with EntityCommandBufferSystem.AddJobHandleForProducer. A well-commented example of this can be found in the HelloCube_06 sample.
You can read about all of these APIs on the GitHub Documentation page. The repository also has Samples which show how these APIs are used.
When will they be removed from the Entities package?
All of these APIs will be marked as Obsolete in either release 0.0.23 or 0.0.24. At the earliest, they will be removed in release 0.0.25.
What about my use case [×]?
It’s possible we’ve missed something, or that the new APIs aren’t completely clear. Feel free to use this thread as a place to discuss your individual use cases and provide feedback.
@tertle Thanks for reply, I didn’t know that ForEach can iterate non-struct component. But it seems that using ForEach for Transform cannot obtain any advantage of IJob and Burst. CopyTransformFromGameObjectSystem still used GetTransformAccessArray() in p24.
There is going to have to be a replacement because the Unity Hybrid systems depend on
IJobParallelForTransform but I don’t think you should really be using this yourself. You’re probably better off manipulating the Position, Rotation, Scale components and letting the CopyTransfromToGameObjectSystem handle the sync back.
We use IJobParallelForTransform quite a bit although mostly because it was there not that we can’t replace it easily. It was a good bridge for transforms between ECS and non ECS code. Plus just using TransformAccess everywhere in non ECS code for read only access shaved half a ms per frame, transforms are expensive suckers to access.
We’re still working on the right replacement for TransformAccessArray. It’ll likely be the last of these APIs to be officially deprecated. If we don’t find a good replacement, we may end up just keeping it and deprecating the others.
I’ve wanted to avoid ComponentDataArray. There’s this one case where I couldn’t find an alternative. I use ComponentGroup.SetFilter() then pass an instance of a SharedComponent to filter entities under a certain grouping, say manager. The filtered entities only works with ComponentGroup.GetComponentDataArray() after calling SetFilter(). It doesn’t work with CreateArchetypeChunkArray() (still returns all entities).
Let me quote something from the source code of the package.
m_FrozenGroup.SetFilter(subsceneTag);
//@TODO - revert to CreateArchetypeChunkArray once it supports filtering
//var filteredChunks = m_FrozenGroup.CreateArchetypeChunkArray(Allocator.TempJob);
var filteredChunks = m_FrozenGroup.GetAllMatchingChunks(Allocator.TempJob);
So they know about it. Hopefully be supported by time it is officially marked as depreciated otherwise that’ll be a bit awkward.
I haven’t used GetAllMatchingChunks but maybe that’s a workaround?
Say, I have entities with only this an IBufferElemenData
Does accessing them in a job require me to add a “dummy” component?
example
// components
public struct KeyBuffer: IBufferElementData {public int Value;}
public struct KeyBufferDummy: IComponentData {public byte Dummy;}
// job
public struct ClearKeyBufferJob : IJobProcessComponentDataWithEntity<KeyBufferDummy>
{
[NativeDisableParallelForRestriction, WriteOnly] public BufferFromEntity<KeyBuffer> keyBufferFromEntity;
public void Execute(Entity e, int i, [ReadOnly] ref KeyBufferDummy dummy)
{
keyBufferFromEntity[e].Clear();
}
}
I’m having trouble understanding how to not use these in the newest version.
Here’s a preview of a system I have that changes Volume weight based on the time of the day.
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using UnityEngine;
using UnityEngine.Rendering;
namespace Game
{
public class WorldTimeVolumeSystem : ComponentSystem
{ ComponentGroup m_volumes;
protected override void OnStartRunning()
{
base.OnStartRunning();
m_volumes = GetComponentGroup(
typeof(WorldTimeSpan),
typeof(WorldTimeVolume),
typeof(Volume));
}
protected override void OnUpdate()
{
var volumes = m_volumes.GetComponentArray<Volume>();
var wtVolumes = m_volumes.GetComponentDataArray<WorldTimeVolume>();
var spans = m_volumes.GetComponentDataArray<WorldTimeSpan>();
// DO THINGS
}
}
}
Now the “GetComponentDataArray” parts get underlined in green saying the method is deprecated.
It seems like the suggested alternatives are for Jobs, but what if, like in my case, I can’t use Jobs because I’m playing with a legacy component (UnityEngine.Rendering.Volume)? And I can’t use prefabs as these things are level art related and therefore are better if they stay in the scene.
It would be nice if ECS examples provided this kind of scenario where it shows how we can play with non-jobifiable components such as rigidbodies, lights, animators or volumes. And not instanced as prefabs but just regular scene objects.
I may be able to figure how out to convert my existing code to fit the deprecation, but everytime these changes come I’m a bit lost I know it is a preview but any hint would be greatly appreciated Cheers!
Also as far as ToEntityArray()/ToComponentDataArray() etc goes, these functions are copying data from the chunks. This has a cost associated with it. Using IJobProcessComponentData, IJobChunk, or CreateArchetypeChunkArray will allow you to access and transform the data in place, and will generally be faster and allocate less memory.
Both interfaces can’t be used with non-IComponentData. As for CreateArchetypeChunkArray, I simply don’t know how to use this, and again unsure this can query standard components.
That only works with IComponentData, it seems.
So my question remains: What’s the best / fastest way to iterate through standard components in ECS if not the two deprecated methods?
Any example of that would be greatly appreciated as they aren’t shown in the GitHub Samples (RotationSystem uses ForEach which can’t process my Volume components as they aren’t IComponentData) nor are they documented anywhere.
Standard components, such as Volumes, Lights and Rigidbodies won’t be ECS-compliant for quite a while (years?) so keeping them examplified would be really nice IMO.
The order of the parameters for the ForEach delegate is very specific. If you look at the ForEachIterator.generated.cs in Unity.Entities/Iterators in the packages folder you’ll find a each of the different possible delegates one can use as well as their constraints. I’ve used some regex to extract each of the different permutations - all 178 of them - and jammed it into the file I attached with this post. It essentially lists the delegates with the naming schema of F_xxxx where xxxx is the combination and order of specific parameter types. The legend to those types can be seen here:
E - Entity
C - Component
B - IBufferElementData
D - IComponentData
S - ISharedComponentData
This list might still be very incomplete, but it should give you a basic idea of what you can and a can not do. For IJobProcessComponentData the type Component can’t be used as these don’t have the same performance guarantees an IComponentData would have.
I assume this is a temporary measure as scrolling through 178 permutations to find the right order isn’t super convenient but anyway good to know at least it is compatible with components.