#archived-dots
1 messages ยท Page 185 of 1
Tags to implement a statemachine ? So you mean... i simply gonna mark the entity with components ?
yes
Like Entity{ ChasePlayerIfNearby } ? Well... in this case its easier than expected
And is this the common approach ? Or are there other ones we are missing out ? ^^
it's the common approach but there is other ways too
Thanks, both of you ! Im gonna look at that one ^^
I just wonder how we could keep it a bit more flexible... lets say we have two different entities, one is chasing the player in a straight line... and the other one tries to intercept the players route. Would we simply have two Entity{ ChaseWhenPlayerNearby, ChaseStraight }, Entity { ChaseWhenPlayerNearby, Intercept } and two systems which process System{ ChaseStraight, Chasing }, System{ Intercept, Chasing } ? This sounds like a lot of work for the different variatons, but i guess its the same with class based state machines
like you said, that's how a state machine works. you have to code all the possible different states yourself
you can use flag enums for increasing your permutations but... I don't much like state machines. I also think that having 'tags' as states (as with flags) you've gotta be really careful because you don't have a set of explicitly declared states. You have many permutations that are non-explicit. i.e. you define ChaseWhenPlayerNearby tag but how should this 'state' behave if there is also a FleeWhenPlayerNearby tag too - tags aren't mutually exclusive so you lose one of the main benefits of state machines imo. Caveat: I think I'm unusual in this respect - others seem to not find them so objectionable.
@stone osprey you are getting into somewhat uncharted waters for best practises and performance in the context of unity's ecs so imo experiment with what works best for you ๐
@amber flicker Well that sounds reasonable... We would need to define extra rules, which require extra components like Entity{ Chase, Flee, FleeFirst }... which sounds kinda strange.... or as you said solving this with enums like Entity{ WhenPlayerNearby{ enum : Chase, Flee }}... but both of those solutions are weird.
for the tagging, I would make sure only 1 possible of those is possible at a time. keeping it simple
That would solve the problem, otherwhise we could simply define rules like : "No fleeing when chasing cmp is attached"
But its actually pretty hard to decide between those both variants... Either a fully driven state system by tag components or some sort of state machine that relies on one component StateMachine{ enum, next, previous, ... }... the tag based state machine would require a lot of different systems, but is probably more efficient and more flexible
I don't think there are any magic answers unfortunately. Last couple of thoughts though - 1) I think that example repo is quite clean and easy to understand, 2) I'm a fan of coding what you need and nothing more. I'd try to resist the temptation to code something 'general' (esp with dod). If you know every combination of state you will need up-front, that's a different story and that's something useful to architect around.
@amber flicker Thanks for your help ๐ Im รกlready looking at that repo for several minutes... reading their describtion e.g. I also heard about "Behavior trees", some sort of alternative to state machines... which also sound kinda interessting
So behaviour trees look a lot cooler than statemachines and could scale pretty well... Now i only need to figure out how to implement these into the ecs, i have read that its not a good idea to use tags in this case, because that gets "overwhelming" pretty fast
You can take a look at this: https://github.com/quabug/EntitiesBT
you can't use Burst with it, but could give you insight on the design
otherwise stick a plain pointer to a struct and construct a Behavior Tree from those structs + put it in a component data if you want so you can run it
Hello, iam new to Unity ECS System so my question, i have the following problem, ```csharp
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;
[GenerateAuthoringComponent]
public struct UnitData : IComponentData
{
public int objectId;
public float speed;
public float3 movePosition;
public int health;
public float3 attackPosition;
public Entity healthbar;
}
which is attached to a prefab gameobject, which i intantiate like thiscsharp
private void InstantiateEntity(float3 position)
{
Entity myEntity = entityManager.Instantiate(entityPrefab);
entityManager.AddComponentData(myEntity, new UnitData
{
objectId = objSeed,
attackPosition = new float3(5, 1, 5),
speed = 2,
});
// entities.Add(myEntity);
}``` now i try to find this entity by a socket.on Event to manipulate the attackPosition, but iam not sure how i can find a Entity by the ```objectId```
I would be happy if someone could help me with a tip, to make the start with ecs easier
i think it is something like csharp GetEntityQuery( typeof(UnitData) ); but how i can find the one Entity with the specific objectid
there's definitely a way to do both of those things
for the first i think you can go by the networkidcomponent
as in query for that/run a foreach
and as for the second i don't remember how but i don't remember the exact method
i have a question about burst
is it an all-or-nothing thing
so does a job/function need to be completely burst compatable to be used with burst?
so does a job/function need to be completely burst compatable to be used with burst?
@shy pilot yes
it does AOT compilation each time you go back to the editor..
ah ok, thanks
hi, what is the corresponding function in Unity.Mathematics for Mathf.FloorToInt ?
math.floor cast to int most likely - I don't remember seeing an explicit api for flooring to int
@coarse turtle ah ok, thanks. Then it should work like that: int someInt = (int)math.floor(someFloat) ?
when doing Entities.ForEach, is it possible to process 4 of them at a time instead of just 1?
is int someInt = (int)someFloat not better?
@slim nebula Not really, because if someFloat is i.e. -2.3 then (int)someFloat will return -2, but I need it to be -3
And WOW for NoiseGeneration the JobSystem ist blazing fast!!
with regular for loop for a 17x17x17 grid (17 contains the 0 of the neighbours, easier that way) and 2 octaves (simply getting the noise for coordinates 1 time with one scale and another time with other scale and then adding both values) of simplex noise, it takes 288ms to generate new noise when reloading 3x3 areas without Jobs and about 12 ms with Jobs and [BurstCompile] That's crazy! Factor 24 โผ๏ธ
๐ฎ ๐ฒ just WOW - ๐
without burst about 76ms
yeah, regular c# is just very very slow. if you'd take that same code in c++, you'd have that kind of performance by default
@odd ridge yes, but my code for mesh creation did not speed up nearly that much. But on the other side the mesh one is regular IJob, called from each copy of the GameObject, it only speeds up about factor 2,7 (only the jobs, not setting the mesh or setting colliders)
but for the noise generation, just wow!!
nice
@coarse turtle ah ok, thanks. Then it should work like that:
int someInt = (int)math.floor(someFloat)?
@steady blaze Just saw the msg - but yes tht's how it would work
does someone know why the Burst inspector isn't showing my ecs code?
I believe burst inspector shows Assembly code
yes, I want to see the assembly code for my code
from 2021.1.0a4 release notes:
* Burst: Burst enters RC phase.
* Burst: Eager-compilation is now cancelled when script compilation starts, to prevent spurious errors related to recompiled assemblies.
* Burst: Open-generic static methods are not supported by Burst, but they were previously visible in Burst InspectorBurst: they are now hidden.
I actually thought Burst was "released" long time ago (when non-preview 1.0 came out)
this was also on previous notes: md Burst: Bursted DOTS Runtime Jobs are now decorated with [NativePInvokeCallback] instead of [MonoPInvokeCallback] which could generate callback wrappers which could cause native code to inadvertently interop with the managed VM.
how can I retrieve an ecs component array as a NativeArray?
@odd ridge https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/ecs_entity_query.html
woah waoh. RC in 2021? :wow:
thanks, I'm trying to use simd with ecs code. watching a Unity tutorial on simd says to use float4s to compute 4 at a time, but I'm confused as to how I can convert my ecs code to use float4s, because ecs code seems to work with only 1 at a time
I don't know a lot about it but I think the idea is you just make sure your for loops are linear and don't have branches. Burst should be able to optimize a lot just from that.
As far as I understand it at least
You shouldn't need to manually force your data into actual float4s
I think as Sark says, if you get everything "correct" burst will do auto-vectorisation for you. However, if you want the best chance I think you need to use e.g. IJobChunk where you can iterate 4 in a chunk at a time.
is there such a thing as Entities.ForChunk() ? that would be pretty handy
sadly not
it was aired on the forums - Joachim said it was among the things they were considering.. but that was like a year ago and no word of anything like it since
I see
my guess is there's a horrible amount of codegen code to support with the lambdas and doing ForChunk or something would double it - meaning they have to move a lot slower and it takes longer to maintain etc. I could imagine it surfacing in a couple of years. Writing an IJobChunk is a quick way to be reminded of how useful the lambdas are ๐
hmm weren't they making an effort to use c# generators also ๐ค
might also be why there's no word of IJobChunk lambdas
yea very likely too - I think I read that's mostly done now?
(could well be wrong)
yea - guessing there's still no dots blog too right? ๐
i haven't been checking the forums/blogs much lately
๐คฃ ๐คฃ ๐คฃ dots blog post ๐คฃ ๐คฃ ๐คฃ
๐
i dont expect one this year tbh
๐ญ
meanwhile, I still keep getting Burst compiling ~550 methods on every startup with latest dots packages + 2021.1 alpha
does it do that on older unity versions?
while it's under one minute, it's an annoyance I could do without ๐
i dont recall it happening unless its happening without it being visible
ah it does it on background task
like how it always finds something new to "import" on start
it doesn't pop it up but you can see the progress bar on the bottom right in the editor and can expand it there
heh
I am trying to use CalculateDistance in ForEach but I am getting some weird errors:
"The previously scheduled job TargetingSystem:<>c__DisplayClass_OnUpdate_LambdaJob0 reads from the Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter]"
Anybody has an idea whats the problem?
I'm trying to use an EntityCommandBuffer to add/remove components, but it's causing pretty bad stutters with huge spikes in the main thread. is there a faster way to enable/disable components?
You can add a bool Enabled flag to your component and check it before you process it
Or use batch operations via entity queries
physics samples updated today at https://github.com/Unity-Technologies/EntityComponentSystemSamples
I want to do something like this: var type = typeof(Component); Entities.WithAll(type) but it won't let me ;p
is it possible to name a lambda so I can reuse it in many systems like I would call a function?
to reuse logic between systems, either create static methods or use IJobChunks instead
I looked at IJobChunk but there's so much code that I wished there would be an easier way
do you know of a way to disable a system from running? I want to use a system just as a base to inherit from
what makes me wonder a little:
If have the method for noise-generation of that certain index outside of the job and call it from within the job & burstcompile it is the same speed advantage and you can use Mathf there.
maybe it is a very slight difference, if you use math or Mathf, but nothing I can measure, of course mainly because it is just used for rounding one value
but yeah, it seems you can circumvent some limitations when calling methods from within a job (without losing performance)
right now the Execute is quite short ```cs
public void Execute(int index)
{
map[index] = GetVoxelValue(index, size, worldPos, scale, amplitude);
}
I want to reuse an Entities.ForEach lambda, but with different component conditions
@odd ridge sorry, did not learn to use ECS yet, only Jobs/Mathematics/Burst so far
so my issue is I have 2 systems which very much use the same code, except each system require a different component tag
duplicating the whole thing would be the easiest way, but would get tedious having to copy my changes over at 2 places everytime
IJobForEach does what I want to do but it got removed
Why not just create a struct like so:
struct SomeJobStruct {
// Fill your struct with data like ComponentDataFromEntity<T> and such
public void Execute(ref T1 c1, in T2 c2) {
// Do your lambda work here
}
}
var jobToExecute = new SomeJobStruct { ... };
Entities.WithAll<SomeTag>().ForEach((...) => {
jobToExecute.Execute(...);
});
otherwise IJobChunk/static functions for reused functionality - but if the two systems kind of run similar then IJobChunk sounds like the right approach - you're just executing a different logic per chunk
yes, I wanted to avoid doing that to not having to copy paste the whole Entities.ForEach signature everytime
IJobChunk would work but it's so much more comlicated to use, lots of boilerplate
so... just to mention it... you can use GetComponent to switch logic within the foreach - yes it is a random access (per entity rather than per chunk) that you want to avoid in your hot path but it's also not 'slow'
sometimes that's worth doing while your in the early stages - then you can always optimise it later with an IJobChunk if needed
I want to duplicate a system, but 1 system has an extra tag to it
I would want to inherit the first system, and then add the extra tag on top
there is no inheritance and you can't re-use a foreach signature - but it is very easy to check for a tag within the lambda
if(HasComponent<OtherTag>(e))
{ // do stuff }
else { // do other stuff }
});```
any way I can do something like this? var tagType = typeof(SomeTag); Entities.WithAll(tagType).ForEach
Well you can create queries in that way and operate over them but be careful if you're going down the route of generics - a lot appears to work in editor but it actually doesn't work in a build. The rules are pretty complicated on that.
if I use queries I can't use the lambdas anymore right?
such as EntityQuery q = ...; q.ForEach(){}.Schedule();
no afaik - the one that's being generated would clash with the one you'd be passing - can't see how that would work.
Additional note - if you're not going to heed above advice of either
- Using HasComponent in lambda
- Separating out body to a struct or static methods
- or just writing an IJobChunk
Then I'd strongly recommend writing an IJobChunk and understanding what's going on. It's what things get compiled to and underlies all the magic stuff. The restrictions will also then hopefully make more sense.
do you know why IJobForEach is obsolete? there's so much boilerplate with IJobChunk if I just want to test something quick
do you know why IJobForEach is obsolete? there's so much boilerplate with IJobChunk if I just want to test something quick
@odd ridge https://forum.unity.com/threads/feedback-request-ijobentity.888121/
ah I see, thanks!
why is there a OnCreate() method for systems? why not just use the constructor?
probably to avoid the mistake of forgetting to call the base constructor, as there is stuff like World that needs to be populated before OnCreate
why do unity physics bodies go through each other when converting to entity with conversion mode set to "convert and inject game object"?
nvm i figured it out
nvm another related question - why do physics bodies ignore childed physics shapes when conversion mode is "convert and inject game object" but not when it's "convert and destroy"?
thing is, im trying to use hybrid ecs rn (as in, physics calculations are calculated with unity/havok physics and then transforms are copied over to gameobjects) because of me having problems with hybrid renderer. right now i have this hierarchy:
- Car (has PhysicsBody, CopyTransformToGameObjectComponent (an authoring component that adds CopyTransformToGameObject to the entity) and ConvertToEntity)
- BodyAndCollision (has PhysicsShape and MeshRenderer)
- WheelMesh (multiple, has MeshRenderer)
- Plane (has PhysicsBody, PhysicsShape, MeshRenderer and ConvertToEntity)
when i run the scene, the Car falls through the Plane. what am i doing wrong?
also i insist on using unity/havok physics because the raycasting there is much faster, which is essential for my game
if you use inject, nothing outside of the injected entity is converted
you will need to manually convert anything if it is a child using inject
is it recommended practice to use scriptable objects for ECS configuration data?
right now I'm using simple hardcoded data structures, but I can't edit it in the editor
@odd ridge you can use SO's and then convert it to blobassets
Anyone know a good pattern for splitting code into 2 sides/teams in ECS? I have several systems that I split for optimization such as searching for enemy targets.
I've tried with Side1 and Side2 components, but because I can't use Entities.ForEach in generic functions, I end up with a lot of duplicated code.
I've also tried a Side SharedComponentData, but have run into a couple of roadblocks with that too (such as not being able to use it in a burst job, and only being able to do 1 WithSharedComponentFilter)
I did a test of it using empty Tags, but I used IJobChunks, so it was easy to not duplicate code, as I only had to create 2 similar EntityQueries
yeah, entities.ForEach just seems so much more elegant :/
but these little catches keep getting me
@wet epoch I was trying to do the same thing, right now it's impossible with Entities.ForEach
only with Job structs
ok, thanks
is it possible to change the Text of a TextMesh with ECS -->
yes
should i attach the entity in a convert script then?
so my problem is, idk how to access the text variable
i have this, where myEntity is the Parent Capsule --->
an i wanne change the text to the globalUnitId Variable
any ideas @odd ridge sorry for tagging, i spent 8h to find a solution without a result ๐ฆ
@safe lintel i added a converttoentity to child objects, none of them get converted according to entity debugger
ok so what i did is set conversion method of the parent to Convert And Destroy and added the CopyTransformToGameObjectComponent to all meshes and set their conversion method to Convert And Inject Game Object
and it worked
but im not sure whether thats the best method
if you have inject on a parent, child with inject wont work, you need to do it manually
@red marsh TextMesh is not an ECS structure so you cannot access it from inside your jobs. this is how you access it EntityQuery query = GetEntityQuery(new ComponentType[] { typeof(TextMesh) }); NativeArray<Entity> entities = query.ToEntityArray(Allocator.TempJob); int i = 0; foreach (Entity entity in entities) { var textMesh = EntityManager.GetComponentObject<TextMesh>(entity); textMesh.text = i.ToString(); i++; } entities.Dispose();
you can just use ForEach
Entities.ForEach((Entity entity, TextMesh textMesh)=> {
textMesh.text = "potato";
}).Run();
You'd need WithoutBurst though
thank you very much, i will test it in view minutes
oh yeah that's much better
as long as you are not using generic system types, that will work
how do i add arrays to components?
i think it's using dynamicbuffers, but explanation online is a bit confusing
We're not going to be able to explain it better than https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/dynamic_buffers.html
If there's something specific about that page you don't understand we can help
so, i create a new component that inherits IBufferElementData and that will be like, a separate component on entities?
Yeah, it's acts exactly like IComponentData except you access it a little differently
so i have this
using System;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
[Serializable]
[GenerateAuthoringComponent]
public struct CarAxle : IBufferElementData
{
public int wheels;
}
it only lets me assign integers. how do i create a buffer that references entities?
Change int to an Entity
it no longer generates an authoring component with a list inside. is the only way to fix this write an authoring component myself?
Yes, you'd have to have a gameobject authoring component with a list of your gameobjects, then add their converted entities to your buffer during your CarAxle conversion
It's a bit complicated too. You have to make sure your wheel gameobjects get converted first, then access their entity with conversionSystem.GetPrimaryEntity
But as long as your wheel gameobjects are children of your CarAxle they will be converted first
Although now that I think about it if they are already child gameobjects then Unity will automatically generate the Parent components and Child buffer. So your wheels will be in the Child buffer on your CarAxle, assuming you're converting it in the normal way
hm, might as well just get the children of an object instead of using an array yeah
how do i access children with a ForEach? in Child[] children? because Child only has one entity in a value
oh nvm burst hinted me a bit
Good morning everyone.
I'm trying to wrap my head around DOTS.
Need to find a good entry point. Should I go with the Project Tiny samples?
My end goal is a rather complicated RTS. So, asking if Tiny is a good learning stepping stone, or would I be constrained to those web and mobile projects?
@vocal talon I would suggest the ecs samples first and then the physics samples.
Does anyone know how Visual Effects graph conversion works into dots? I see a heavy update coming from it when converting it. Is it using cpu if converted?
I suppose that would make sense if it is updating it in jobs and such.
@vocal talon If you're looking for something more guided after reading the docs, i've been doing this tutorial and i recommend it:
https://www.udemy.com/course/unitydotsfundamentals/
Does anyone know how Visual Effects graph conversion works into dots? I see a heavy update coming from it when converting it. Is it using cpu if converted?
@olive kite currently there's no conversion of vsgraph. you're probably looking at a hybrid-ed entity there, which imo, is quite heavy.
@deft stump oh okay, dang. good to know. For the HDRP features then it has a list of features for V2, so that just means it can hybrid them?
well i guess it's still the same renderer right, just not in gameobject hierarchy form
yeh i think it might be converted with hybrid renderer v2
(you need to add the preprocessor command to your project settings to enable it)
quick question, ping me for answers. I need Vector3.RotateTowards math equivalent
@foggy stream You can copy https://github.com/jamesjlinden/unity-decompiled/blob/master/UnityEngine/UnityEngine/Quaternion.cs#L354
Just remember the new math library uses radians instead of degrees
@zenith wyvern Oh, I meant the Vector3 RotateTowards. I can't find it here... https://github.com/jamesjlinden/unity-decompiled/blob/master/UnityEngine/UnityEngine/Vector3.cs#L371
Oh sorry, my mistake
i know it isn't really a dots question, but is there any alternative to Mathf.Approximately in Unity.Mathematics?
I dunno if there is but you could roll a better on on your own
I'm assuming it does something like the snippet here: https://docs.unity3d.com/ScriptReference/Mathf.Epsilon.html
@maiden delta
@vocal talon If you're looking for something more guided after reading the docs, i've been doing this tutorial and i recommend it:
https://www.udemy.com/course/unitydotsfundamentals/
@spiral stirrup Yeah. I actually bought this just prior to asking
Lets say theres a way to serialize single entities at some point... would you rather use a sql or nosql database for storing entities in a large amount ?
@deft stump Thanks ! Well thats true... im just not that sure about the component count... lets say each component is its own table and we have one table that stores the entity itself, that would require a join if we would want to select that entity. Too many joins do have a bad performance, furthermore theres a join limit of 64 in mysql :p
@stone osprey chunk = table
Entity as a primary index
and the rest are coloumns of components
@deft stump Well... i thought following tables : Entity{ id, index, version} Position{ id, x,y,z} and then if we wanna load entity with the id 5 for example we would need to join those : select * from entity inner join position where id = 5
@stone osprey well that's a lot of joins. my idea is just getting around that giant headache
biggest reason why I quit being the database guy
@deft stump Yes it is, thats because i have been looking for better solutions recently :/ So you would favor one big table ? Atleast it looks like you would have one table with position, rotation, scale embedded ^^ That would work great for transform stuff, but what if you had a player component ? A weapon component ? Ai components e.g. all of them wouldnt fit into one table
I actually dont like databases... i always have too much trouble with them. My server uses an ecs with hibernate and currently im struggling with multithreading the update operations
Can I somehow use Unity to write the backend and do the frontend mainly in html5? I know I can compile to webGL but I mean write some of the html/js frontendstuff myself? I mainly want to use the unity ecs with its multicore support as backend and do the frontend myself, since the game will be mostly simulation (heavy) in backend, and menus and light 2d in frontend
putting aside how unpleasant that sounds to me ๐ ... pretty sure webgl support doesn't include multi-threading? perhaps that's changed.
Are Unity Jobs runned preemptive? I mean, can a Unity Job be suspended in the middle of execution so another job take its place (or the main thread continue execution, for example, if in WebGL)?
pre-emptive? Jobs launch from the main thread when you call e.g. Schedule. You can't suspend them or something like that afaik. Not sure how that's relevant to webgl either.
When you call Schedule, a job gets queued. It will run whenever it wants to do it.
WebGL is single threaded, so all Unity Jobs actually run in the same thread. That is why I ask if they are preemptive. Otherwise a 3 second Unity Job will freeze the UI for that duration in WebGL
Also you can;t suspend a job in the middle of its run. It has to complete otherwise you're gonna get some lovely mem leaks with those native containers hanging around
I'm actually using managed objects inside unity jobs ๐. It's not the best practice but it works XD
how? :0
how? :0
@deft stump
struct Example : IJob
{
private GCHandle a_;
public Example(string a) => a_ = GCHandle.Alloc(a, GCHandleOption.Pinned);
public void Execute()
{
string a = (string)a_.Target;
// If you don't use the Burst Compiler you can do whatever you wanat!
string b = new string('q', 5); // allocate managed objects!!! (warning: super slow)
a_.Free();
}
}
oooooh.
if it's slow then I don't want to do it XD
You don't need to allocate objects inside the Unity Job
I mean... I could use C# async
They can be allocated before!
A lot of algorithms doesn't require allocation actually
Even more, you can use lock()s inside Unity Jobs
Hello, i have a problem, i try to to lock the rotation of healthbar that it always is in one direction but it doesnt work--->
i try to set a float4x4 to 0 but doesnt work
does someone have a solution for that
LocalToWorld is set in TransformSystemGroup when you have Position and/or Rotation component (or any other of the Tramsform-related components)
What you want is to either:
A. Set the Position and Rotation component values before TransformSystemGroup runs
B. Only if you really know what you are doing: remove position and rotation component and set the LocalToWorld matrix manually
@rancid geode problem is, the healthbar should always Rotate to the direction of camera like i did it in mono unity, but idk how i can handle this in ecs with the child object
I mean i can store the Rotation of the parent in the struct of the child then i can transform from local to World Rotation, but i hope there is a cleaner and easier solution
Or does someone have a good example to rotate the healthbar in direction of camere in ecs
How can I pass a managed object reference to a Unity Job in WebGL? (I'm not using the Burst Compiler, so I can do managed stuff inside jobs)
Normally, I would use a GCHandle or IntPtr to store the reference of the object, but in WebGL build this doesn't work (I get "ArgumentExcection: Object contains non-primitive or non-blittable data.")
if it's erroring because its not blittable that means you can't use managed stuff @lean raptor that would be my guess
that or its a bug
does anyone know if it's possible to add to a nativelist from an ijobparallelfor
Hi guys,I'm working on a new RPG project, need a really strong pathfinding system. wander dots or compute shader, which one will make the best use of GPU
@frigid quarry dots is cpu only just like monobehaviours, the difference is the performance boost granted by jobs and burst
if you really want to use the gpu
then you'll have to use a compute shader
but that's definitely not the purpose of a compute shader so i wouldn't reccomend that
so dots is the best choice overall
i'm pretty sure you can use the unity navmesh from jobs as well
there are definitely repositories for pathfinding in dots
i saw one that could handle i think 50,000 concurrent entities
using the traditional navmesh system for calculations
I saw burst will use gpu in some tutorials
hmm
not sure but saw it somewhere
i'm not aware of that
the primary concept of dots is to use the whole cpu instead of just one thread
i'll check though
yeah, but dots code can be used by gpu as well
i don't think so
the selling point of dots is multithreading
so doing stuff in parallel
but on the cpu not the gpu
i'm not 100% sure it's just that this is the first i've heard of dots on the gpu
hmm
that entire conversation (as far as i can tell) is about shaders
the purpose of a shader is for rendering behaviour not things like pathfinding and actual "game-code"
ok, my mistake
and since dots is already difficult to use i can imagine adding the extra complexity of using gpu VRAM to store information would be incredibly annoying ๐
by the way, gpu is able to pathfinding,https://www.youtube.com/watch?v=1OSXWhd3hvI&t=1s
In this video, I demonstrate different pathfinding solutions for many agents. As a reference I used Unity's NavMesh pathfinding, which is always single-threaded. Unity's implementation on the CPU uses A* as a pathfinding algorithm. On the GPU, I implemented two different versi...
oh, i wasn't aware that was possible ๐
with a hugh number of agents, gpu may works better
oh it definitely would
but dots can already handle tens even hundreds of thousands of entities
so before I start work ,wanna know which one will do better ,dots or compute shader
if you can get it to work somehow a compute shader might be better
my only concern is that to calculate paths you'd need to copy a lot of information from ram to vram
and that is a famously slow and inefficient process
(the same reason the vfx graph can barely interact with the physics engine at all)
My game is not a fancy AAA graphic game, there should be a lot room for GPU,but dots on the other way if can achieve same amount of GPU can do,will same me alot time fight with compute shader
RPG with multiplayer no more than 16
everything is calculated on the host machine
yeah
this sounds like a very difficult project ๐
dots netcode is designed for first person games
so its not optimised for this kind of application
so you may encounter some friction there
i konw , but the host only have to steam result to clients,will not be alot npc on screen
they just do some dirty work off screen
yep
as long as the world is fairly small it should be ok
you may need to write your own netcode though using the transport layer manually
cause this really isn't what unity's netcode is built for
I'm trying to make a world every npc acts like Really living in there
yeah
so those things don;t have to give to client until client get to the place
yep, area of interest/selective data streaming is going to be super important
but i don't think netcode has anything built in to do that
since its designed for fps games on fairly small maps
my main advice is to be careful cause these kinds of games are very very difficult to make
mmorpgs usually have teams of 200 to 300 developers
I'm mainly using dots for calculation and the network I'm about to use mirror
even with a small game this is a lot of work
so you should definitely make sure you're ok with that before starting
Yes, picking the tool is very important
not so much the tool but the project
while MMO games have been made with small dev teams
you'd have a lot of work to do
it's definitely a big commitment
well, that is me personal problem isn't it
yeah
so ultimately its up to you, just want to make sure you know what you're getting into ๐
not the first time, I can say that
this stackexchange post has some examples of mmo games made by small teams
that is a multiplayer game but not mmo really, like terraria
maybe you get it wrong
yeah i understand that you want a small multiplayer game (lan and such)
so one person hosts and their game does all the server calculations
yes,and most time people can just play alone
so it won't be as hard as any of those things
basically what i'd reccomend doing is starting small
and then expanding up to what you want your end result to look like
you could definitely do it
it'll be hard but its definitely possible
either way, good luck and i hope the project goes well ๐
Thanks, but I still need an answer about dots and compute shader which one will be better on path finding
so far the showcases I found on youtube both result about 2000-3000 agents
well in that case
go with dots
this implimentation can supposedly reach 100,000
on good, that is a kill
using unity's built in navmesh
with 40-50 fps
but it will be less than that for you since your game won't just be a bunch of things moving around ๐
Yes, that will do
hmm
only concern with that is that it doesn't work for the latest ecs
so you may need to manually update it
that is already a lot easier
ok, good luck :)
๐
@dull copper sorry for ping but curious if youre getting this error.
UnityEngine.StackTraceUtility:ExtractStackTrace ()```
with subscenes
in 2021.1.0a4
Cant remember
if it's erroring because its not blittable that means you can't use managed stuff @lean raptor that would be my guess
@shy pilot It's possible to use managed code in Unity Jobs. But it's not possible for astructwhich imeplementsIJobhave managed fields, so it's quite difficult to move managed code to a job
Hi people,
im working on a wavespawner system for Dots which should allow to assign wavestypes/settings and the relevant enemyprefab in the inspector.
-arrays/lists in IComponentData lead me to the neither primitive nor blittable issue
-a wavesettings IComponentData script on converted Gameobjects in hierarchy leads to non-nullable issue when entity querying them into native array
I'm somewhat at a loss as to how to approach this.
Any help/tips would be much appreciated.
Thank you.
For associating a list with an entity you should use a dynamic buffer
As for the rest you'll need to be more specific - show what you tried and the error you're getting
Ok thank you i'll give the Dynamic buffer a try and post a more specific issue statement if the issue persists!
@lean raptor i'd reccomend just doing what i've been doing and only use managed code in systems then put as much of the logic as you can in a burst job
as in have the non burst compatible code in its own job that updates afterwards
it's not always possible to do this and i don't know exactly what you're trying to do but it works for me :)
Hello! Is there a way to tell a system to not update if there is no Entities usable in the Entities.ForEach present in the system? I have a system with nativearray allocation and dispose outside of ForEach, so it does it every frame for nothing if there is no corresponding entities
No, the system runs, but I am also doing some SystemBase.GetSingleton in the OnUpdate, which might mess things up
Good to know that it is supposed to be automatic tho, will try to find out what happens in my code, thanks !
Yep it is the singleton, just tested it: removing the call mark the system as "not run" in the entity debugger !
also for full explanation, normally you use RequireForUpdate(entityquery) to make a system only update when there are entities matching, but Entities.ForEach adds it automatically with unity's codegen
ah
Ohhhhhh thats intresting, thank you!
https://forum.unity.com/threads/ilpostprocessing-slow.913814/#post-6500213 - code gen speed-ups expected in 0.17
@hollow sorrel Actually, calling RequireForUpdate(entityquery) at the start of the update before the singleton stuff make it so that the system is not run if the query is empty!
oh nice, maybe codegen doesn't add it automatically then
Seems to be a problem though, as when I put the following code at the start of my OnUpdate, the time it take for my System to run if the Query find something increase little by little every frame, like it starts at ~0.04ms and after ~20 second of running reach ~0.40ms
generateTagQuery = GetEntityQuery(typeof(GenerateMapTag)); RequireForUpdate(generateTagQuery);
oh yeah
you don't want to put that in onupdate
use https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/ecs_entities_foreach.html#accessing-the-entityquery-object to store the entityquery and then do requireforupdate once on start
can use getentityquery instead of that foreach way too but should still do that on start
ohhhh its on start ! Thanks !
how many components is too much components?
coz each time I approach a problem, it always comes down to adding a new component for better caching
Is anyone using 2020.1.* to build for Android? I have 100% official bug with a trivial repo scenario and it doesn't seem to have been fixed in 2.5 months.
So if anyone uses com.unity.platforms.android, which should be anyone building dots for Android on 2020.1 or later, please let me know โค๏ธ
Ohh gawd... I figured it out: https://forum.unity.com/threads/2020-1-3f1-il2cpp-build-error.959796/#post-6501657
how many components is too much components?
@deft stump For efficiency I think that is intentional, so each system only works on the minimum amount of data. But I think there is a limit for how many components you can use for .foreach iterations, not sure if there is a way to do it on an array of components.
But yeah, I feel I am doing the same
I just upgraded to the entities 0.16 version. Can you not use EntityCommandBuffer in a SystemBase anymore?
EntityCommandBuffer was recorded in ConnectedServerSystem and played back in Unity.Entities.BeginInitializationEntityCommandBufferSystem.
The previously scheduled job ConnectedServerSystem:<>c__DisplayClass_OnUpdate_LambdaJob0 writes to the Unity.Entities.EntityCommandBuffer <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.ecb. You must call JobHandle.Complete() on the job ConnectedServerSystem:<>c__DisplayClass_OnUpdate_LambdaJob0, before you can write to the Unity.Entities.EntityCommandBuffer safely.
Looks like you did forget to pass the ConnectServerSystem Dependency/Jobhandle to the BeginInitializationEntityCommandBufferSystem by calling AddJobHandleForProducer on it.
I'm not sure how old my Entities version was but I haven't had to deal with dependencies and job handles so far. I would just use Entities.ForEach inside OnUpdate
So in my OnCreate of my ConnectServerSystem I have to call AddJobHandleForProducer on the BeginInitializationEntityCommandBufferSystem?
No after you schedule your Entities.ForEach. The structure of your OnUpdate should look like this:
var commandBuffer = m_barrier.CreateCommandBuffer();
Entities.ForEach( ( Entity ent ) => { commandBuffer.AddComponent<Whatever>(ent);} ).Schedule( );
m_barrier.AddJobHandleForProducer( Dependency );
What is m_barrier in your case? I would create the ECB from EntityCommandBufferSystem
Yea the barrier is just the EntityCommandBufferSystem
Cool thank you very much!
No problem ๐
Does Unity Jobs run immediately when you execute job.Schedule() in WebGL platform or they are queue as in other platforms? I though the second one, but I did some tests and it seems to do the first option.
Why could I be getting not disposed exceptions on a persistent native list?
in editor?
what does your code look like? maybe you are creating them more than once?
or maybe you didn't dipose them? in editor persistent containers has a timer when throw to exception. note they're already leaking
Hi, where is this CONVENTIONS.md? can't find it
you can't find it because it's not there
I have a feeling that's some internal file they use as guideline that accidentally got marked on the public changelog
for another example, I don't think we have gotten the HDRP / URP hybrid renderer v2 samples which docs tell to be there
๐ thanks
Good Lord, finally got animations running in Android ๐๐๐
2020.1 + (essentially) alpha packages + mobile builds.... I must hate myself ๐
๐ฅณ๐ฅณ๐ฅณ
Iโve got questions(after I drink some coffee)!
@spark glade are you switching animations at all? do you rebuild your graph when you do so? or is it through dfg nodes(and if so did you make a custom dfg node?)
what does your code look like? maybe you are creating them more than once?
@safe lintel @deft stump It's in the OnCreate of a system. But I'll try to dispose of it in the OnDestroy
I can't seem to find the DOTS equivalent of Camera.ScreenToWorldPoint() with an entity camera. Is there yet a way?
I can't seem to find the DOTS equivalent of Camera.ScreenToWorldPoint() with an entity camera. Is there yet a way?
@fluid kiln
var cam = EntityManager.GetComponentObject<Camera>(cameraEntity);
cam.ScreenToWorldPoint()
Well now that seems obvious ๐
is there a way to trigger an update of systems immediately at game start instead of at the end of the timestep?
since I put my systems in FixedStepSimulationSystemGroup, when I click play, I can see my entities are not ready when I start the game for a very short moment because the first timestep hasn't been reached yet
I would need an attribute to my system like [UpdateOnStart] that would do an initial update of the system when starting instead of waiting for the timestep
alternatively, is there a way to change the update sequence such that system updates happen at the beginning of a timestep instead of at the end of the timestep
Get all the systems in FixedStepSimulationSystemGroup and call Update() on the start of the game?
hello, how can i convert byte array to FixedListBytes64?
@radiant sentinel
Guys can you help me ? please
I don't see anything wrong with the code you posted. Why do you think it's so bad?
Aside from it being a foreach. If you use a normal for loop and run it in burst it will be pretty dang fast.
@radiant sentinel
unsafe
{
fixed (byte* ptr = &arr[0])
{
fixedBytes.AddRange(ptr, arr.Length);
}
}
@spark glade are you switching animations at all? do you rebuild your graph when you do so? or is it through dfg nodes(and if so did you make a custom dfg node?)
@safe lintel literally one fixed animation for now. Upgrading to 2020.1 for android was a real pain. Currently can't even build an AAB, just a APK. If it turns out to be stable, I'll happily release it. Anything is better than T poses, hahaha
ah, ok
Two unrelated questions.
- How can I check if some code is running inside a Unity Job thread.?
- Is there any way, even if obscured, to jump from the Unity Job thread to the main one for a while?
Two unrelated questions.
- How can I check if some code is running inside a Unity Job thread.?
- Is there any way, even if obscured, to jump from the Unity Job thread to the main one for a while?
@lean raptor
- JobsUtility.IsExecutingJob https://docs.unity3d.com/ScriptReference/Unity.Jobs.LowLevel.Unsafe.JobsUtility.IsExecutingJob.html
- AFAIK no, the "recommended approach" (I personally don't recommend that lol) is to create a coroutine that waits for the job to be complete, then execute the stuff needed and then schedule a new job. My recommendation here is to avoid coroutines all together and use UniTask instead, the overall logic would be the same, but coroutine is an issue by itself ๐
Ok thanks @rancid geode
I'm currently trying to update some outdated scripts from a public repository
but some of this is so old that i have no idea what it means
what is the meaning of [Inject]
i'm trying to adapt https://github.com/zulfajuniadi/unity-ecs-navmesh to the latest version of entities
@coarse turtle I'm calling World.GetOrCreateSystem<FixedStepSimulationSystemGroup>().Update(); in my system's OnStartRunning() yet I'm still seeing a delay before the first update happens. what am I doing wrong
maybe you need to use World.PushTime(...) or a similar API since it's probably still doing the time checks
can't remember what the exact API was but you can probably just overwrite the time initially so that FixedStep runs initially
I mainly push Time in my own tests just to check some conditions if I'm too lazy to playtest whether some time stamping thing works
Is dots performate enough to maybe do something like minecraft but with the objects instead of mesh generation
I'd say not but it would be interesting if it could do something like that (obviously you'd still have chunk loading)
@coarse turtle I tried World.PushTime(300,300); but my systems still have a delay before the first update ๐ค
I call it in the OnCreate() function of my SystemGroup which is inheriting from FixedStepSimulationSystemGroup
i'm trying to convert gameobjects to entities
FromWorld returns a GameObjectConversionSettings with EntityManager set to null
so i can't use it?
any ideas
or better solutions, i'm new to DOTS
@odd ridge hmm sorry I'd need to look into the source to see how update works.
what is the equivalent of [Inject] in the current ecs version
making an entityquery @shy pilot
ok thanks
does anyone have a version of this
that works for the latest entities
i'm a bit pressed for time so if someone else has already done this i'd really appreciate it
@shy pilot did you try https://github.com/reeseschultz/ReeseUnityDemos ?
that is out of date a couple of versions too to my knowledge
it is newer though so i might try that
oh wait nevermind i didn't notice the separate branch
looks good to me
time to figure out how to use it
@rancid geode do you have any experience with this package?
@shy pilot tried once, but didn't actually used it in the end
Do you guys use the new Input System? I've not been able to get it to work in my DOTS project since i first tried it around a year ago (and last tried it today). Wondering if it's a specific package conflict or something ๐ฆ
Odd question, I found a way of how to jump to the main thread from an Unity Job, but I don't know how to jump it back to the thread job. Any idea?
With this code you can jump to the main thread.
public struct ThreadSwitcherUnity
{
public static SynchronizationContext UnitySynchronizationContext { get; private set; }
#if UNITY_EDITOR
[InitializeOnLoadMethod]
#endif
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialize() => UnitySynchronizationContext = SynchronizationContext.Current;
public ThreadSwitcherUnity GetAwaiter() => this;
public bool IsCompleted => SynchronizationContext.Current == UnitySynchronizationContext;
public void GetResult() { }
public void OnCompleted(Action continuation)
{
if (continuation == null)
throw new ArgumentNullException(nameof(continuation));
UnitySynchronizationContext.Post(_ => continuation(), null);
}
IThreadSwitcher IThreadSwitcher.GetAwaiter() => this;
}
No idea, but be aware that this won't work with Burst
Do you guys use the new Input System? I've not been able to get it to work in my DOTS project since i first tried it around a year ago (and last tried it today). Wondering if it's a specific package conflict or something ๐ฆ
@wary anchor I do and it works great. What part isn't working for you?
Make sure you have it enabled in project settings. It still defaults to "Old input system only"
@zenith wyvern I posted over in #๐ฑ๏ธโinput-system with lots of details. I wonder which package it is that's conflicting?
Not sure what could be causing that, it doesn't look dots related though
There is another version available from the package manager, maybe try that
You have to pick it manually
It's been this way for almost a year now across all the various different packages from both dots and input system and several different unity versions
You're saying it works without dots?
In a completely empty new project, I install and set up new input and it'll give me that console error I posted in the last message I wrote, but the input system package window is populated in that case
So it seems to be 2 separate errors, with dots it's completely nonfunctional
No idea what could be doing it. I would open a bug report and post it on the input system forums
Maybe this time it won't be ignored like it was when I posted several months ago ๐คท Cheers Sark!
@lean raptor by curiosity, why would you try to jump back to main thread from within a job thread?
and did anyone succeed at triggering system updates right at the start instead of waiting for the timestep? I put my systems in fixed step group and I can see my entities suddenly jump at the start because it's waiting for the first timestep to do a first update. I tried many things and I can't get it to work. for example, I set the world time to 300 seconds so that it's immediatly above the timestep at the start for it to immediately do a system update World.DefaultGameObjectInjectionWorld.PushTime(new Unity.Core.TimeData(300, 300));, but it doesn't work. system doesn't update until timestep
I called Update() on my system and group in the OnStartRunning() function so that as soon as the game start, it does an initial update. doesn't work either
@lean raptor by curiosity, why would you try to jump back to main thread from within a job thread?
@odd ridge It's useful to perfom task that can only be done in the main thread, such as spawn a gameobject, or perform a raycast.
I know that the best practice would be splitting the Unity Job in two and toJob -> Main Thread -> Another Job, but...
@lean raptor - have you looked at async-await support in Unity? It supports launching tasks and awaiting them on the main thread, via a similar method to coroutines.
how do you access the iterator in a scheduleparallel
with foreach syntatic sugar
for parallel buffer purposes
follow up question:
i have a design plan but i'm not sure how dots friendly it is
each entity in my game has a state, searching for food, searching for a mate etc
and i need a component to hold that data
so my plan was to make an interface that extends icomponentdata and then use that to make a component for each state value (so i can filter it in a foreach)
would it be better to just use one component type and store an enum in there and just filter with an if statement?
i tried implimenting the former:
public static void SetState(Entity creature, StateComponentBase stateComponent, EntityCommandBuffer buffer)
{
//Clear the state
buffer.RemoveComponent(creature, typeof(StateComponentBase));
//Set the new state
buffer.AddComponent(creature, stateComponent);
}
public static void SetState(int iterator, Entity creature, StateComponentBase stateComponent, EntityCommandBuffer.ParallelWriter buffer)
{
//Clear the state
buffer.RemoveComponent<StateComponentBase>(iterator, creature);
//Set the new state
buffer.AddComponent(iterator, creature, stateComponent.GetType());
buffer.SetComponent(iterator, creature, stateComponent);
}
but for some reason using an instance of StateComponentBase isn't acceptable when using a parallel command buffer
@shy pilot i dont think you should use inheritance inheritance for this, but is your statecomponentbase a struct?
also, wouldnt your code still be the same there if it was just using icomponentdata
that is a good point actually
i'll change it to that and see if anything changes
i just don't understand why it compiles with a standard buffer and not a parallel one
not sure
oh wait, i remember why i had statecomponentbase now
because to filter the entities properly i need to remove the existing state component from the entity
and if i removed statecomponentbase i'd end up removing all the components from my entity :/
Why not have a separate component for each state?
What's the point of it being an enum?
struct FindingFood : IComponentData struct DoingWhatever : IComponentData
Etc
Then you can filter directly by state
because isn't it more efficient to use that to filter them instead of looping through all of them (especially if using scheduleparallel)
since then it would be making jobs that just return immediately etc
also some states require extra data that wouldn't be needed for others so this made more sense
I'm not sure what you mean, more efficient how?
i can imagine that scheduling jobs unecissarily isn't good practice?
Can you give an example of how separate components would cause you to schedule a job unnecessarily?
separate components isn't the problem
that's the ideal solution, it just doesn't work with a parallel buffer for some reason
Can you elaborate on that? What doesn't work?
that compiles just fine
which would be the non parallel implimentation
but that does not
p.s the add component and set component are separate cause i ran into the same problem with addcomponent
i get the message
I'm still confused about what you need this statecomponent base for. It sounds like you're trying to do OOP
yeah, i guess this is fairly oop-ish
but it also feels oop-ish to put all states in one component
since there would be unused variables depending on the state
...again, why can't they be separate components?
oh, you mean like unrelated?
Yes. Like each one is it's own IComponentData.
@shy pilot can you show statecomponentbase
That has nothing to do with the others.
That's how ECS is supposed to work. Then you can filter on each component as needed
@hollow sorrel it's just an empty interface
i was trying to do it that way because having to run removecomponent on each state type seemed inefficient as well
Well I don't know how you're using these things exactly but if you want to avoid state change performance hits I would say go for ECB first, then an event system if that's still too slow
entity command buffer?
the state is re-evaluated every frame for every entity so i was trying to keep optimisation in mind when i wrote that code
Ahh okay, then yeah that's a lot of structural changes. You could look at Unity's state machine example they made
I don't remember how they did it
ok, thanks i'll have a look
thanks
hmm, they seem to have two functions for each state, one to transition to (adding components) and others to transition from(removing components)
as opposed to one state change method
Yeah I was just glancing at the readme. They actually go in depth about the performance trade-offs they considered based on their requirements. They suggest some alternatives too
yeah, thanks for putting me onto this ๐
@lean raptor - have you looked at async-await support in Unity? It supports launching tasks and awaiting them on the main thread, via a similar method to coroutines.
@untold night Oh, didn't know that. I'll give a check
Hi!
Anyone had problems with similar error?
(0,0): Burst error BC1060: An entry point function `BurstClass.BurstTest(ref BurstClass cls)` cannot be called internally
It's simple call like:
[BurstCompile]
public struct BurstUse
{
public int Int;
[BurstCompile]
public static void Use(ref BurstUse use)
{
BurstClass.BurstTest(out var test); // Causing the issue
}
// ...
}
[BurstCompile]
public struct BurstClass
{
// ...
[BurstCompile]
public static void BurstTest(out BurstClass cls)
{
cls = new BurstClass
{
Int = 0
};
}
// ...
}
Got a repro, so I'll report it if I'm not doing anything dumb. (using Burst 1.3.9 same thing on 1.3.7)
IMO it looks like burst is trying to inline the BurstTest function but also call it...?
@cerulean wren i could be wrong, but i don't think what you're doing is supported by burst
Yeah, that is what I think that might /be/ wrong, but I'm unable to find any info on that.
are you calling this from a burst compiled job?
Ah, and overall, it does compile the code, but fails to build the player.
No, I'm not even calling this code, it's just these 2 files.
And while I'm building the player it logs the error.
ah
well first off those burstcompile attributes will at best do nothing, i don't think you need to put them on static classes/methods unless you're using function pointers
might be causing your issue even since it's erroring during building not executing
I'll look at it
i said first off but that's the only thing that stands out to me ๐
Ok, it does work when I remove the [BurstCompile] class atribute from the BurstClass struct.
sounds like that's the issue then, burstcompile on class tells burst to look for burst attributes in that class, but it's meant for functionpointers not for static methods
should be able to get rid of the method attributes too since they shoul be doing nothing now
if you're executing these static methods from a bursted job they'll already be burst compiled without using attributes, assuming they fit the same criteria as burst jobs (no managed objects etc)
Yeah, I get it now.
Primarily I was kinda confused when I couldn't find compiled functions in the Inspector. But it totally makes sense. Thanks ๐
Hi,
does anyone have experience using CollisionWorld.CalculateDistance?
In my example it trows a bunch of errors, but still gives me the wanted results, and im at a loss.
[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateAfter(typeof(EndFramePhysicsSystem))]
class...
protected override void OnUpdate()
{
var collisionWorld = this.buildPhysicsWorld.PhysicsWorld.CollisionWorld;
this.Dependency =
JobHandle.CombineDependencies(this.Dependency, this.endFramePhysicsSystem.GetOutputDependency());
Entities.WithAll<TagTower>().ForEach(
(SphereTargeting sphereTargeting , DynamicBuffer<Target> targets) =>
{
var hits = new NativeList<DistanceHit>(Allocator.Temp);
var filter = new CollisionFilter()
{
BelongsTo = ~0u,
CollidesWith = ~0u, // all 1s, so all layers, collide with everything
GroupIndex = 0
};
var distanceInput = new PointDistanceInput()
{
Position = float3.zero,
MaxDistance = sphereTargeting.Radius,
Filter = filter
};
bool hasHit = collisionWorld.CalculateDistance(distanceInput, ref hits);
//targets.Clear();
// for (int i = 0; i < hits.Length; i++)
// {
// targets.Add(new Target()
// {
// Entity = hits[i].Entity,
// Position = hits[i].Position
// });
// }
hits.Dispose();
}).ScheduleParallel();
}
The errors:
InvalidOperationException: The previously scheduled job TargetingSystem:<>c__DisplayClass_OnUpdate_LambdaJob0 writes to the Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.collisionWorld.Broadphase.m_StaticTree.BodyFilters. You are trying to schedule a new job Broadphase:PrepareStaticBodyDataJob, which writes to the same
InvalidOperationException: The previously scheduled job TargetingSystem:<>c__DisplayClass_OnUpdate_LambdaJob0 writes to the Unity.Collections.NativeArray`1[System.Int32] <>c__DisplayClass_OnUpdate_LambdaJob0.JobData.collisionWorld.Broadphase.m_DynamicTree.BranchCount. You are trying to schedule a new job Broadphase:AllocateDynamicVsStaticNodePairs, which reads from the same Unity.Collections.NativeArray`1[System.Int32] (via AllocateDynamicVsStaticNodePairs.dynamicBranchCount). To guarantee safety, you must include TargetingSystem:<>
InvalidOperationException: Adding/removing components or changing position/rotation/velocity/collider ECS data on dynamic entities during physics step
InvalidOperationException: The previously scheduled job Broadphase:PrepareNumStaticBodiesJob writes to the Unity.Collections.NativeArray`1[System.Int32] PrepareNumStaticBodiesJob.BuildStaticTree. You must call JobHandle.Complete() on the job Broadphase:PrepareNumStaticBodiesJob, before you can write to the Unity.Collections.NativeArray`1[System.Int32] safely.
InvalidOperationException: Adding/removing components or changing position/rotation/velocity/collider ECS data on dynamic entities during physics step
A Native Collection has not been disposed, resulting in a memory leak. Enable Full StackTraces to get more details.
I'm hopping this is the right place to ask about Job related questions. I'm having trouble figuring out how to translate my current working code into a Job. The problem im having is the way i need to store the data
what i need is to be able to work over a "2d array" of points. for each point I have to fill in a list of points
but a struct can't contain a nativeList. and im not sure how to go about storing the information I need
the "2d array" length can be of any (int > 1) times its self. but the list of points in the point struct can be anything between 0 to 255+
it is supposed to be an array
the size shouldn't change that often and it will always be count^2 making it always a square
Then can't it just be a normal array?
does Jobs and burst work with a normal array?
I mean a normal NativeArray
inside of the Job it is a Native array.
inside of the point struct it is 2 Separate lists of floats
but i dont know how many values each will contain
You said its going to be count*count
But still, what is the list of points for?
a 2d array is almost never the solution to a problem
Whats the 2d list for?
@stiff skiff I assumed you were talking about the 2D array in the job
the list of points of if for holding Y values of hit point from a raycast
This is what my working code looks like right now (Not using Jobs)
its getting the hit points in a grid of points
depending on criteria each hit point is either a free point or a blocked point
Then why not flip the data structure around?
What do you mean?
(We've resolved the conversation in DM)
(Sad, it's usually nice to see it and learn from it :p)
The result was having 2 NativeQueue<(int RayIndex, float value)> (obviously with an actual struct)
1 for the free list and 1 for the blocked list
for the whole job. instead of 2 lists for each ray
@odd ridge thank you
Its wait on main thread , can i call it async?
can you not use a NativeList or NativeQueue in a IJobParallelFor?
invalidOperationException: GeneratePolls.freePoints is not declared [ReadOnly] in a IJobParallelFor job. The container does not support parallel writing. Please use a more suitable container type.
apparently you cant do a raycast job inside of a job... F#$@....
@spark glade are you switching animations at all? do you rebuild your graph when you do so? or is it through dfg nodes(and if so did you make a custom dfg node?)
@safe lintel for animations, do you know if there is a way to not have to use subscenes for the conversion flow?
From the UnityAnimation.Examples most the relevant things are within a #ifdef UNITY_EDITOR and only run during the subscene conversion step in the editor.
Ideally I don't have to "bake" my animations into a subscene, but instead can just convert and instantiate from prefabs at runtime somehow (just like with ParticleSystems and HybridComponents) :/
Jobs are not as straight forward as I had hoped...
Im trying to call this code inside a job
public static NativeArray<RaycastHit> RaycastHitSortByY(ref NativeArray<RaycastHit> hits, int startIndex, int maxHits)
{
RaycastHit temp;
int j;
for (int i = startIndex + 1; i < maxHits && hits[i].collider != null; i++) //Error is on this line
{
temp = hits[i];
for (j = i; j > 0 && temp.point.y < hits[j - 1].point.y; j--)
{
hits[j] = hits[j - 1];
}
hits[j] = temp;
}
return hits;
}```
and i'm getting this error
`UnityException: FindObjectFromInstanceID can only be called from the main thread.`
But i dont think im trying to find and object
also is ref the fastest way to pass in a readonly array?
It's probably your hits[i].collider != null that is causing the issue
with can only be called from the main thread
Unity null objects are not exactly null in the same sense as a plain c# object
awesome......
I forget what they do in the background, but they do some stuff so it makes it easy to debug
as for ref the fastest way to pass in a readonly array - probably, you could also try in or NativeArray<T>.ReadOnly ๐ค
is there anyother way to see if a raycast hit is vaild?
hmm i don't really know if there's a better way to check if the hit was valid on a separate thread
ah shit im trying to sort a read only array, that certainly doesn't help...
I assume you're using RaycastCommand?
Yea
well a user created version of it, because RaycastCommand only returns one hit
The first invalid result is identified by the collider being null.
this is literally in the RaycastCommand docs... but you can't use it in a Job...
Well on the scripting API page, they pretty much just check it on the main thread ๐ค
Well yes, but i assumed they would understand that someone may have 1000's of raycasts hits and may want to deal with them in a job
Well maybe one of the other blittable properties in RaycastHit might be helpful. I'm not really sure what their values are if a Raycast doesn't hit
I looked through but i haven't seen anything that stands out
hmm sorry, I wouldn't know :/
@boreal forge I had to do something similar before switching to dots physics. I think i just checked if the hit point or some other property is not equal to default which worked fine for my use case.
The first invalid result is identified by the collider being null.
this is literally in the RaycastCommand docs... but you can't use it in a Job...
@boreal forge You can check for the normal too, if it is 0,0,0 then the hit is invalid
Thank you both
I wonder if there is something like a shift function for NativeArray and if this would be faster than using a list (could always has the same size) and do cs nextElement = list[0]; list.RemoveAt(0);?
there's removeAtSwapBack or whatever it's called if that's what you mean?
hm, don't think so, array should always stay the same size, just shift all elements down one index (and return element at index 0), like the Shift in javascript
guess i have to keep nativelist, just thought as there is no size change, it could be faster to use nativearray, but also think, when i have to do the shift in my own loop, it will be slower than nativelist
You could implement a circular buffer using a nativearray. I wouldn't bother unless you're actually seeing a performance problem though
yes, seems like circular buffer is the right thing. maybe i could have an integer value for offset, so the oldest element does not need to be index 0, but can be any, so i just need to increment the int by 1 every time.
then read the value @ offset and set value @ย offset - 1, and if offset >= nativeArray.length, offset = 0 โฆย ?
There's plenty of material online on how to write a circular buffer, it's pretty simple
But it sounds to me like you might be trying to optimize for no reason
the main thing i want to achieve is better performance as with nativelist, so i think having fixed size and just changing offset, instead the need to copy all elements down one index everytime (+ resizing the needed memory), should be a lot faster โฆย hmm
yeah, not sure, if really needed (yet) - as noise generation is still the slowest part and baking phyiscs colider the second slowest. but it shouldn't hurt to optimise other stuff
but yes, circular buffer seems to be exactly what i search for - just wonder how to implement, as i would like to hide the circular buffer code/values from the Job. As nativearray seems to be a struct, maybe create a struct that has a native (or managed-array) and the needed values and methods
guess i will just add it on my todo-list and do it later, when i better know how to order stuff using just structs (normally I would create a subclass, as i am used to that)
Also a thing I wonder: I have the NoiseGenerator and there a public static method to generate noise (that again calls an IJobParallelFor for that) and return the result as a float[] - but in the main class, i then need to convert the result to a NativeArray to pass it to the meshing job.
But I don't think it is the right way then, to have NativeArray<float> as return type, and persistent NativeArray<float> in the main class.
Guess it would be the right way, to pass the persistent NativeArray<float> to the NoiseGenerator as Parameter that then get's filled there, or am I wrong with that assumption?
Ive got a question about about the Unity Physics Package, can you run queries against colliders while not in play mode? I'm writing an editor tool that needs to check raycasts queries. And I'm worried because (if im reading the documentation correctly) you have to convert the gameobject to an a physics entity and I don't know if that works in editor mode. Does anyone have any insight that could help me?
@boreal forge yup, it's certainly possible afaik - there are quite a few subtleties/edge cases so it might take a while to get it working 100%. i.e. if subscenes are closed you might need to manually create a world, whether a subscene is open or closed has some small differences etc
Awesome, do you by any chance have any example code that I could read up on? Ive never used the ECS side of dots yet
conversion generally happens at edit-time - ideally conversion shouldn't happen at runtime but if it did, obviously an editor tool wouldn't be expected to e.g. raycast against them. Sorry, almost no docs exist about this stuff and it requires a lot of trial and error.
No worries, thanks for the help. I'll go do some trial and error
good luck! I'd get comfortable with the different conversion worlds and subscenes and what happens when before introducing physics.
all this just to get some raycasts inside of jobs... hahaha ill look into man thank you
hey timboc have you spent much time in looking at dataflowgraph?
No... I installed it, looked at some of the examples and then went... I don't understand any of this.
Bit beyond me tbh.
yeah, trying my best to get a grips with it and not sure if im wasting my time - not sure if this is really something they expect many people to be touching this or if its really more of an internal tool to facilitate stuff like animation(saw some mentions of dspgraph in the examples so i dont know if eventually they will also have some sort of overlap)
yea... making my animation/tweening lib I was like "ah man, another new dots thing you may one day be able to tween with"... I took a look and I was like.... .... ... I don't know. What is this? What have you worked out? What is it beyond an interface with an Update method?
where they started talking about simulation and rendering i kinda mentally checked out, need much more time to brute force cram it into memory
i did see nodes can be burst jobed, though not really sure why virtually every single animation example is mainthread without burst
Unfortunately the last one I tried they had broken so I haven't actually tried the animation examples yet. I assume it's very performant?
but without burst? maybe it's just early
so far all the dfg examples seem to work for me
yea they fixed it on the latest I believe
why are some of my entities marked as "Clean Up" entity ? What does that mean ?
that's the ISystemStateComponentData's
So is that a component ? Would be usefull if we could query for "Clean Up" entities ^^
yea.. think there's something a little bit nasty with that.. like if you mistakenly declare a CleanUp component of your own it clashes but their CleanUp tag is internal or something.
Basically you shouldn't touch it is the reason
as it's something the Unity systems use to destroy the entities that have ISystemStateComponentData's - it doesn't destroy the entity until there are 0 components left so the idea is you manually remove the ISSCDs
Alright thanks ! ๐
structs are copy by value right ? so when i do something like "transform.pos = transform.previousPos" and both are vector2, then those should be two different objects, right ?
hmmm im able to start the ECS editor world but there are no entities in it. I'm using this bit of code to start the world
public void OnEnable()
{
if (EditorApplication.isPlaying) return;
DefaultWorldInitialization.DefaultLazyEditModeInitialize();//boots the ECS
}
``` Anyone know how to get a gameobject in the scene to be converted into the editor world? It converts in playmode so i know its working correctly.
@stone osprey structs are value types yes... transform is usually a class so not totally sure which bit you're asking is a different object
@boreal forge just put a gameobject in a subscene (right-click in the hierarchy and choose create subscene from selection). I feel like I should mention in case you're new to this all that conversion only supports a very small subset of Monobehaviours by default. Say you were making a 'scatter' tool for the asset store... don't waste your time making a jobified raycast system using dots imo - users having to make everything (like terrain) entitified is a substantial ask
I'll try the subscene and thanks for the heads up!
hmmm @amber flicker there is now a SceneSection and a Scene in the entity debugger but I'm not seeing the cube i dropped into the sub scene. The cub has a Physics Body and a Convert to Entity scripts attached. is that the correct way todo it?
guessing you don't have the hybrid renderer package installed
Yea I do
you shouldn't need the convert to entity scripts on it anymore
ahhh my bad
you'll also only see the entity in the converted world I believe (dropdown in entity debugger)
I put it below the sub scene not in it
I thought a subscene worked like when you have two scenes loaded... my bad haha
it's literally just a gameobject with a monobehaviour and the contents are its children ๐
in the converted world, not the default one, yes
but it'll only have a name if the subscene is open I think (otherwise it'd be like Entity 1)
screenshot?
let me send one
win+shift+s in case it's handy
what happens if you remove the box collider? I haven't used physics but wasn't it replaced with physics shape or something?
worth a quick try without the physics components
just removed both the collider and physics and its still not in the entity list
I made sure to save the subscene too
in play mode the cube does show up in the subscene
ah have you checked the editor world?
yea it's weird, I think that should be working
e.g.
might be worth a Unity restart? Which package versions & unity version are you on?
unity is 2019.4.8f1
and im using the recommend or higher for the entites
and ill try a restart now
you'll definitely run into issues on 2019 eventually (it's capped at entities 0.11 for a start) but the screenshot above is from 2019.4 so that much should at least work
hmmm still not showing up after a restart
sorry, not sure what to suggest - you see them in the entity debugger when you hit play?
yea i see it in playmode
how about if you close the subscene? (the converted subscene will be empty so check Editor World)
thats strange as soon as i hit the check mark on the sub scene to turn it off 3 new entities show up
hmm perhaps a rendering/update bug
one of them seems to be my cube though
So i just need to have the subscene turned off for it to work... thats strange
well.. I need to shoot but quickly, what's happening is when your subscene is open your monobehaviour & entity versions kind of exist simultaneously and the entities are kept in a subscene world. When you close a subscene it only exists as converted binary data sat ready to basically load straight into ram. Thus the entities that were in that subscene world are now in your editor world (even if the entity debugger isn't necessarily showing them).
it look like its not "off" its just not open for modification
well.. I need to shoot but quickly, what's happening is when your subscene is open your monobehaviour & entity versions kind of exist simultaneously and the entities are kept in a subscene world. When you close a subscene it only exists as converted binary data sat ready to basically load straight into ram. Thus the entities that were in that subscene world are now in your editor world (even if the entity debugger isn't necessarily showing them).
@amber flicker ahhhhh ok
yes - converted representation only ๐
Thank you so much for your help Tim! You're awesome!
you're very welcome - best of luck!
now to see if i can get raycast inside of jobs working ๐ฅณ ๐ฅณ
Hello there!
I've been working on a tool to convert the tiles used from the Tilemap Package in Unity to be managed as entities instead.
I've been using some of the code from https://github.com/fabriziospadaro/SpriteSheetRenderer and rewritten and added some code slightly.
It renders all the sprites with the same Mesh with 1 setPass (drawcall) using the DrawInstancedMeshIndirect Method, and it works fine!
But now that I've ran into trying to implement some lighting system I've kind of hit a roadblock. I've looked at plenty of different sources regarding
how I could calculate the light inside the shader: https://pastebin.com/aGK4KxVV
So with the current method, all the instances being rendered have the same Mesh and Material, but different UVs of the texture is used when rendering each instance (using ComputeBuffers and/or StructuredBuffer for multiple instance rendering)
But whenever I try to apply the light effect (Using formula: diffuse = Kd x lightColor x max(N ยท L, 0)) I get this as result:
A powerful Unity ECS system to render massive numbers of animated sprites. - fabriziospadaro/SpriteSheetRenderer
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.
I'm open for all kinds of suggestions in how I could solve this. The lighting doesn't even have to be dynamic either and could be prepared and bake beforehand too, but I'm not sure how I would do that!
@tired mulch i think you should ask this in the shader channel
Yeah I realized that, so I posted in there as well ๐
Does anyone know what this error means. Im calling one IJobParallelFor that is calling a dots physics raycast
invalidOperationException: The previously scheduled job GeneratePollsJob reads from the NativeArray GeneratePollsJob.world.CollisionWorld.Broadphase.m_StaticTree.BodyFilters. You are trying to schedule a new job Broadphase:PrepareStaticBodyDataJob, which writes to the same NativeArray (via PrepareStaticBodyDataJob.FiltersOut). To guarantee safety, you must include GeneratePollsJob as a dependency of the newly scheduled job.
it works perfectly in editor mode, but as soon as i go into play mode it losses its mind
some things because i can never remember the specifics but: make sure dependencies are set properly, it might need something like
Dependency = JobHandle.CombineDependencies(Dependency, buildPhysicsWorldSystem.GetOutputDependency());
could also be an issue with the ordering, if it needs to be updated before the EndFramePhysicsSystem and inside the FixedStepSimulationSystemGroup
ohhhh ok that makes sense
ymmv ๐
hahaha lets try it and see
hmmm did not help
pollsJobHandle = pollsJob.Schedule(sideCount * sideCount, 64, buildPhysicsWorld.GetOutputDependency());
is this how im supposed to use it?
im trying to make sure my job doesn't get schedule until the physics world is done?
whats weird is that the code works, like the job is still running. But im getting that error.
not sure if you need to combine jobhandles beforehand in your case
if you do buildPhysicsWorld.Complete(); prior to scheduling your job, does it still error?
let me try
nope that doesn't help
I got it working, It seems to not like the way I'm setting up the job to work in edit mode.
I just have to figure out how to get both to work at the same time
hmm I dont suppose anyone got the dots animation package working with other humanoid models? ๐ค
I feel like im banging my head against a wall. Would there be any reason that a sub scene with 20 primitive in it, would run 4 TIMES slower then a normal scene with all those as normal gameobjects. Isn't ECS supposed to be faster?
--Redacted--
I had full stack leak trace. now the sub scene runs at 200fps and just game objects run at 400fps. not nearly as bad when it was a difference of 50 vs 200
@coarse turtle can you try to set the rig to generic even if its humanoid?
oh
that works thanks @safe lintel
hmm wonder why the rig should be generic tho ๐ค
snacktime on the forums mentioned something about issues with humanoid
though the terraformer model is humanoid i think so no idea but generic works for me too on a previously humanoid char
fyi the dataflowgraph examples are almost essential to understanding animation
@safe lintel I remember having issues with the animation import settings in previous versions of the package. I haven't changed things since and everything is still working.
These were the settings I had ended up with:
Iirc Resample Curves and Anim Compression were what made it work for me. Support might be better by now or maybe my animations formats were just not supported yet back then ๐
fyi the dataflowgraph examples are almost essential to understanding animation
@safe lintel Oh where can I find the data flow graph examples? ๐
ah nvm, didn't know there were samples in the package manager
is there a size limit to dynamic buffers?
[InternalBufferCapacity(498)] can't go above 498 without an EntityArchetype component data is to large warning
that's just the initial capacity reserved per entity - that capacity can be exceeded anytime, it's just that it'll be moved to the heap
that warning is saying that you're making the entity so large that you can't even one in a chunk
I thought it was the number of elements ๐
thanks, probably best to leave that blank then
cool - you generally want it to be the lowest most common value you expect so that most of the time you're getting linear access. If that's larger than e.g. 5 though it starts to become a bit pointless as it potentially fragments your entities massively.
I mean I'm putting this into a buffer
{
public float3 worldPos;
public int2 gridIndex;
public byte cost;
public ushort bestCost;
public int2 bestDirection;
}```
how many of those do you expect each entity to have on average? Or are you like keeping them all on one entity? In which case yea, just leave that attribute off.
I'm keeping them all on one entity in a dynamicbuffer
I've got a question about passing data between Jobs with out hanging up the main thread. Heres some sudo code.
void Update()
{
NativeQueue q;
NativeArray a;
Job1 = new Job1()
{
queue = q
}
handle1 = Job1.Schedule();
//Don't I have to wait for Job1 to finish before I can get the length
//Of the queue. Thus holding up the main thread.
a = new NativeArray(q.Length);
Job2 = new Job2()
{
queue = q,
array = a
}
Job2.Schedule(handle1);
}```
So in this scenario im trying to get all the elements from a NativeQueue into a native array
you may want to take a look at AsDeferredJobArray()
yes you have to wait for the NativeQueue to fill up before grabbing its length
@amber flicker thank you ill look it up
I haven't ever had to use it myself but I believe it's meant for the kind of situation you're talking about
one more question, say that Job1 computes an int and i need that int in Job2. In the construction of Job2, can i pass in job1 handle to get the int inside of Job2? as long as Job2 is dependent on Job1?
to pass that data you could use a native container (like nativearray) or a NativeReference<int> or a pointer to the int because the int you pass to jobs are copied over and not their actual references
NativeReference<int> i;
Job1 = new Job1()
{
result = i
}
handle1 = Job1.Schedule();
Job2 = new Job2()
{
input = i
}
Job2.Schedule(handle1);```
like this?
Yeah
What about this? can you pass a job into another job to access its members?
void Update()
{
Job1 = new Job1(){};
handle1 = Job1.Schedule();
Job2 = new Job2()
{
jobHandle = handle1
}
Job2.Schedule(handle1);
}
Job2 Execute()
{
jobhandle.result;
} ```
never tried that exactly
don't think it works for all cases, depends on the struct's content and if the assigned value are all value types, you pretty much take a copy of the struct and assign it
ok thank you ill look it to it
I'm not sure what the above is supposed to represent exactly. If it's referring to two jobs being in different systems, you can do that through World.GetExistingSystem<SystemA>().resultQueue for example - though it tends to be nice to avoid inter-system dependencies like that where possible imo.
I think worlds are part of ECS right? im only using jobs right now. And im just trying to learn about passing data between jobs. What options are available.
I was working with ECS last night but not right now
Well passing data between jobs is largely with NativeContainers/Pointers
there's also SharedStatic from burst side if you need to pass in static mutable data
oh ok thank you
never used it before, but it is an option
and then of course, stuffing something on an entity / singleton
awesome thank you guys
Hi, I'm new to DOTS. I'm just wondering if its possible to get a NativeArray<T> of Entities with a specific ComponentData?
I think I'm dumb
Its saying T for ToComponentDataArray must be a reference type @_@
I'm trying to get a nativearray of this
yeah that should work, might be the IDE, does it compile in Unity?
You have to specify an allocator that it should use
ah, there might be a different API call
Oh ok let me try
Oh nice now it works
Apparently I was using another version
Thanks
I have another question
Say I do this
ECs = GetEntityQuery(typeof(EntityComp)).ToComponentDataArray<EntityComp>(Allocator.Persistent);
And then I create another entity with EntityComp componentdata
My question is, would ECs be updated?
i assume you're just calling it once?
yeah probably not, tocomponentdataarray would only gather the entities at that frame, so it doesn't know it exists prior, also I'm pretty sure the structures are copied over and not direct pointers to the component data in the chunks
Rippp
I thought they would implement their own nativearray internally to store entities with the same componentdata
Because from what I read, NativeArray is like a pointer to unmanaged memory
I want to keep an update collection of specific entities
So I can access them via index
EntityQuery has a CopyFromComponentDataArray method so you can get the array, make changes, and then copy it back
I assume it's pretty efficient
What's the difference between the copy and .ToComponentDataArray<EntityComp>(Allocator.Persistent);
I don't understand the question. It's CopyFROMDataArray. As in it take the array that you copied earlier and writes the contents back to the entities
Oh
Yeah me dumb
Do I have to do that? I thought changing the contents of the ComponentData itself would work @_@
If you want to modify a bunch of entity components in bulk without using ForEach then that's a good way to do it
But I would say just do a foreach instead. If you can.
But say if I do ECs = GetEntityQuery(typeof(EntityComp)).ToComponentDataArray<EntityComp>(Allocator.Persistent);
And I loop through ECs
Modifying their values
Would it reflect on the entity?
No. ToComponentDataArray is giving you a copy. The allocator just refers to how you need to dispose it
Rippp
yes it's doing a memcpy here
Is there somehow I can store references to them
that's the job executed for ToComponentDataArray<T>(...)
store the entity for easy access is the simplest way
Yeah the entity is the reference
Ohhh
So I store the entity
And I do Entity.GetComponentData<T>
Or whatever it is called
I can't recall lol
If you're in a system it's just GetComponent. But keep in mind random access like that is pretty slow
But if I store specific entities in a nativearray
Its no longer random access if I get by index right
Wait can you even store entities in nativearray
๐ง
Oh its a struct
If you're using GetComponent it's random access
How do you access the physicscollider's collisionfilter component data? to change the collision filter on an existing entity.
Really quick question is this allowed? NativeArray<NativeList<float>>
I'm not getting compiler errors with it but I'm getting errors else were
nvm im getting an InvalidOperationException with it
no, cant have nested native stuff
@olive kite collider.Value.Value.Filter = limb.Filter;
thanks!
@safe lintel is this also not allowed? NativeHashMap<int, NativeList<float>> it looks like people were using it in 2018 but I'm getting an error trying to create the NativeHashMap
where were people using it?
maybe the safety mechanisms werent in place to disallow it then? i could be wrong but i really dont recall any instances of being able to nest native types
man thats a bummer... no worries thanks though
well you can always do NativeHashMap<key, IntPtr> where intPtr points to some unsafelist, but at this point why not just use NativeMultiValuedHashMap ๐ค
@coarse turtle Because I'm brand new at Jobs and the new collection system never new NativeMultiValuedHashMap existed, thank you for point me in a new direction๐ฅณ While I look that up, how does one use pointers in C#. I used them plenty in C and C++ but ive never used them in C#
Uh usually in the unsafe context
you can use a pointer - like c/cpp, you can declare them naturally with primitive types
but for more complex things like objects, in C# you typically marshal them
Marshal?
it's kind of like "serializing" C# managed memory to a native memory layout
Do I need anything special to make them work with Jobs and Burst? or can I just look up normal C# tutorials?
well in the context of jobs + burst, stick with primitive types/structs with blittable data
there's also Unity.Collections.LowLevel.Unsafe namespace if you're interested in looking at some similar c/cpp functions
you have Malloc, MemSet, Free etc in that namespace
I will look into those thank you. Also Unity doesn't seem to have any documentation for NativeMultiValuedHashMap?
ah there we go thank you
so for NativeMultiHashMap I can just store as many floats as I want per 'index' or key, and treat it like its a list of lists?
am i reading this right?
yea pretty much.
So you can do
key: 1, values: a, b, c, d, e, f
key: 2, values: z, x, y, w```
alright perfect thats exactly what I need, thank you so much
Im very confused. Im getting an error that says the hash map is full. Im just doing testing so I set its capacity at 4 and then tried to add 4 things to the map. The first 3 work fine but the forth one throws an error?
All 4 entries use different keys and values.
And isn't setting the capacity just telling it how many unique keys to expect? Can it not grow bigger like a list?
capacity is the maximum you can reserve
you can't exceed the capacity
if you do happen to exceed it, you would have to reallocate and increase the capacity
so typically it's better to know how many elements you can expect and reserve the right amount
or reserve an estimation + some padding
so the maximum amount of values not the maximum amount of unique keys @coarse turtle?
So its more of a 2d array then a ragged array?
well you can have raggedness in it
Right but i mean memory wise?
not sure, best to look at the source on how they reserve memory
Well that really only matter later if I can get this working. I set the allocated size to more then 2 the maximum it should excpirence and im still getting a map full exception.
I'm re using the hash map every frame, but at the end of the frame once all the jobs are done I call clear on it. that should make it empty right?
yea
hmmmm
It sounds like you should be using native stream
Based on how it sounds like you're using it it sounds like exactly what native stream was made for
Basically what I'm trying to represent is a 2dArray of classes, where each class holds a list of points. So I transform the 2dArray into a 1D Array, and then using the multi hash maps to hold the list of points for each index.
What is a native stream?
And I got it working, I was setting the size wrong in one place but not another
I'll take a look thanks man
I have a simple situation that seems somehow challenging: in a job, I want to do something like entities.foreach() over a component type and count all that have a certain condition... any advice?
You can split into 3 jobs (the part before the counting, the counting itself which would be an entities.foreach ans the part after the counting), juat use native containers to link the necessary data
Another option is to use random access in case you are looking for simplicity and not worring about the ultra-optimal performance
@rancid geode not sure I understand how I'd use native containers to link the data
The only way to get data out of a job is using a native container. For a count you can just use NativeReference<int>
You create the container first then pass it into the job to populate
if I implement ICustomBootstrap, would I get a default world or I have to create it?
rephrasing it would be: I don't know how to get the default world as I don't have World.Active anymore
World.DefaultGameObjectInjectionWorld is the new active
yes I was aware of the field, I hoped this wouldn't be the answer tho
if I call DefaultWorldInitialization.Initialize("default"), would replace the automatically created world?
ah not sure in this context
the comment says: /// Initializes the default world or runs ICustomBootstrap if one is available.
that I gues means I shouldn't call it from inside a ICustomBootstrap
var world = new World("Custom world");
var systems = DefaultWorldInitialization.GetAllSystems(WorldSystemFilterFlags.Default);
DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
World.DefaultGameObjectInjectionWorld = world;
but then I was wondering: wait a sec, but shouldn't there be a default world at this point already?
if so, it would be awkward to get it through World.DefaultGameObjectInjectionWorld, but I wouldn't be surprised
oh I see I forgot I can use this #UNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTSTRAP
and create it myself
I am looking for a forum thread in which someone showed his implementation of optional components for entity iterations, does anyone remember something like that? I just cannot find it anymore.
can ComponentSystemGroup be sorted with UpdateBefore and After? I don't remember
let's say I want a group that ticks before InitializationSystemGroup and another after PresentationSystemGroup
I don't really need to do it automatically, as I can tick it myself, but I was wondering
yes
thanks Scorr, but if I am adding them directly to the world, and not inside another group, what put them in the right order?
yes
not sure bout those
yeah i guess that is the way to go
i don't think they took custom top level systemgroups into account since world.update just ticks init/sim/presentation groups hardcoded
for my custom worlds i didn't bother and just put all the custom stuff in simulationsystemgroup and leave the other ones empty
funny enough I was doing the same, but in my custom world I add the default systems, including havok ones
havok now uses the initialization group
so I need to tick the whole world
ah
@rancid geode @zenith wyvern thanks for the tips.. I'm trying to get that working, haven't really used native containers really
I'm trying to modify the value of the NativeReference<int> inside a job initiated with Entities.ForEach(...).Schedule() and am getting " container does not support parallel writing" errors -- can I not use this in such a way?
I thought you would be able to
I'll test it
@hollow mist Works fine for me https://hatebin.com/ifonrhfuhn
If you're trying to use it with ScheduleParallel then that error would make sense
@zenith wyvern I'm using a JobComponentSystem -- think that would make a difference? also, the only reason I'm using a JCS is because I wanted to sequentially schedule my jobs, passing in the jobhandle from one into the next for sequencing... is this a bad approach?
You shouldn't be using JobComponentSystem anymore, SystemBase is meant to replace it.
It automatically does what you're doing with the dependency property
But no it's not a bad approach. It's the default behaviour for SystemBase
ahh, nice, thanks for the info! I'll give it a try!
worked, thanks! @zenith wyvern ++
Hey, how would you store an array/buffer in a icomponentdata? Iโm guessing you canโt.
You can store the collections with the prefix Fixed or Unsafe on an IComponentData
You can also use class ICDs, but then you can't use them in job structs or with burst. They also exist outside the normal ECS chunk memory. They're meant for porting code from non-ECS to ECS-
https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/component_data.html#managed-icomponentdata
You might also want to look up dynamic buffers
https://docs.unity3d.com/Packages/com.unity.entities@0.16/manual/dynamic_buffers.html