#archived-dots
1 messages Β· Page 222 of 1
structs must either have no constructor, or must have a parameterless constructor that populates all fields. so if you create an EntityQuery variable without assigning anything to it, it will construct it that way
with the value equivillant to default(EntityQuery)
EntityQuery blah; and EntityQuery blah = default(EntityQuery); statements are identical
default of a struct is a populated struct
oo interesting, seems like entityqueries use same trick as nativearrays where it just holds a ptr to allocated data somewhere else
don't see a way to check if they're actually initialized tho 
i think unity just assumes they're always gonna be initialized if you're using them
i mean you could make a nullable one. EntityQuery? blah; then you can do if (blah.HasValue) MyFunction(blah.Value)
it removes the error so I don't know I'll keep going and see if it messes up π
burst might hate that tho I dunno
you're null checking the EntityQuery object? that should give you a compile error
can you go to definition on EntityQuery?
f12 by default if you're using vs or vs code
does it say class? or struct? are you sure you're on the right entities version?
I'm having to sort out other errors though so it still might not fully compile yet
I have weird ordering issues
so I think this would be right @pliant pike
EntityQuery a = default;
if (a == default)
{
}
ok np I'll use that instead thanks
Does anyone know the formula to extract scale as float3 format from a float4x4 matrix? Say from LocalToWorld or LocalToParent?
I am having trouble understanding how to resolve this error. I moved it outside... π€
var localMySqrt = mySqrt;, then reference localMySqrt in your query
burst doesn't want to lookup the class instance from inside your job to get the current value.
I didnt follow that second part
MyUpdatePositionsToGridFormations is a class
you could update the value on that class instance from somewhere else
blue variables are good for burst, white variables are bad for burst, it seems
burst can't handle that
Is it that simple?
maaaaaybe? I'm not 100% on that
If it was that would be sweet for simple street joe me
Im having trouble following past the second thing you posted
Well the good news is, it compiles and runs, and runs fast with 200,000 entities
I got it! Your equation was backwards lol. Multiplying 4x4 matrix by float4x4.Scale(scale) returns the 4x4 matrix SCALED by the amount you multiplied, it does NOT extract the scale that exists in the matrix originally.
Here is the formula to extract the scale from a matrix:
new float3(math.length(matrix[0].xyz), math.length(matrix[1].xyz), math.length(matrix[2].xyz));
When I apply that to LTW, it will give me the world scale of the entity even if it's scale LTP is set to 1.
The set back is that it takes a couple of frames before the LTW scale is changed from the moment it is parented to another...
And to make the formula more performant:
public static float3 Scale(this float4x4 matrix) => math.sqrt(new float3(
math.lengthsq(matrix[0].xyz),
math.lengthsq(matrix[1].xyz),
math.lengthsq(matrix[2].xyz)));
var entityScale = entityLocalToWorld.Value.Scale();
π
Is there any built-in way to execute a Entities.ForEach at fixed intervals (say every 2 seconds)? Or do I just add a counter to a system and just do a condition check against that on each frame?
I don't know of any built in timeouts
Yeah I can't find anything either.
did anyone get a chance to build a navigation grid in ECS? or at least use OverlapBox in ECS context?
Hmm, not sure why it wasn't working for you. This gives me the same results as your formula:
public static float3 Scale(this float4x4 matrix) => math.mul(matrix, new float4(1, 1, 1, 0)).xyz;
Hmm...I'll try again, maybe I made a typo somewhere lol. If yours works, then it sure it much more efficient than my way.
Nope...scale is not even close!
I accomplished this by creating a CustomSystemGroup and then overriding the FixedRateManager field. There are some built-in options you can use such as FixedRateSimpleManager. Once set up, any system you put in this system group will update at the specified fixed rate.
I am applying this formula to an entity that is nested deep inside a tree, and the parents can have different scales. I want to extract the WORLD scale from that entity. Using the formula I posted, I was able to successfully extract an exact scale from LocalToWorld.Value
Genius! Thank you!
I guess I'm assuming that your matrix is all zeros except for the diagonals. Is that not true?
Yeah that was my first question I asked you when you posted the formula lol
Ah got it, sorry! Yeah I thought you were just asking hypothetically since float4x4.Scale() never populates the non-diagonals parts of the matrix. But I guess with a complex parenting setup that isn't true.
Yeah, no worries, you got the gears turning and a result was born nevertheless π
It works! Make sure component will have a CompositeScale and at the moment of parenting:
compositeScale.Value = float4x4.Scale(entityLocalToWorldMatrix.Value.Scale() / rootParentLocalToWorldMatrix.Value.Scale());
Bam! Entity will not change sizes π
Nice!
But this assumes that all the nodes between root parent and the entity are default scale. Once you tweak them, it scales wrong. I'm working on a method to traverse the tree and offset the scale for each parent until it gets to root.
Got it. Man that took forever. Thanks @whole gyro for all your help man. You gave me the push in the right direction.
Very dumb question: If I use unity dots for physics only, but still render the gameobjects on top of those entities (so I can use gameobject unity stuff), am I no longer getting an increase in performance? (Because I still have many instantiated gameobjects)
Legacy unity physics objects will NOT interact with ECS physics objects. A Rigidbody answers to a different Physics engine than does a PhysicsMass, PhysicsBody, and PhysicsVelocity. ECS physics was build completely from scratch and not on top of legacy physics.
So if you want the two worlds to interact, you will need to implement an ECS conversion workflow. DOTS does allow you to setup your scene using traditional components, it's when you hit that play button is when all the magic happens under the hood. But you need to tell ECS which legacy gameobjects you want to send to that world.
Does that make sense?
But you can have them BOTH working together side-by-side. Just not intertwined with each other.
Yes I know, I guess what im asking, is rendering those gameobjects less efficient than dots?
I have them both working
So I just have a game object follow the position of my entities
instead of it being purely entity based
Got it
will this slow everything down more?
You mean you took an entire legacy setup, and just created counterpart entities and have the gameobjects follow the entities?
Oh yeah, then consider them as ECS and not traditional game objects.
and then I have code that just caches the gaemobject, and has it follow the entity
ah ok
Wait, why do you need the game object to follow the entity?
ECS Physics has racasting and more, and it's much more performant.
It's not as simple as Physics.Raycast, but once you setup it up, it's much more optimal.
yes but much less documentation, basic things are hard to implement, and unity dots is difficult to get specific data from individual objects
Yes, I can't argue there. It took me a couple days to figure it out...and let me tell you it's worth it.
I mean I guess its a scale of performant vs how much you implement ecs
I ran simulations side by side with apples-to-apples comparison, and ECS physics outperformed by a long shot.
because im using a hybrid system right now to try for the best of both worlds
The objects fell and reacted way more smoother and accurate.
right but if I use this ecs physics
and tie my gameobjects to those entities
im still rendering tons of gameobjects, which I thought were heavy and inefficient
is that correct
sorry if this sounds odd
Yeah, I would concentrate creating ECS systems for the parts that control the tons of gameobjects and have them all converted to pure ECS. That will boost your performance drastically.
Just leave the singleton objects and such on teh legacy, concentrate porting over the parts that are the most resource intensive.
ahh that makes sense
If you do it right, you will be able to place tons x10 gameobjects and keep the same FPS π
I can't lie, it took me a good solid week to wrap my head around it. And I have to admit, I don't think I can ever go back to legacy...
for me this makes much more sense, I felt like I been waiting for something like this for a long time.
I know the feeling. I think I only scratched the surface.
Building a game with all dots would be pretty next level
but I dont think im up for the challenge lol
It's a LOT more coding, not a lot of mainstream boilerplate utilities like in legacy, but I think that by the time they get to the official release, that will be taken care of.
Just take your time, baby steps. If you're in a rush, then yeah don't do it.
I think it will always be more code and more complex. thats why most coding is object oriented, it just makes sense
π
Whew, it was hard enough figuring out how to compensate for scale when parenting entity into a tree of parents...I thought it would be the hardest thing to do. Now I'm trying to compensate for translation...and I'm just not getting it. I need the entity to remain where it is in world space after it has been parented to something. It's parented several levels deep in the parent tree, so it needs to calculate offsets for all parents up the tree. I assumed that the translation for each parent entity is local to their respective parent (and root to world), but I am not getting it to align. Was that an incorrect assumption?
what's the best way to set the LocalToWorld value? i know that i have to set Translation and Rotation as well, but im having trouble converting world space (which i know the value of) to local space (which i don't know)
Legacy unity allowed you to do all this on a high level. But now we are dealing with it one level lower, what unity (and pretty much all game engines) do under the hood, and that is to store pos, rot, and scale in a single matrix. With this, itβs not as simple as calculating offsets between two entities using ltw.Position - otherltw.Position like we did in legacy. This is because all three transform types are combined into a single 4x4 matrix.
If youβre not familiar with this, you gonna have to learn about transform matrixes to understand how this works. Once you do, youβll easily understand how to convert this data.
For example, if you want to know what the local position will be for an entity against another entity, then you would need to take the inverse ltw from entity a and multiply it by entity b world position (wp) like so: inverseLTW * new float4(wp.x, wp.y, wp.z, 1). And the result would be a float4 just grab result.xyz and that will be your local cords for entity b relative to entity a.
ok, that makes a bit of sense. since i've got the target world translation and rotation, i could do something like this for the translation, if im understanding correctly
float4x4 newLTW = float4x4.TRS(affine.Translation, affine.Rotation, 1);
localToWorld.Value = newLTW;
translation.Value = math.mul(math.inverse(newLTW), new float4(affine.Translation, 1)).xyz;
```with `affine` being the component i update in the IK code, containing a float3 (world translation) and quaternion (world rotation)
is there any good way to have array in component datas
a dynamicbuffer?
I haven't heard of nativeslice π
but as far as I'm aware dynamicbuffers are the only way to store arrays on componentdatas
The correct way to set the LocalToWorld is to never set it. That's why you have Position, Rotation, Scale, etc, components. If you parent an entity to another one then those components are in local (to the parent) space.
If you need world space on any child entity you read from the LocalToWorld component.
@gusty comet yea can be, dynamicbuffers can be used as NativeArray and unity is prob doing that internally somewhere if that error's not from your own code
oh yea they don't go inside components
they're a component themselves
yes, but you'd have to use something like UnsafeList(or Array? not sure), which I think has been implemented in collections package now but could be wrong
and you need to be sure to allocate/dispose manually
same as nativearrays, but dynamicbuffers take care of that part internally so thought I'd mention it
are you putting reference types in nativearrays? 
the main thing to worry about is that you have to make sure to dispose them yourself, because if you don't you'll have memoryleaks and unity won't warn you about it
I don't think they're thread safe
but like one of the main thing of ECS is that you don't have the same component being accessed by two threads at the same time, so if that happens maybe your dependencies are wrong somewhere
what is buffer in this case?
oh do you mean dynamicbuffers, sry I lost the context there
it's a component so if you want to store a reference you store the entity and then grab the buffer on that entity
yea
same goes for dynamicbuffers
There's something like FixedList which you can store into an IComponentData
FixedList.Add?
https://forum.unity.com/threads/notice-on-dots-compatibility-with-unity-2021-1.1091800/page-5#post-7247630 Martin is catching up again π
yay!
heresy, the true king is joachim
Joachim made this repo public today https://github.com/joeante/BurstIterationBenchmark
@north bay have you tried it?
No I just noticed it in my github feed today
so fucking cancer putting ads on your broadcast unity...
i keep tuning in every 10-20 minutes but it continues to be terrible
Are you using DOTS Physics? Rigidbody is the MonoBehaviour one that you can only iterate over with Run and WithoutBurst
Ohhhhh
I just now am getting into physics, that I have the staples outside physics there
I have the preview Unity.Physics, yes
Then you probably want to use PhysicsVelocity
I think there are some extension methods for MoveTowards target and stuff but I'm not sure
PhysicsVelocity.CalculateVelocityToTarget() should be it
This was the solution I ended on, and is all I really need right now XD
I have another system for feeding the input componants, so I can use them however
I put the physics script on the authoring object so it already has gravity in this instance
I think I did good
quick question: whats the equivalent to Vector3.magnitude when using float3?
math.length
ill rephrase my question. how do i set the world transform (translation, scale) of an entity with a parent?
I actually have this exact thing pinned cause I always forget π https://forum.unity.com/threads/setting-the-world-position-on-a-child-entity-using-the-transforms-system.1053320/
ah perfect, thank you!
Any idea why I'm getting System added twice when manually adding a system to a group during runtime? I'm removing it from its current group beforehand
You know about performance penalty when using, or should I say overusing, math.length right?
Anyone has or had experience with ECS and DOTween?
I jumped on the ECS wagon only a week ago, so I am not familiar with old deprecated code. I cloned a repo that I want to use in my project but it seems that it is using deprecated code. I managed to convert some on my own, but I'm stuck on this one. What are they trying to do here?
JobComponentSystem
EntityQuery m_TranslateGroup;
override JobHandle Onupdate
var translateTransforms = m_TranslateGroup.GetTransformAccessArray();
I can post the actual method, maybe someone can help me convert it?
no, what's that?
it uses math.sqrt under the hood
if you only need to compare against another length, you can use math.lengthsq for both to skip the sqrt calculation
thanks for that link! i was finally able to get my IK system working thanks to you π
i'm doing math.length(onefloat - otherfloat) to calculate distance betweeen them
is there a better approach?
if you need the real, actual distance, then that's the best way to go afaik (you can use math.distance(x, y) to make it a little clearer though)
gotcha, thanks
there might be a different approach for this, i'm doing it to find the closest grid cell from any world position
ah! i dealt with something like that a while back. to make the comparisons quicker, i converted the cell position and entity position to 2 uints and compared those. gimme a sec and i'll get some example code
this is the code i used to get the uint (and back out, but it'll give the position of the bin, not the original input). it's not perfect since it has to be constrained, but it works pretty well imo.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint PositionToBin(float3 position, int3 gridSize, float cellSize)
{
position = math.floor((position + (float3)gridSize * 0.5f) / cellSize);
return (uint)(position.x * gridSize.x * gridSize.x
+ position.y * gridSize.y
+ position.z);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float3 BinToPosition(uint bin, int3 gridSize, float cellSize)
{
float3 gridSizeHalf = (float3)gridSize * 0.5f;
int binInt = (int)bin;
float x = binInt / (gridSize.x * gridSize.x);
float y = (binInt / gridSize.y) % gridSize.y;
float z = binInt % gridSize.z;
return (new float3(x, y, z) - gridSizeHalf) * cellSize * cellSize;
}
so the usage would be
BinToPosition(PositionToBin(enttiyPos)) ?
ah no
1 sec ill get some more code π
your use case might be very different from mine. it really depends on how you want to structure your code. as i look over my code again, i realize that there's a few things i need to fix, but here's an example of how im using it as a vector field to control entity movement. there can be multiple entities in a "bin", but im using the bins to narrow down the comparisons instead of checking against every single tile. i'm a little tired so i'm not able to comment everything right now, but if there's something you need clarification on in my code, lmk
https://hastebin.com/unupuretub.csharp
i'm actually trying to do the same thing - force field navigation
your code should be a godsend thanks
btw am I the only one crashing unity like 20 times a day?
specifically when dealing with dots stuff
Is that because you disabled burst safeties? π
nope
is it possible to schedule jobs while inside ScheduleParallel?
You mean schedule a job while inside another job? No you can't
damn okay
If you need that pattern you can usually schedule job A and then Job B, just make sure that B depends on A. Then if you don't want to run job B you can early exit it with return;
I wanted to make a job that calculates distances between two positions, with IJobParallelFor
struct CalculateDistanceJob : IJobParallelFor
{
public NativeList<float3> positions;
public float3 origin;
public NativeList<float>.ParallelWriter distances;
public void Execute(int index)
{
distances.AddNoResize(math.distance(positions[index], origin));
}
}
making a Job A and then Job B pattern won't work here, because the array im iterating over is not recognized
I think I misunderstood your question then. This job seems valid to me, what is the issue exactly?
I need this job to work from inside another IJobParallelFor
Entities
.WithAll<FlowFieldAgentComponent>()
.WithReadOnly(gridLocs)
.WithReadOnly(gridBest)
.ForEach(
(ref FlowFieldAgentComponent agent, ref Translation translation) =>
{
var handle = new CalculateDistanceJob
{
}.schedule(gridCellPositions, 128).Complete()
}
)
.ScheduleParallel();
in essence
Ah I see, give me a minute. But yeah you can't do this
but I read now that jobs can only be scheduled and completed on the main thread
Where do you intend to get NativeList<float3> positions from?
Is that the position in the translation component?
that one is determined inside OnStartRunning()
Right, where do you need FlowFieldAgentComponent agent and Translation translation?
I think you can fix this by using an Entity Query as opposed to a ForEach job.
I didn't link the entire code but it does more things inside this foreach loop
i can send you the code
basically this loops over all my nav agents, and for each of them it iterates over all the grid cell positions to find the one they are standing on
im doing this by measuring their real world position's distance from all cells
and the closest distance is the one im picking
Yeah put all of it in a bin please. I doesn't matter if it doesn't work as I just need to see the overall idea, to make sure we're on the same page
lines 138 commented is the working but underperforming version
line 147 is my attempt which doesn't work
So what you could do here is completely skip the Entities.ForEach that calls GetNextCellDestination
Convert that ForEach in to a query and do query.ToComponetDataAsync<T>(Allocator.TempJob, out var THandle) for each component you need, and then ToEntityArrayAsync to get your entities. Then modify your CalculateDistanceJob to manually take all of those components. Since Execute(int i) gives you an index to work with you can use that to safely access the correct components/entities and perform your heavy calculations.
I will try it out, thanks!
also, it was suggested earlier to try to conver the positions into int2 to make the distance comparisons simpler, seeing as if I remove that line alone everything runs very smoothly
I'm not sure why int2 here would make it better. It depends completely on if you need decimal precision or not, so if you don't then you use int2. But if you need decimal precision stay with float.
I don't really need that much precision
worth testing out the accuracy loss and performance gain
Then the decision is in your hands π Keep in mind that you want to register your query with GetEntityQuery as opposed to EntityManager.CreateEntityQuery. To make sure your system is not run if you have no matches.
there's also an option to iterate over a radius from the position rather than the entire array of cell positions every time
I just figured out how stupid I am, the entire thing can be solved with this line:
int closestIndex = ((int)origin.x / cellSize * gridWidth) + ((int)origin.y / cellSize);
instead of iterating over all the grid, i can straight up know which cell the agent is on if i know the width and the cell size
We will come back to you with an updated plan, that will describe how we fix this situation.``` https://forum.unity.com/threads/dots-audio-discussion.651982/page-6#post-7247231 π₯²
shit happens, engine development is a complicated thing, hopefully they don't just give up with it
wish they would just let us have a look at whats been done
hahahahahaha so in the end.
they went and admitted that "holy crap we're riding a wrecked train"
"stop! stop! let's go back to station 1 and see what went wrong"
βοΈ This is only for DOTS Audio though, not DOTS in general.
did we go off the track somewhere? π
I wont' be surprised if they extended this reasoning to other parts of DOTS
I noticed that old code has World.Active.EntityManager, which is no longer the case, is World.DefaultGameObjectInjectionWorld.EnityManager the same thing?
ye
Still no posts from Martin? This teasing act is a bit sadistic, isn't it?
I have a separate system I am creating that I can call statically from anywhere, even inside ForEach Burst Schedule loops. Inside these methods, it does a check to see if entity has required ComponentData structs before it updates their state. The only problem is that I do it using var manager = World.DefaultGameObjectInjectionWorld.EntityManager; which all operations aren't burstable. I tried creating a command buffer, but it doesn't have things like: manager.GetComponentData<LocalToWorld>(entity); or manager.HasComponent<MyDataStruct>(entity);
Is there a way for me to achieve the same thing but make it burst compatible, and without having to pass in ComponentDataFromEntity structs from the caller's context?
If this is not possible, perhaps my static method will need to create a job that will wait for a sync point or main-thread before executing? Is possible to do?
@drowsy pagoda you sure the get/set/hascomponent methods aren't burstable?
I think they are. In my static method I am getting the active world entity manager, and World.DefaultGameObjectInjectionWorld getter is NOT burstable.
Iβm thinking my approach to this would be to create a native array outside ForEach. Then after that Job.WithCode(() => StaticMethod(nativeArray)).Run().
I tried. It gave me conflicting errors during runtime. Something about writing to Entity Manager without calling Job.Complete.
I tried Dependency.Complete but it created another error.
oic
What do I have to do to get shader graph shaders to work in URP HRv2? It used to work before but now I'm getting ```A Hybrid Renderer V2 batch is using the shader "Shader Graphs/Health Bar", but the shader is either not compatible with Hybrid Renderer V2, is missing the DOTS_INSTANCING_ON variant, or there is a problem with the DOTS_INSTANCING_ON variant.
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
I don't suppose anyone knows how you use the Nativearray.Sort() method or whether you can use LINQ with nativarrays? I need to sort a dynamicbuffer in ascending order
I thought you can pass in a Comparer to the Sort methods?
yeah that may be the part I'm trying to figure out, Comparer.default doesn't work
I guess I have to manually create the code for the Comparer, it just doesn't seem to be working
It just uses the default IComparer interface
If you need an example let me know
its cool thanks roamer I finally solved it
It is a limit of my understanding, or the ECS system? I have a SystemBase that runs ForEach with Burst and Schedule. In there, I need to fire off a static method that will take an entity and check if it has a certain component, and add/set it based on that condition. This static sits outside SystemBase in it's own class.
The only way I was able to accomplish the check and mutation was via World.DefaultGameObjectInjectionWorld.EntityManager but that is not burst compatible.
What would be a way I can do this? I was also thinking of maybe doing a NativeArray outside ForEach, have the ForEach store the entities in the NativeArray, and then cycle the array on the main thread? But I don't know how to do that. Can someone give me some advice?
is there any way to modify global shader properties from threads like jobs? it looks like Shader.Set* API is exclusive to main thread which makes it impossible to use jobs or traditional threads for what I had in mind, but maybe Unity added other thread friendly API I'm not aware of at some point
afaik you need to pass in the ComponentData/BufferFromEntity to the function for this. Calling functions on EntityManager is just not possible from a job unless running with .WithoutBurst().Run()
what can I do when I have two systems running on the same entity, and one of those systems destroyed the entity while the other is running and then I try to access the entity that got destroyed? right now accessing the destroyed entity either crashes the entire editor or throws exceptions
ArgumentException: The Unity.Entities.EntityCommandBuffer has been deallocated, it is not allowed to access it
Second system cant run on destroyed entity. Do you mean you trying make structural changes through ECB on destroyed entity?
If you do this with a regular job and componentdatafromentity its possible @drowsy pagoda
Thanks guys @safe lintel @keen root
Is it computationally cheaper to add/remove from dynamic buffer than to add/remove component data? Or is it about the same?
@drowsy pagoda add/removing buffer elements should be cheaper than add/removing an entire component from an entity
adding buffer elements should be similar to adding stuff to a list, doesn't change archetype which is the expensive part about add/removing components
Yeah, I presumed the same thing, just wanted to see if I was missing anything. Thank you for the confirmation!
Ok, I finally setup my static method issue to take in a command buffer as an optional parameter. If you are scheduling and calling this method, you pass in the command buffer and it will use that instead of entitymanager.
It determines this via an if (commandBuffer.HasValue) and runs code accordingly.
HOWEVER, now the issue is that the burst check is giving me burst error saying that it doesn't support EntityManager code on burst. But the issue is that it WILL not be executing that part because of the conditional.
Is there a way to disable that burst check for that method? Or am I stuck with it?
afaik burst is simply not able to compile it
It will run your function as a normal managed function
Ideally you split it into multiple pieces and burst those that you can, or just disable burst for that piece of code
The code runs fine even with that warning, but I didn't think about that it won't compile burst even though it is being called within a ForEach Burst?
If it throws a burst error it will simply be run as managed code
(until you fix the error)
Got it. Thanks.
Quick question. Is ForEach.Schedule(); CompleteDependency(); the same as ForEach.Run();?
not sure what other things CompleteDependency does, but between .Schedule() + .Complete() and just .Run(), afaik .Run is guaranteed to run main thread, while with the .Complete it might be scheduled on a different thread and the main thread waits on that thread
and also the .Run doesn't incur the .Schedule overhead
so doing .Run is generally better compared to doing .Complete right away
Perfect explanation, just what I was looking for thanks!
just curious was looking to see if mike acton was still lead of dots and yeah
also it looks like the team had a overhaul 5 months ago
restructuring makes sense for all the silence and we dont knows
so good news they haven't abandoned it quite yet
yeah def not
that looks like a double down and trying to clean up disjoint teams
better product comes out of that, but it gets a bit of the big team tax on speed
makes sense building dots into an engine is a complicated thing
its basically a rewrite of the whole engine almost
yeah its been a long ride since 2018
need to actually check, but I only remember a few strong talks at unite lately
2019 was a good year, seems like 2020 was rough/less short term progress
I have a need to use a NativeHashMap in a system ForEach. This one does not let you instantiate with only the Allocator, you MUST specify capacity. At that stage, I don't know what capacity I need. The ForEach job cycles through the entity's DynamicBuffer, and there could be anywhere between 1 and 1000 items to cycle. Should I specify a capacity of 5000 to be safe, or is that just inefficient and bad coding? Or should I pick a low number like 20, and limit the iteration to 20 BufferElements, sort of spread out the work to several frames?
Also, it's throwing a fit if I try to ScheduleParallel, should I avoid scheduling parallel on ForEach jobs that need to write to a Native[Array][List][HashMap][etc]?
if you need to write using multiple thread take a look at NativeHashMap.AsParallelWriter(), this returns a container which allows concurrent writing.
I would allocate more up front, because the way unity resizes containers like NativeLists when it needs to do a resize is NativeList.Length + 1.
Oh awesome thanks!
Is there an updated guide for ECS in Unity 2020?
I couldnβt find anything, only thing I can recommend is youtube. There is TurboMakesGames user who does a pretty good job breaking you into it. And there was one more, I think it was Code Monkey.
Anything beyond that was docs, trial and error. Iβm a little over a week into it, and the training wheels are about to come off.
Thanks! Last I heard, ECS wasn't a thing in 2020. Anything is better than nothing π
Glad to hear it's still usable π
Depends on where you heard it from lol.
So I declared it AsParallelWriter, and I can't find option to Add, Remove, ContainsKey, Clear, and all that good stuff. How does this work?
Or am I supposed to declare it, then call AsParallelWriter separately?
Oh, how about reading?
If you can only write, not quite sure how to utilize this then lol
well you can't read and write with a parallel writer because that's not a safe operation to do simultaneously
you need to write first and then read later
Ok, how would I read later then?
you read from the native hash map
the parallelwriter is just a container that points to the same data buffer
Oh, so I create just the HashMap. And in the part where I want to run parallel I AsParallelWriter. And then when that is done, in a non-parallel container I just refer back to my original instantiated HashMap and use Add, Remove, Clear, and all that and it will have been populated by the parallel writer?
yea
Wow cool. Thanks for the explanation!
Thanks to all your help guys. I managed to write my own Tween system fully compatible with ECS, Jobs (Single and Parallel), Burst. It can been called from anywhere background thread or main thread via static method var tweenManager = Tween.Manager, and then inside ForEach tweenManager.Translate(entity, from, to, duration, true) or tweenManager.Rotate(entity, from, to, duration, true)
It's still in early stages, but will build on it.
π
I assume you saw all the links in the pinned messages
- there's a short guide on Unity learn
If youβre working on a game (or other real-time simulation) that requires the most efficient CPU usage possible, then Unityβs Data Oriented Technology Stack (DOTS) is a great way to get the performance you need. However, to use DOTS successfully, you canβt simply grab the API documentation and dive straight in. Before you begin creating a projec...
Hope that helps
Hey cool. Iβm gonna dive into this. Thanks.
@low tangle did mike acton leave unity? Thought he was vp of dots
Oh I thought that image was a job listing my bad, got worried there π
I just found out the hard way that this: inventory.Item = commandBuffer.Instantiate(player.RightHandItem); was storing an entity -1:0 instead of the instantiated one. This makes sense because it cannot know the entity id at this stage since it is a deferred job.
Is there a convention for something like this already, or I need to get creative?
Is there a way to query all the ComponentData<MyType> based on one of their values? Kind of like components.Where(c => c.myValue == mysearchquery) ?
He didn't, that's what I was checking
Entity queries have Filters on value for shared components, don't know if there's an equivalent for regular ones
Alright so looks like the regular one only checks a change in value. So I guess you'd have to query everything and check yourself. Or put a tag or something.
Where can I find example code of a query of a shared component based on it's containing value?
thx
we're having an issue with burst compiled function pointers that live inside of a static generic class
i managed to boil the issue down to a pretty simple example: https://pastebin.com/0tEEwATF
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.
short question: anyone know of a way to force feed Burst specific functions that might not be explicitly used by our code?
I have 30,000 entities moving in my game, and I want them to not overlap with one another. How would I go about this? what's the most efficient way to implement this behavior?
I tried enabling collisions but because of their amount it just crashes
if you figure it out let me know , because I've been trying to find something that works like that in dots for a while
you need something like Unitys Navmesh system with RVO, local avoidance in dots
I have a grid that I can increase the cost of moving to a cell to the max if an entity is on that cell, but because I have something like 50,000 cells it also crashes
(flow field)
cool, I built a flow field too
iterating over the cells is crazy expensive though
yeah I think I had to limit mine to stay under 40,000
not because of the performance, because of using a byte to store some data
it shouldn't be that expensive to iterate through them all though
well, I have to check if an entity exists in each
which is a raycast
raycasting 50,000 times a frame is rip
you shouldn't need to use raycasts
i could send the indexes of each entity from the entity itself i guess
but then i have to keep track of when they leave the cell too
if you know the size of the grid and the cell sizes you can convert that to a world grid position to find where they are
yep, i have that functionality
but what happens when they leave the cell they are currently in
I have to store it's previous value somewhere
how do you mean they are just in a new cell then
the previous cell's cost was increased
it needs to be reset back once they leave it
are you counting the actual moving entities into the flowfield cost
thats what i was thinking
how would you do it?
I was thinking that if every cell that has an entity in it have increased cost, other entities wont overlap with it
interesting but that would surely mean you'd have to have a seperate flow field calculated for each entity surely
why?
Is this correct? When an entity is created, it's index will always be greater than -1. When an entity is scheduled for creation via commandBuffer.Instantiate(entity), an entity is created with an index less than 0 until the sync point actually creates the entity, which it will just change the index on that entity to next available index that is greater than -1.
I don't know maybe not π€
the only flaw in my algorithm is knowing when to playback the previous cost of a cell once an entity been through it
if I don't raycast, by default I iterate always over the cells which do have entities in them
so I have to iterate over all the cells minus the ones the entities report they are in
Any way to NOT have a subscene convert to entities?
so your making it so the cells turn into obstacles
could you not just have a bool component to tell if an cell is occupied or not
and then iterate over all those that don't currently have an entity in them but are set as occupied
then decrement their cost back and set it to false
could work
yeah well only set it to true when the cells are occupied
yeah maybe π€
then it gotta be integrated into the flow field
if(occupied dont go here) etc
might go with the cost so the flow field will do the work out of the box
forum post and bug report made if anyone else was curious: https://forum.unity.com/threads/burst-issue-with-function-pointers-compiled-inside-of-generic-class.1129022/
Why does stuff like Bytes16 not have the IEquatable interface implemented? Really annoying...
a few months ago I tried to do:
NativeList n;
foreach (var element in n) {
}```
And I discovered that the implementation for `GetEnumerator()` for NativeList at the time was:
```cs
throw new NotImplementedException();
not sure if they fixed that yet...
its not iirc
tried the same recently
I just use a normal for loop anyways so I don't really mind
indeed - I was just illustrating that the API still has a long ways to go
just to check, I assume 16 is far more than math.all offers?
It is, but now I finally know how to check if a bool2 is true. You have saved me from despair
What does it do for types like float2?
Another option
public unsafe bool IsEqual(this Bytes16 b, Bytes16 other) {
byte* bytePtr = &b;
byte* bytePtrOther = &other;
for (int i = 0; i < 16; i++) {
if (bytePtr[i] != bytePtrOther[i]) {
return false;
}
}
return true;
}
I only need Bytes16 for now so I went the non-sophisticated route for now :)
otherwise you could try
return math.hash(&byte, 16) == math.hash(&other, 16)
are the hashes unique?
Well it uses xxhash algorithm
so it's really a fast hash
believe int2. float2 uses this for hash overrides
yeah but for equality I need it to actually be unique and have no false positives
yeah idk much about xxhash algorithm to give you a good answer lol
no worries, this is fine for now, thanks :)
I'm not too good at this stuff - this could well be a super dumb suggestion - but can you reinterpret the 16 bytes as e.g. a float4 for comparison? π
i guess you can lol
float4* ptr = (float4*)bytes16; // I assume float4 is exactly 16 bytes, most likely it is lol
yea... not sure how bad that is but it would make the comparison succinct π
I just realized that using GetComponent and SetComponent directly in ForEach is allowed on burst and schedule and even parallel. Before I was using the GetComponentDataFromEntity approach.
I just updated my code with this simpler approach, but it did raise a question for me about performance. Is first method the same as second method in terms of performance, or is there a difference between them?
I think it is auto converted
i.e. performance is the same
although I am not 100% sure
Also not sure how read only access is done in that case...
Yeah, I can't tell if they considered that or not. Would be nice to find out somehow.
Actually, in the first method, I would set all the GetComponentDataFromEntity to readonly. And using commandBuffer.SetComponent still worked.
So I have a feeling the readonly thing is covered. Just only worried about performance mainly.
Both GetComponent and SetComponent get auto converted to ComponentDataFromEntity. It's different from commandBuffer.SetComponent because the set is not deferred until the Command Buffer Playback. It's slower than setting the component directly (by passing it with ref). GetComponent is readonly unless you also do SetComponent (was a while since I tested this but I'm like 95% sure that's how it worked.)
All of the above only applies to SystemBase and Entities.ForEach
Awesome thanks for the explanation
Yeah, that's pretty much how it works. Keep in mind that an entity is an index and version. Since index alone wouldn't be stable. Regarding what you wrote earlier about the same thing. If you need to store the entity (let's call it "A") you are creating through commandBuffer.Instantiate in a component on an existing entity ("B") , the easiest way would be to attach a component on A that has a field pointing to B. Then you have a job that looks for this component, and assigns A to B, in the correct component.
Yup, that's exactly the solution I had to come up with. Feels a bit dirty, but I don't see another way. I suppose later I can come up with a system that I can call from anywhere for any data structure.
Yeah. There you can do some things to keep it fast though. Instead of AddComponent make sure the "pointer component" already exists on whatever you instantiate, so you can use commandBuffer.SetComponent instead. Also when removing it sometime later, use a query instead of marking every entity for deletion.
Can you give me an example of the query for deletion protocol?
It's identical to a normal commandBuffer.RemoveComponent only it takes an EntityQuery (I would give you a better example but it's too hard on the phone). This page explains them fairly well: https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/ecs_entity_query.html
Thanks, I'll look into it
So many cool features in 2021.2, and two concrete i need - URP 2D VFX and render features support, but we locked on boring 2020 π₯²
and uitk still breaks entities subscenes on 2020
yes, more pain plsπ
I think 2021.1.12 still works
actually yeah updated and reimported my project for 2021.1.12 and looks like entities is still working - I should make a built to see if that's still the case tho lol
Lol yeah, when they made the announcement I was already on 2021 and I just froze it at version 1.2 π
Figured I'd try to see if later versions would work
I am destroying an entity that resides within a dynamic buffer. How do I remove the destroyed entity from the buffer? Or how can I check if an entity has been destroyed? π
@coarse turtle yeah it works in later editors but i'm annoyed that they act like updating beyond 2020 has supposed major incompatibilities and they don't even acknowledge one of the most pressing ones in 2020. they wont accept bug reports beyond 2020 either, which is why I grudgingly went back to 2020, and tore out uitk for the time being.
o π
Honestly I'm having a problem with UITK where the debugger isn't displaying the font in 2021.1.12 which sucks
i found that 2021.2a9 was totally solid(with uitk as well), and then beyond that entities did break. wouldve stayed on it if it werent for the bug report thing.
Ah damn, that sucks. Yeah the current beta version UITK - complains with the dots editor afaik
yeah I really wanted to try out and give feedback for the new toolbar stuff
also I think submitting bugs might be the only sane way to get a new gpu these days, even if it is like a lottery system
True lol
Is it correct to assume that in a Schedule/Parallel ForEach job, if I use just SetComponent it will defer the execution of that method until the next upcoming sync-point? Or does it default to the end or some place specific each time?
[Unity.Burst.BurstCompile]
public struct TerrainMeshJob : IJobParallelFor
{
[ReadOnly] public NativeArray<float> texture;
[ReadOnly] public TerrainMeshSettings settings;
[WriteOnly] public NativeArray<Vertex> vertices;
[WriteOnly] public NativeArray<ushort> indices;
}
I have a job like this, but i am getting error
InvalidOperationException: The writeable UNKNOWN_OBJECT_TYPE TerrainMeshJob.vertices is the same UNKNOWN_OBJECT_TYPE as TerrainMeshJob.indices, two containers may not be the same (aliasing).
I am new to job system and burst. I dont understand what this means. I read the blog post on aliasing, but i cant understand what i am doing wrong.
Whole code -> https://hastebin.com/oravuxilum.csharp
you don't need to do [WriteOnly], it's implicitly there if you don't add [ReadOnly] adding it may force the field to be unreadable, which could explain the error.
same error without [WriteOnly], just tried
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct Vertex
{
public float3 pos;
public float2 uv;
}
it is this
that should be fine. hmm
what is the data type for LOD?
I don't see it in the paste
I see, I missed it the first time
2 things left I can think of:
- You need
[NativeDisableParallelForRestriction]on both of your write target native arrays. (Likely) - There's some burst compiler issue with splitting things into two sections with the same file. (unlikely, but stranger things have happened)
If it's indeed the first, you should still report a bug, as that error message is the opposite of helpful
okay, i am trying both. thanks
same error with first one. for second one what should I do? move the job to a separate file?
using [WriteOnly, NativeDisableContainerSafetyRestriction] public NativeArray<ushort> indices;
no, that shouldn't be an issue at all.
I am not getting the error anymore
huh
you Shouldn't need WriteOnly, but if that makes it work you should be ok.
I'd still report an error as I've never seen this happen.
Also, there could also be an issue with the mesh data API, if it returns an invalidly sized vertex or index array.
Verify you're getting the correct data back from GetVertexData<Vertex>() and GetIndexData<ushort>() in terms of those array's lengths, just in case
I'm not as familiar with the Mesh Alloc API
okay, i will do that. my mesh is still not generating properly because of some indexoutofrange exception. Thanks for the help!
no problem
you may want to be a bit more pedantic with the VertexAttributeDescriptor setup and ensure it's float32, sizes you expect. AH!
The default size is 3
your uv discriptor should be 2 if you're just using normal UVs
and the stream defaults to 0, you may not need to setup the additional submesh information
mesh.SetVertexBufferParams(verts * verts, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, 2));
mesh.SetIndexBufferParams((verts - 1) * (verts - 1) * 6, IndexFormat.UInt16);
mesh.subMeshCount = 1;
mesh.SetSubMesh(0, new SubMeshDescriptor(0, (verts - 1) * (verts - 1) * 6, MeshTopology.Triangles));
Sorry i made this change but forgot to update in paste.
you mean like this right?
yes
if the Vertex structure and the VertexBufferDescriptor data doesn't match, that would cause wonky stuff and buffer overruns
yeah, i just found more problems with my code. Will fix those.
CommandBuffer.SetComponent or SystemBase.SetComponent? SystemBase.SetComponent can't be used in a Parallel job. Only the CommandBuffer commands are deferred (hence it being a command buffer), the other ones are immediate.
I don't suppose anyone knows what the current best ways to make a UI with Dots are?
One entity(dot) per pixel is the way to go - just give it a Color : IComponentData{ public float4 Value; }, collate data into a buffer -> gpu via compute -> render - then just gotta set the entity values as appropriate π π
cool sounds simple and straightforward enough 
On a more serious note... nothing particularly helpful to say - I think most people I've seen try and use UITK with some abstraction layer but.. yea.. compatibility woes for some atm. A 'Pure' dots approach is a long way off having good/any editor tooling so think some form of hybrid is probably the way to go?
There isn't a UI solution for DOTS atm. Your best bet right now is to use Unity UI and use EntityManager in MonoBehaviours to communicate with ECS world
yeah figured that might be the case as always, but best to check first, thanks guys
random non-dots question.
but has FSR been integrated into Unity yet?
is that the AMD upscaling thing?
yeah.
I doubt it I haven't heard anything, I mean Nvidia's DSR barely has yet
hrmm.
I just saw a pic that Unity is an FSR partner so...
well it'll probably take months to integrate it
yeah plus we have yet to know if its even any good
I see thanks.
I still didn't manage to implement collision avoidance for my grid navigation, did anyone achieve this?
I tried increasing the navigation cost of a grid cell if an entity is already in that cell, but that caused navigation bugs
Not sure if this interests you @crude sierra - https://github.com/reeseschultz/ReeseUnityDemos
interesting, thanks!
btw, is it possible to change a value by index using NativeList.ParallelWriter?
for example list[index] = 5 doesn't compile, is there an API for this?
Is there any point in Job.WithCode().WithoutBurst().Run()?
If you need to do something with managed objects
But otherwise I don't see too much of a point
I mean at that point its just main thread managed code
Whatβs an efficient way of removing items from NativeListA that are contained in NativeListB?
Yea pretty much haha
You can take a look at IJobParallelFilter jobs
you can either store a list of indices to include or a list of indices to exclude with it if you need specifically done in a job.
ListA and ListB get set from different places of the program at different times (non-interval). And so if I use the indices approach, I will STILL have to "search" for the index in A when element is about to be committed to B.
No, Job.WithCode().Run() will ensure that previous jobs have completed before being run. But then you may aswell just Dependency.Complete();
The only real kicker for it is if you have a Job.WithCode().Schedule() that you need to debug, then you can just convert Schedule to Run.
Quick question, anyone have an example of how to assign a material to renderMesh component
Is this a good place to ask a Job system question even if im not using dots?
this channel should be ideal for that.
Hi, I'm just starting with the Jobs System and I'm having a hard time finding the info I need. I'm working on a modular system that will iterate over a large list of "entities" (but I'm not using dots or ecs). Most of those modules will use jobs and will either work on the same data, without changing it, and others will need to work on the output from a previous job. Question 1- Do I have to create a new array for each job, or can I share a single array for the jobs that only read the data? If they do write, it will never be at the same place. Question 2- For the jobs that need the output of other jobs do I need to copy the results to a new array for the next job or can the array be passed on to the 2nd job or reused somehow? Question 3- Do I even have to worry about the performance of creating arrays? i.e.: if I have 10 arrays with 10,000 values each and 5 jobs that need all 10 arrays? If someone can point me to the appropriate part of the manual, that would also help.
Q1: You don't have to create a new array for each job. You can mark them with the [ReadOnly] attribute to allow reuse between jobs. If you want to do parallel writing and you can guarantee you won't write to the same index from two jobs, you can use the [NativeDisableParallelForRestrictionAttribute] attribute. This will disable any warnings though, so now it's all on your table.
Q2: You can just pass the same container with the results to the next job, no need to make copies. You should use Dependencies to ensure that your jobs won't accidentally run parallel if you expect them to run sequentially (if JobB needs the output from JobA, then JobB will depend on JobA.) You set and get the dependencies when scheduling a job.
Q3: No there will be no real performance issues. The way NativeContainers work is that they are themselves small structs that just contains pointers to the real memory. So there will be no "copy" or similar when inputting them in the jobs. Manual link: https://docs.unity3d.com/Manual/JobSystemNativeContainer.html
Can I instantiate, destroy, change materials, use triggers, and all basic gameplay stuff with DOTs?
Any good projects out there with this stuff in it? is Unity tiny recommended?
Yes you can. But your question is broad because dots is broad. If you mean ecs, then also yes, but because ecs (entities package) is still early, and secondary feature packages as well (physics, audio, animation, etc), you have to find ways to deal with missing features or refactor against api changes.
But you can use burst and jobs with existing mb projects without much hassle.
thanks for the reply
so is hybrid method ok. mono behavious cant interact with dots?
They can through the EntityManager. Your question is still too broad. If you mean stuff like "can an entity trigger OnTriggerEnter?" then the answer is no.
trigger dont work?
does it have its own triggers?
Is the DOTS community in limbo, or is anyone actually making anything ?
because the forum is full of ambiguity
so I can have a dots player controller.....and dots triggers?
No animation, timeline stuff?
Cinemachine?
I never used DOTS Physics so far so I can't answer for sure. Yes people are making stuff with it. Keep in mind that it's not production ready. So don't expect to release anything made with it (yet).
You can use practically none of the tools that exist in Unity editor for it at the moment.
ok. I guess I should wait then
DOTS is still in very early development.
none of the features you expect from MonoUnity will be present at the current state of dots. Chinemachine, Animation. none of it.
You really have to roll your own.
the community isn't in limbo per se, it's still quite active like this channel.
Yes there are people actually making stuff on this early tech.
UI? nope
No, no
It's no like you can't use it, because you can. But for all of those you need a wrapper to get the data from DOTS world
WHat about the hybrid method. I'm only interested because of the high number of Gameobjects i want in the scene.
Hybrid approach is just way for you to design the game via Unity's UI and then have it convert to Entities.
And some components that doesn't exist in ECS you can "borrow" it from the Mono side
do i specefically need entities, for many many GameObjects?
No
The concept of GameObject doesn't exist in DOTS.
There's lots of hacks you can do to keep your game performant even with plenty of GOs
I could give you better answers if you would give me a concrete question instead of just theory
sure. like, its a block based game dealing with very large numbers........on a 2d plane.
Okay, what do you do in this game
ok. well you would basically be drawing graphs....like equations.....and then beable to modify them yourself by turning blacks on and off.
but the numbers get very very large
so when the user types 10000....every block of that will be able to turn on and off
imagine like...instead of minecraft...this sounds off the wall I know...but imagine minecraft but instead of drawing a block you would draw a funtion like xsq
and then you could draw that anywhere on the graph.
just imagine graph paper......
Having a hard time grasping the concept. But DOTS is best when you have a lot of data, where you need to do a lot of operations. Say you have an RTS where there's 5000 vs 5000 tanks fighting and now you need for each tank to shoot at the closest enemy tank. This would be a good usage of DOTS. The whole point of DOTS is to make performance better by using multithreading and well thought out memory structures.
this is why i am intersted. because of the large number of objects
You could try it, I think it could be a good use case, but make a small sample to figure out how DOTS works first. It will take you quite some time to get in to. Make sure to read the manual throughly. There are some examples here: https://github.com/Unity-Technologies/EntityComponentSystemSamples
But they are a little outdated, but not a lot.
thanks. I will give it a look.
Be prepared to roll your own solution for a lot of stuff though.
It's up to you, I would recommend against it unless you already have at least, say 5+ years of Unity and programming knowledge.
RIP my dreams
Thanks . probably saved my days
i have 4 years...but my programming is just starting to make sense to me
Then I wouldn't recommend you use it at the moment and just work on your normal C#/Unity skills.
cool. You wouldnt just happen to know how to programme tilemaps?
does int2 serialize properly? i had public variables with arrays for longg time but they all dissapeared (theyre now array size 0) and i literally have zero code that could reset, destroy, null or cancel such array
I'm fairly confident they do? I worked on a project where we used intX and floatX, floatX,Y all over the place, but I can't say for certain that we used specifically int2, but it's very likely we did. We didn't have any issues regarding them.
Are your sure the issue isn't with your containers?
could be
you'll be wanting to do all of this on the GPU
Vfx graph
Have one object handle all the logic
if you are generating stuff via math formula that involves placing the same mesh in a bunch of different spots
Send all the completed tasks to a texture
the GPU can do that much faster
I never considered that.
if you do it appropriately you can render upwards of 1 million 2d quads on desktop GPUs
at 60+fps
while they move around
you couldn't do anything like that on a CPU
Can i read something about dots serialization? some guide? maybe thread on forum with tips?
can you program each instance of the quad to be at a specific position?
Yep
cool thanks.
can you use text mesh pro with vfx graph?
I just tried to make 10! tiles in a scene....
still waiting
10! is 3.6 millions
yeah
At this point, aren't you looking more for infographics?
in unity?
Is it safe to call Dispose() on a NativeArray<T> more than once? Similarly, is it safe to do it if the NativeArray just = default?
So which units should I use?
which node name for set position
in vfx graph
@vivid lotus in both cases that should throw an exception
sorry to be bugging, but what about shader graph? would that be way more performant?
shader graph generates... a shader
so you can do it in shader graph
or write the shader yourself
I have no idea what pipeline you are using
urp
but if you search for messages from me in the #archived-shaders channel
I have messages with cyan about doing instancing in URP and HDRP
it's pretty complicated though
@dense crypt Thank you so much for all that info you posted earlier!
Is dots/instant games a thing ?
With Project Tiny, Unity's upcoming new highly modular runtime powered by DOTS, you will be able to build instant games that are small, light and fast.
thats a very vague question, its a "thing" under development.
Hey, I don't know if I'm on the right thread, but I made this CSharp Job that generates a terrain from a mesh with biomes etc, now my issue is that the separation of the biomes create ugly cliffs because of the height difference between the biomes noise, I'm trying to make a CSharp job that will smooth the terrain after it's been generated, so my question is, how can I run my SmoothJob after the GenerateTerrainJob to get the datas from the terrain?
@gusty comet Your 1st job can write to some native container and then 2nd can read from it. You need to chain your jobs through JobHandle dependencies. In SystemBase it goes automatically.
Could you give me an example code of JobHandle dependencies?
Do you use unity ECS or just Jobs?
oh sorry didn't see the message, I'm planning to use ECS in the future and my environment is already set up
I found this : var jobHandle = new SerializerJob{...}.Schedule(); new PacketWriterJob{...}.Schedule(jobHandle);
where PacketWriterJob can only run when SerializerJob is done is that how you do dependancies? if so how would I go if my job is in a separate file?
yes. If your jobs in separate systems, then you have no need to chain them manually, but they need to somehow transfer data between each other. There can be 2 variants:
- Use entities as technical (i mean not game) data to make systems interactable
- Inject data to system by Word.GetOrCreate<T>
There is no special need to separate logic if it always goes the same way
yeah it worked I got my vertices from the mesh thanks π
i have edited previous message
When you said use Entities as technical... so for example I have my Native Array of vector3 that get me the vertices of the mesh, I'd need to create an entity for each vertex with a float3 property containing the vertexpos?
has anyone brought serialization to a working state in 0.17?
yes, instead of array you can create bunch of entities. it is not good way though. But sometimes i see how people talking about how they rewrite their linked list as linked entities
what if.. my mesh contains 62500 vertices? it's not great to have 62500 entities is it? since I'm going to use entities to create animals, plants etc...
yes
If an entity has a Parent component, can it ever have Value == Entity.Null? If so, that would mean it actually is NOT a child? Or will Unity automatically toss the component if the Value ever equals null?
Unity never automatically tosses components. Uninitialized components would start with Entity.Null if the value of that component is set.
Thanks.
How do I query entity with disable component
If I want it enable them by removing the component
Is seems like queries totally ignore entities with a disable component
You have to explicitely add the <Disabled> component in the query
Or Entity Query have a filter to specifically include disabled entities
Similar way as Prefabs components
βοΈ Also, if it's an Entites.ForEach you need to include .WithEntityQueryOptions()
Hello, I'm trying to build my DOTS project for windows and I have this compile error from the scriptable build pipeline : error CS0117: 'NativeArrayUnsafeUtility' does not contain a definition for 'SetAtomicSafetyHandle'. Everything works in the editor and as far as I can tell, this particular "missing" script is part of "Assembly UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" which is unity itself, so I don't get how it could be missing. Any one as any sugesstions ?
solved it, some of my code was missing the #if ENABLE_UNITY_COLLECTIONS_CHECKS :/
Does anybody have an idea how to solve this without reflections:
this.getComponentDataMethod = typeof(EntityManager).GetMethod("GetComponentData").MakeGenericMethod(genericType);
var componentData = this.getComponentDataMethod.Invoke(this.EntityManager, new object[] { entity }) as IComponentData;
del.Invoke(componentData);
I am trying to get component data via type.
But using reflection causes AOT errors.
I don't see a public way of doing that, unfortunately? The functions you would need to make an IComponentData GetComponentData(Entity,ComponentType) method all exist, but some of them are internal so you wouldn't be able to call them without local modifications to the entities package.
I guess you mean EntityManager.GetComponentDataRawRW? If I reference the entities package via assembly reference file I could be able to use it π€
Actually, now that I look at it more thoroughly maybe this isn't possible without reflection? You can get a void* to the data, but to copy it into a C# structure you would need to create an object of genericType using Activator and that might fail in the same way as the reflected method calls.
Wouldnt it be possible to cast it to an IComponentData somehow?
IComponentData has to point to a managed object, the void* is going to be unmanaged.
imo you should look into an approach that uses a shared noise function that works across chunk boundaries
so you don't have to smooth
Yeah but how would I detect an edge ?
And how would I apply noise to it? Since I only want to apply noise on the y axis of the vertices
so each chunk is a square mesh right
you would want the chunks to overlap on the edges with a vertex from each chunk in the exact same spot
with a noise function that looks something like y = terrainHeight(x,z)
and on the borders the chunks would call that with the exact same x,z
inside terrain height you could map the x/z to whatever biome/noise function you wanted
but then the edge of chunks would always have the exact same height and overlapping vertices
so you shouldn't need any extra passes
That sound good I'll test that later!
I see. Thats a problem π€
But I guess if Unity can do this:
var componentData = entityManager.GetComponentDataRawRO(sectionEntity, typeIndex);
var data = builder.Allocate(ref metadataArray[i].Data, typeInfo.TypeSize);
UnsafeUtility.MemCpy(data.GetUnsafePtr(), componentData, typeInfo.TypeSize);
So can I?
Depends on the context, I guess? If you're in a context where that stuff works then I would expect Activator.CreateInstance(genericType) to work as well.
(Which would probably do the same thing for structs.)
Currently have an issue with instantiating entities and to have to be assigned to struct fields in scheduled containers. Not sure if there is a conventional approach to this but I had to come up with something like this: myData.Entity = entityDelegator.InstantiateCheck(sourceEntity, myData.Entity, startPos, startRot, newParent, out bool assigned);
This will instantiate the entity, assign optional pos/rot/parent and on the next frame will actually assign the struct field with the new entity. Once assigned starts returning true, then youβll know on this cycle itβs a valid entity. This will work on Schedule and ParallelSchedule threads.
If there is a simpler way, please point me in the right direction.
If this is addressing what I think it is, I just add e.g. Created to the archetype/prefab I'm going to instantiate. A system runs for all entities with the tag and e.g. at the end of frame another one removes them via entity query batch method.
Thatβs a great idea. I didnβt think about that. But it doesnβt address the issue of auto-assigning the new instantiated entity to a struct field. If it does, can you elaborate?
Oh I just mean this instant games description sounds amazing !
"
Unityβs new, highly-modular runtime lets you build instant games that are small, light and fast.
Complete control over your file size
Work with the Editor you know and love
Unparalleled performance and scalability
"
and this !
"With Project Tiny, Unity's upcoming new highly modular runtime powered by DOTS, you will be able to build instant games that are small, light and fast"
Yeah problem is, Tiny is not ready so that's just marketing jibberish for now
Sorry I don't know what that means. What defines the relationship between the newly created entity and 'struct field' - is this field a component on another entity? Or some public property of a system somewhere or something?
Well in the use case that caused me to side track to create this system was that I have an item that needs a "ghost" counter part. So when user wants to place it, a ghost appears showing how it would look if it were placed at the spot. So when the player holds down the Release request button, the ghost will instantiate, then move around based on his look point.
And when he releases it, the ghost gets destroyed (will implement pooling later).
This all happens on a Schedule thread for the player, and all the items have ParallelSchedule logic, none run on main thread. If I just do item.Ghost.Entity = commandBuffer.Instantiate(item.Ghost.Prefab); it will instantiate the item correctly, but the item.Ghost.Entity will be a temporary value like [-1:0] or whatever is available.
Then I have to create a whole thing to "catch" the newly created entity and then assign it to item.Ghost.Entity
Instead of creating a specific code for the player-item relationship, I created an EntityDelegatorSystem that will do all this from anywhere you call it. And it will auto assign the new entity to item.Ghost.Entity on the next OnUpdate iteration.
To set it up, you need to first create an entityDelegator outside the ForEach like this:
var entityDelegator = EntityDelegatorSystem.CreateDelegator(Dependency);
or for parallel:
var entityDelegator = EntityDelegatorSystem.CreateDelegator(Dependency).AsParallelWriter();
And then inside the ForEach iterations you can request instantiation and catch it on the next iteration automatically like so:
item.Ghost.Entity = entityDelegator.InstantiatieCheck(item.Ghost.Prefab, item.Ghost.Entity, null, null, null, out bool assigned);
Then check:
if (assigned) // then you can use item.Ghost.Entity here
hmm.. just wondering if you may be slightly over-engineering here? Why does the original item need to know about the ghost btw?
sidenote: if these are entities, you shouldn't need to do any pooling (instantiate is very fast) - I'm also highly skeptical that the cost of scheduling the job in parallel will be less than executing it on main thread for < 10000 entities
It's true, DOD and DOTS patterns is new to me, so there is a big chance that you are right about me over-engineering. But in some cases, I need to instantiate something and use it, and I would have to make a sync-point if I want to save the entity reference to another data struct. With many calls like that it can cause me to create many sync points. So I over-engineered this pattern so that it consolidates to a single sync point regardless of how many times instantiation requests are made and where they are made.
As for your sidenote, I think that does make sense, I'm still finding myself brushing off legacy pattern coding mindset. Thank you for that sidenote π
π - just always keep in mind "what's the data". Instantiate takes care of having two identical visual representations. A tag makes one follow the mouse & be 'droppable'. A system can, on mouse up, check if any droppables are in dropzones & destroy all entities with the ghost tag? I'm likely oversimplifying your use-case, just trying to give you an idea of the direction I approach this type of problem.
I don't quite understand what you are trying to archive, why are you not able to use a EntityCommandBuffer?
Thanks for that. I will rethink my architecture, now that I realize instantiating and swapping archetypes is not as costly as I would assume if it was on legacy pattern. Appreciate your input, this helps clear the air a lot.
Thanks, but I think I got what I was looking for from previous responses π
Has anyone had success with changing an entity's parent on the same frame that the old parent is destroyed?
Reading through the logic in ParentSystem, it first calls UpdateDeletedParents(). This looks for deleted parents and removes the Parent and LocalToParent from all children, even if that child has a new parent. There is logic for changing parents in UpdateChangeParents(), but this runs after UpdateDeletedParents() so its too late.
does anyone know when i should expect radians and when to expect degrees?
basically always radians when ecs/math class
Is there a way to get the last element in a NativeQueue without removing elements?
the only way I can see is to use queue.ToArray() and then use that I guess
That's the only way, though if you're doing that regularly that suggests that Queue probably isn't the collection type you should be using in the first place.
Thanks!
Does anyone know if multiplication between float2 and float works and if it changes the x and y individually scaled or based on the vector magnitude?
All math in Unity.Mathematics is component wise. So AB * C = A * C, B * C
there's no nativequeue.contains() too 
You could write your own extension method for that.
I have no clue how to do that 
Would you know how to write the code to check if your queue contains the item? Or do you mean both the code and how to make an extension method?
yeah I just did this csharp foreach(var boodle in robotqueuearray) { if(currobjID.IntVal == boodle.IntVal) { return; } }
public static class NativeQueueExtension
{
public static bool Contains<T>(this NativeQueue<T> queue, T target) where T : struct, IEquatable<T>
{
}
}```
yikes formatting, one second
Can't be better apparently π€·
Put your code in that method, and you'll be able to call it like this:
var contains = myQueue.Contains(myItem);
I think you have to ToArray the Queue though :/
cool so I just place that anywhere basically
yeah exactly
But yeah, that type of method is called an extension method. They're super useful for stuff like this and I highly recommend you check it out
Doesn't seem that long to me? 70 microseconds. I'm fairly sure it's the main thread you're seeing. Check the Profiler if it seems wrong
Well don't trust the values you see in editor. Make a build and profile it. DOTS is notoriously slow in the editor because of the safety system/JIT-compiled burst instead of AOT and a whole slew of more things. But find the frame where it takes 0.40ms and see what's happening in the Profiler.
Sounds like a good time to read up on it now then! π
Sounds more like you just need more experience using it. https://youtu.be/uXRURWwabF4
Profiling is one of the best ways to optimize your game. Learn how to use Unityβs highly effective profiling tools and how to interpret the data they produce.
Speaker:
Ciro Continisio (Lead Evangelist, EMEA)
Ask your questions here: https://on.unity.com/2SWT8ph
Did you find this video useful? Room for improvement? Let us know: https://on.unity...
This is one of the best videos Unity put out, you should check it out when you have time
does the HybridRenderer in HDRP actually use the compute shader for culling?
Might help if you're making gameplay code using DOTS:
If this is the entity debugger, I wouldnt use it for stats atm. Profiler will be far more accurate; however, some usual causes of high times in a system: completing a job that could have run throughout the frame, debug statements, inadvertent sync point, scheduling lots of jobs
Ideally the profiler shows you a graph of all frames if live, and in any given frame you can see the timeline for what was called and how long it took
Is there a simple way to make subscene works when authoring creates additional entities? I have tried to use ConversionSystem.CreateAdditionalEntity, but it changes nothing
I've found that I needed to nuke the subscene cache
Just to have the additional entities show up in the Entity Debugger
It's really not ideal
have tried
in fact when i try to CreateAdditionalEntities() console shows me terrible error about some corrupted meta data
O - I haven't ran into that issue yet :/
this two threads are helpful. Seems like i wrote something wrong and CreateAdditionalEntity works. It is hard to understand what was wrong because of uninformative error logs.
https://forum.unity.com/threads/is-it-possible-to-create-new-entities-for-a-subscene-during-conversion.1113991/#post-7168432
https://forum.unity.com/threads/subscenes-help-with-live-link.699470/
Ok Been trying for past 3 days to get subScenes working , trolled through MegaCity and the HelloCube subscens example but im just not getting this....
Soooo
Hi!
After realizing that Unity is not planning on supporting actual ECS workflows. I decided to still give it a try.... even tho the base idea of forcing people to use the conversion workflow is stupid
I have a question how do I convert from a GameObject reference? (Reference a GO / Entity in the same scene)
conversion is tangential to "ecs workflow", your runtime data in some instances is just not the same as edit time data. could you elaborate what you mean by "convert from a GameObject reference"
public class Node : MonoBehaviour
{
public List<Node> graph;
}
you cant use managed types inside burst jobs, dynamic buffers are more or less the equivalent as a list that exists on an entity
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/dynamic_buffers.html
but if you dont need burst/job and simply want to use that as is you can store references inside of class IComponentData, or add that Node as a hybrid component to your entity
well you see my whole problem comes from that....
This DOST gives way too many options and ways
And none of it is straight forward
And the whole conversion workflow just adds extra confusin
as i can't even actually interact with the stuff i'm making
so do you just want to access that list as a regular monobehaviour component without any data speedup or do you want some sort of speed increase from jobs and burst?
also you can just use jobs and burst outside of ecs, as I dont know if you are even using entities
Well this is gonna be a pedestrian system with many nodes... so i was thinking why not give the DOTS stuff a try
the plan is to use ECS
my idea was to add the "NodeLink" component for each link it as....
but i think i can't do that
i dont know what nodelink is, first thing you should familiarize yourself with reference types and value types, as ideally you should be avoiding any reference types where you want performance.
if you havent already read it, this is a good primer on using dots https://learn.unity.com/course/dots-best-practices
Yeah sorry forgot to send the whole code
And i do know what ref and value types are (I used c# for a long time and also come from cpp.... so I get the whole idea for this)
ok my assumption here is WaypointLink should be a dynamic buffer so WaypointLink : IBufferElementData not IComponentData
add the buffer via var buffer = DstEntityManager.AddBuffer<WaypointLink>(entity);
inside the loop buffer.Add(new WaypointLink());
okay... and how do I do the link?
what do you mean?
well.... Entity is a struct.... so as far as i understand it it is a value type... so i can't do public Entity as that will be just a copy of the data
Soo like what can i use to ref an entity?
well you will have to figure out a way of updating that buffer any time the entities are removed
Sooo what i store the fully copy and make sure i don't delete the real ones?
(or iterate and remove if i do)
I see that the entity has a GUID component... so maybe i could use that as the ref point
there are systemstate components that give you a chance to do cleanup work but I think this is a case of just geting used to working mostly without reference types
i mean some for of references are needed if i want to do path finding in my graph....
you could try storing a pointer or an index to know which element you need from the DynamicBuffer
but yeah as thelebaron said, you need to do cleanup work and make sure the data is all valid in case of removals/shifting/move
hmmm okay So public Entity link; it is
Wondering if anyone has done a click and drag on a prefab entity
Packages\com.unity.entities@0.17.0-preview.41\Unity.Entities\ApiCompatibilityLevelTest.cs(2,10): warning CS1030: #warning: 'Project is expected to have API Compatibility Level set to .NET Standard 2.0'
I see this warning and... Is it normal that project with entities expected to have 2.0 comp level???
I'm not master of dots docs but i have never seen any notice about comp level
That is indeed normal
Ok, thank you. Just trying to fix terrible Cannot find TypeIndex for type hash 8075963649556656072 error in build so i'm now looking at any message in console because i feel like i have already tried everything
Are you perhaps using a generic typed component?
No
I have even found what type is 8075963649556656072 and it is UnityEngine.Rendering.SortingGroup
so it is even not my component π
why is the enity GUID 2 ulongs?
while there is a GUID from unity?
what is the best way to store a link to an other Enity that is in a different sub scene?
I dont think entities inside different subscenes are supposed to know each other
I'm thinking that maybe i would be better of not using enities for my nav graph....
but idk what options i have to save extra data for scenes....
i use shared components to index into subscenes
my subscene has an entity with a shared component on it, i load the subscene, then go to that entity then everything I need I can get to from that entity
so I can just link that entity to something when I load the subscene so I dont have to look it up repeatedly
the idea is that this graph would have data for pedestrian walking, stuff like lights and destinations (shops / workplaces etc..) and than i would find a path in that graph with destinations
can you give a bit more detail on this?
As far as i understand you have a special entity in each sub scene that you can find with ease
and that entity links to the rest?
yup exactly
when you query for an entity, you can specify the value for a shared component. Then it does a hash lookup to find it, instead of looping through every entity of that architype
looping would be faster tho if you have very few subscenes loaded at a time
then your special entity would just have a tag component instead of a shared component
and what would i store for the reference?
this the the code i have currently:
as you can see my problem is what to store in the component for the ref...
not even sure if storing this graph in entities is the best way to do it...
but not sure what other options i have for storing data for scenes
well... this is even trickier... as it seams that not even the normal GO inspector lets me ref a node in an other scene
Hmm. this is strange. I have a companion link setup, but for some reason, the transform doesn't get updated.
I can confirm that the entity's TRS get's updated when I trigger it, but the Companion GO's transform does nothing. I even did conversionSystem.AddHybridComponent(transform); just in case, and I confirm that CompanionLink exists, the referenced components are correct. But there is no transform syncing going on. The entity even gets the Companion Game Object Update Transform System State tag, which I looked at the code, seems pretty straight forward, but nothing is being updated with the entity's transformation.
if anyone had interest in zulfa juniadi's pathfinding repo updated to the latest dots packages, just posted my take on it https://forum.unity.com/threads/dots-pathfinding-zulfas-repo-updated-to-0-17.1133773/
https://github.com/thelebaron/unity-ecs-navmesh
More technical details on use/issues are in the readme.
I've been wanting to update Zulfa Juniadi's...
How can I detect if a gameobject is in a SubScene? I am writing an Authoring component that has IConvertGameObjectToEntity. And I want it to be able to be attached to objects inside sub scenes and outside subscenes. In the awake function I want to detect if it isn't in sub scene and then do some extra logic with it.
I tried: _inSubScene = GetComponentInParent<Unity.Scenes.SubScene>() != null but it keeps returning false for all objects regardless.
Is there a utility I can use?
Little horror story with happy end in 10 messages https://forum.unity.com/threads/use-dots-with-multiplayer.1132831/#post-7283374
Has there been any news on the DOTS ecs lately?
only compatibility apocalypse
So the usual
the latest thing
Lol 13 days to catch up
to not catch up
not that big actually if consider how big is this thread and how long we have literally months of silence
Honestly if I managed Public Relations like that with my clients, I would have become quickly jobless
Iβm sure it was well intended, quickly followed by someone tapping them on the shoulder and saying itβs better they leave it to official messaging.
Is there anyway to filter queries by componentdata value in an entity query? I know there are for shared components, but what if you just want to query a group of entities with a specific component value
Sooo if i'm understanding how ECS is supposed to be used. In my case when i want to make a pedestrian npc system:
I would make the following systems:
- To move towards the next position, this would use a
TargetComponentthat has the target pos inside it - Make one that chooses a new target when it is close enough to the current target
And i guess i could split the first one down even more with making one that only moves in a direction and one that sets the direction to point to the target?
Also what is the difference between Vector3 and float3?
You can write simple filtering job
ok that's what I suspected, just didn't know if there was an easy filter option like with sharedcomponents
thanks
but the really bad thing. that after that you can't use lambda syntax
yeah technically all the querys and getting the data(.ToComponentdataArray etc) are jobs themselves
Also you can use tag components to separate entities. And this will be filtering by memory
an i right that i can't have a scene view like free camera for moving in a dots world?
Sure you can? I'm not fully sure what you mean though.
Wel when i press start than the scene view is not updating.... and i can only see what is up in the game view
Have you created your own rendering system?
i mean i did import the hybrid renderer for the ECS subscenes to render
but no render code that i wrote...
That seems odd. Do you notice any other strange behavior?
this is the first time using it..... so everything is strange? 
because i'm not sure how it should work i don't know what is a bug and what is just not finished yet
Yeah understandable. But it renders just fine in the Game View?
Yeah and my test moves in the game view
but in the scene view it does not move and stays in the original place
Ok, can your screencap the components attached to your entity?
If you have both the Game View and Scene View open at the same time, does it work then?
Seems very odd. Maybe it's a 2021 thing? They officially don't support that engine version for ECS (yet)
Well than i guess i will give them a bug report... does ECS use the built in bug reporter or GH issues?
It'll probably just get closed since 2021 is not supported. But I guess the built in one.
Ahhh so the cutting edge new technology only works on a old version.... Nice
I i do not understand how can there be projects shipping with ECS if the dam thing is still in experimental/preview
Well i really hope that they are moving away from the Conversion workflow. The new editor window gives me hope that maybe we might get direct editor access to the ECS scenes
most likely by simply picking a single unity version and not updating
being on betas does not correlate with being able to ship a product
either you want to experiment with the latest features
or you want to build off a stable platform
Well than it might just be a difference in how i understand beta stuff
cause this suggests that there are production ready versions of ECS while never getting a release that didn't have the -beta tag
Soo i guess some people stay on a single version and fix / work around it to make it sable
I'm really hopeful and see the potential in what ECS can bring to the table
I'm just concerned that Unity is not willing to make a it a huge change and with that it will be a half measure and confusing thing
as it is quite confusing now.... and not the programming principles but the implementation of it
they are only doubling down on conversion, but the new editor may give you the ability to edit entities after they get converted
Can someone explain to me what are the cons of converting my projectile system (not using rigidbodies) to DOTS?
idk .... i really don't like the conversion workflow... i get it, but still not being able to see/edit the actual runtime data is bad
i think it gives you too much room for error, at least the current implementation of it
Hmm I'm really perplexed on what to do with my project....
I think I'm going to use MBs for now and transition later....
I think i can still use the Jobs and similar systems, just not the ECS package.
I could "remake" it and basically make my own ECS..... really not sure what to do
By "reamke" i mean i could make a similar system where I would use Native Arrays (I think that is what they are called) and store my components and make some simple inspector for them...... This would mean that I could use it for nodes and similar non visual things
For the rest I could make a data and visual separation where the complex logic for where to go and path finding is in the ecs part and the rest is GO based and they have a 1:1 link
Well if Unity's ECS is a deal breaker, there are other ECS frameworks like Svelto's, Entitas, LeoECS which you can use as alternatives (they may not be archetype chunk based)
DISCLAMER:
I know this is stupid, but i like to learn these more complex systems by making. None of this is supposed to be for production, or even necessarily a playable game
Unity ECS is deal breaker because i want to use 2021.2b1
And as per this post it is not supposed to work on that
Well i guess i will give my thing a try....
The ECS sub scene stuff showed me that I should be able to do this quite easily...
Yea could possibly work as long as you do GetPrimaryEntity(component) to link entities together
nah that is not what i meant.... At this point i could make a authoring experience for my own entity stuff
what that thing showed me is that i can add a """subscene""" where the items are entities directly
@glossy saffron if your projectiles are hitting things that are gameobjects, well you will need to have a way to translate your ecs data to gameobject data, the result could be messy. thats actually how I ended up going full ecs for my fps, and tbh having some regrets given the current pace of development.
What if im using Physics.linecast for it?
and by the sounds of it, ECS isnt really worth it 
you would use raycastcommand to batch your projectile raycasts, not sure what you mean by use dots though, you want the rendering, transform and raycasting to be dots or just raycasting or just transform/rendering?
i meant using ECS

was confused what was exactly the difference between dots/ecs/burst when asking this
https://forum.unity.com/threads/notice-on-dots-compatibility-with-unity-2021-1.1091800/
Soo this talks about in Scenario A that non entities packages are working and stuff....
What is and what is not entities based?
you should just make a simple test of having an ecs entity move and raycast to a physx gameobject. that will give you an idea of the complexity required to do what you want. from this tidbit of "ECS", if you dont mean raycastcommand, you are essentially wanting to build a bridge between Unity physics and Physx which there is none(gotta make it yourself). not impossible but maybe more hassle than its worth
@queen crest it means if you are primarily using jobs and burst(and possibly collections), but no reliance on anything ecs
yeah im just going to wait for later gens of this tech
it seems too much of a pain to implement now
Is there any way to know what packages fall into that category?
cause for example i can't see Collections Package in the package managger
uh yeah jobs burst and collections(and dspgraph) are not entities, just about every other package thats mentioned in terms of dots is entities based
Are Unity.Mathematics calls mapped to hardware SIMD only on Burst compilation or even without it (eg in MonoBehavior.Update)?
I know how to instantiate prefabs (and how to register them during convert). But how do I instantiate a hybrid prefab? I have an object that I made that is linked via Companion link. Iβm going to turn that object into a prefab, how do I tell ECS to hybrid it during instantiating at runtime?
Only on burst compilation, even then its not for sure, you need to use float4 in some cases for example, even when a float3 would do.
It will do it automatically so you don't need to worry about that. At least it does it for me when I spawn entities that have VFXGraph game objects companions
I have a basic stupid off topic question but If I have a method that returns a type like int,float3 or whatever is there no way for it to to return a null value or something like that
not unless you use a nullable operator, or just return a bool and have an out parameter to read the int/float variants
that's what I figured, thanks, maybe I'll use the out param then
I did think I might try setting a single float3 value as the null value like 0,0,0 is equal to an null value, but I can't be entirely sure that wouldn't come up legitimately
Maybe I explained wrong. It does instantiate the converted prefab, but it isnβt hybrid, it comes with all its children converted and what I want is just an entity that ties to the prefab with transform copy to game object pattern.
Sooo I think this is the best place to ask this....
Last time I decided to try and make a custom ECS using all the other dots goodness. (Burst, collections etc). The reason? Well originally cause 2021.2 isn't supported, but now more to just learn and improve myself. This is NOT meant to be used in any project or release or anything. Just to see what I can learn from it.
Where I'm stuck now is the allocation, I spent the last day going through what the official ECS does for allocation. I think I have a somewhat usable understanding of what it is doing for allocation.
I did write an allocator for my own game engine (written in cpp) before and I was thinking I could maybe use that logic/pattern for my new c# experiment.
But I found that c# really doesn't want to let me do my pointer magic.
If anybody would be willing to help me learn about this that would be really apreciated.
The old cpp code:
https://github.com/dpeter99/ShadowEngine/blob/d3d12/ShadowEngine/src/EntitySystem/EntityContainer.h
What I tried to do:
https://github.com/dpeter99/NECS/blob/main/src/Runtime/Allocator.cs
Type in C# is a managed class, so you're going to have to Marshal the Element struct so you can grab a ptr to Element
The way I remember how entities does it is via TypeIndex so they map type into an index and store into a lookup table with the necessary metadata
Also i did find this thing: https://blog.adamfurmanek.pl/2016/06/25/custom-memory-allocation-in-c-part-4/
But it feels like it is abusing the undelying memory layout that i don't think i can use cause il2cpp / burst / unity might have a different layout
Huh this is kind of interesting
the main magic of that seams to be in:
Marshal.WriteInt32((IntPtr)(address), 0);
Marshal.WriteInt32((IntPtr)(address + 1*sizeof(int)), (int)typeHandle);
Yea - maybe worth a try in il2 π€
as far as i understand it what it does is basically it has a correctly sized meory
than it constructs manually a ref to that
and uses that ref as the object
@queen crest you don't need to use Marshal for anything, as long as you're only using structs you can directly use ptr's for everything
what is the part you're stuck on?
well for my idea to work i would need a reliable way to convert from / to ptrs and structs
and also i'm a bit confused how I handle structs without copying them
if you know the memory address and what struct type it is you can just cast it
to and from ptr's
As long as the data in the struct is blittable
ah yea
also whenever i try to use cast to a pointer it complains that I can't do that cause it is a managed object
i tend to add where T : unmanaged if you're working with T structs
ahh that is the magic i was missing... (tho that removes the use of strings i think)
yea it does
you can build your own NativeString using structs, but from what i noticed after doing that is for 99% of things to interact with it you have to convert back to a managed string at some point so isn't really worth the effort
tho unity has some nativestring types with fixed sizes that you could use if you can make assumptions about the max length
you can do that with refs or by writing to the memory address directly
Stack only structs
So you can't store the struct on the heap
that is... not useful for this i think
you probably don't want your element to be a class or to use managed arrays, cause then u can't use burst.
yeah
this might be interesting for you https://github.com/jeffvella/UnityEcsEvents/blob/master/UnityEcsEvents/Runtime/EntityEventSystem.cs
Sooo if i do this, the alloc should give back the data in the element right?
or maybe more precisely how should I do the signature for the allocation function
so that it can return a ref to the data
yeah looks like data should be a reference to the data inside the array
but since element is a class and your array is managed it wouldnt need to be ref
let me update the code on gh
should be up to date now
i used the suggested "unmanaged"
looks like it should work
sidenote do you have some sort of constraint where you can't use nativearrays? if not those managed arrays will prob prevent you from using burst
well....
my problem with managed arrays was that i couldn't get the start pointer
and for me to know witch element to free up i needed that
the problem with managed? or the problem with native?
native arrays
WHY is it soo hidden...
i spent 2 days....
and that was the solution
that one function

Soo I hammered it a bit more...
https://github.com/dpeter99/NECS/blob/main/src/Runtime/Allocator.cs
https://github.com/dpeter99/NECS/blob/main/src/Tests/MemoryChunkTests.cs
But i think what i get back is still somehow not correct
As that test fails... even tho it tells me that it is the same mem address
(found the poblem... it wasn't a union)
I don't suppose anyone knows why if it put Enabled = false; at the beginning of the Onupdate() in a system that Onupdate only runs once, whereas if I put it an the bottom below all the code then it doesn't work, the Onupdate runs constantly? π
@hollow sorrel Sorry for the ping, do you have any idea how unity ecs links the entities and components?
Second question is there any way to have NativeArray/NativeList where i can set a specific element. Cause when i'm using NativeList I can't set a position unless i have added enough items even tho i gave it a starting size
@queen crest so could be missing something but afaik
unity has one big array containing some metadata about what chunk each entity lives in and what its index in the chunk is
each chunk contains an archetype describing what components are in the chunk, so if you want to get a component it checks the offset of that component in that archetype, and then uses the entity index to get where that component is in the chunk
if you're making your own ecs you should decide whether you want an archetype based ecs like unity or sparse set based (maybe there's other types too but dunno)
yeah i think i know what/how i want to do it
yea dunno if NativeList will let you do that since it's meant to be treated only as big as its count (even if its real size is bigger)
you'd prob have to do it with NativeArray and resize yourself if it's too small
Is there a util for resizing?
If you set the capacity of the NativeList it will do resizing
var nativeList = new NativeList(50, some_allocator);
nativeList.Capacity = 10;
yea but if your capacity is 10 but you only add 1 element so index 0 is set to something, count = 1
it won't let you set index 8 even tho it exists, because then would count be 2? but that would imply index 1 is set when it is not
so would count be 9? but that implies you suddenly added 1-8 as well even tho you only wanted to set 8
really? doing something like nativeList[8] = some_value would throw an error or something? π
yes
Oh it calls CheckIndexInRange(index, m_ListData->Length)
I guess if you want to access the internals of NativeList, maybe you can do something like (T*)(nativeList.m_ListData->Ptr)[i] = some_value π€
yes but that won't update the data of how many there are
so if i were to add a new one it would add it to the 0th element
so you just need to keep track of an offset to write to then?
Well i think i got something to work....
But it is a bit janky, iterators/Enumerators always mess with me.... so if any of you have the free time to give it a look / give feedback I would be really thankful
https://github.com/dpeter99/NECS/tree/main/src
I don't think I will focus too much on memory optimization as I don't really have the know how or the time. And rater focus on the in editor authoring experience.
what are you goals with this?
Sorry for the late response. My goal for this is to learn.
As for what I would like to achieve.... Well I would like to be able to directly author Entities in the world no conversation workflow. So something similar to what the DOTS Editor has but it being and actual editor. And also as a small experiment to see how fast a naΓ―ve ECS system can be using the Burst compiler.
But the main goal is to make a proof of concept authoring experience. Also not sure if I would make a renderer for it... My first idea is to allow some Entities to have a linked GO that has the same position and stuff. So the GO is only there for rendering.
This would allow me to do special code for how they are linked so maybe even use skinned mesh and similar
cool, that's helpful to give useful feedback, and i totally get the projects to learn and test how far with things you can go, i do stuff like that all the time for fun. A couple things come to mind.
I'm seeing a lot of classes, need to be careful with that and id suggest maybe trying to have it run in burst sooner than you'd planned because you really can't do anything in burst with managed code, maybe call a utility method but that's about it, classes can't be passed around, created, etc I think you'll find that everything has to be converted into a struct.
If you're interested in seeing how fast it can go, you might want to look at unmanaged arrays (nativeList unsafelist etc) as your storage whenever possible because i think linkedlists are going to be slow in comparison, following pointers all the time jumps around and you won't get cache hits compared to being able to just slam a 128 block in and do the same operation 4x with SIMD etc. That's why UECS is structured the way it is.
You've written a crap load of code already and picked up a lot of new stuff seems like, it's pretty impressive.
Well thanks for that last part.
Yes I know I still have a lot of classes... It is because first I wanted it to compile and also have a constructor to use for init...
Most of this code is a scarily 1:1 copy of my code for my own engine... But yes c#'s pointers and all the unsafe stuff is new to me. I think the only thing that is managed and will need to find a way around is the allocator map that maps them to the type.....
I could use the same thing I did in my engine and make up a ID for each type. Most of the other places should be easy to swap out for native arrays..
Anyone have any tips for efficiency turning on and off rendering an entity
Add and removing a DisableRender component is a structural change and too slow for my needs
Well, you could either use your own instance-based rendering system (like https://forum.unity.com/threads/200k-dynamic-animated-sprites-at-80fps.695809/), or you could use pooling to reduce the amount of structural changes (instead of disabling renderables, you reposition them for what needs rendering each frame)
i set the scale to zero for a few minor things when I dont want to do a structural change
If you're using instanced rendering, pass along a per-instance flag to the shader and early out if it's enabled. π
Setting scale to 0 is a neat trick, but may eat more GPU bandwidth than necessary - depends on the situation. Profile and see what's faster!
@naive ice any examples how to pass a per instance flag with shader graph and hybrid renderer
hey has anyone here been using the double3 type
I'm benchmarking it against some other available double types
and I'm getting significantly worse results using double3
Comparing SharpDx's Vector3D
and DoubleMathematics Vector3D
200k vector adds for both of those is ~0.075ms
and using unity math double3
it's 0.4ms
tests were done via a burst compiled job with a for loop doing 100k iterations of 2 adds