#Moving the Camera from ECS
1 messages · Page 1 of 1 (latest)
the most basic way would simply be, Camera.main.transform.position = yourposition
but this obviously doesn't work from a job
because cameras are managed
a way to do this from a job would be to add the Transform of a camera to an entity then use TransformAccessArray to move it
then the question becomes, is this even worth the effort over just writing to it from OnUpdate?
alternatively you can use HYBRID_ENTITIES_CAMERA_CONVERSION
Does it really need to be a job? If this is the sole purpose of job - you are wasting performance. If it's not - you can read result of job on next frame on main thread.
You could go with something like this:
- Have an Entity that represents the camera. It has transform components, and a
CameraRefcomponent that holds aUnityObjectRef<Camera>. - Your camera GameObject could have some monobehaviour that creates the camera entity on Awake and sets up the
UnityObjectRef<Camera>. Or alternatively, the camera entity could already exist in a subscene, and then you'd spawn a camera GameObject prefab on start and assign it to theUnityObjectRef<Camera>. If you go with the latter approach, your camera authoring can store aUnityObjectRef<GameObject>on the entity for the camera prefab to spawn. - In the
SimulationSystemGroup, write the system that handles your camera movement. It can either be main thread, or a job if you want to avoid creating a sync point in the middle of the frame just to handle your camera. (sometimes gameplay code needs an up-to-date camera position, so that can be useful in these cases). - In the
PresentationSystemGroup, write a main thread system that iterates entities withLocalTransformandCameraRef, gets the Camera GameObject transform via theUnityObjectRef<Camera>, and copies the camera entityLocalTransformto it
I find that UnityObjectRef<T> in entity components is a good default way to handle cases where you need Entity and GameObject stuff to communicate. It's not the most performant way to handle it, but it probably won't really matter unless you're dealing with thousands of things (which is surely not the case for cameras)
Phil, thanks for that response.
I want to be honest here, because I think I have some confusion about how Unity as a company thinks about DOTS:
From the very beginning, Joachim’s sell has always been that you should be able to write a game’s main logic using DOTS. Or at least that eventually that was the company’s goal.
But the fact that doing something as common as moving a camera requires all those different parts - and that a suggested approach doesn’t seem to be advertised anywhere - suggests that Unity has stopped thinking about DOTS in this way.
Maybe the mission statement has changed, and Unity no longer expects users to write their main game logic in ECS/Bursted Jobs? Is that the right way to look at it these days?
We're well aware of the difficulties of hybrid workflows, or the difficulties caused by the way some parts of the engine are not DOTS-compatible (or job-compatible) and some glue code is required to make all this work
However at Unite 2024, we revealed our plans to tackle this:
https://discussions.unity.com/t/dots-development-status-and-milestones-ecs-for-all-september-2024/1519286
You can also look for some of the replies by "topher_r" in this tread for additional details.
The short version of it:
- Every GameObject is an Entity. You can easily get an Entity from a GameObject, or a GameObject from an Entity.
- A GameObject and its Entity will share the same transform. If you move an Entity, it moves its GameObject, and vice-versa.
- Subscenes & baking are no longer the only real way of working with entities. You can have GameObjects in scenes that are also entities, or you can have pure entities in scenes.
So with that, the camera example could become this:
- You spawn a camera GameObject that also has some
EntityCameracomponent that's added to that GameObject's entity. - You write an ECS system that iterates entities that have a transform component and a
EntityCameracomponent, and moves that transform. - Since Entities and GameObjects now share their transform, the GameObject camera will be automatically moved along with its entity.
Now if, let's say, a pure entity character controller needs a reference to the camera and move towards where the camera points, it can store it as a public Entity CameraEntity field and get the camera's transform via lookup, and move in the camera transform's forward direction. All in a burst job
Let me be the first to admit that this isn't as ideal for code simplicity as having the entire engine built on DOTS and having all engine features be job-compatible, but I think it does make hybrid workflows much more viable and easy
Thank you so much for such a detailed response.
I watched the roadmap video you linked with excitement the other day. It’s sounds like an awesome direction, but the talk didn’t go into enough detail to understand some of what you described. Ty!
It also sounded like those changes were likely planned to be ~5 years off.
…I have so many follow questions about this…and the info I’m after is very important to me, to plan my future.
I don’t want to take up too much of your time, so I am resisting the urge to write them here. But - can you point me at a resource or contact from which I can get official answers and advice about these things from the company? I am happy to pay for reliable information and guidance.
The thread linked above would be a good place for more questions. Unity devs working on this "ECS for All" initiative are likely to answer you there
can you point me at a resource or contact from which I can get official answers and advice
You could look here: https://unity.com/products/success-plans
But I'd recommend starting with the thread first. I don't know how clearly we can answer questions about all this entities/GameObjects integration future plans at this moment, to be honest