#archived-dots
1 messages Β· Page 272 of 1
not sure why you need activator
yeah, that's just brain fart
I can't think of a way to create a "constructor" of saved entities
most of the time, things I want to save require a lot of children
I either need some kind of prefab system
or idk
inability to remove render mesh really hurts
it's for managing it, so I can remove it during authoring, and use child for all visuals
so in case I want to change visuals - I Just remove child, add new
Yep it completely broke after the upgrade for me as well
that seems much more complicated than just having a prefab
you can change
hmm, how would work restoring entity references?
for example I have pathfinding with entity attachment
in case I remove old, instantiate new from prefab
it'll require also restoring them
i wrote about entity mapping here
oh, I see
conveniently typemanager already stores all entity fields for ecb remapping
so you already know exactly every component that needs remapping and can automate the whole thing
public static unsafe void RemapEntityFields([ReadOnly] byte* ptr, TypeManager.EntityOffsetInfo* offsets, int offsetCount, NativeHashMap<Entity, Entity> remap)
{
for (var i = 0; i < offsetCount; i++)
{
var entity = (Entity*)(ptr + offsets[i].Offset);
*entity = remap.TryGetValue(*entity, out var newEntity) ? newEntity : Entity.Null;
}
}
hmm
that's... very confusing
The funny part is that I just do not seem to understand joint authoring at all
So working around that issue was really fun lol
But the RagdollJoint works fine which I ended up using as a replacement
You might want to have a look at Game Torrahod's implementation detailed here
https://gametorrahod-com.cdn.ampproject.org/v/s/gametorrahod.com/entity-remapping/amp/?amp_js_v=a6&_gsa=1&usqp=mq331AQKKAFQArABIIACAw%3D%3D#aoh=16536411098968&referrer=https%3A%2F%2Fwww.google.com&_tf=SourceΒ %3A %251%24s&share=https%3A%2F%2Fgametorrahod.com%2Fentity-remapping%2F
Might be more friendly to start with
thanks, looking into it
hmm, maybe I should just create uint identifier during serialization
but that's actually interesting thing anyway
but I can't use it during deseralization, because all future entity values are unknown
you can use it as much as your own unique uint
when deserialize you have
entity (old)
data (position, rotation etc)
you create your new entity and add it to your remap hashmap (remap.add(oldentity, newentity)) then apply your data to it
then to remap you just replace any component with an entity field with the remapped version
component.entityField = remap[component.entityField];
yeah, I see
I need some kind of Def system, in which all prefabs will be identified through string DefName
so for example when I save entity, I only write this defName as value for prefab to instantiate from
this way I also will create a possibility for modders to create their own prefabs through defs
yeah its a pain
just some background
it took me 4 full weekends to write my current save system which is not that bad
but its based off a full month of fulltime work for writing my save system at work
Oh man xD
then probably another month of work tweaking, fixing issues, etc
so my current system was only that fast because i had both very good understanding of entities and a lot of experience writing saving beforehand
now you probably dont need such a universal versatile system
but I actually do
if i was to leave you with 1 piece of advice is though, is think about how you will migrate data
my goal: to have a large sandbox practically
once you've launched your game and want to make changes
I might want to replicate XML/Json Def system
where all prefab defenitions will be stored in xml/json files
in some data folder
and during launch, it'll create a prefab for each def
later from which I can instantiate entities
sounds like this might be something you were considering for your game anyway for easy modding?
yyyep
I just couldn't figure out how to do in the first place
now it starts to make sense
mentioned this before, but yeah its very good you're thinking about this earlier than later
much easier to build your game around your save requirements
I do wonder if I can somehow integrate those serialised defs into editor
so let's say I'll write my def in text file and upon start, game will read it and turn into class
but would it be possible for editor to do the same during authoring? hmm
Any idea what's up with this package?
https://docs.unity3d.com/Packages/com.unity.platforms@0.60/index.html
I need to try and build
What about it
yep
0.50 removed the need for platform specific versions
it also comes as a dependency with entities so no need to install a new package you already have it
very weird, that entity id shader is not included into Build, even though in Project Settings it is selected as always included
bruh
that's weird
huh, crashing in build
========== OUTPUTTING STACK TRACE ==================
0x00007FFB189C7CBE (lib_burst_generated) [F:\UnityProjects\Space Tycoon\Library\PackageCache\com.unity.entities@0.50.1-preview.2\Unity.Entities\IJobEntityBatch.cs:917] Unity.Entities.JobEntityBatchExtensions.JobEntityBatchProducer`1<Unity.Transforms.TRSToLocalToParentSystem.TRSToLocalToParent>.ExecuteInternal
0x00007FFB13153F96 (UnityPlayer) UnityMain
ecb crashes
the worst
@rustic rain are you storing typeindex somewhere?
it seems like a typeindex that doesn't exist is being used
this is usually caused by someone trying to store a typeindex in a settings file or something
typeindex are not stable, they will be different in builds, editor, different platforms etc
what typeIndex?
The stack you posted doesn't show
Here's the only interaction I do with ECB in IJobEntityBatch
public static void SkipToNext<T>(this DynamicBuffer<QueuedAction> queue, Entity e,
EntityCommandBuffer.ParallelWriter buffer, int sortKey) where T : IComponentData
{
buffer.RemoveComponent<T>(sortKey, e);
queue.RemoveAt(0);
if (queue.Length != 0)
{
buffer.AddComponent(sortKey, e, queue[0].actionType);
}
else
{
buffer.RemoveComponent<QueuedAction>(sortKey, e);
}
}
There is nothing to indicate this is from an ijobentitybatch unless I'm missing something
So you're definitely not storing type index somewhere? If not I'm not sure what's going on, it's crashing in a very peculiar spot
I think it's trying to find a component and not finding it
I use ComponentType fields
in order to add components
Yeah that's just a wrapper to type index
You can't store that
Yes because the type index is the same on editor
When you make a build the type index changes
but I create all of them during runtime only
Oh if you're not saving them to disk that's fine
If you do want to same them to disk at some point you can use stable type hash instead
Yeah that should be fine
hmm, what if I try to access this [ReadOnly] public ComponentDataFromEntity<LocalToWorld> ltws;
with Entity that doesn't have LTW?
I'll go check
nope, still crashes
is batchIndex appropriate sortIndex for ECB?
hmm
I don't have too much IJobEntity or IJobEntityBatch, so maybe I can just double check them all
also crash dump gives this
So I do wonder what is it about
Has anyone got modding working with ECS 0.50.0?
I made a post about it on the forums, but I figured maybe someone here might have tried already (https://forum.unity.com/threads/loading-a-system-from-a-mod-dll-in-entities-0-50-0.1287467/).
It seems like maybe some of the generated code isn't being included in the .dll generated by assembly definitions.
At least some of it is, though.
The docs for IJobEntityBatch<T>.EarlyJobInit() say it is meant to be called by generated code, but even for working systems I can't find that call anywhere in the generated code.
@north bay glad Iβm not going completely insane. I did see ragdoll joint converts, but figuring out a 1-1 replacement for physx to authoring components seems like itβs own challenge π₯²
Also if those change in the future, seems like just going by physx thereβs an upgrade path, joint authoring components still arenβt official unfortunately
Yep it is π¦
I did take what the Unity guys did in the physics ragdoll sample as reference and tried to somehow get the proper authoring values from their code
It's still not perfect or nearly working as good as before but everything is better than the character shrinking into one piece of meat with an endlessly spinning head lol
Worst case, once the conversion errors are fixed I run the ragdoll creator again and I'm back to normal π€·ββοΈ
afaik not yet. i'm keeping on top of this topic as much as i can as well, but there's not much to go on out there yet
@north bay sort of fixed it, luckily had copied some of the old joint conversion code into my project, and didnt remove it. https://forum.unity.com/threads/character-configurable-joint-conversion-0-50p43-seems-wrong.1287362/#post-8162060 still some awkward spinning on close inspection but that could be my setup
I'll join the club as well
focusing my game around modding
I'll update here if I figure it out.
hmm, I don't really get the timeline of your bootstrap from forum post
public void Startup()
{
Debug.Log("Starting ItsAnotherMod");
var world = World.DefaultGameObjectInjectionWorld;
var systemGroup = world.GetOrCreateSystem<SimulationSystemGroup>();
systemGroup.AddSystemToUpdateList(world.GetOrCreateSystem<RisingCubeSystem>());
systemGroup.SortSystems();
}
Are you doing it after creating world or not?
btw, I remember someone mentioning that burst has some bootstrap code as well
maybe you need to try and load your mod before burst
I have a situation where I add a collection of prefabs to authoring and then register them as prefabs for ECS, but on top of that I want to somehow "copy" the prefab, change it's material, and register as a separate prefab for ECS side. I want to do this programmatically so that in future when I change the initial prefabs, I don't have to also manually go in an make copies and change their materials. Any advice on how I would go about this?
Example, I add a prefab via inspector. During registration, it will register that prefab as usual. Then it will take that prefab, copy it, modify it's material (making it "ghost" like), and then register that version as another prefab. So on ECS side, I can instantiate either the original, or the ghost version without dealing with tapping into RenderMesh via unsafe code and changing the material that way during game-runtime.
just instantiate prefab, change components as you wish and then add prefab component
prefab tag*
Ah, that easy huh? Then just destroy GO after registration (clean-up) and that's it?
Prefab entities are nothing special
literally just same entity with prefab tag
which makes it ignored by all systems
Oh right on. Thanks for input.
huh, so that's interesting. i write around 500k elements to a list for every thread. so, the more threads I have, the less I write to a single thread list. with 8 threads and 62500 writes I have 41.4ms overall thread time. with 128 threads and 3900 writes I get 13.71ms. How's that even possible. I don't have more than 8 threads and the job utilization is filled 100%. Do I actually have more and I'm just not understanding my CPU? π i7-4770k
CPU's cores can do parallel work afaik
or maybe it's just magic of burst
more like the job system. I mean, it's great I just don't get it
and the difference is massive!
3 times faster, at least
ah wait, I think I know what's happening. It's maybe the resize of the thread lists that have to resize much more often with less threads. but then again, the capacity should be reached after the first cycles and no resize should be happening at all- yeah, that's not it. resizing is done after the first frame
What's a good way to hold references to structs? For example, for pathfinding nodes need to know their parent node, and the parent node needs to be changed if a cheaper path is found. I'm not sure how to store and modify that reference though...
I guess one approach would be to just allocate all my structs on the heap, and store pointers instead of holding the struct in my open / closed list, but that doesn't seem like the way to go about it
just get ref variable?
You can't store a ref in a struct
you can get ref to a struct though
Yes, but the nodes need to store their parent node
You'd need to elaborate what you are trying to do
pointers π
e.g.
struct PathfindingNode
{
int cost;
someTypeThatCanHoldAreferenceToPathfindingNode parent;
}
Yeah, but I can't hold a pointer to the struct contained in the set, since It will be moved on reallocation I assume
Assuming the set stores the actual struct, and not a pointer to it
well that sounds like a bigger problem then. obviously the path has to be updated with the new data
not even a class would save you there
what are you trying to do though?
sounds like A*
^
I don't have one around but there are good burst implementations of A* already around that solved this kind of issue
Guess I'll take a look at those
The issue is my grid is too large to hold in memory, so I need to only create nodes that are currently in the search space, and pre-emptively abort if the path gets too long
hm, is the chunk streamed?
It's procedural, but the paths are very simple
so you compute the A* star node list on requests?
Yes
when the terrain is mostly flat I'd try a simple navmesh
they are exceptionally fast to build and can be streamed
I'll look into it, thanks. The pathfinding is hierarchical, and the top-most stage is just a simple neighbour search with some neighbours being impassable, so I need to implement A* anyways. But maybe I'll try navmeshes for the actual tile navigation
I think I will just use hashmaps to store node information for now, since that seems a lot simpler than using struct pointers. I'll see how performance is and if I need to improve it after that
good luck! keep us updated
how big is your grid?!
It's not actually too large :P, it's just very large, and I need potentially multiple grids
It depends on the map size, but currently it's 1024*512*16*16, although that's probably too big. A large portion of it is water
That's after the world is created. I've tried just loading the DLL for the modded system as well without doing anything in Startup(), but it doesn't pick the system up at all then.
if that's as large as it gets that seems fine
I'm looking for some Burst initialization code to override now. Do you have any idea what it looked like?
nvm that
I don't think it's related
sigh. do you ever just wake up and your navmesh is just completely generating garbage even though you have no changes and rolling back doesn't fix it π
I would still need multiples, since the world has these kind of "layers"
Is burst the issue or does it not work at all, even without burst?
Yep that's why I was asking π
But since there was some talk further up about bootstrapping I wasn't sure what the issue was exactly
Burst compilation enabled/disabled doesn't change anything, but I haven't tried compiling a burst compiled mod dll.
it's about World not picking up system to create
from mod dll
oh sounded like they were talking about burst initialize or something
not sure how related to systems
but yep on the same page
oh well RisingCubeSystem does include burst
im pretty sure you'll have a hard to injecting code gen based jobs in a mod
how are you compiling this mod/dll
tertle, do you know what's going on here? #archived-dots message
Oh, okay. I'll try disabling Burst on the job and see what that does.
i would get rid of entities.foreach
and just write a ijobentitybatch or ijob
to test
free performance π
apart from that no idea
had a think about it but nothing i considered would explain the significant difference
hehe, let's call it m-a-g-i-c then
Can you post your testing code?
I'm making a new Unity project, copying a compiled asmdef with PluginInterface, my components, systems, etc. into the new project's assets, writing the mod, then building the project in the Unity editor.
you could try the true modder way:
create class project in VS and compile it into single dll
while referencing dlls from Managed folder
I did that first, but I couldn't compile the generated code that way.
I managed to load regular classes from the mod and run them, but not systems.
yeah just try it without a entities.foreach
so same thing I guess?
sure, had to reduce it a little because I have more than the write test in it
another funny thing is that the parallelList is as fast as the parallelBlockList I wrote yesterday. Quite unexpected when one has a large chunk of linear memory and the other has small memory blocks all around
right now I'm trying to write a hashMap that can index several smaller arrays. basically I want to skip the merge process
not even the memcpy saved me in terms of speed. quite interesting and unintuitive behaviour I must say.
How did you do the test that only wrote 3900 entries, did you schedule it 16 times after each other?
Ah nevermind, I misread
i need to write better testing code π still stuck in write some stuff, hit play. too lazy, eh, I know how to write proper tests
Regardless of what you pass to length, you aren't actually changing the amount of operating system threads that unity uses, that number is preset according to your CPU thread count iirc
I think the amount of worker threads used is CPU_threadcount - 1
You can check under JobUtility.JobWorkerCount
how does that correlate with the scheduled arrayLength 8 vs 128? in either case, all worker threads are running the job
I'm not entirely sure tbh. Best guess is work stealing
Can you try with 7?
Or ideally use JobUtility.JobWorkerMaximumCount
jobs are hard coded to have 128 threads
workers are by default set to your core count - 1
thread != worker
thread != cpu core
that all said, unity only seems to use thread counts, in general, up to your worker count
Where is it set to 128?
JobsUtility.MaxJobThreadCount
{
/// <summary>
/// <para>Maximum job thread count.</para>
/// </summary>
public const int MaxJobThreadCount = 128;```
How does that relate to the worker threads?
it doesn't directly
I'll rephrase then, what's the difference
fyi, I have 4 cores, 8 threads and 7 worker threads.
your computer can have 234123432 threads
your computer only has 8 cores
Yes, I know
I meant what is the difference between a job and a worker thread in the unity context
unfortunately job scheduling is a bit of a black box

