#archived-dots
1 messages · Page 270 of 1
What if you did .Run() instead of .ScheduleParallel() on your jobs that only do cheap iterations on a few entities at most?
make sure to put them into according update order, to avoid unwanted sync point
What do you mean?
if you do .Run() in the middle of your group where everyhting else is scheduled
it'll force all previous jobs to be complete
which is sync point
Oh
and that means a lot of perfomance can be lost, since not enough workload will be scheduled for other threads to steal
But didn't you mean earlier that the overhead of scheduling jobs on worker threads is not worth it if the jobs take too little time to execute?
Oh you meant in a system group
in other words: I made a small game in a style of flappy bird in Dots. Perfomance was poor, compared to GO version of it. So I remade it in classic UNity and got x2 perfomance.
meanwhile I am doing rn a tycoon kind of game and simulated thousands of entities took me only 2ms of total time on all game logic
thats not entirely true. you force all depending jobs to complete. not evey job. So in some cases it wouldnt be a problem at all. the real problematic snyc points are the ones with structural changes. these force all jobs to complete.
And if you only .Run() then there is nothing to complete
In this case you will have mainthread only ECS game which should be better for small games
what about a game where you want 10000 instances?
that's dots is for sir
what are the limitations of Dots...can they be used with game objects in the same scene?
Yes
but its hybrid now...or not?
What do you mean?
Mixing GameObjects and entities is what Unity Technologies refers to as a "hybrid environment of GameObjects and entities," yes
great
You can but GO can't be multithreaded so it's tricky to get any gains in simple ways
so gameobjects can run on the mIn thread? and entities on the other threads?
There are things that do not have a DOTS equivalent planned, such as the Camera GameObject component and all the GUI stuff, because it is believed that they would not perform much better, so any game using entities will be a GameObject/entities hybrid really
Unity executes GameObject/MonoBehaviour OnUpdate methods only on the main thread. The same goes for DOTS systems, but they're more likely to schedule jobs on worker threads to parallelize the actual updating of entities.
couldn't you make UI very limited. and the main thread...with gameobjects, and then 1000's of entities in ECS
What do you mean by "couldn't you make UI very limited"?
I doubt that the UI is the bottleneck in any game
You don't have to make the UI "very limited"
You can and probably must have GameObjects which will be updated on the main thread
But you can also have thousands more entities which will be updated faster by jobs scheduled to run in parallel on several worker threads
great.
so then i heard it is composition over onheritance
do i need to learn some basic composition book?
There's not much to learn about composition
I think you should read the Entities package's manual: https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/ecs_core.html
Yeah I am making my through it.
There are also several conference presentations about DOTS on Unity's YouTube channel
I'm sure the concepts definitely are, but some parts of code examples may no longer be relevant because of significant updates to the APIs
but i was a bad coder then so it didnt make sense.
but idea behind them is the same
Yeah that's what I meant by concepts
yeah, figured that out after sending message 😛 sorry
any idea at what value does sin/cos do a full cycle?
math.sincos(curTick, out float sin, out float cos);
Basically, what would be modulo value for ticks?
hm
it says it's in radians
I assume that value would be 2
2PI?
anyone tested burst 1.8?
Okay, rendering... rendering is important. Trying to update the RenderMesh component to assign a mesh. How do this? What can I pass in as a mesh and how'n the heckfire do I get it in there?
Rendering seems less obtuse then before in dots .5, but not NOT-obtuse 😄
Assign a mesh to the RenderMesh component. Y'know, so I can see shit 😄
right now though I am reinstalling because I realized I had the wrong version of Unity for the 100,00th time
So, what is troubling you about it?
I'm sure I'll get it
If you want the easiest way and also the recommended one: Create a subscene in your scene and put the GOs in the subscene. They are automatically converted to an entity with the correct RenderMesh and material. You need to install the HybridRenderer package too, otherwise those entities are not rendered in runtime
Then take a look at the DOTS hierarchy what the conversion process actually created. What was created/converted can be created manually too.
It ended up being a bug in netcode 😦
I assume they've fixed it or at least added an error message in 0.50, because it's very obscure what is happening and causing infinite memory allocation
you are not on the latest?
No, I'm on 2021.3
oh boy ^^ well, hopefully 0.51 is just around the corner
and I want to have custom attribute UpdateOnStart which will do one update cycle on all those systems, irrelevant of rate state
basicailly, if game starts paused (not Unity pause, but internal pause in system group), I want to run all those systems anyway
Is there a way I can do that?
ouch
how would you determine that Start is happening? at that point you could just call Update on the Component group, like Simulation
well, I simply want to run code in actual Update
with some boolean set to false, once first update is over
Problem is that updating systems is not that simple xD
it is, just get the component system group and call update
but all systems exist in it
meanwhile I only need to do update once
on certain systems
doing it on other systems might cause unwanted behaviour
you can also get the systems individually from a MB and Update.
yeah sure, if any jobs are scheduled though it could trip up the dependency system if you call it in between so make sure you call .Complete if that happens
hehe, I only learned this when doing a simulation fast-forward once. it's all really straight forward
if (sys.GetType().GetCustomAttributes(typeof(UpdateOnStart), true).Length > 0)
{
}
Is that enough to check system class for UpdateOnStart attribute?
i'm not sure, looks good to me
so was it 2 or 2pi?
tbh, doesn't matter
I didn't use modulo
I just turned value into double
xD
and with it's precision, I'll never run out of it unless player will play for literally years
but can I do this: public BlobArray<Action> Actions;
and
public struct Action
{
public BlobArray<int> AxisID;
}
```?
Sure
when do Conversion systems run relative to Authoring classes?
but I need to remember to blob.Allocate() everything yes?
Yes, you need to allocate an array for every index
❤️ thanks
blobs are really great when you get around their usage
they are also sequentially layed out in memory. I painfully confirmed this with debugging pointers 😄
not totally linear though but pointers are just behind the blobRoot
Omg
lack of rendering tools in ECS
feels so bad
I need line renderer and trail renderers so bad
but hybrid approach is such a pain
welp, so far I only have guesses on how to do it
but tbh
that sounds like the only real solution
hybrid approach in this regard is more of a patchwork
any tip tho how it works?
It just creates tons of meshes?
it's more about editing
nice tutorial with use of this API: https://catlikecoding.com/unity/tutorials/procedural-meshes/
particle rendering is quite good. the need for a dots solution is not that important. line renderer on the other hand, yeah, either an asset store package or throwing one together
but how does throwing one together work?
let's say for trail renderer
do I just create thousands of meshes or?
i would make trails with a particle system
some procedural giant mesh?
dots has particle system?
nah, go one. gpu anyway
Okay so. How do I get around not being able to make a nativearray of native containers
do i make an array... of pointers?...
well if there are lists they could be stale
Also: How can I search through a nativearray in a job to find for example a float3 with an x value of 25
normally I'd use an Array.Find or a LINQ but those aren't burstable
Why do they have to be 2 dimensional? Can you flatten them? If they are for entities, a DynamicBuffer is the more sane option. Otherwise, UnsafeContainers are the answer
I'm trying to have an array of a KD tree I got online, that has an internal NativeArray so I can't store it in the array
and pass it to a job
boy I wish I had Rust's boxes right now
Sadly there's no UnsafeArray but you can make one yourself as it's just a struct with a pointer and a length
I like the dynamicbuffer idea but i don't know how largeeach KD tree is
yeah you could model the KD tree as entity. But honestly, I'd go with the Unsafe option. If you don't want to write one yourself you can use an UnsafeList
Ogh but I don’t want an unsafe class… the trees are stored persistently in a mono behavior
what namespace is that
Unity.Collections.LowLevel.Unsafe
a NativeList itself has only internal UnsafeList<T>* m_ListData; You're just missing the safety stuff around it. Leak detection, etc...
this is how NativeList creates it: m_ListData = UnsafeList<T>.Create(initialCapacity, ref allocator);
now, is there a way I can search a nativearray using a predicate like Array.Find()? a lambda expression like n => n.x = 4
not really, linear search is quite of slow. AFAIK linq Contains or smth is pretty dumb and just goes through the array until it finds it
if I loop through everything that's O(n) and that's no good
oh does it
well, I have no choice then
sure, hashMap 🙂
What about BinarySearch?
hashmap isn't really compatible with my setup unfortunately, not in this case
array must be sorted. is it?
I have a nativearray of type Node, and Node has a Position value. I just want to find a node with a position
uuhhhh no? sorted by what?
oh. by my comparison.
yeah no that won't work
dang, I guess I do have to loop through it. Painful.
what about a hashmap<Position, int> where the int is the index to the array?
really, anything is better than just looping. I did this a few days ago and my program needed 8 seconds for a frame
down to just a few ms with a hashmap
I think I looked up some value in a dynamicbuffer (lots of entities 250k)
That might be a good idea. I should construct that outside of the job, right? my node graph will not be changed after it has been created, so
i guess, a point cloud
should work, just keep inaccuracies in mind when they are float positions. if you reuse the same values, no problem
yeah no the KD tree and the node graph are using the same set
goodnight. thanks!
i could make... a linked list...
...nevermind.
Okay. New idea. In the job I already know which of these trees I need, but not in the entities foreach.
So if I had an array of this managed type, how could I pass it into the entities foreach?
why don't you just look at unity physics implementation of their bvh and how they handle it
sure they're different containers but they do similar things and would have the same issues you're having
Where is it on GitHub?
it's not on github
just look at the package source
well actually thats not true
it is on github
via needle mirror
BoundingVolumeHierarchy.cs
BoundingVolumeHierarchyBuilder.cs
probably the 2 primary parts
alternatively just use their bvh unless you really need a kdtree for some reason
these are stucts, not classes
I'm very close with this whole kd tree thing, I just have to figure out how to pass them into the entities system
and i dont know how to do that.
because I can't use a this[] on a managed array or list inside of a foreach
wait... can I have a managed array be readonly? will that work?
well of course they are
because its designed to work in burst/jobs
yeah
wait, my thing is also a struct. Right. The problem is I cannot hold them in an array because they have nativecontainers inside of them
so I'm trying to find a workaround
and I can't figure it out
and a BVS won't work because I need a structure that can hold a point cloud and get the closest one to a certain point
can a bvs hold a point cloud
🤷♂️ no idea
i was mostly suggesting just looking at how they tackled the problem then applying the techniques to your own work
a quick google has a few papers that seem to do this in a bvh - for example https://ieeexplore.ieee.org/document/6376712
I'm getting a little frustrated. It can't be that hard to have some kind of buffer or array or list or Something that can hold something with a NativeArray inside
In Rust, all I'd need to do is Box it, but C# works totally differently so I can't do that
How do I get a pointer to a managed type?
before you research
you still can't have pointer to managed type in unmanaged components
btw, you can hold Unsafe containers inside containers
It says I can't?
but afaik you need to define beforehand total capacity
Hmm how do I do that
lemme find example
var chunks = new NativeList<Chunk>(count, Allocator.TempJob);
private struct Chunk
{
public int Mesh;
public UnsafeList<Vector4> Colors;
public UnsafeList<Matrix4x4> Transforms;
}
ngl, I never gave a thought about what they actually are
and now I'm interested
judging by internal fields
it's just a pointer to other container
native container*
I need the opposite though, a native container inside an unsafe one
do I just... wrap it in a struct?
@rotund token in this case NativeList's chunk count should be amount of chunks? Not smth else?
Since in your selection tool code, you used total entity count from query.
I don't think you can have native container inside other container
Nuts.
I mean
you want to put resizable unmanaged chunk of memory into fixed sized chunk of memory
dont have code in front of me but ah yes it should calculatechunkcount not calculateentitycount if thats not setup right
I might be wrong here
Well. since I have the package right here and a nativecontainer is a wrapper for unsafe container (i think) I could just go in and swap them out
well, why can't you just opposite
unsafe inside native?
that would make sense and it's possible
and it's the same thing: container inside container
thats what im saying.
I'm using a package that is a burst-compatible k-d tree. The point cloud is stored internally inside a nativearray.
I want a nativearray of these k-d trees, but I since the k-d tree uses a nativearray internally, I cannot do that.
So what if I went into the k-d tree package and swapped out the native stuff for unsafe alternatives
I think you could retrieve NativeArray from unsafe
when you'd need it
it has pointer to internal buffer
which I assume
can be interpreted as NativeContainer
I don't totally know what that means!
well, I'm not sure what you actually want to do with containers either
I have a couple K-d trees each corresponding to different sections of a node graph (it's complicated but yes they need to be separate). I want to pass these trees into an entities system. I do not know which trees I need until I am actually doing the job, though. If I am able to pass an array, list, some kind of container in, I will be able to select which I need easily. but I cannot pass in an array because I am not allowed to store this type inside of a nativearray
I tried to make a sort of linked list, but the k-d tree struct appears to be managed, even if the point cloud it contains is not.
I get it why, you want to do this
but what is actual interface of communication with whatever system you are working?
if it's a method: what argument does it take for those arrays
kind of like this, because I don't really get why any of that even a problem
It is a pathfinding job that selects one of these trees to find the closest point in a node graph
well, I suppose I could select which trees I need in the foreach. but I still need to figure out how to pass the array in and I can't do that
what argument list of that method
which method. the job? closest point?
I guess, I don't know what is it yet xD
the job takes these parameters in:
public GoalPosition start; //input; where we start
public GoalPosition end; //input; our goal
public NativeArray<Node> nodeGraphSource; //input; the node graph
public NativeArray<Connection> connectionsSource; //input; connection map
public NativeList<int> outList; //output; paths
public UnsafeHashMap<int, KnnContainer> trees; //K-D trees, one day
public NativeHashMap<PointCloudPoint, int> pointCloud;
and the function to get the closest point looks like this
```cs
static int getClosestNode(NativeHashMap<PointCloudPoint, int> cloud, GoalPosition goal, UnsafeHashMap<int, KnnContainer> trees)
{
and you want to find clsest node out of several arrays?
each tree corresponds to a "world" the NPC is in. the array contains the correct tree for a given world (each index corresponds to a world).
What this function does is selects the tree for the world that the NPC is in, and finds the closest point to goal
(and then it maps it to the master node graph using the point cloud but that's not relevant)
I was trying to use a hashmap yes
but then it told me this
so I can't use that
and I am trying to figure out an alternative
and what exactly did you do there?
error is on this line here:
public static UnsafeHashMap<int, KnnContainer> kdTrees;
//...
kdTrees = new UnsafeHashMap<int, KnnContainer>(worldLUT.Count(), Allocator.Persistent);
this is in the script that builds and manages the trees and the node graph
how would that help me
It’s a package off GitHub https://github.com/ArthurBrussee/KNN
some complex container, I see
well, I think you either grab all data from inside and put into your own containers to do it in single job
or maybe each job for each knn container
since this container uses Native containers, you won't be able to put it inside other
I was trying to make my own k-d tree implementation but it wasn’t working very well
And this sucks because this tree here does exactly what I want it to except for the nativecontainer restriction
Well. I can access arrays inside of foreach but I can’t run it in parallel which was my entire goal
you won't be able to have array of such structure
you need to make it fixed size (filled with Unsafe containers instead of natives)
What if I made a 4D tree. 3 dimensions of space and one of “world”. Then I just have a single tree
And I don’t have to monkey around with arrays
Is there any way to check an OverlapSphere ignoring bounds? I just want to check if the position of an entitiy is inside the sphere. Should be cheaper than checking its AABB if it isnt necessary.
You can do a point distance query
You mean the one in DistanceQueries?
Yeah it's already built in in dots physics
But I need to direktliy input 2 points into that method
I dont know the points. I still want to query for all objects on a physics layer
Wait a minute actually the point is on the collider if I remember well so still not what you want
Atm I am using OverlapSphereCustom. But that does check intersection with boundingboxes afaik
You want to input 2 points you don't know, something wrong in that statement
No. Basically I want a Sphere Point intersection with all physics objects on the layer
Ok so what's wrong with first an overlap query to filter first results, then a simple distance check on matches
It is still pretty slow for many entities
and I have to filter the results because I get duplicates
if it would just check 1 position per entity it should be faster and remove the duplicates
Sorry got no other simple idea than an overlap or any spatial query first to filter, then the real check on limited results
Ok thx. Thought there should be a simpler way cause its a simpler query
I mean the way i see it is "just" a few more lines of code in a custom hit collector but maybe I'm forgetting smthg obvious
Yeah sure it is. But the reason I want to check the position instead of the bounding boxes is mainly because it should be more performant. If I am doing both that wouldnt help 😅
yes exactly. That should also avoid the need to filter bacause it should only return one result per entity
Yeah sure a distance check is straightforward but still you don't want to query against everything so need some way to filter
And physics already computes bounding colliders anyway so...
yeah I def need the broadphase
my first implementation was just a naive entity query for all targets + sqrdistance check
which was slower than the OverlapSphere
so best thing would still be to use only position both in broad phase and distance chek
but I guess it might not be so easy to change how the broad phase works
This I can't talk about. I did not dig into the broadphase yet so still a blackbox for me. I trust Unity to improve it where need be while I focus on problems I am responsible about :P
I just dug into the collision code and I cannot even find the point where it is iterating over multiple entities.
I only see OverlapSphereCustom -> CalculateDistance -> DistanceQueries.PointCollider -> DistanceQueries.PointCollider -> PointPoint
PointPoint checks the distance between two points. I dont even get where the whole iteration part is hidden 😬
the broadphase should be handled prior to any query (the query is done agains a built world representation of the colliders) so I'd look more towards one of the physics systems
didn't launch Unity for months actually so don't remember how they're called
probably smthg like "buildphysicsworldsystem" or close
and btw if any engine uses bounding volume to optimize I'm sure it brings greater value than without, otherwise there would be no point complicating things. Thus I would not try to overcome bounding volumes in the first place
you've seen teh value yourself with your overlap vs distance-check-everything first implementation
yeah I just found out there is a point collider 🤔
this might actually do what I want. there is just no way to author it so I will have to attach it by script
the point distance collider ?
oooh didnt know this one 😮
you cannot select it from the physics shapes
but its what is internally used for the distance checks
I wonder if creating hundreds of unique RenderMesh is a good idea
xD
or maybe I should create my own Component for this case
would definitely save on chunk memory
How do you guys handle ECB commands that reference potentially destroyed entities? We ran into that problem several times now. It just happens that a system or a command buffer may destroy an entity before an ecb referencing it is run
Is there any kind of safeguard to make the ecbs check if the entity still exists instead of just crashing?
we use a separate system for destroying that runs after the system used for everything else
i.e.
EndSimulationCommandBufferSystem <- Set, Add, Create, Remove components
DestroyCommandBufferSystem <- Destroy
that's what we do at work anyway
personally for my own projects I just try to really carefully wrote my code in a way that doesn't have this issue
by having clearly defined ownership of lifecycles
yeah I was actually doing the same with the destroy system in fixed update. which worked for the most part. But we just found that we use a MainThread system with run for unloading the levels 😑
I guess this method also has another problem.
It is a public method UnloadLevel on a LevelSystem which uses an entity query. Can anybody tell me if Unity will handle the dependencies properly in this case?
they wont
dependencies are only handled when system calls Update
the query itself will be fine though
What do you mean by fine?
In this case it works like this:
WinSystem calls LevelSystem.UnloadLevel()
UnloadLevel has a query to find specific entities and destroy the via a command buffer
the query should be able to get correct dependencies
yeah that's /probably/ fine
though i consider it pretty bad design
yes I know 😬
how would you handle it? spawn an entity with a component which triggers the level unload?
that seems fine (and what unity would probably do)
or simply just do it in the WinSystem and turn LevelSystem into a standalone struct/helper
But a helper struct cannot (easily) run an entity query can it?
you can pass in the owner system and do what you want
personally it's a pattern i quite like for re-usable code
but yeah it's not something that necessarily makes sense for this use case
it's hard for me to say without seeing what it's doing
public void UnloadAll()
{
EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.Temp);
Entities
.WithoutBurst()
.ForEach((Entity entity, in Level level) => { ecb.DestroyEntity(entity); }).Run();
ecb.Playback(EntityManager);
ecb.Dispose();
}
Thats what its currently doing
Trying to change it to use the external destroy ecb though
Which is problematic as you have to pass a dependency to the ecbSystem
The run was causing my initial problem. Destroying entities during run causes every ecb that still references it to fail
why not do Run after ECB?
How should I assure there is no other system that queued ecb commands this frame?
hm
the only thing I worry about is begin sim ecb
everything else seems to be fine, if you run it after end sim ecb
I usually use BeginSimulationECB for the usual stuff and BeginFixedStepECB for destroying
This way they do not collide and physics queries always return valid entities
But using Run breaks it because there might be Systems that ran before this System that added stuff to any of the ECBs
I could ensure that the System can only run directly after the ECB but that does not seem like a good solution to me
you can run rigth after them
cause otherwise
you are causing sync point
somewhere you probably don't want it
which probably just sends to waste all scheduling
yeah thats why there are ecbs in the first place
ao it woul make most sense to just use them to destroy the entities
then for what this monstrocity?
yeah thats what the code looks like atm. I am trying to change it to use the correct ecb. Problem is it is called from several systems and even GameObjects. So dependency management is a problem
Game objects should never access ecs
Only vice versa
Unity recommends to never access world
From game objects
ArgumentException: All entities passed to EntityManager must exist. One of the entities has already been destroyed or was never created. Entity (748:11) was previously destroyed by Unity.Entities.BeginFixedStepSimulationEntityCommandBufferSystem. This command was requested from EnemyEntityDeleteSystem.
Unity.Entities.EntityComponentStore.AssertEntitiesExist (Unity.Entities.Entity* entities, System.Int32 count) (at Library/PackageCache/com.unity.entities@0.50.1-preview.2/Unity.Entities/EntityComponentStoreDebug.cs:273)
Unity.Entities.EntityManager.AddComponent (Unity.Collections.NativeArray`1[T] entities, Unity.Entities.ComponentType componentType) (at Library/PackageCache/com.unity.entities@0.50.1-preview.2/Unity.Entities/EntityManager.cs:888)
Unity.Transforms.ParentSystem.UpdateChangeParents (Unity.Entities.SystemState& state) (at Library/PackageCache/com.unity.entities@0.50.1-preview.2/Unity.Transforms/ParentSystem.cs:317)
Unity.Transforms.ParentSystem.OnUpdate (Unity.Entities.SystemState& state) (at Library/PackageCache/com.unity.entities@0.50.1-preview.2/Unity.Transforms/ParentSystem.cs:418)
Unity.Transforms.ParentSystem.__codegen__OnUpdate (System.IntPtr self, System.IntPtr state) (at <03123a18c5ac42fb99a9907c3248ab1d>:0)
Unity.Entities.SystemBaseRegistry+<>c__DisplayClass10_0.<SelectBurstFn>b__0 (System.IntPtr system, System.IntPtr state) (at Library/PackageCache/com.unity.entities@0.50.1-preview.2/Unity.Entities/SystemBaseRegistry.cs:246)
Now that even happens in Perenting System 😕
That is really out of my control
You should centralize entity destruction maybe?
I did. I centralized it in BeginFixedStepSimulationEntityCommandBufferSystem
Considering you have way too many things that do this
Do you have special destruction component?
But the parenting system seems to interfere with it now
Yeah a DeadTag for the eneimies
So why entity is destroyed when it reaches your system ?
You destroyed it somewhere else
Meaning destruction is not centralized
protected override void OnUpdate()
{
var ecb = this.ecbSystem.CreateCommandBuffer().AsParallelWriter();
Entities.WithAll<DeathMarker>().ForEach(
(int entityInQueryIndex, Entity e) => { ecb.DestroyEntity(entityInQueryIndex, e); }).ScheduleParallel();
this.ecbSystem.AddJobHandleForProducer(Dependency);
}
that is the destruction code
it gets destroyed in BeginFixedStepSimulationEntityCommandBufferSystem
and parent system fails to access the entity
but I dont have any control of parent system. its unitys system
Hm
Can you look through project
And search for destroy entity?
Just to be certain it's really the only thing that destroys entities
Wait a second
Where does this system update
@pulsar jay
In fixed or normal update?
Fixed update
because otherwise physics queries will return objects that have already be destroyed
So
I suggest you to either create new buffer
Right after your current
Or manually do removal
Cause it seems
Like different actions in buffer get mixed
And when destruction happens first
And adding some comp next
It results in exception
It does not even seem to happen in the same buffer
The parentSystem just does Unity.Entities.EntityManager.AddComponent
welp
in this case I can only say, that you have spaghetti
kek
yay, I'm getting a great idea about procedural meshes
hm?
so, to make a system that multithreaded-ly calculates paths for entities, I would:
-in the foreach, collect a list of every entity that needs a new path
-afterwards, run the pathfinding job in parallel, with sets of data corresponding to every entity's start and end points
-Take the data and then apply it to everyone in the list
...right?
@white island hmm not sure if i understand what you mean with collect all entities that need a new path.
I would probably just
Entities.Foreach((in NavmeshAgent agent) =>
{
if(!agent.hasPath)
{
CalculatePath();
}
}).ScheduleParallel();```
so on mainthread you are not gathering anything at all. you just schedule the pathfinding and skip work if you have a path. You could combine this with ChangeFilters that get active whenever an agent reaches its goal to get rid of the if(!hasPath) check.
ChangeFilters seem especially useful when your chunk utilization is low (which mine is for all of my AI stuff...)
4k lines in that file
Could be worse
Hey, quick q: in 0.50, how do I Raycast only for a specific PhysicsWorldIndex?
sigh, why does dots physics work from the sample project, but not the one i set up from scratch ☹️ alt-tabbing between the two projects shows no difference
guess ill sleep on it
You do your raycast in the context of a collisionworld, so it's already restrained to a single and specific world. Now if you're asking how to retrieve the physics world associated with a specific index, I can't help yet because didn't migrate to 0.50 yet
Maybe that's something you're supposed to track yourself ? 🤔
ok, so I can fake component arrays with dynamicbuffers, but how do I fake having lists with components?
but doesn't my job have to be declared as an IJobParallel to do that?
hey question, the compiler complains that I'm using a this here, but I don't see anything wrong? Unless I'm not supposed to get data from outside sources like this, which I thought I had to. What's up?
https://pastebin.com/brg0pdy3
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
it helpfully doesn't tell me where in the foreach it is
oh I got it, it was EntityManager
no. Entities.Foreach gets codegenerated to IJobEntityBatch which can run parallel as well.
IJobParallelFor is old API anyways. new API is IJobFor.ScheduleParallel().
what about IJobBurstSchedulable
never seen that.
my point was about not getting the list of entities which need a path by looping over them on the mainthread. filter them inside the jobs
dynamicbuffers are lists on entites. why fake anything?
yeah I got it eventually
Could somebody explain how to vectorise this loop via Burst? Burst says the "loop control flow is not understood by vectorizer"; https://pastebin.com/N2cL0j3g
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
As far as I know, Burst doesn't like if or any other sort of logic splitting
vectorization doesn't work with a conditional return
hm
I wonder if it's possible to write bool as int
and do loop where you simply constantly add to value a result of comparison
casted to int
Yeah, I suspected as much 😦
Could you try it? xD
Yeah, interesting theory. Just compiling ATM but will give it a go in a few minutes
what maybe could work is if the ValidBiomes is bool4. but tbh, it's a bad application of simd
I'll take a bad application of SIMD over a good application of scalar 😛
and as you are struct comparing it would only work with an int4 hash or smth
int kek = 0;
for (var i = 0; i < ValidBiomes.Length; i++)
{
kek += (int) (ValidBiomes[i] == biome);
}
return (bool)kek;
Could that work? xD
don't think so because you write to the same value
kek needs to be an array to work with simd
It seems to have accepted this; (I can't paste as code as server keeps deleting messages for some reason);
int4 payload = new int4(0, 0, 0, 0);
for (var i = 0; i < ValidBiomes.Length; i++)
{
payload[i] = (ValidBiomes[i] == biome) ? 1 : 0;
}
return ((payload.x + payload.y + payload.z + payload.w) > 0);
Obviously that doesn't scale
doesn't work but it's simd code 🙂
I'm always amazed how dumb simd code still is and how little progress CPUs have made. Maybe that's why apples M1 is so good, I dunno but having some kind of condition just break simd code is just dumb architecture.
Yeah, I'm trying to update a poisson disk burst job I wrote that accepts a single biome as valid to accepting multiple valid biomes. But right now it's actually faster to just run a separate job for each valid biome.
I'm very green to SIMD (as I'm sure is obvious 😛 ) I might just give up on this one
Any idea whether LocalToWorld is being written every update or when there are changes to rot/translation/scale?
hmm, judging by source
it checks batch for changes
but does it already add to component version
simply by getting type handle
of LTW
or it only increases version after getting native array?
Getting handle is not a problem. as soon as you call chunk.GetnativeArray(handle) on a not readonly handle you bump the change version.
So, that means ChangeVersion filter will work with LTW?
havent tried it but seems like it should
ofc that is also depending on how you write to localtoworld and translation yourself
if you declare write access on translation every frame then you trigger changes that will declare write access in localtoworld
which then bumps the version...
So you would need to be super careful on how to write to translations/rotations etc
if you only use Entities.Foreach(ref Translation t) just once you can already not use changefilter on localtoworld
I made it a habit to call handles by their RW access. Translation_ReadHandle for example. Are all your handles read?
ah, yeah then the version gets bumped
so your long DidChange if is always true
As there's only 1 version per chunk checking more than one comp is redundant
DidChange is next to unusable imo. Should be chunk version + comp version
Any idea what's wrong with this Camera drag script?
It works perfectly fine in mono
private void OnCameraDragPress(InputAction.CallbackContext obj)
{
_dragging = true;
_origin = _inputController.CursorWorldSpace;
}
private void OnCameraDragRelease(InputAction.CallbackContext obj) { _dragging = false; }
protected override void OnUpdate()
{
if (_dragging)
{
var curPos = _inputController.CursorWorldSpace;
var origin = _origin;
Entities.WithAll<CurrentView>()
.ForEach((ref Translation translation, in LocalToWorld ltw) =>
{
var difference = curPos - ltw.Position;
translation.Value = origin - difference;
translation.Value.z = -10f;
})
.Schedule();
}
}
What happens is that when I try to drag and hold drag keybind
Camera starts to shake harder and harder with every second
hmmm, looks like this is why
world cursor position is constantly shaking, hmm
ah, looks I needed to do it in late sim system group
oh god
why tf is it eating 0.25 ms
ah, nvm. It was debug log
xD
hey I want to use ECS for a bunch of features in my game, but I'm not sure where to start. Should I start by making prefabs and then converting them to entities via the prefab workflow or are there other options as to choice of workflow for developing the mechanics that use ECS?
for what features do you want to use ECS?
if you haven't already, make sure you understand the fundamental concepts by reading the conceptual part of the manual: https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/ecs_core.html
I want to store a bunch of lots, blocks, and buildings in memory for a city builder such that I can efficiently have a ton of buildings in a scene. The plan is to have a bunch of vertices that are just positions in 3D space and then have each city block or lot contain a list of the vertices by their index to define their shape in 3D space. or maybe use 2D polygon colliders for intersection detection in their trigger mode?
Like I want to say to the engine "ok there is a specific entity archetype that has XYZ components called a plotVertex and I want you to create N amount of these here"
i guess this is OOP mindset
whats the difference between a runtime and an authoring component type
based on research, looks like I should use a dynamic buffer to store the data on which vertices are used for each city block or lot
I'm a little confused. Like, what are you trying to solve? It sounds to me like efficient rendering. But that is pretty much solved with the hybrid renderer
idk im kinda half thinking out loud here
that's okay, just tackle one thing at a time. split your way how you think about the buildings, there are several parts here and none have much in common. data/game mechanics, collision/targeting, rendering
Anyone got a NativeContainer working? I'm not sure what I'm missing other then the NativeContainer tag. It works fine from the main thread but when I use the container in a job the values are not written back.
Am I not allowed to use a NativeContainer inside a NativeContainer maybe? I have a NativeList instead of an UnsafeList
You can only have unsafe container inside native
you can not
Are entities created during conversion in dstMansger valid?
Hmm.
I have this problem I am trying to solve, but so far I can't figure out a fine solution:
I need to create a planet trail, that will follow planet while it moves around star.
I decided to generate mesh for this trail, which I did. But turns out I need to also rotate this mesh correctly. And this rotation doesn't go along with planet's rotation.
Ok, so make trail entity separate. But here I go again. If that entity is parented on planet: it's rotation will be local to parent and thus, will be incorrect if I rotate planet. If that entity is not parented on planet -I'd need to do the calculations for position twice.
what do you mean by valid?
they exist but they will have a different ID by time they're copied into game
it will continue to exist, in game world, right?
dstEntityManager
dstEntityManager exists in a conversion world
so if I do dst.CreateEntity(archetype); will that be transfered into game world?
hmmm
so dst world is getting copied after conversion is over, huh?
that meaning
if I create 100 temporary archetypes in conversion world
they will cease to exist in actual world?
bruh, is there any reason why subscene in edit mode is about 50% times faster than closed subscene?
literally, 150 fps in edit
100 in closed
check which systems are active in edit mode when closed
probably some transform system
Unity.Entities.SystemBase:Update() (at Library\PackageCache\com.unity.entities@0.50.1-preview.2\Unity.Entities\SystemBase.cs:400)``` Gee, thanks. That's so helpful ... 🤣
hmm
looks same to me
ooooh
looks like it's related to lighting
I removed all light sources
and boom
even more fps
hmm
Is there a way to run loop on entities only once, each time they appear?
Basically, I have my systems with planets in subscene
But it appears, that subscene is loading only after actual system does OnStartRunning
So, once subscene is loaded, it doesn't get treatment of getting loop once
basic question but how do I use this NativeQueue<int2>.ParallelWriter indicesToCheck = new NativeQueue<int2>.ParallelWriter();
I presumed it was like this but indicesToCheck[nativeThreadIndex] it doesn't seem to work 😕
Doesn't it have Add method?
or smth similiar?
Enqueue
maybe
afaik, it's not safe in parallel
that's weird
@pliant pike Where are you stuck? reading or writing?
either, both?
just need an example for how to use it, even if that doesn't work nativelist.parrallel will do
split your jobs
1 to fill your queue/list
through parallel writer
other to read info from it
thats what I did with a single thread queue but I need to do that with a parallel one now
in single thread you can read AND write
in parallel only either read or write, it seems
well that is just weird
well
having random access for reading doesn't seem too safe when you write to same memory in parallel
each thread should have its own separate queue though so should be fine surely
I mean I could set up separate queues manually if I really have to and put them into a schedule.paralell I guess
you can safely write in parallel to the NativeQueue.ParallelWriter
I don't really understand where the problem is?
reading is with while(queue.Count > 0) var item = queue.Dequeue();
probably you want a NativeStream though. NativeQueue is pretty crappy
that does'n work for me I just get nativqueue.parallel writer does not contain a definition for count
is nativestream pretty much the same then
the 2nd job just needs NativeQueue not the ParallelWriter one
it's pretty much the same, yeah, just writing/reading is faster and works better for parallel processing
so I'm guessing nativequeue.pararallel is just one long queue that works in multiple threads
a nativequeue, parallel - every thread gets a memory block it writes to
that's not what I thought it was I'm sure we used to have a way to setup multiple arrays for parralell jobs
hm? I don't understand. Anyway, the sucky thing about NativeQueue is that reading doesn't work in parallel, because there's no real, only reading, every read dequeues an item so a write is happening. I don't know, I don't like Queues 😄
one of the worst NativeContainers there is, they should just get rid of it imo
yeah that's what I'm thinking its probably not the best thing to use
I might just use a unsafelist with an nativelist in it if I can figure out how to get it to work
it hardly has any use at all. It's pretty much superseded by NativeStream
NativeList sucks to write in parallel
how so
the interlocked.add on the length causes thread stalling - you either allocate blocks or use a NativeStream
I guess I'll have a look at nativestream then thanks
do you know how much items you'll write? then a pre-allocated array or list is your best bet with direct index access
yeah, I'm thinking I will just create an nativearray<unsafestream<int2>> or something like that and then use that in a ijobparralellfor
huh? why wrap a nativeArray around the stream?
A NativeStream is built for that. No need to wrap it around another array
no worries I'll figure it out
I think this is the right place to ask but if not please let me know. I'd love some advice for this; I have a large amount of entities with some world position and I need an ideally very efficient way to do render a square quad (square in view space) for each of those entities such that the quad is facing the camera at all times and only scales with distance. Roughly similar to your average particle system really. (to be clear the entire thing is DOTS based so looking on pointers on how to efficiently get my little friends on the screen).
Quad rotation depends on what kind of rotation you are seeking.
For efficiency you could use gpu instancing
I actually did today a little system to draw quad as a line between two objects
Was kind of simple
With quaternion.lookrotation
Well I'm ideally seeking to avoid the rotation to begin with since my real need is essentially : world coordinate -> screen coordinate -> draw rect quad manually scaled by distance. To actually "physically" rotate each quad would require the engine to apply that rotation and then project the rotated quad to view space. That's significantly more work than is really needed for this case. I'd like some way to go :
- Get world pos W and project it to camera space C
- Determine distance from camera D
- Draw quad manually with the four vertices around C scaled by D
(for context, this is part of a simulation that ideally runs 100K-1M entities depending on hw)
Your quads have same rotation?
Btw with that large amount of entities to draw you'd better off use indirect instancing
Yes, same rotation, same material. They should all be facing the camera much like particles in your average particle system are billboard projected.
And yes Graphics.DrawMeshInstancedIndirect or something is on my "probably this" list 😉
so the need is entity position (in world space) -> entity position (in screen space) -> manually draw rect around that screen position scaled by camera distance.
Is it? Isn't that essentially what every particle system with billboard rendering does?
You need to ship to gpu a large amount of data
Which will be a bottleneck
Huge bottleneck
Well my hope was just world coordinates and a projection matrix of some sort along with a vertex shader that does the billboarding.
It's easy to get 1m float3's to the gpu
You only need float3 per entity in this case
Right
1 million is a lot though
Well let's say 100k. This is one of those "more is better" situations.
Even 60k vector3 is a lot
You can try, but cpu gpu bandwidth is not that great
My approach was to ship index array
While position buffer wad kept on gpu all the time
And to get vertex position I just access that array with instance index
Hm. And positions were updated with a compute shader?
That would be hard(er) for me given the logic needed to update the positions.
Well, same difference I think right. Some GPU shader.
Vertex shader if I remember correctly
But since your positions aren't grid based
That approach doesn't seem to work
No it's conceptually similar to the Unity Boids example project in terms of needs.
There's relatively complex logic to update the positions, velocities and there's hit and collision detection needs.
I suggest just to try and do dumbest way possible
And see how it goes
Every other complex optimization will only make it better
I was just hoping the actual rendering would be easy enough. Maybe I was wrong. I was hoping the new pipeline would allow you to do some custom mesh rendering that would bypass the transformation and projection pipeline of Unity.
Yeah I guess.
Mesh rendering is same as in built in
At least api
It is quite simple tho
Until you need instancing
And then until you need indirect
xD
Which in this case would be a huge optimisation 😉
Since I literally just need exactly the same mesh rendered with exactly the same material and uvs.
Oh well. I'll puzzle along.
Thanks for your input.
Dunno if I'm late to the party on this one but did you guys know V-Rising is made with DOTS?
If you haven't played it yet I very highly recommend it, especially if you loved Valheim.
really, that's cool, how do you know, and what did they use it for
I got a weird bug. I wrote code for next version of my game. I ran tests in editor and it works without any issues. I went to Build it (using DOTS platform build, done it loads of times before, no issues). And it gives me a NullRef error when it was trying to run a static method.
I resolved the issue by making it avoid that method and saved the files, Unity refreshed and shows the changes were made when I open the script in the inspector. HOWEVER, when building, it gives me the same error as before referencing lines that no longer exist!
I trashed the build folder entirely, I restarted the editor and it still gives me the same issue, it's using some cached version of my script (before my changes). How can I flush this cache or where does the BuildConfiguration asset keep cached files?
Has anyone else had this before?
never had this, maybe the good old deleting Library works. Which Burst version are you using? 1.7+ had weird caching problems
I am using Burst 1.6.4. Yeah I was hoping to avoid nuking Library lol, but I suppose I have no choice. Gonna try it now.
they wrote it on their blog
maybe don't nuke all, there are some Build* folders in Library. Start with those
it just sounds like your code is being stripped
are you calling it indirectly?
(unless I'm misreading this)
thanks tertle, I'll totally read that, I knew dots was useful
Yeah there were three, I backed them up, nuked them and still same error. I already nuked entire Library folder, building new one right now. Will let you know what happens once it's ready.
@rotund token finally got the ArrayHashMap container working. now I can create a hashMap out of 2 arrays without abusing the NMHM 🙂
pretty cool, I needed source/target as keys and had the same value array and now it can be shared without maintaining a second (redundant) values array
Nuking Library worked. I suspect something broke when I updated the editor to the next version.
great! was it a minor version upgrade from 2020.3 or a bigger one?
2020.3.33 -> 2020.3.34
oh damn, I'll keep that in mind when I upgrade myself. still on .33
anyone able to figure this out: thrown when scheduling a CalculateBucketsJob. The system NZSpellCasting.HandleCombatEventsSystem reads NZSpellCasting.AvatarStatsBlobReference via CalculateSpellSystem:CalculateSpellJobFromNativeList but that type was not assigned to the Dependency property.
for some reason the calculateHandle is not respected
this is the rest, I do set Dependency at the end
NativeList
yeah i think that's your problem
those AsArray
{
#if ENABLE_UNITY_COLLECTIONS_CHECKS
AtomicSafetyHandle.CheckGetSecondaryDataPointerAndThrow(m_Safety);```
if you cache the asarray before calculatespelljobfromnativelist
i think it'd be fine
or just pass them in as lists and cast in the job
though hmm
i thought that issue was fixed in collections that 0.50 uses
Ok, solved it. I just rewrote the NativeArray to a NativeList in the job. I still don't get it.
well, at least I don't understand why the dependency safety has a problem with it. what I do understand is that the length in NativeArray would be copied by value so the previous calculate job would not increase the length unlike with a NativeList where the length is handled differently (in unmanaged space)
well, took a quick break which reminded me of the CheckGetSecondaryDataPointerAndThrow you mentioned. Guess this is really it. Pretty confusing error message though. 😄 Should just say so, and not tell me something about some random comp that isn't even used in the job that is scheduled.
UnsafeArrayHashMap.cs(167,13): Burst error BC1020: Boxing a valuetype `Unity.Entities.Entity` to a managed object is not supported Wait, what? How does that work for every other NativeContainer?
what is your line
while (!(*(TKey*) (Keys + entryIdx * sizeof(TKey))).Equals(it.key))
odd, I have the same line in a hashmap extension that also uses Entity
(btw. you can congratulate me how unreadable that line is 😄 )
your extension probably has IEquatable
this is why all the Find, IndexOf, etc methods
are in extension methods not the actual collection
dayum, you are way too good at this.
yep, added IEquatable<TKey>. all fine now. thanks!
What does this error mean?
you're using a container in a parallel job without [ReadOnly]
yeah i just figured that out, testing my solution
wait, what. What container does it want
I really dislike the implementation of ContainsKey in NHM. It reads and outs the value which is unneeded
how can I tell which container is bad?
is it a nativelist
the errors mentioned tree.nodes
it tells you in the error - what enzi said
ah, ok. the errors are hard for my brain to parse...
ok, so it's a nativelist. I can't mark it as readonly though, because I write to it a bit, but before I start the job
you get used to them after reading them a 1000 times 😄
then you have to use NativeList.ParallelWriter instead of your NativeList
ah before you start the job. hm
then readonly is okay? the statement is confusing
you either write to it in the job or not 🙂
I don't need to write anything in the job
the struct is passed in as a paramenter
in the job, the paramenter is declared as
[ReadOnly]
public KDTree.KDTree tree;
and the nodes in tree?
nope. ok using the [ReadOnly] attribute fixed that. But now a hashmap in the system needs to be declared readonly, but i'm not 100% sure how to do that in this way
what's different? you can put the [ReadOnly] in the same way there
is the hashmap a parameter in the job or not?
in a forEach you can declare .WithReadOnly(yourHashmapVariable)
where? where I read it? intellisense doesn't give me anything like that
okay, cool. should I use an entity command buffer for parallel writing instead of just the entity manager?
yeah, it's a good habit
using entity manager creates structural changes on pretty much anything create/destroy/set/remove
private EndSimulationEntityCommandBufferSystem endBarrier;
in OnCreate: endBarrier = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
in OnUpdate: var commandBuffer = endBarrier.CreateCommandBuffer();
in job: commandBuffer = commandBuffer.AsParallelWriter()
after schedule: endBarrier.AddJobHandleForProducer(Dependency);
when you use it in a ForEach you could just write: var commandBuffer = endBarrier.CreateCommandBuffer().AsParallelWriter();
as the commandBuffer in parallel needs an index, either int nativeThreadIndex or int entityInQueryIndex works as input parameter in the ForEach parameter list
that was my next question
can an ECB get a buffer? It says EntityManager.getBuffer causes a write
you can AppendToBuffer with an ecb
yeah but i need to read the buffer's length
is the buffer on the entity?
yes
then use it as an input
like use DynamicBuffer<foo> bar in the argument list?
boy howdy. the hydra of errors here. Never heard of dependencies here, what does this error mean?
get used to it with scheduling 🙂 means data that you want to access is written to by another job and you have not set a dependency to it
have you just forgotten to set the Dependency? Dependency = Entities.ForEach().Schedule(Dependency);
if it still doesn't work you have to get the jobhandle from the MobOffScreenMovementSystem and use it as dependency handle for your job
well, I'm using a .ScheduleParallel() so that everything runs in parallel
that much was clear 🙂 do you really have to split the 2 jobs in 2 systems? would be easier if you schedule them from just one because then you have the handle immediately.
what do you mean by that
going back to that: means data that you want to access is written to by another job and you have not set a dependency to it
which also means, the 2nd job doesn't wait for the first one to complete
the job system doesn't figure that out automatically
apparently it should but it never does for me so I'm at a point where I think it's pretty dumb and doesn't figure anything out on its own 😄
here's how I do it when more than 1 system is involved
you don't have to Complete the handle, in your case just use the handle instead of ScheduleParallel(Dependency)
that doesn't make any sense. No jobs set the dependency it's complaining about
in fact it's listed as in in the foreach
look at the stacktrace and where it's thrown
is it a line where a schedule happens?
yes, thats the wscheduleparallel
yeah, then that's what it is 🙂 I've had my fair share of grief with the error messages. the important bits are where it's thrown so you know which job is missing the dependency and the mentioned job so you know which dependency you have to set
either way, in one job you are writing to InSceneComponent
huh? do you use playback?
do you have this line after the schedule? endBarrier.AddJobHandleForProducer(Dependency);
yeah, I define an entity command buffer like so:
EntityManager em = EntityManager;
EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.TempJob);
var ecbp = ecb.AsParallelWriter();
and then after the foreach where I use ecbp, I call
ecb.Playback(em);
well, that's no good. I posted the code :/
that breaks scheduling
a commandbuffer should run at the end of a frame when all is finished
with the code you used it's running in the middle of it and creates structural changes which breaks any schedule that happened so far
I thought the end barrier was a custom class
yeah, the playback runs after foreach
that's just the variable name. everyone has EndSimulationEntityCommandBufferSystem
after foreach != end of frame 🙂
you can copy/paste what I wrote above #archived-dots message
what is Dependency
a SystemBase variable. every SystemBase has it
Do I play this back now?
do I need to dispose the entity command buffer and parallelwriter?
what are you doing 🧐
var meshRenderer = GetComponent<MeshRenderer>();
var desc = new RenderMeshDescription(
GetComponent<MeshFilter>().sharedMesh,
meshRenderer.sharedMaterial,
meshRenderer.shadowCastingMode,
meshRenderer.receiveShadows,
meshRenderer.motionVectorGenerationMode,
gameObject.layer,
meshRenderer.subMeshStartIndex,
meshRenderer.renderingLayerMask
);
RenderMeshUtility.AddComponents(renderingEntity, dstManager, desc);
in authoring mono
ah why not just let it do its own thing?
I need renderer outside of main entity
and I don't want to have complex authoring
so far I managed to achieve this with trail system
but classic Render mesh seems to fail me
Hi... What libraries do I need to install to start working with dots...
just install Hybrid Renderer, it will install all necessities itself
Turns out, error is caused when I remove rendering components from original entity
{
dstManager.RemoveComponent<WorldRenderBounds>(entity);
dstManager.RemoveComponent<RenderBounds>(entity);
dstManager.RemoveComponent<RenderMesh>(entity);
dstManager.RemoveComponent<PerInstanceCullingTag>(entity);
dstManager.RemoveComponent<BlendProbeTag>(entity);
}
hm
@rustic rain thanjs5... Can I also ask one question... Do you know if I can use a character controller in the dots system?
feel like you've left a bunch components behind on that removal
what does the remaining archetype look like?
idk, it errors
so it doesn't even finish removing
turns out
it errors on removing RenderMesh
only
no need for anything else
OOOOH
it's Shared
me dum dum
hmm, no different method for shared components
no, you need to write/buy/find one yourself
classic unity components don't exist in ECS world
and hybrid approach is dogshit IMO
I see @rustic rain thank you
yeah was about to say, it should make no difference
well, it errors
even if I remove other componnets only
wtf
I'll restart Unity
lol, it errors even during non-play authoring
Seems like this problem is from 2020
oof
Yeah removing the RenderMesh component is not a good idea. You want to add the DisableRendering component instead.
Also RenderMesh component will go away in the near future as we move to use the new BRG interfaces where we can use different meshes and materials within a single chunk
I have a problem with DisableRendering since it's key component for my rendering systems
seems like I'll need to implement some other tag to fix it for a while
feels bad
hmm
or maybe I can simply remove entity
and create new
xD
Hm... Yeah sorry I'm not of much help here :/
What is it that you are trying to do?
Move rendering to child entity
while authoring through 1 game object
since I'll need a ton of prefabs, which will make it a nightmare if I'll have to keep it 1 to 1 in gameobject/entity ratio
moving rendering is important, cause I will need specific rotation for this rendering, while keeping hierarchy intact
can we work with normal game objects and entities at the same time? like have a character controller and lots of other game objects that have entities ?
Entities world and Game Object world work separately
communication between two is not recommended
yeah I've done that
there's also a unity gdc talk I think where they explain how they do it
its not as hard as you'd think
can you give me the link please
I can't find it I'm afraid
This is called a "hybrid" setup. You can access ECS data from a MonoBehaviour with World.All[0].EntityManager.GetComponentData, for example. And you can access GameObject data from a System normally, like mainCamera.transform. You can get a reference with mainCamera = GameObject.Find("Main Camera") for example
it's ok , thank you for helping
I see thank you
oh man, because of inability to remove RenderMesh
I literally can't finish my mechanic
xD
now I can't wait for 1.0 10x more
what's an example of needing to do this? Perhaps without revealing your mechanic if it's secret
I need to move rendering components to child entity, without making authoring be a pain
cause the other way I can do it: make child game object, put all rendering here
PAIN
every time I'll select object, it'll pick child and etc
Maybe you can write an editor script that selects the parent of a selected GameObject when it has a certain GameObject component (e.g. some empty MonoBehaviour serving as a tag for your editor script)
that still makes creation of prefabs painful
What is this second pain? Maybe there's a way to automate it away, too
welp, that's what I wanted: automate it
what i want: put components on GO, components do all the job themselves
but instead I have to create hierarchy of those children in gameobject myself
since I can't remove rendering components from main entity
which will be parent for all children
During conversion, maybe you can move the MeshRenderer to the child before the hybrid renderer converts it to a RenderMesh. (But maybe I'm not understanding the problem yet)
hm
Via a custom conversion system
I see
eh, still tweaking with game objects
instead of doing whatever I want in entites world
sadge
but that's a plan
at least
I think writing custom conversion systems will be a skill that will pay boons for years, because as far as I know the Unity DOTS team believes in conversion from GameObjects as authoring data to Entities as runtime data as a fundamentally good thing
"It is a fundamental part of DOTS, and not something temporary" https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/conversion.html
I already work in custom conversion systems kek
I just didn't think of option
to actually move GO components before entities are created
i cant share details here but i saw a major AA title (made with unity) rolling their own conversion pipeline to reduce loadtimes, memoryfootprint, complexity and guarantee good authoring workflows for designers. It seemed like their whole toolchain was built around this conversion too.
DOTS Conversion does all that and enables easy runtime performance gains through better memory layout too. I really like the decision to make Hybrid & Conversion the standard workflow (even though i personally go "pure" as much as possible).
Is it possible to get entity query in authoring component and run ForEach loop inside?
in dstWorld
during conversion
I am trying to implement world gen this way
not sure what you want. what stops you from using conversionsystems?
and you should not run queries on dstWorld but only on Conversionworld while converting
not sure rn what approach even to use.
Basically I have a choice between:
- Fully generated world
- Premade world, but with randomized positions and stats
in either case you can use conversionsystems to create the world i think
but there is one huge downside if you fully generate the world. You cant use EntityManager.Instantiate in Conversion... So its a PITA to spawn entites... Honestly i would probably generate the world with GameObjects first in early conversion and then convert all the generated objects to entites.
And you need to be aware that conversion runs everytime you close a subscene
if I generate GO world in early
so you want a deterministic way of generating the world
that means all of them will be converted as if I author them before pressing RUn?
i hope so. i cant guarantee it
from docs : [GameObjectDeclareReferencedObjectsGroup] - before the creation of entities in the destination world.
so as i would understand it if you instantiated gameonjects during this step it would be the same as if you hand authored it
btw, how do I get dependency from casual loop?
var pos = Entities.WithAll<StarSystem.StarSystem>()
.ForEach(() =>
{
})
.Schedule(new JobHandle());
will that work?
the dependency is resolved through passing jobhandles. im not sure about that new JobHandle there. you tell this Job to wait until a new Jobhandle is completed (which should be never).
what are you trying to achieve here
yes that is what "pos" is
Basically I have job X, Y and Z.
Y requires X and Z to complete, while X and Z can run independent.
and job above is X
while Z is var count = _starSystemQuery.ToEntityArrayAsync(Allocator.TempJob, out var dep);
which gives me jobHandle itself
so you need to pass dep into the .Schedule() of the other jobs so they wait for it
sry reading it again you only want Y to wait. so it should be in Y
well yeah, but how do I get job handle from job X
so I can pass it as dependency into job Y
var jobhandleX = jobX.Schedule()
if I leave parameters empty it returns void
rly? in that case you'd need to pass Systems Dependency
var jobhandleX = jobX.Schedule(Dependency)
but sounds weird. i thought if you leave the paramenter empty is automatically uses Systems Dependency