- Home /
Are components contiguous in memory?
One of the benefits of using a component/entity driven paradigm is that the components are contiguous in memory. That's cache friendly and well suited to multi-threaded applications. Does unity take this approach? Could you easily get a list of all components of type T in a scene and have systems that operate on these in unity?
Answer by Cygon4 · Apr 06, 2013 at 08:56 PM
Unity components are allocated by the Mono runtime and garbage collected, thus, unless the Unity developers have heavily modified Mono's allocation behavior, you'd get this behavior:
Memory is dealt out sequentially. Allocated objects will be placed in memory one after another ordered by creation time (but not type).
At any time, a compaction can occur which juggles objects around in physical memory randomly to close gaps where freed objects were located.
On top of that, your OS runs the CPU in protected mode, so each 4K page can (and likely will) be at a completely different location in physical memory.
Cache coherency is an interesting topic in CPU-side particle systems and anything dealing with mass data, but from my point of view Unity components are high-level enough (you only have a few hundred active per scene typically) that I'd focus solely on convenience and algorithmic efficiency.
Now if you have a specific problem you're thinking about, maybe Unity already offers an efficient solution other than enumerating all components of a type.
Many such queries can be supported by the highly optimized code in PhysX. For example, if your space combat game's targeting system needs a list of the closest X enemies, you can put a sphere collider on the ship with a component that keeps a list of in-range enemies via OnTriggerEnter() and OnTriggerLeave(), letting PhysX handle spatial indexing and object island building.
Answer by ThePunisher · Feb 13, 2013 at 12:39 AM
So you can get a list of all GameObjects in the scene using components of type T by calling GameObject.FindObjectOfType(typeof(T)) as T
but I'm not sure that's done in the same method you are referring to as this method is very slow for obvious reasons.
http://docs.unity3d.com/Documentation/ScriptReference/Object.FindObjectOfType.html
This method being slow leads me to assume components of type T aren't all stored in some collection. I suppose I could wrap $$anonymous$$onoBehaviour to do this myself, although that would only work for custom components.
Why couldn't you make it work for the built-in components? Also, it could be a pain to maintain that collection if you are constantly adding/removing components dynamically.
So what is it that you are trying to do which would need this collection to be available?
When I first heard about unity being component based I assumed it was a system similar to this: http://gamadu.com/artemis/index.html Artemis isn't a unique pattern, just google 'entity system' and you see countless posts on this.
The idea is you separate data (variables, state) from the logic. In unity you attach 'behaviors' to objects which contain both data and logic and I can imagine on large projects you could get into 'reference hell' where all these behaviors are referencing each other and it becomes hard to track.
So say you add a Rotating
component to an object, all that component would have is a public variable angularVelocity
. You would then have a RotatingSystem
that will keep a list of all objects that contain a Transform
component and a Rotating
component and each update rotate all of them in one go. Components should never reference other components, but systems should talk to other systems.
I understand, but you'd be able to recreate that type of system very easily by having an object manager singleton that objects can register with by implementing an interface (let's say I$$anonymous$$yObject) and calling a register method in their Awake. Then you can have your IRotatingObject inherit from I$$anonymous$$yObject. When you go to your object manager you say:
IRotatingObject[] objects = Object$$anonymous$$anager.Instance.GetObjects>IRotatingObject<();
foreach (IRotatingObject rotObject in objects)
{
rotObject.CallSome$$anonymous$$ethod();
}
That's what I do in my game simply because searching through the hierarchy/scene is way too expensive.
PS: Had to flip the angled brackets because this thing's formatting doesn't like an open/close angled bracket pair.
Your answer
Follow this Question
Related Questions
Error CS0425: Works in DLL but not in Unity 0 Answers
Webplayer Dynamic Audio Loading 0 Answers
Is it okay if I use two similar components (AudioSource) in the same GameObject? 1 Answer
2D Animation does not start 1 Answer
WebGL changes memory usgage 0 Answers