my guess is it can schedule up to MaxJobThreadCount workers but only execute on JobWorkerMaximumCount but who knows
So those numbers don't actually really mean anything. Does unity use 128 threads or 7 threads to handle jobs?
Try your test with 4 and 7
that's pretty much the best description. π
with 4. slower and the expected 4 worker threads
If you can, show pictures with 7 and 128
Also you still have 7 worker threads in that picture, 3 are just idle
But that's fine for the test
7/8/128
worker stealing is a good explanation but it doesn't really answer the massive difference. and even though the 8 case is not fully utilized, it's good enough that I can't explain a difference of 5 to 1.4ms
It's also interesting that in the 7 case, it only scheduled the batches to 6 threads
the seventh is the small one at the top, running in main thread
Ah, I missed it
so yeah, I've no explanation. I'll just keep in mind to schedule as much as possible so the job system can figure out what to do best
why not 512!
Can you do one last test with 8, but set the innerloopbatchsize to 128
@viral sonnet
{
_parallelSourceList = new UnsafeParallelList<Entity>(8, Allocator.Persistent);
_parallelTargetList = new UnsafeParallelList<Entity>(8, Allocator.Persistent);
_parallelValuesList = new UnsafeParallelList<ParallelListTestStruct>(8, Allocator.Persistent);```
what's this hard coded 8
leftover from dreamings code π I figured it's a good initial capacity to keep growing the list
8 and inner 128
so its faster to run it on a single thread than multi thread?
because your other 8 was 5ms per thread
not really, the fastest is 1.4ms with 128 "threads"
yeah im not saying fastest
not by a lot though
yeah overall time is much much faster
You are still saving time in the end though, because the overhead from context swaps is gone
that doesn't make much sense
since from what i understand of this container
there shouldn't be contention
It still needs to swap thread if the batch count is greater than the worker thread count
But tbh the test size is so small I can't imagine that is the issue
each thread has its own buffer, there are no interlocks
so while there is definitely overhead of multiple threads
i would expect it to still be faster
yeah it's weird :/
yes
isn't this always the casE?
why would you ever run parallel code if that was always the case?
its not completing faster
thats the problem
its completing in 3ms on single thread
5ms on max threads
but max total or 5ms per thread?
5ms per thread
oh then is derfinetly something wrong
id expect total cpu time to be higher on parallel version. and if there was contention due to locks i can understand multithread actually taking longer
but i dont believe this is the case so yeah
not sure what is up - test code looks /fine/
@viral sonnet , can you try with testSizeSingle = 1, threadCount = 500000, innerloopbatchcount = 128
That should definitely be faster than the single thread version
ScheduleParallel(threadCount, 1, Dependency);
yeah the 1 here is definitely a performance killer though
^
i think the problem is in the write method as it gets the pointer to the list over and over again
i cant see that really being an issue?
it'd be the same on all tests
}.ScheduleParallel(threadCount, 1, Dependency);
i suspect its all this
this really isn't threadCount
true, I could just think of an explanation that the single thread is so fast that the pointer is expected and cached
Try what a wrote I bit higher up
I'll be very confused if that isn't faster than a single thread
I can only have 128 parallel lists right now. I tried with 500 before but got weird stalls and wrong results
ah ok
didnt realize you were manually selecting the list with that index but makes sense
very inconsistent. ranges from 1.8ms to 3.6ms with 1/500000/128
it doesn't really make sense
all that is doing over 8/1
is causing more job worker stealing
{
int beginIndex;
int endIndex;
if (!JobsUtility.GetWorkStealingRange(ref ranges, jobIndex, out beginIndex, out endIndex))
return;
JobsUtility.PatchBufferMinMaxRanges(bufferRangePatchData, UnsafeUtility.AddressOf<T>(ref jobData), beginIndex, endIndex - beginIndex);
int num = endIndex;
for (int index = beginIndex; index < num; ++index)
jobData.Execute(index);
}```
why is running this multiple times better π¬
I just wanted to write a nice, clean and fast parallel list with no contention and instead I got a puzzle that confuses everyone π€£
Quick update on the ECS 0.50.0 modding situation before I go to bed:
- Compiling with an
IJobEntityinstead ofEntities.ForEachdoesn't change anything (also weirdly the codegen messes up if I put the job or system in a namespace). - Removing the logic entirely and replacing it with a
Debug.Log()statement has the system working fine. - Un-referencing Burst in the mod asmdef doesn't change anything
- Removing the logic from the system and leaving only a debug statement seems to stop codegen (at least, nothing goes into
Temp/GeneratedCode), and also stops the error, so I'm leaning toward this being an issue with the generated code not being used properly when loaded in main program, or something like that.
you should try IJobEntityBatch, so no code gen is used
yeah ijobentity doesn't help its the same codgen thing as entities.foreach
ijobentitybatch, ijob, ijobfor etc
the ones without codegen
man, I was confused right now because I couldn't get the timings down to the previous tests. I still used the threadIndex (going from 1-8) and that tanks. instead when the full range is used of 128 I get the <1.5ms again
how that makes ANY difference ... i need a break π€£
Ooh, I didn't know that. I'll try IJobEntityBatch in the morning.
Did anyone get Havok working on AWS Linux 2 instances?
Seems like the glibc version that Havok requires it too new π’
/lib64/libm.so.6: version `GLIBC_2.27' not found (required by /mnt/e/Stuff/HavokLinux/Builds/Empty Build Configuration/HavokLinux_Data/Plugins/HavokNative.so)
I have some new findings as we were confused why 8 threads was slower than 128. I rewrote this private struct PerThreadList { public UnsafeList<T>* list; } to a pointer. Before it was a simple struct and it turns out with a pointer I get the same (fast) timings with 8 or 128
how would i best malloc this UnsafeList<T>** sizeof pointer doesn't work
Seems similar to doing an UnsafeList<IntPtr> where an IntPtr points to an UnsafeList<T> on a high level π€
I want to make it work with a double pointer to try out if there are any differences to [NativeDisableUnsafePtrRestriction] private readonly PerThreadList* m_perThreadBlockLists; private struct PerThreadList { public UnsafeList<T>* list; } There shouldn't be any but today's a weird day so everything goes.
how different is DOTS Physics from DOTS Havok?
havok has rigidbody caching(sleeping) and a decent visual debugger
it also has builtin contact point welding
other than that, should be identical(i think)
What are some good resources on learning about the gameobject to entity conversion workflow? I've read up on it and I still have many questions
like what questions? checking out the basic samples in the samples repo probably has the most hands on stuff that exists, docs have some info but probably a lot you will need to glean from trial and error
- What does it actually do?
- What are the limitations?
- What happens to my monobehaviours?
- How do I code for this in mind?
- How are authoring components different from runtime components?
- Can I use things like NavMeshAgent and the animator?
why is this not vectorized? -.- [MethodImpl(MethodImplOptions.NoInlining)] public void CopyMethod(int count, [NoAlias] T* nativeListPtr, [NoAlias] T* threadListPtr) { for (int i = 0; i < count; i++) { Unity.Burst.CompilerServices.Loop.ExpectVectorized(); nativeListPtr[i] = threadListPtr[i]; } } It can't go any more simple π¦
does it just not work for structs?
What instructions are you expecting to vectorise?
You aren't doing anything in the loop
huh? I'm copying
should just use memcpy but I wanted to give it a try
I see mostly such copy examples
Yeah but what size is T
doesn't the compiler know? π
If it's larger than 4 bytes how are you going to pack it into a register
ah that makes sense. thanks!
I always fail keeping simd restrictions in mind. zero experience really :/
ok, i dont use monobehaviors. I get that part now
What does it actually do?
It creates either entities or entity prefabs, which are modeled in a seperate stage, the authoring stage where you create normal gameobjects and monobehaviour components which are used for the IComps, buffers or blobs that are put on the entity. The normal method is creating a monoBehaviour MonsterData_Authoring and implementing IConvertGameObjectToEntity.
What are the limitations?
Hard to say. I haven't found any tbh.
What happens to my monobehaviours?
They are destroyed and never used. They simply serve as data to create entities/entity prefabs.
How do I code for this in mind?
Very similar to usual prefabs. You just instantiate entities and not gameobjects.
How are authoring components different from runtime components?
You can put managed data like lists, etc... on them. Something like a list would be converted (manually) to a DynamicBuffer or can be used to create seperate entities. Get creative π
Can I use things like NavMeshAgent and the animator?
You can put monoBehaviours on entities with AddComponentObject. So yes, but as they are unmanaged Burst and Schedule will not work. Only WithoutBurst and Run.
Anyone had luck break pointing inside a burst job with rider recently?
With their recentish additions of a native debugger I can now break point in native code called from burst jobs, I've just had no luck break pointing inside the actual burst job.
I can break point in both the native code and the burst code with VS debugger though.
e.g. this native code was called from a burst job and i have no issue break pointing it, but I can't break pointer any earlier.
I can give it a try, do I need Native Debug Mode Compilation enabled?
yes
you need to attach it as a native debugger not managed
but yeah i have no issue break pointing inside burst with visual studios
start of a burst job is good enough?
just make sure burst has actually compiled and isn't still executing under mono
not breaking for me either. breaks on some random ForEach unbursted though
if you're breaking on a foreach
it means you haven't attached as a native debugger
because once attached as native, you can't break point anywhere managed
it's kind of the thing i'm having issue with
I've used "Attach to process"
hmm yeah not sure, that should work and is what i'm trying
but yeah i guess no luck shame
i might go ask unity and rider devs what needs to be setup to get this to work
i would love to not have to switch to vs just to debug burst code
Very similar to usual prefabs. You just instantiate entities and not gameobjects.
I mean, how do I code my monobehaviours with this in mind?
IConvertGameObjectToEntity
so is the idea to take my data from the monobehaviour and then, put it in a bunch of components?
You can put monoBehaviours on entities with AddComponentObject. So yes, but as they are unmanaged Burst and Schedule will not work. Only WithoutBurst and Run.
This means no multithreading, then?
In my case I have a "Mob" gameobject with a few scripts, like a "Mob" script that controls behavior and all of that. The monobehaviours have awake and update and all of that, and use animators and nav mesh agents. How much would I have to restructure my script to get it to convert?
yeah, no luck here either. just tried another process Unity.exe. If you find anything out keep me posted. Haven't debugged in aaaages. Would be great to have it though.
at least i can debug this native library
since my navmesh is mostly still just a wrapper for a native library
and i want to slowly port to burst but only small parts at a time
performance: win some, lose some π
wanted to get rid of the data transformation from blockList to arrays. even built a hashmap that can index the 128 lists. problem with that, lookup is slooow
all I gained, lost in the end haha
damn, can't find it. how do I write a simple lambda job that waits for a dependency where I can iterate through a system array and call some monobehaviour methods?
slightly confused by what you're trying to do
you want to wait for another systems dependency?
it's a hybrid system that wants to spawn some particles based on animation state. it was quite slow so I bursted it, the system now writes to a nativeList and the nativeList gets iterated after the job is done so I can spawn the particles. problem is that I need a .Complete for the latter code
you either need to store your handle as a property on the system you can read
or write to a buffer instead for automatic safety handling
or add a fake dependency to something else the system is using
(im assuming you're iterating this nativeList in a different system and want to get the dependency handle to complete before this)
maybe I just need to write an unbursted job and put the SpawnParticle methods there?
anything you do
needs to complete this handle
your best bet is to move the spawning to a separate system in Presentation (where it sounds like it belongs anyway)
so the job has time to naturally complete in background before complete needs to run
I'm only allowed run and withoutBurst because I use manage objects. So how do I wait for the dependency when I can't schedule?
the particles are all gameobjects sadly
that I want to get rid of it as it stalls the main thread π
but that's what you have to do
well, shit π
the only way around it is to defer it to later
so it has a time to run/complete
before you need to execute
i.e.
SimulationSystemGroup
- SpawnParticlesJob();
- Other work
PresentationSystemGroup()
- SpawnParticlesHandle.Complete()
- Spawn hybrid stuff
hm, yeah I think moving to the presentation group actually works. the job will be long done by then
thanks for the input π
it's also useful if you're running multiple thin clients in networking for testing
you don't actually want to be spawning these particles in a thin client!
true, I need to move some systems that don't belong in sim
yup, works fine now in presentation. if anything goes wrong. I complete the handle before the list gets pulled
funny that I need at least a 1000 casters so I can actually find anything in the profiler timeline and then it's just <0.01 ms jobs π first world dots problems
put some thread.sleep in there
and then release a patch later to greatly improve performance
π€£ good one. then I need some dramatic youtube video that tells a redemption story
@white island sorry dude, had dinner and then totally forgot about your question(s)
- What does it actually do?
Conversion is simply converting data from an authoring friendly format, into an optimized for runtime format. Not everything necessarily needs to be "transformed" into something different, but in some cases it makes sense: consider a complex shape like a chair, you could create 4 colliders for the legs, plus two for the seat and back(and more if it were really wild), but then in gameobject terms thats 6 gameobjects used up for an item as simple as a chair. With conversion you can bake that down into a single collider, and a single entity. Far more optimized during runtime & better for your players in terms of performance. - What are the limitations?
Generally, unity is making a lot of conversion systems for builtin types but theres still a lot that doesn't get converted to "pure" ecs data(eg lights, animators, cameras). - What happens to my monobehaviours?
They and your gameobjects get destroyed after being processed by aGameObjectConversionSystemsystem(or theIConvertGameObjectToEntityinterface) - How do I code for this in mind?
Examples of this are in the samples repo https://github.com/Unity-Technologies/EntityComponentSystemSamples - How are authoring components different from runtime components?
More or less answered in the first question. - Can I use things like NavMeshAgent and the animator?
Theres no builtin conversion for navmeshagents or animators. You can use them as regular gameobjects, or as hybrid components.
you should really take your time to go through https://docs.unity3d.com/Packages/com.unity.entities@0.50/manual/conversion.html if you havent already. also recommend some simple tests, like convert a gameobject cube with a rigidbody and collider on it, and inspect the resulting entity to see what conversion does.
I am starting to get my head wrapped around the realities of GameObject conversion. However, is there a workflow for building up entities without using GameObjects for authoring/orchestration that has been documented? It seems like this is so confusing.
Specifically my concern is related to rendering, effects, and actual on-screen stuff. Like, how do I create a component that easily points at a mesh, shader, animation, collider, material, etc and adds that to an entity? What is the best practice workflow to do this?
Rendermesh has helper method to add all components
It's in hybrid renderer manual
Animations are absent atm
You can also make your own systems
That draw stuff
I made render mesh clone that isn't shared component
That helps to draw procedural mesges
In this case you'll be the one who gets to decide how components will be added
Hi there
can someone help me out? I'm new to the job system of unity and I'm trying to create a heightmap which I then apply to a terrain object
But the job I create still runs on the main thread and I don't understand why
This is my generator function which starts the job
public void GenerateTerrain()
{
var size = TerrainData.heightmapResolution;
var nativeNoiseMap = new NativeArray<float>(size * size, Allocator.TempJob);
var heightMapJob = new CreateHeightMapJob
{
Width = TerrainData.heightmapResolution,
Height = TerrainData.heightmapResolution,
NoiseData = heightMapSettings.noiseSettings.ToNoiseData(),
SampleCenter = Vector2.zero,
NoiseMap = nativeNoiseMap
};
var jobHandle = heightMapJob.Schedule();
jobHandle.Complete();
var noiseMap = GetHeightMapFromNativeArray(nativeNoiseMap, size, size);
nativeNoiseMap.Dispose();
var heightMap = HeightMapFactory.GenerateHeightMap(size, size, Vector2.zero, noiseMap, heightMapSettings);
TerrainData.SetHeights(0, 0, heightMap.Values);
}
and this is the job I've made for that
private struct CreateHeightMapJob : IJob
{
[ReadOnly] public int Width, Height;
[ReadOnly] public NoiseData NoiseData;
[ReadOnly] public Vector2 SampleCenter;
public NativeArray<float> NoiseMap;
public void Execute()
{
var noiseMap = NoiseFactory.GenerateNoiseMap(Width, Height, NoiseData, SampleCenter);
for (var i = 0; i < Width * Height; i++)
{
var x = i % Height;
var y = i / Height;
NoiseMap[i] = noiseMap[x, y];
}
}
}
The NoiseFactory.GenerateNoiseMap is a straightforward static function which just creates a 2d float array with perlin noise values (with minor manipulation)
But that function takes quite some time if the texture size is large
do you have [BurstCompile]?
on job
not yet
try
doesnt help
job is still blocking main thread and editor gets stuck for a second
any other ideas? @rustic rain
jobhandle.complete forces it to run on mainthread
Try to profile, how much each method takes
to figure out
what exactly is eating this second
maybe it's not job
You're calling var jobHandle = heightMapJob.Schedule();, then immediately jobHandle.Complete(), which will force the main thread to wait for the job to complete.
that's how no-ECS jobs are done usually though
how should that be done though? I'm trying to offload the work to a separate thread so it wont block the Editor
where did you get that info from?
How else do you run jobs without ECS systems?
diffrent possibilities. you can check if the jobhandle is complete each frame and only if it is you continue your function for example
or you force the job to complete only in the next frame
so you put jobhandle.complete before the job.schedule. then your job has 1 frame time to complete
or you shedule a job dependent on another job...
etc
@sharp stump its generally not recommended and you will just make things harder for yourself
That will help if you're using Burst (the job will be burst compiled) or it's a parallelized job, but if it's a single threaded job you wont get any performance benefits.
Like @solemn hollow said, you need to keep the job handle around and check it each frame.
but in case you just need to execute job
in some quick action
like input action
do you just wait until it completes itself?
through while loop?
same thing
So you would schedule the job, and hold on to the job handle. Then in the script's Update() method you check jobHandle.IsCompleted to see if it's finished.
That way the rest of the game keeps running while the job is working in the background.
A while loop will block the main thread.
well, that would work in async code
But in case of fast job - nope
like I mentioned: things like mouse click with job
You can block the main thread to launch a job and wait for it to complete if you want, but you wont get a performance benefit unless the job is burst compiled or a parallel job (like IJobParallelFor).
Re: Getting mods to work with Unity.Entites/Jobs 0.50.0:
Switching to IJobEntityBatch gets rid of the generated code for the system, but the error is the same.
I think I'm getting closer to the root of the issue. As described by deplinenoise here (https://forum.unity.com/threads/will-registergenericjobtype-be-required-for-all-generic-jobs-going-forward.974187/#post-6384873), jobs pre-register their reflection data during compilation/startup (I'm not sure which). I can't see that code anywhere in Temp/GeneratedCode, and I can't see how that gets done under normal circumstances, and I can't seem to step into that code in a debugger, but from reading through the source,Unity.Jobs.CodeGen.JobReflectionDataPostProcessor does it explicitly for generic jobs marked with the attribute [assembly:RegisterGenericJobType(...)].
I tried making my job (trvially) generic, and including that attribute on it, but still no change. I don't see the generated code that I'm pretty sure should be in Temp/GeneratedCode, I also don't see any logs for it in /Temp/GeneratedCode/SourceGen.log, so I'm guessing that JobReflectionDataPostProcessor isn't running for my mod assembly.
Thanks. This helps. I understand now that I can create RenderMesh and use .mesh to set that. I suppose than I would have to load a file using System.IO I guess? Seems strange, but hey. One step closer.
But see, this is what gets me. Why? To me ECS is so much more straightforward than OOP, yet for some reason I have to build so much of my game as Objects and than turn it into entities? It defeats the whole purpose doesn't it? Why isn't there just a straight forward "Create Entity->add Mesh->add Mat-> add shader-> DONE kind of a thing? Seems so unnecessarily complicated.
Well, see I feel like I could ask you the same. Why do I need a monobehaviour to load a mesh? Why can't I just say. Use this mesh right here, the one at this file path. Thanks a bunch. Yours Truly, programmer. π
you don't, it's just one way to load data
Resources/Addressable/AssetBundles
are another
authoring workflow has its place. its not made for programmers. its what programmers make for designers. designers can do their dirty unperformant setups and you as a programmer convert it to how it should be. if you dont want to expose any authoring control to anybody of course you can create the entites purely in code
Codegen doesnt run for generic systems/jobs. So you cant use IJobEntity. IJobEntityBatch should work (because there is no codegen involved)
i dont think jobs should be used for fast jobs. scheduling costs are not worth it. you need some decent workload to gain sth from it.
ahem, burst
multithreading
what if you need to schedule something on event
in 3 layers
prep job X, prep job Y, finish job Z
X ->
}-> Z
Y ->
it does not matter. if the workload is not big enough burst performance gains are less than scheduling costs. Also btw i found its generally better to schedule less jobs with more workload. So if you could reduce your suggested jobchain to less jobs you probably should
So triggering a RaycastJob on mouseclick and then after it hit sth triggering a job that does damage to a single unit would be nonsensical
there is need for worse performance than necassary? 0.o
btw i am not saying you cant use job.run() and have that bursted
This is with IJobEntityBatch, but it still seems like there is some codegen intended.
The way deplinenoise explains it, it sounds like that codegen should have existed since 0.16, though (https://forum.unity.com/threads/will-registergenericjobtype-be-required-for-all-generic-jobs-going-forward.974187/#post-6384873).
Sorry, Jobs 0.7.0, which was released with Entities 0.16.0.
@woeful comet hmm i didnt see anything about codegen for jobs there. its about how burst discovers generics. but im not familiar with compiler internals so i cant give u detailed explanations there sry
can you try and load simple System without any code at all? With maybe just some fields filled in OnCreate and in OnStartRunning so you can check whether it was detected and run?
I'm not an expert on any of this, but I think it's this bit:
To solve those two problems we've made an IL post processor that makes the job reflection data ahead of time for all jobs and stores them in SharedStatic variables, so that Burst code can later find them and schedule jobs.
This isJobReflectionDataPostProcessor.cswhich adds some code called at some point (when? I have no idea) that initializes each job. The error I'm getting is saying that that initialization hasn't been performed.
Systems without jobs run fine. It seems to be the jobs that's the issue.
I see
maybe it's job's code that needs to be researched then?
I still have to addit manually
Yeah, ECS and jobs are very interconnected. I'm hoping that it's the same root issue causing both not to work.
might want to take a look how world is getting initialized
maybe here lies a key for how it detects systems to instantiate
I "could" but I am not skilled enough π
I understand basically what I would have to do, but its probably not worth it. I just really can't wait for a full ECS implementation.
So I've stepped through the world creation quite a few times now, and I think part of the issue is that some kind of initialization happens before user code (or a debugger) gets to access the engine.
For example TypeManager is a class that Unity.Entities uses to check which components and systems need to be picked up, and has a Initialize() method that sets s_Initialized to true.
how can I set rotation of one axis in quaternion?
But that class starts off initialized as far as I can see. I can't get the debugger to stop anywhere with an uninitialized TypeManager.
full ECS implementation will have exactly this authoring workflow. unity stated that
@woeful comet I had some issues with generic systems too. @rotund token showed me his way :
before that i could only make generic systems work with IJobFor and manual chunk iteration
The highlighted part is the part that makes Burst understand the used generics
Thanks for that snippet. I was just trying making the job generic to see if I could trigger JobReflectionDataPostProcessor.cs to run for my job. I can't see what exactly makes it pick regular jobs up automatically, but it seems to look for the generic job attribute explicitly, so I thought that's the best way to know for sure that the initialization code for the job should be run.
not sure I understand what you mean.
Converting from gameobjects to entities with subscenes will be the standard way to create entities. There wont be a full pure ECS version of unity without gameobjects or anything like that
nothing stops people from literally creating prefab themselves
that would be actually pure
and I'm currently in development of it xD
so you write editor tooling to create pure entities?
yah yell for modding i guess
yyyep
else this is just conversion with extra steps
it kind of is
it's a conversion with input from XML
instead of GameObjects
hopefully it'll work fine
How can i get all the component types that can match a system?
if that even make sense
not really sure what you mean. Entities match a Query defined by ComponentTypes. Systems have Queries
so do you want a list of all componenttypes a system is using in its queries?
Do managed components bring much size to entity per chunk?
you can loop over all queries the system has and call query.GetEntityQueryDesc().All ,query.GetEntityQueryDesc().Any, query.GetEntityQueryDesc().None
but i never needed that so i am wondering what you are trying to do
Im modding a game,
interesting
i dont have access to the source and im patching into the BaseSystem class
trying to retrieve data but im not sure what component type to query
so if i could just list all of them that would help to figure it out
what exactly are you trying to do?
Have you tried decompiling the game? I would think that would tell you which components are being used in a system.
im pretty new to all of this, i did, and its pretty hard to read to me
for example right now im trying to to grab every kill event (im modding the server) to make a leaderboard
public class DeathEventListenerSystem : SystemBase
thats the system im patching in
which has this in it
im guessing "OnKillCallResult" is a component"
idk.. i just keep trying stuff until it doesnt crash lol
Last time I checked decompiled code contained original code
it might be easier to read it
instead
to get a general idea what codegen will create
il2cpp isnt as easy
if someone created game with il2cpp, that just means he really didn't want it to be modded
π
they're ok with modding
yeah, but you should feel the pain from it xD
THIS! π This is why ECS makes so much sense to me. My background is in XML based dev. Are there docs on this approach? I thought about making some prefabs and looking at the components once they are converted and trying to sort of reverse engineer a workflow. Is that what you did?
no docs, I'm in embrio stage of xml parsing
ack. I never parsed XML with C# so I'd be in roughly the same boat
so far I just managed to get this parsed
<Defs>
<ShipDef>
<defName>Normal</defName>
<speed>0,1</speed>
<rotationSpeed>0,1</rotationSpeed>
</ShipDef>
<ShipDef>
<defName>Faster</defName>
<speed>0,2</speed>
<rotationSpeed>0,2</rotationSpeed>
</ShipDef>
</Defs>
trying to figure out
how to manage rendering now
Okay, nice. And do you convert each element into a component for a "ship" entity or what?
well I think of it being hardcoded
basically, I'll instantiate entity
add my ship components, just like in authoring component
add any other components defined in def
which will be list of some kind of XML authoring for other component
in other words
this XML
will be same as game object prefab
but no game objects
okay, so you sort of reference it as live data? Do you update the XML ever?
from a system I mean
no
XML is just input data at start of game
which then written to database
as entity
Cool!
This will be my afternoon now π spending my time looking into how to leverage XML
I know you can't do animation directly from any ECS packages, but can you run animations from a converted game object?
there is nothing about animations in ECS
if you want animations - you implement them yourself
no components will be converted
unless you make conversion system for it
Can you elaborate what you mean? How would I do that? Do you mean make a bones system or spritesheet system or what have you?
exactly this: there is nothing about animations in ECS rn
same applies to pretty much everything tbh...
Any info about how much managed component take over size in chunk per entity?
I just wonder if I should attach shitload of managed components to entity to store data
that is only accessed during saving/loading
or some other huge structural change
what would be a better option to store some large data on entity for the time to come?
Does the data change?
nah
well, idk yet
potentially no
potentially yes
I want to keep "prefab" data on it, or pointer to it
Storing a single managed object not going to be that costly
so during recreation of entity after save I'd know what kind of data to use to recreate it
what archetype basically
hmmm, I'm trying to think of a way to store graphical data:
Basically, my visuals might include more than render related components on single entity.
It could potentially include lots of children with their own graphic data
And what the hardest part - I need it all to be interchangeable hopefully on 1 entity. So I don't have to do entity remapping in runtime.
Basically I want NPCs pilots to be able to switch their ships at some point
I'm starting to respect NativeStream a lot more, the added abstraction of the ForEachIndex nets a much more balanced reading performance
Was it NativeSlice so I can get a certain (the 2nd variable) of a struct?
hm, I've tried quite a few things but when it comes to copying, there's really no difference multi threaded or single threaded. :/
Have you guys ever been in the scenario where some system is waiting on a dependency but you dunno what the dependency is? Is there a way to figure that out?
Its like the first sync point hit is taking up all the time and I can't find who is actually taking the time.
should show the job in the profiler
turn on flow events
but not really since i have no sync points
haha I knew this would be your response XD
Have you guys been able to get the standalone profiler to attach to the editor playmode in 0.50? It doesn't seem to work for me, only the built-in
yeah i dont recall having any issues with that
think ive used it recently, i'll test next time i load up unity
i rarely use it though
the startup time always bugs me
So @rotund token I'd like to get your opinion on this setup for my "destructible" objects:
- moving platform as root physics ghost (either kinematic or dynamic, unsure yet)
-- primitive physics shape forming the platform body (actual physics sim should run using this simplified model)
--- destructible object spawn (spawns a ghost destructible object at runtime when root spawns, then parents to the root on the client, just a bunch of fragment entities with colliders)
The root basically acts as the actual physics object on the server as a simplified model (just primitives).
Each destructible object is parented to the root on the client on spawn, so they should just follow the root ghost as it moves around.
When part of the root physics ghost is "destroyed", I will "deactivate" the primitive collider on the server and set the fragments to dynamic on the client (really just for visuals).
The part I'm not sure about is the primitive physics objects.
If these are just children of the root then they get baked into the parent which makes them hard to selectively "deactivate".
I could maybe use joints or something like that but it might be way too expensive.
Do you have any ideas?
your setup sounds fine
but unfortunately of all the parts of DOTS physics is the area i'm least knowledgeable in so I'm really not sure what best practice would be for your setup
i personally kept my destructable chunks as a separate prefab that was just referenced
so they weren't instantiated until it was required
If these are just children of the root then they get baked into the parent which makes them hard to selectively "deactivate".
I could maybe use joints or something like that but it might be way too expensive.
Do you have any ideas?```
Yee compounds are kinda difficult to manage in DOTS Physics at the moment
But the CompoundCollider children should have an entity field now that you can use to get the 'original' collider entity from (no idea if that's properly remapped)
I haven't had to deal with doing magic to dynamic bodies with multiple child colliders yet
If it would be static you could just have a structure like this and DOTS Physics wouldn't build a compound out of it...
Root:
- Child One (PhysicsShape)
- Child Two (PhysicsShape)
@sharp stump the main issue isnt simple cases like those, its dealing with complicated setups where the runtime data is wildly different from editing time data. take a complex character rig with attachments and physics. the entire gameobject hierarchy is destroyed and replaced by 3 buffers that live on the main entity, every physics collider gets deparented into a flat hierarchy, every joint becomes its own entity, and attachments also live as deparented entities. this would be a nightmare to edit in entity form, but in gameobject form it is human readable.
any way to default safety checks off?
you can disable safety checks from the top menu bar
?
I know that π Have you read my name for the first time? I want the default setting to off on every start
uhhh....turn it off?
why would you intentionally have safety checks off? that just reeks of issues
i've not checked, but i think the setting is stored as a session state value. so theoretically you could run a script on project startup that sets the session state value to false
hi guys, im getting this error Cannot resolve symbol 'JobComponentSystem
ive googled and goolged and it seems this is a valid dots class so not sure why its saying that? all my dots,jobs,burst dependences and packages are installed as well
@viral sonnet it should be serialized, not sure why it isnt for you.
Have a look in BurstEditorOptions for the code.
this is the line that should load the setting global.ForceEnableBurstSafetyChecks = EditorPrefs.GetBool(ForceEnableBurstSafetyChecksText, false);
jobcomponentsystem is deprecated
Pretty sure that's out of date/obsolete/deprecated, but just guessing
long time ago
ahhh true, just searched this discord, should have done that, thank you
thanks, I'll take a look.
https://docs.unity3d.com/Packages/com.unity.entities@0.7/api/Unity.Entities.SystemBase.html doesnt have an onupdate, what do you use instead?
startrunning?
^^
π ty
you got some catching up to do XD
yep
@molten flame which burst version are you using? is it possible they added this in 1.7+?
ah no, found the code. huh, wonder why it's never saved for me.
yeah that's strange then
global.EnableBurstSafetyChecks = SessionState.GetBool(EnableBurstSafetyChecksText, true); ok, I have this line. so not using EditorPrefs. only force enable uses editorPrefs
There is another line after that for me
#if UNITY_2019_3_OR_NEWER
// Session only properties
global.EnableBurstSafetyChecks = SessionState.GetBool(EnableBurstSafetyChecksText, true);
#else
right, only older versions use the EditorPrefs state sadly
Im on 1.6.4
well, like i said. just make a small editor script that sets the sessionstate
I have an editor window that does some stuff like that, e.g. load multiple scenes on start up cos for some reason unity does not do this
yeah. [InitializeOnLoad] does wonders
...but i'd also like one that ONLY runs on the very startup of the project
Yeah I got mine on button press cos of this
yeah been wanting that for a while
pretty easy actually. just set an own SessionState after you've run once. and check for that before running again
prob also sessionstate
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public static class DisableSafetyByDefault
{
private const string DisableSafetyByDefaultCheck = "DisableSafetyByDefaultCheck";
private const string EnableBurstSafetyChecksText = "BurstSafetyChecks";
static DisableSafetyByDefault()
{
if (SessionState.GetBool(DisableSafetyByDefaultCheck, false))
return;
BurstCompiler.Options.EnableBurstSafetyChecks = false;
SessionState.SetBool(EnableBurstSafetyChecksText, false);
SessionState.SetBool(DisableSafetyByDefaultCheck, true);
Debug.Log("Safety checks have been turned off by DisableSafetyByDefault script");
}
}```
this seems silly tbh but whatever!
imo only time you should turn off safety is when testing code vectorization
^^ +1
i can guarantee at some point this will cause you to miss a super rare ecb issue or something similar
performance tanks with safety on. this is not just about vectorization. i'll make sure to turn it on when i need it π
much better to just turn it off on your specific job
you're missing my point
you will miss a 1 in a million timing error
and then spend 4 weeks trying to repo a crash from a user
if you have jobs that you are certain are safe
and performance is really bad with safety on
just turn safety off for the job?
why would I ever do that when there's a simple global option? π€£
because you turn off ecb safety
stop worrying π
if you complain about 'safety ruins performance' then you should always build your projects. because in-editor ruins performance waaaay more
I'm in pointer land right now. safety doesn't safe me π no, I won't waste 6 minutes to make a build that runs minimally faster
but disable safety so it runs e^-29 times faster?
left: safety off right safety on
hm, ok
Any word on .51 having 2021 support
I canβt paint rocks on terrain in 2020 and itβs bothering me greatly
It was Q2 right, or is it pushed back
still Q2
my parallelList has gotten a bit more complex now and has a reader/writer for arbitrary index counts, designed for chunkIndex. much better load now on schedules as it gets balanced neatly now. it's now basically a nativestream with persistent memory (optional) with linear memory and a bit worse allocation because of it. copying and reading is also faster.
I hope it remains so
Is there a way to list all component types that can be attached to an entity?
You can get archetype
i think i found
entityManager.GetChunk(killed).Archetype.GetComponentTypes(Allocator.Temp);
or entityManager.GetComponentTypes(entity);
both seem to work
hi guys, im basically trying to do this ... but in 0.50 entites
{
JobHandle handle = Entities.ForEach((in T comp) =>
{
}).Schedule(inputDeps);
return handle;
}```
but i cant figure out how to convert it
my code/code monkeys
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
float deltaTime = Time.DeltaTime;
return Entities.ForEach((Entity entity, DynamicBuffer<PathPosition> pathPositionBuffer, ref Translation translation, ref PathFollow pathFollow) =>
{
if (pathFollow.pathIndex >= 0) {
...
}
}).Schedule(inputDeps);
return handle;
}
use SystemBase for system
and ForEach doesn't need to return anything
and requires no parameters
JobHandle is hanlded itself
ohh cool so something like this..
{
float deltaTime = Time.DeltaTime;
return Entities.ForEach(() =>
{
if (pathFollow.pathIndex >= 0) {
// Has path to follow
PathPosition pathPosition = pathPositionBuffer[pathFollow.pathIndex];
float3 targetPosition = new float3(pathPosition.position.x, pathPosition.position.y, 0);
float3 moveDir = math.normalizesafe(targetPosition - translation.Value);
float moveSpeed = 3f;
translation.Value += moveDir * moveSpeed * deltaTime;
if (math.distance(translation.Value, targetPosition) < .1f) {
// Next waypoint
pathFollow.pathIndex--;
}
}
});
}```
no
or do i just return void for OnUpdate
thank you
I would re-read all the manual (or at least the migration to 0.50 part) and follow the official samples, if you didnt already.
Will save you a lot of questions
yeah good idea, i tried.. but everytime i google something it finds the v3 version π
I'll just use the link above and work from that
Notice the version in the link, you can change it yourself.
Or look for the blue "latest version" button on top of the page
Anyway, have fun π
Is it possible to write GameObject prefabs without Unity editor or sources?
I'm a bit dissapointed in XML approach
I allow full moddability, but I cut my own perfomance
You gotta love this XML parsing xD
Check out prefab utility
well, I do see that you can load assets from path, but it's more about how can you create those assets, without sources
hmm
if I create entity through adding all components one by one
but within one method call
will that create loads of unnecessary archetype chunks?
yes
calculate all your components you need to add then do it in a single call
then apply the data
I guess I could do a merge ComponentType array kind of thing
you can calculate the X components
there is a specific type for this
ComponentTypes?
yep
but isn't it limited to amount of components?
limit is 31 i think
so use 2?
or 3
or 4
(ok you aren't going to hvae 120 components on a single entity but you get the idea)
xD
tbh, I have doubts about 31 capacity
on the other hand
it does have FixedByte128 parameter in one of constructors
it's just that I looked into souces
and it has separate fields for different kinds of components
which made me think it has limited capacity per type of component type
like system state, shared, normal
noice, my new ParallelList outperforms NativeStream
not to shit on NativeStream, it's really fast for temp memory. But I had some troubles with, what to do now with the data. I need some data transformation and then NativeStream is kind of getting in the way of itself with the 4k memory blocks
updated tests with copy2array
nativestream is only great if you can parallel write and read
not just that, it's also good when you don't know how many elements will be written
if you know how many elements will be written, the NativeList reserve trick is king. No need for a NativeStream then
aside from that, NativeStream is the only good non blocking parallel writer out of the box. but what about code that doesn't just read the same data in parallel again? there's a pretty hole then. I'd argue, if you write and read data the same way, why not just process them without the write/read when they are linear anyway. for anything non-linear, some data transformation has to happen and this is where NativeStream falls behind
I'd argue, if you write and read data the same way
it's very useful for libraries that only handle one half of the data
and it's up to the user of the library to implement the other half
e.g. unity.transport
the primary example of where nativestream spawned from
it provides you a stream of packets, it's up to you to read and handle them
or maybe the opposite, i have a library that reads a stream and it's up to the user to implement the writer
e.g. user writes to the stream to request a path
if your own code that is both reading/writing as you say, there is not much point
What are you arguing about? NativeStream is great. Not saying otherwise. I mentioned a very specific data transformation that the ParallelList solves that NativeStream can't do. So any example that are tailored to NativeStreams design that are linear are obviously okay.
maybe i missunderstood what you were saying. i thought you were saying if you are writing to a native stream and simply reading back in parallel you may as well just do it on the spot you were writing instead.
I still hold true to that, if that's possible, do it - but then you started about libraries where obviously, you can't do what I'm saying.
and i agree with you
i was doing was pointing out a case reading/writing in parallel was still very useful.
all good
where an array output really shines is when you want some indexing. lots of stuff that I have coded is non-linear and indexing is a great way to speed up performance and eliminate race conditions with ease. I have not found a better way to solve non-linear problems and race conditions
I've also written an ArrayHashMap that can index any array at high speed, either with key inside the array or double array with keys/values
huge fan of your custom containers
if you want max performance you really need to write containers that fit your specific requirements
thanks π the downside of the ParallelList is that constant memory is allocated. For a constant stream of data that's pretty much a non-issue though. And I could add some methods to make allocations better and to free up some unneeded memory. I've lazily used the SetCapacity of UnsafeList which can be optimised quite heavily to only request capacity * 2 instead of length + 1.
doesn't SetCapacity already do capacity to power of 2?
oh, yeah it does. haven't looked at the internal of SetCapacity. in that case, all is good π
I'm starved for a finely grained DidChange feature for components using something like bitfields.
hi guys, i looked through the docs but i can't seem to figure out how to change this to 0.50 entities.
Entities.WithNone<PathfindingParams>().ForEach((Entity entity, int entityInQueryIndex, in PathFollow pathFollow, in Translation translation) => {
if (pathFollow.pathIndex == -1)
{
GetXY(translation.Value + new float3(1, 1, 0) * cellSize * +.5f, originPosition, cellSize, out int startX, out int startY);
ValidateGridPosition(ref startX, ref startY, mapWidth, mapHeight);
int endX = random.NextInt(0, mapWidth);
int endY = random.NextInt(0, mapHeight);
// entityCommandBuffer.AddComponent(entityInQueryIndex, entity, new PathfindingParams {
// startPosition = new int2(startX, startY), endPosition = new int2(endX, endY)
// });
entityCommandBuffer.AddComponent(entity, new PathfindingParams {
startPosition = new int2(startX, startY), endPosition = new int2(endX, endY)
});
}
}).Schedule();```
can anyone help?
error i get is.. `error DC0004: Entities.ForEach Lambda expression captures a non-value type 'this'. This is only allowed with .WithoutBurst() and .Run()`
you haven't posted the part of the code that's failing
hmm that is line 80 in my code PathFollowSystem.cs(80,9): error DC0004:...
i updated the op with the full code
sorry in a meeting
where are cellSize, originPosition, mapWidth, mapHeight, random defined?
are any of them fields in the system?
all good, no rush
{
int mapWidth = PathfindingGridSetup.Instance.pathfindingGrid.GetWidth();
int mapHeight = PathfindingGridSetup.Instance.pathfindingGrid.GetHeight();
float3 originPosition = float3.zero;
float cellSize = PathfindingGridSetup.Instance.pathfindingGrid.GetCellSize();
Unity.Mathematics.Random random = new Unity.Mathematics.Random(this.random.NextUInt(1, 10000));
// EntityCommandBuffer.Concurrent entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent();
entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer();
Entities.WithNone<PathfindingParams>().ForEach((Entity entity, int entityInQueryIndex, in PathFollow pathFollow, in Translation translation) => {
if (pathFollow.pathIndex == -1)
{
GetXY(translation.Value + new float3(1, 1, 0) * cellSize * +.5f, originPosition, cellSize, out int startX, out int startY);
ValidateGridPosition(ref startX, ref startY, mapWidth, mapHeight);
int endX = random.NextInt(0, mapWidth);
int endY = random.NextInt(0, mapHeight);
// entityCommandBuffer.AddComponent(entityInQueryIndex, entity, new PathfindingParams {
// startPosition = new int2(startX, startY), endPosition = new int2(endX, endY)
// });
entityCommandBuffer.AddComponent(entity, new PathfindingParams {
startPosition = new int2(startX, startY), endPosition = new int2(endX, endY)
});
}
}).Schedule();
// endSimulationEntityCommandBufferSystem.AddJobHandleForProducer();
}```
this is the entire onupdate method, so to answer your question, yes? i think
hmm
GetXY and ValidateGridPosition
are both static methods correct?
i'm not seeing something obviously wrong
PathfindingParams is a stuct?
pretty sure GetXY and ValidateGridPosition are class methods and therefore the this error
aside from that, the error means you are using a variable in the ForEach that's only defined outside the OnUpdate method. Everything in OnUpdate will get snapped and can be used inside the ForEach. At least, as long as it's a simple type or struct
yeah GetXY and ValidateGridPosition are inside this class
https://pasteio.com/xmJWIizM3o7k
hmm ok right, meaning it cant get anything from those methods?
can you try commenting out the method calls just to make sure those are okay
just replace the startX, startY with a local dummy variable
ah, the entityCommandBuffer is the problem. it's a class field so can't be used. make a local variable inside the OnUpdate
var localECB = entityCommandBuffer is enough. then use localECB inside
entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer();
it has one
yep, was just about to say, i commented out the methods adn the command buffer and it compiles
am i confused
it's assigned to the class field
hmm im not following, sorry
also rename random, you make a new variable with the same name
delete this
private EntityCommandBuffer entityCommandBuffer;
change this
entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer();
to
var entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer();
yeah this bothers me as well π€£ , though probably shouldn't break anything π€
awesome, ok thanks guys, it compiles now and onto the next debugging adventure, thanks again
how do y'all handle text with dots?
I wanna make little prompts with an image and some text that billboard
you mean, as saving the text in an IComp?
yeah, tmp, all managed aside from some FixedString512Bytes in Icomp
hi guys, sorry to ask a similar question again im trying to convert this section.., i fixed up some other issues but stuck on this again
https://pasteio.com/xE57vtSZMw06
getting this error:
error DC0004: Entities.ForEach Lambda expression captures a non-value type 'findPathJobList'. This is only allowed with .WithoutBurst() and .Run()
yeah you cant use managed types, e.g. List inside of a Entities.ForEach unless you run it on the main thread without burst
use NativeList instead
Unfortunately DOTS is not really one of those things that you can hack your way through...
That's how I started almost a year ago and I'm still learning how all this shit works lol
wait, you can schedule in scheduled jobs?
ahh i see, whoa this will be a big refactor I think, ok cool
thanks
you shouldn't be able to
you can schedule in burst though*
ISystem OnUpdate already is burstable
Wait
Scheduling is burstable?
Ooor doing non-structural changes in entity manager?
most of entity manager is burstable
they even have the methods marked that are/aren't
public bool AddComponent<T>(Entity entity)```
public void AddComponentData<T>(EntityQuery entityQuery, NativeArray<T> componentArray) where T : struct, IComponentData```
ijobchunk schedule was burstable in 0.17
they added support for a bunch more in 0.50
Oh man I didn't know
How do you do it?
So you need some kind of prep work to make all vars local or?
just use ISystem
mark it BurstCompile
and you're pretty much done
you'll find it quite limiting atm though like
no ecbs
Hm
Can't I declare a new method and burst it?
Which I will call from onupdate
And which will have as parameters all locals
sure
you aren't getting nearly as much of a benefit as you think
scheduling jobs isn't nearly as costly as people make out
combining dependencies on the other hand...
it's for Manager's component manipulation though
not really for scheduling
ah
i want to try unity physics and havok, what steps do i take for that? do i make a normal unity project and just add the packages? are there specific settings required?
hi guys, i spent some time changing from array to nativelist to try and solve the issue earlier today but still getting the same error
https://pasteio.com/xtFqPNKpfxi4
error DC0004: Entities.ForEach Lambda expression captures a non-value type 'findPathJobList'. This is only allowed with .WithoutBurst() and .Run()
protected override void OnUpdate() { int gridWidth = PathfindingGridSetup.Instance.pathfindingGrid.GetWidth(); int gridHeight = PathfindingGridSetup.Instance.pathfindingGrid.GetHeight(); ...
this is managed list, not native list
you need
NativeList<T>
25 line
uses managed list in foreach lambda
hmm, any idea how many symbols can FixedString128 fit?
like characters?
yeah
I need to have DefDatabase which is accessed by string
but since string is managed
I gotta use umanaged alternative
125
FixedString128Bytes.UTF8MaxLengthInBytes or Capacity
note that utf8 characters are 1-4 bytes
so 125 1 byte characters
or up to 31 4 byte characters
Library\PackageCache\com.unity.entities@0.50.1-preview.2\Unity.Entities\RetainBlobAssetSystem.cs(6,5): error SGICE002: Seeing this error indicates a bug in the dots compiler. We'd appreciate a bug report (About->Report a Bug...). Thnx! <3 System.IO.IOException: Cannot create 'C:\Users\froze\Desktop\My project (1)\Library\Bee\artifacts\1900b0aE.dag\Unity.Entities.AdditionalFile.txt' because a file or directory with the same name already exists.
whats this
i removed that file by hand but it just reappears along with the error
properties on a system?
its a new project havent added any code yet
oh
just the entities/platform/physics/havok packages
no how do i do that?
I will only use letters + underscores, if that matters
yea burst is up to date
???
public partial struct FixedString32Bytes
error remains, anyone knows to help out?
so completely empty project
unity 2020.3.3X
just packages added
only thing im not sure about is havoc
since i dont use it
but i assume it should work
unity version is the only wrong, im trying with 20.3.3 now
I suggest instead of jerking with packages, just add hybrid renderer. It will add everything else as dependency. Except physics package
hybrid renderer is a package?
yes
ok ill try it and tell u thanks
im saying 2020.3.30+ (30, 31, 32, not 3)
got sick of not being able to inspect physic colliders, so wrote inspectors for them
vs
who can help
with?
it worked. so now the rigidbodies use the havok engine?
you're missing a
{
after the Start() and MonoBehaviour
you're probably asking in the wrong channel though
might want to try #π»βcode-beginner
I remember I saw a person here who tried Havok engine, you might want to use search to find him
very few people use it, so doubt generally asking will do much help
the API is the same as com.unity.physics but yeah never tried neither so can't talk about the specifics
Basic question but how do I profile a job properly to figure out why its taking so long?
I have a simple pathing type job system where if I double the search grid it takes up to 200 times longer
it goes from roughly 15ms to 3500ms plus
I'm not even sure where to look to figure that out
burst debugger
look at generated code
see whether it's vectorized
I'm not sure how to read the burst complied code to be honest
is there a diffrerence between calling CreateEntityQuery from a system instance or entitymanager?
but essentially: if it's pink -> awesome, if it's not pink -> not awesome
there's not a lot of pink 
screenshot?