#archived-dots

1 messages ยท Page 34 of 1

viral sonnet
#

Could be TempJob too. WorldUpdateAllocator is the more modern approach today

spice vale
#

How do you handle writing to same index twice? @viral sonnet

misty wedge
#

WorldUpdateAllocator is also cleared automatically, right?

misty wedge
viral sonnet
#

same index in 1 frame doesn't work.

#

i tried making a persistent NativeStream but it doesn't make much sense

misty wedge
spice vale
#

so If I have two systems producing damage events that can't work with nativestream

viral sonnet
#

it can work but the performance difference is nearly 0

#

sure, it's like a new alloc

misty wedge
#

So it's basically like a better tempjob

spice vale
#

That's what I thought

viral sonnet
#

or you make sure with some form of index that it's only written once. but i don't see the point really

#

i also had the same problem, not really with damage but spells that are fired which can come from the caster, effects or triggers. i need 3 streams, well in my case custom parallel lists.

spice vale
#

I made a custom parallel blocklist implementation similar to the one dreaming has, for this reason

whole gyro
#

This is cool, thanks for sharing the code!
Couple of questions. It looks like you are iterating the target types and copying from the source to the target. Do you assume that the source has all of the components that the target has? And this doesn't work with dynamic buffers, right?

viral sonnet
rustic rain
#

exactly same, so yeah

#

they have all same components

whole gyro
#

ah got it

viral sonnet
#

oh right @rustic rain what i wanted to ask. for the method you posted earlier you need to have the correct entity already and not a deferred entiry from ecb, right?

rustic rain
viral sonnet
#

doesn't look like it would scale that well

spice vale
#

@viral sonnet why the switch from a block list to list? Isn't block based list better?

misty wedge
#

What's the intended way to fetch system state entities? GetSingleton or use the systemhandle

spice vale
#

using system handle seems more robust

spice vale
#

but you get more allocations if your list grows?

misty wedge
spice vale
misty wedge
#

I'll try both and see what I like more

viral sonnet
#

that's why i dropped the blocklist. reading and merging was so slow

misty wedge
#

Still kind of weird that if you stick state in a component it kind of breaks encapsulation, unless you also somewhat manage that state in the component itself, which isn't really in the spirit of dots

spice vale
viral sonnet
#

sure but it's not persistent so the alloc time will eat into the frame budget

spice vale
#

persistent?

viral sonnet
#

i've written it for a very specific reason. a parallel job writes data and then, due to race conditions, the data needs to be read in a single threaded job. the parallelList is best of both worlds for writing and then reading

viral sonnet
# spice vale persistent?

the parallel block list is created/alloced on every frame. the parallelList is persistent over several frames.

spice vale
#

not mine ๐Ÿ˜›

#

I can have it persistant

viral sonnet
#

that's good then! ๐Ÿ™‚

#

i asked dreaming if he could make his list persistent but he didn't want to

#

the way it was setup is was quite annoying to rewrite

#

and as i meantioned before, the biggest problem i had wasn't with the writing but then reading. if you read in parallel, perfect. if you need to merge though, quite meh ๐Ÿ˜„

#

so much about high performance code is writing the right data containers that are perfect for the job

#

with burst i never had once a case where just instructions/arithmetics were a bottleneck. it's always data and data access

whole gyro
#

InstantiateInto

pliant pike
misty wedge
#

Although I'm guessing that memory access is also already optimized in burst, I've never checked though

spice vale
misty wedge
spice vale
misty wedge
#

To an extent sure. But if the methods are named and commented properly it makes it more clear what's going on instead of just have a single list in there

viral sonnet
#

just a few days ago i found a regression in one of my jobs. the job iterated on actors and processed combat events. for actors that only had a source event and no target event i had new timings of 2.5ms instead of 1.5ms. turned out when i rewrote my stat system i also acquired a stat byte* and read the health when it wasn't neccesary. well, i moved the data access and again down to 1.5ms. so, just that. reading a health value from a byte stream that's located in an IComp. (really inside the chunk, not outside so can't get any faster really.)

spice vale
misty wedge
#

afaik you aren't supposed to have non-pure methods on your data containers in pure dots

spice vale
#

if they are simple its fine

misty wedge
#

Depends on who you ask

spice vale
#

just to improve the interface

misty wedge
#

I'm sure mindstyler would disagree

spice vale
#

well in that case, it should not be allowed to have any fields inside either, because those are just abstractions over the underlying bits

misty wedge
#

Well no, since it's only data

spice vale
#

just make all components empty, with an excplicit size lol

misty wedge
#

The point of DOTS is to separate state and behaviour

spice vale
#

an int field is not data

#

1 and 0 is data

misty wedge
#

an integer is just a type of data

#

Besides, I don't really care. I'll put methods in places if I think it makes sense

#

Unity breaks this convention in their code as well fyi

spice vale
#

I know, I'm on your side, just showing how absurd it would be if one followed that view dogmatically.

misty wedge
#

mindstyler has analyzers that throw compile errors if they put a method in an icomponentdata

spice vale
#

basically an int field can be seen as a method that takes the underlying data and reinterprets it as an int

misty wedge
pliant pike
#

According to the data oriented design book, if I recall and to be pedantic, everything in dots is kind of data including systems

spice vale
#

So system in component is allowed, nice ๐Ÿ˜†

misty wedge
#

Yeah it's definitely a design thing

#

Unity recommends no methods though, but again, they also ignore that same advice

viral sonnet
#

when a method is reused a bunch of times and code duplications starts to happen it's much better to put a method in a comp it is related to. (if it is)

#

could also go to a static method but for readability it's much clearer

misty wedge
rotund token
#

You just cheat and put all the methods in extensions

spice vale
#

haha

rotund token
#

Everyone happy

viral sonnet
#

yeah extensions are much nicer

#

the biggest problem is how to make a dev aware that the method exists

misty wedge
#

Yeah I think at the end of the day everyone has to figure out what works for them / their team, a lot of it is too pedantic imo

viral sonnet
#

in teams i often had a problem where methods were written multiple times just because a dev wasn't aware of some dumb namespace

#

i mean, how should he?

misty wedge
viral sonnet
#

a lot is way too pedantic. namespace discussions alone. god damnit i nearly went mad sometime

#

like WHY in gods name do you care so much about how a namespace is called.

#

and why do we need 30 of them

misty wedge
#

Hey in the startup where I work people accept PRs even if the tests fail

viral sonnet
#

lol how does that happen? ๐Ÿ˜„

misty wedge
#

They click the red button that says "accept anyways" or whatever it's called on git ๐Ÿ˜…

rotund token
#

We accept prs when tests fail but you can't merge with a failed test

misty wedge
#

Oh, I meant merging

rotund token
#

Hard prevented

misty wedge
#

Not if you are admin

#

๐Ÿ™ƒ

rotund token
#

I am the only admin

misty wedge
#

Well yes, I meant in my case

rotund token
#

But yeah that's dumb because if they're failing tests then once merged everyone will fail tests

misty wedge
#

exactly

rotund token
#

At which point just delete your tests

rustic rain
#

anyone figured this component?
RenderMeshArray

misty wedge
#

and then tickets take 5 times as long because everyone needs to fix the test and they have no idea whats going on

viral sonnet
#

don't test. EZ

rustic rain
#

I just don't get how to get Mesh out of it

#

correct mesh

rotund token
#

From memory issue it's just used to pass meshes to batch renderer

#

I don't think you do get meshes out of it

rustic rain
#

I need meshes out ofit

viral sonnet
#

btw. entity graphics has a huge regression with performance. if anyone's wondering, will be fixed in upcoming 2022.2 beta

rustic rain
#

or I need to be able to define RenderTexture to batch renderer

rotund token
viral sonnet
#

related to the new batch renderer

rustic rain
#

also

#

I checked manually all entities

#

they do contain their mesh in this component

rotund token
#

Then use that component

rustic rain
#

but I can't figure a way to get index

#

sometimes correct index as is, sometimes it's index-2

#

I'm just confused

#

one example

#

the other example

#

red line is correct mesh

#

both at index one, but MMI value is different

#

๐Ÿฅด

rotund token
#

RenderMeshArray is not used at rendering time, it is used for loading baked entities.

#

If you would let me finish

misty wedge
#

Huh, you can't RequireForUpdate a system component?

rotund token
#

You probably want to read this

#

Material mesh info usually does not point to the mesh in the array

#

It points to the mesh in the brg

rustic rain
#

๐Ÿฅด

rotund token
#

To render in brg you must register your mesh

#

At which point you just have an index

rustic rain
#

already registered I guess

rotund token
#

And the whole thing is unmanaged

rustic rain
#

is there any tutorial on BRG?

#

I haven't really touched it

#

and I need it it seems

rotund token
#

You can change what you render by simply changing index

rustic rain
#

no no no

rotund token
#

The array is ignored once loaded

rustic rain
#

it's for selection system

rotund token
#

I know

rustic rain
#

I need to render things now

rotund token
#

I'm just explaining the system

rotund token
#

See if the Entities graphic system has a method to get mesh

rustic rain
#

so I create new

#

ok, I'll try to play with it

misty wedge
#

Are system entities somehow different so they don't match a query?

rustic rain
#

oh bruh, I opened wrong doc

#

kek

rustic rain
#

all dropped in same archetype

misty wedge
#

Yeah, but they interact differently with entity queries

rustic rain
#

๐Ÿค”

misty wedge
#

It seems you need to set an option on the query to find system entities

#

So similar to prefabs, I just didn't see any documentation on it

#

Btw, if I create a random entityquery somewhere, I don't seem to get any leak detection errors, even if I don't dispose it

rotund token
#

Queries auto dispose with world

#

They don't leak long term

misty wedge
#

Yeah, I just saw that

#

I wasn't sure if creating them using World also auto disposes them

#

so that's why

proud jackal
misty wedge
quick gazelle
#

Queries created by GetEntityQuery or EntityQueryBuilder.Build(SystemBase or SystemState) will be disposed with the system. Queries from EntityManager.CreateEntityQuery or EntityQueryBuilder.Build(EntityManager) will be disposed with the World.

misty wedge
proud jackal
rustic rain
#

I think...

quick gazelle
#

Not unless you use the SystemAPI version

proud jackal
#

^^^^ indeed (SystemAPI.QueryBuilder is, Unity.Entities.EntityQueryBuilder is not) :3

misty wedge
#

I'm talking about the code gen version of course ๐Ÿ™‚

misty wedge
rotund token
#

SystemAPI.QueryBuilder needs .RequiredForUpdate()!

proud jackal
#

btw RequireSystemComponentForUpdate<T> is just RequireForUpdate<T> soon tm ๐Ÿ˜›

misty wedge
#

Does anyone else have use for an OnFirstTimeStartRunning? I have having to check in OnStartRunning if this is the first run or not

rotund token
#

Just always update system

#

And early out from isemptyignorefilter

misty wedge
#

I'll need to do that on all queries though if I have multiple in the system

rotund token
#

Should be doing it anyway

#

To avoid setting up jobs with no entities in queries

misty wedge
#

But I'm lazy...

#

you keep forgetting this important facet

rotund token
#

Just always update system then without check ๐Ÿ˜…

#

Laziest way

rustic rain
rotund token
#

That's all require for update is doing

rustic rain
#

I mean

#

just the fact that it made it to OnUpdate

rotund token
#

The one important difference is if the system wouldn't run then you are adding overhead of dependency calls

rustic rain
#

there's OnBeforeUpdate

#

and etc

rotund token
#

But the point is more for systems that would be running nearly every frame anyway

#

But maybe not the whole system

raw mica
misty wedge
rotund token
#

or use mine in a few weeks! ๐Ÿ˜‰

misty wedge
#

Ah cool, are you nearing a state you are happy with?

#

It looked really promising last time I saw it

rotund token
#

Oh its been in a perfect state for a few months

#

Haven't had to change anything

hot basin
#

is managed component support kinda reduced in 1.0?

misty wedge
proud jackal
hot basin
#

and what is the best method to get entities from MB and to spawn entities from MB for now?

proud jackal
#

Ideally you should ask yourself first - Why are you accessing Entities in MB? Ideally you should use Systems to control your MB's from ECS data.
If you looked at all the options and decided to for some reason to stick to your opinion, then World.DefaultInjectionWorldSomethingSomething gives you the world, where you can get the entitymanager to access and edit your data.

hot basin
#

I want to spawn building ghost from UI - to be precise from button clicked event

#

and I'm using UI Toolkit if it helps

proud jackal
#

UIToolkit should totally still work in systems. Someone in here can explain how, as I've seen people already doing it :3
The gist is you need a managed reference (one thing you can do for that is in your MB Awake function do: var e = World.DefaultInjectionBlahBlah.EntityManager.CreateEntity() and then World.DefaultInjectionBlahBlah.EntityManager.AddComponentObject(this).
Then var e = SystemAPI.GetSingletonEntity<MyMonoBehavoiur>()

misty wedge
#

Yeah just grab all your stuff from the baked components and then its pretty much like a monobehaviour (e.g. set stuff on the ui document, etc)

hot basin
#

ok thanks for advice, I think I just drop foreach and do singleton instead, the problem was I can't make event lambdas inside Entities.ForEach

proud jackal
#

Ideally you should avoid using Entities.ForEach :3

hot basin
#

oh I can't SystemAPI.GetSingleton() on managed components

#

nvm, I can get it's entity

#

wow I can't even get managed component

proud jackal
#

And that's why SystemAPI.ManagedAPI is a thing comming soon tm :3 (for now use the fact that SystemAPI.GetSingletonEntity<T> does work ๐Ÿ‘€)

hot basin
#

but so what I can get entity if I can't get component from it?

rustic rain
#

dud, BRG is way too complex

#

and low level

hot basin
#

I mean, how to use this fact XD

proud jackal
#

So you get the entity and then use EntityManager.GetComponentObject ๐Ÿ˜„

#

EntityManager has mostly everything you need to both access, and change components, SystemAPI will just often be slightly faster, cause it can cache stuff (check source generated output to see it in affect) but nothing wrong in using EntityManager sometimes ๐Ÿ˜„

hot basin
#

thank ๐Ÿ˜„ completely forgot I can use EM ๐Ÿ˜„

#

@proud jackal thanks everything works now ๐Ÿ˜„

proud jackal
#

Yay! I'm glad :3

hot basin
#

why can I not resize buffer in Baker?

viral sonnet
#

huh? you mean setting the capacity?

hot basin
#

yes when I try this, it would throw bunch of strange errors in my subscene

var buildingBuffer = AddBuffer<TileBuilding>();
buildingBuffer.Resize(sizeSQ, NativeArrayOptions.UninitializedMemory);
#

and additionally it seems that accessing buffer by:

var tiles = ecb.SetBuffer<TileBuilding>(mapEntity);
var tile = tiles[id];
tile.building = entity;
tiles[id] = tile;

is breaking whole buffer

viral sonnet
#

resizing isn't supported in a baker. only at runtime. if you want a certain size, set the [InternalBufferCapacity(n)] of the IBufferElement struct

hot basin
#

size of buffer depends on another component value so cant use [InternalBufferCapacity(n)] and I'm using it with value of 0 as it's a huge buffer

#

but then why accessing causes it to reset/break?

viral sonnet
#

most likely the memory space is not setup

#

can you init the capacity at runtime when instantiated?

hot basin
#
buildingBuffer.Resize(sizeSQ, NativeArrayOptions.ClearMemory);

I'm doing this in initializing system now

#

what is equivalent of RequireForUpdate<>() in ISystem for singletons?

viral sonnet
#

most things are accessed through state state.RequireForUpdate<T>();

#

you can also use SystemAPI.GetSingletonRW<T>(); which sets a RW dependency for the scheduled job, not the Update call though

#

or without the RW, whatever you need

misty wedge
#

What you are doing looks more like you should be getting a typehandle on the buffer on the entity, and then just modifying it instead of using an ECB

hot basin
#

strange, inspector shows that buffer has sizeSQ elements

misty wedge
#

SetBuffer is for replacing the buffer

#

not modifying it

misty wedge
#

Huh, interesting. I always thought it was for replacing the entire buffer with a new one

#

Is there a reason you want to do it with an ECB?

misty wedge
hot basin
#

oh maybe you're right

misty wedge
#

I can't see it reading the buffer from the entity anywhere

hot basin
#

I wonder, how to use ECB to change DB, should I do a Lookup and then SetBuffer() to override it at certain BufferSystem?

misty wedge
#

Why do you want to use an ECB? Why not just directly set the contents of the buffer?

rustic notch
#

Hi, I got this. Is there any solutions?

misty wedge
rustic notch
#

Well I don't know where to set my breakpoints

misty wedge
#

You can pause execution and see where the threads currently are

rustic notch
#

Thx, I'll have a try

misty wedge
#

It rarely happens to me to, then I just kill the editor

hot basin
misty wedge
#

What's the error? And how are you changing it?

hot basin
#

nvm, this was a minor bug

#

it works with a lookup thanks a lot!

drowsy pagoda
#

I have a job that needs to look at a referenced entity (not the one being indexed) and use a ComponentLookup for that. It just so happens there is a condition that needs to check the same component against the entity being indexed.

My question is about performance. Is there a difference between:
A) Use both indexed entity and other entity in the ComponentLookup logic, or
B) Use ComponentLookup for other entity and use the in Component arg for indexed entity

gusty comet
#

How do you have a C# Attribute inherit another C# ATtribute? I'm trying to do somethiing like this

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    [AttributeUsage(AttributeTargets.Class, Inherited = true)]
    public class BehaviorSystemAttribute : Attribute
    {

    }

So that I just label all my physics-related systems with [BehaviorSystem] and if I ever decide to switch away from FixedStepSimulationSystemGroup I can just modify the above code instead of changing every single system's attributes

solar spire
#

Can't you just use inheritance, not this?

#

Inherit from UpdateInGroup, if it's not sealed

gusty comet
#

Right, but I want to automatically populate it with a system group behind an abstraction. I ended up just creating a BehaviorSystemBase with the required annotations

solar spire
gusty comet
#

Also, does FixedStepSimulationSystemGroup update like Monobehavior's FixedUpdate?

brave field
molten flame
#

Well it doesn't work for managed types so....

deft pilot
#

anyway to go from List<T> to NativeArray<T>?

molten flame
#

I don't think so, you just gotta loop and add em

brave field
deft pilot
#
public struct FooComponent : IComponentData
{
  public BarComponent Value;
  public ValueTypeT GetValue => Value.Value;
};
#

is this okay?

#

cause otherwise code can become

#
myComponent.Value.Value.Value;
spice vale
deft pilot
#

i've just redid it so i don't need to do that

#

i'll ping you one day if i'm forced to do it

spice vale
deft pilot
#

bookmarked for future

dense storm
#

How to properly destroy Entity properly when GameObject is destroyed?
I get this error : Destroying object multiple times. Don't use DestroyImmediate on the same object in OnDisable or OnDestroy.

private void OnDestroy()
{
  _combatEntityManager.DestroyEntity(_entity);
}
spice vale
#

but you are destroying an entity not object?

dense storm
#

Yes

spice vale
#

do you get that error message from destroying an entity?

dense storm
#

When MonoBehaviour triggers OnDestroy yep

#

Wait, could it be my companion link tries to destroy my GO as well?

#

Mono -> Destroy(Entity) -> Companion Link -> Destroy(GameObject)

#
namespace Unity.Entities
{
    class CompanionLink : IComponentData, IEquatable<CompanionLink>, IDisposable, ICloneable
    {
        public GameObject Companion;
        
        //...

        public void Dispose()
        {
            UnityObject.DestroyImmediate(Companion);
        }

        //...
    }
}
#

Yep, it destroys gameobject as well

spice vale
#

yeah but still weird that you get the error

#

nvm, I see what you mean

dense storm
#

Not sure how to do this properly hmm..

rustic rain
#

so you'll have to create a bridge to entity world

#

either store EntityManager

#

and entity values in your GO

#

or switch to destroying GameObjects from Systems

dense storm
#

That's what I did, I have a Bridge singleton, and _entity is cached in GO.

rustic rain
#

what bridge singleton?

#

that's not smth I meant

dense storm
#

I see, so I have to create a system that destroys them

#

Ok understandable, when GO destroyed, add component data to the entity, and destroy from Entity world

rustic rain
#

no sir

#

that's not what I meant either

#

why is your GO even destroyed in the first place

#

the correct (ECS) way would be destroying entity this GO is attached to

dense storm
rustic rain
#

are you doing ECS or OOP?

dense storm
#

Hybrid?

rustic rain
#

ah, the worst ๐Ÿ˜…

#

well, from what I noticed, ppl do hybrid differently too

#

some do OOP game architecture while keeping some ECS elements or sub systems

#

some do ECS while using certain classic game objects with companion links

dense storm
#

I'll give it a try with system that destroys their entity counterpart.

spice vale
#

but that will destroy the gameobject

rustic rain
#

isn't that's the goal?

#

in perfect scenario - game object don't do anything but rendering

dense storm
#

Yep, that's the goal

spice vale
#

not sure it will work if you do like this "Ok understandable, when GO destroyed, add component data to the entity, and destroy from Entity world"

rustic rain
#

everything can be done from within ECS, unmanaged and bursted

spice vale
#

since you will destroy GO twice then

rustic rain
#

I thought he decided to create a ECS system logic that destroys entity

#

which is it?

spice vale
#

That works

spice vale
#

Just remember that dispose will be called on the CompanionLink as soon as it is removed or the entity is destroyed. So all destroying needs to happen from the ecs side.

rustic rain
#

๐Ÿค”

#

I wonder if it's possible to make game object instantiation into entity burstable

#

or maybe Unity already did that...

#

considering enities with companion link get instantiated bursted right away

spice vale
#

Companion link and gameobject is managed, it can't be bursted

rustic rain
#

but game object itself is not

#

it's in c++ side of engine

#

which can be called from Burst

#

and assigning to entity component is done unmanaged, because it's just index

#

and assuming array/list of managed components is pinned

#

you can fill it out of C++ as well

spice vale
#

GO is just index? did not know that.

rustic rain
#

no

#

managed component on entity

#

is just index to managed component list

spice vale
#

mhm

proud jackal
rustic rain
#

idiomatic foreach?

#

is that Entities.ForEach(()=>{}) or smth else?

proud jackal
#

SystemAPI.Query

rustic rain
#

ah

#

but that's mainthread only, no?

#

or was that a case?

proud jackal
#

Indeed is!.. And IJobEntity is your threaded option :3

#

Entities.ForEach == bad comp time, and it also doesn't allow for normal syntax like continue vs return break etc.

rustic rain
#

bad iteration time?

#

last time I checked

#

it codegens into efficient IJobEntityBatch (0.51)

#

which was pretty much all required for best iteration

brave field
proud jackal
#

Indeed does.. But it's more a problem of CompTime, the dataflow analysis of capturing a lambda is really expensive.

proud jackal
rustic rain
proud jackal
#

indeed

brave field
#

@proud jackal btw how to increase idomatic foreach max 8 parameters limit without using aspect? Something like custom delegate for Entities.ForEach.

rustic rain
#

aaah, I didn't realise what you meant by bad comp time ๐Ÿ˜…

brave field
rustic rain
#

yeah

#

even my IDE struggles

#

when I click inside lambda here

#

offering me dozens of potential arguments

#

ripping perfomance

brave field
#

๐Ÿ‘€ The thing I dun like Entities.ForEach is u always want to create temp var just for Entities.ForEach to consume

rustic rain
#

Could you guys remind me what class/file is responsible for SystemAPI codegen?

#

I want to take a look myself and see whether I can implement my own solution

#

for codegen

proud jackal
# brave field I guess u mean the time taken to scan Entities.Foreach code before codegen?

The act of doing codegen on a lambda == sluggish. ๐Ÿ˜… .. In anycase it also isn't really a nice pattern in general, not very normal foreach by design, the fact that you can't break is not nice to newcomers. It also expects newcommers to think threading is as easy as flipping a switch, which it kinda isn't. foreach->Ijobentity gives you a better idea of oh i should add a number here kinda thing. But I digress..

All sourcegen code can be found in com.unity.entities/Unity.Entities/SourceGenerators/Source paraphrasing the file path. Then you should find a solution called SystemContextSytemModule, which contains a SystemAPI.SystemRewriter ๐Ÿ˜„

brave field
proud jackal
#

Currently not a thing, aspect is needed to do that :3

#

Or again, IJobEntity that can take N amount

brave field
brave field
spice vale
#

Btw @proud jackal how does idiomatic foreach compare to that approach?

#

does it have better performance? or just less boilerplate

rustic rain
late mural
#

can i use memcpy to copy arrays from 1 place to another, and use size as TypeSize*LengthOfArray?

spice vale
#

but the sequence in which you access each entity should be the same, no matter if you use chunk iteration or iterate the entity array? So if memory access is the bottleneck they should have about the same speed?

late mural
spice vale
late mural
spice vale
#

if your array is for example: IntPtr[] that is managed, and would need to be pinned before.

late mural
#

ah, no, rather i meant im using c style arrays, like:

int* IntArray;
spice vale
#

so did you allocate these yourself or?

late mural
#

im using a c api, it allocates them somewhere and gives me the pointers

spice vale
#

Ok, well as long as they don't move its fine.

late mural
#

they move sometimes, but always stay fixed if i tell them to using the api's map function, so it should be fine lol

dense storm
#

Why can't CompanionLink just have another bool parameter for DontDestroyCompanionObject

rustic rain
#

companions are created with entities

#

what would be the reason for them to keep existing once entity is destroyed?

dense storm
#

Because sometimes we want to go 80% GO 20% ECS instead of the other way

rustic rain
#

๐Ÿค”

#

then you might want to use smth other than companion links

late mural
#

im wondering does float3 have any function that does the same thing as Vector3.Scale()?

spice vale
#

its just normal multiplication on float3s

late mural
#

oh nice!

spice vale
#

in general any operation that works on floats, is now componentwise for float3s

late mural
#

wondering, which do you reckon would be faster:

SomeRandomVector3 += (Vector3)(SomeVector3 * SomeOtherFloat3)

or

SomeRandomVector3 += Vector3.Scale(SomeVector3,SomeOtherVector3)

also do you reckon it would be any faster if i put it in a job?

stone osprey
#

unitys ecs already has a way to enable/disable components right ? Or is this still wip ?

late mural
wicked trout
#

Hi! (Sorry if I'm interrupting) I'm trying to generate Physics Bodies from script without using the Physics Body Authoring Component with a Subscene. I've added to the Entity all the necessary components: Translation, Rotation, Physics Mass, Physics Damping, Physics Velocity, Physics Gravity, etc. But when I press play the Entity does not move/fall to infinity. Is it because I need to add a Physics Collider or maybe Because I have to assign a Physics World Index? The Problem is I can't find a way to add an Index. Does anybody know how to do/generate it?

spice vale
late mural
#

anyway i can get tranform.forward as a float3 then?

spice vale
#

it can essentially do just one multiplication that works all elements at the same time, (SIMD)

#

math.forward()

late mural
spice vale
late mural
spice vale
#

then just convert the forward vector to float3

late mural
#

and that wont be too slow?

spice vale
#

I don't think so, I might be wrong but I think burst can optimize the cast away, since its the same data in vector3 as float3

late mural
#

ok, so a faster version would be this?

SomeRandomVector3 += (Vector3)((float3)SomeVector3 * SomeOtherFloat3)
spice vale
#

I think so

late mural
#

ill try that and report back, thanks!

#

wait are float3 and Vector3 the same in size and memory layout? As im dealing with pointers i might be able to just interpret the memory as a float3 assuming they have the same layout

spice vale
#

I think so, but not 100% sure

late mural
#

ill also test that then and see if memory stays good

spice vale
#

You can check the burst inspector and see what it compiles down to

late mural
#

burst has its own inspector? Cool!

spice vale
#

Jobs/Burst/Open Inspector

late mural
#

never heard of any of those lol, where would i find this burst inspector you speak of?

#

note im still in the 2021 version of dots for now

spice vale
#

OK, its somewhere in the top menu then

late mural
#

thanks!

#

yup found it

#

how do i find my function in this cursed menu lol

spice vale
#

you should be able to search for it

late mural
#

im trying, it can't seem to find it

spice vale
#

is your function static, has the burstcompile attribute, and its containing class has it too?

late mural
#

ah i didnt make it static, and the class doesn't have BurstCompile either

#

ill quickly do that, thanks!

#

hmm i dont think i can make it static unfortunately, is it required?

spice vale
#

for burst, yes. But you can make a job also, instead of a static method.

late mural
#

ah and then can i burst that job then?

spice vale
#

yup

late mural
#

good, thanks, ill try that and report back!

wicked trout
#

Alright thanks! I'll try it out.

late mural
#

perhaps im doing it wrong though, ill send my code

#

sorry for flooding chat....

#

hold on ill just resend it as that pastebin site thing so i dont flood chat lol

#

anyway, any speed improvements you can see?

spice vale
#

how long is the array?

late mural
# spice vale how long is the array?

the array can be anywhere from 0 to 30 thousand in length, it shouldnt matter much though right, cause it is just grabbing one index out of it?

spice vale
#

Scheduling a job has some overhead, so it only makes sense if you have a large enough array

late mural
#

ah unfortunate

spice vale
#

even just invoking burst code has some overhead, but for the most part that should be very tiny.

#

try using .Run() instead of schedule

late mural
#

ok i shall!

#

guessing i dont need .complete() then?

spice vale
#

nope

#

but wait, are you running this in a loop?

late mural
#

and yup still way slower than just using the line i commented out

spice vale
#

So basically the operation you are doing is not expensive enough for it to be even worth running it in burst

#

its just a multiplication and add

late mural
#

unfortunate, what would be the fastest alternative then?

spice vale
#

just run it without burst

late mural
#

vector3's or float3's?

spice vale
#

doesn't matter really

late mural
#

float3's seem faster in my testing, so ill use them-ish i guess

#

at some point i would like to run this in a loop, but for now i doubt that is possible due to the odd way i setup my collision detection, thanks for all the help!

spice vale
#

if you would for example launch multiple particles at the same time, it would be worth doing a job that does that with a loop inside.

late mural
#

multiple particles can be in the trigger volume at once, but ive currently got it setup to run the method multiple times, rather than running it once with an array of all the particles in collision with the trigger volume, so eventually ill be able to make it more efficient, thanks for all the help! (for now it is a pain to change, cause everything else that relies on this collision detection system would need to be changed to make this work lol)

open shore
#

I want to make a simple ComponentSystem that runs once per frame in the same rate as MonoBehaviour's Update method. Which attributes do I need to add to the system?

late mural
spice vale
#

if direction and power is always same you don't have to compute that in the job

dense storm
#

Anyone got a sample on how to display graphic with entities?

#

AddComponent<RenderData> no longer available, and don't know the new format

spice vale
dense storm
#

I just need to render basic mesh and materials without animations.

#

Creating entities from scratch need some pointers.

open shore
late mural
spice vale
spice vale
open shore
#

oh I thought I had to specify a system for that attribute good to know it works with groups too.

#

ty!!

spice vale
dense storm
late mural
late mural
#

so ill just do it once before the job and pass it

frosty siren
#

what is ScheduleParallelByRef in 0.51?

deft pilot
#

before i try this

#

can you have a buffer of buffers somehow?

#

or do i need a buffer of entities

#

which also have buffers?

#

basically trying to emulate List<List<T>>

spice vale
#

with like NativeList<NativeList<int>>

misty wedge
#

You will lose the ability to write to the inner list inside of a job though

misty wedge
deft pilot
#

and not use IBufferElement?

misty wedge
#

You can, but the safety system will not let you write to it from a job

deft pilot
#

thats problematic

misty wedge
#

You can use an unsafe container or wait until unity manages to add this functionality to the safety system. But ideally if it's only a single native list you would use a dynamic buffer

deft pilot
#

okay i'll have to rethink my design for now then

#

see if i can flatten it

misty wedge
#

Is this mutable data? Or is it just for reading stuff

deft pilot
#

its like yes and no

#

weirdly

#

context wise

misty wedge
#

Also, a dynamic buffer already behaves like a List<List<T>> since you can have multiple entities with the buffer on them

deft pilot
#

yeah

#

but i need a link to them

#

wait

#

i see what you mean

misty wedge
#

You can store a reference to the entity

deft pilot
#

yeah

#

but thats what i just said

misty wedge
#

I mean it's not really a "buffer of entities", it's just entities

deft pilot
#

yeah

#

hmm

#

i'll go back to my drawing board for alittle bit

#

make sure this is absolutely necessary

misty wedge
#

You can also look into blobs, maybe those are better suited for your problem

deft pilot
#

hmm based on quick google don't think so

#

basically i have an entity that has 1 vector2 and a buffer of vector2s

#

i'm trying to store all the A* pathing outcomes for 1:Many of those

misty wedge
#

The first vector is the starting point and the buffer are the destinations?

deft pilot
#

yeah

#

hmm

#

okay i think i got it

#

i don't care about what the paths belong to

#

so i can just flatten this to 1d

#

just get the AI to pick a random path to use

#

wait no

#

that won't work i need to know the end

#

hmm

misty wedge
#

I'd just go the lazy route and use an UnsafeList<UnsafeList<T>> if you really need it all on 1 component

deft pilot
#

its okay

#

i just need another component

#

i think

#

okay i'll use index's as keys

#

that should work

#

makes it flat and i can reverse lookup both arrays

#

to get path and end point

#

since there will be N array elements for both

spice vale
#

Seems like it is not possible to destroy a GameObject from a system's OnDestroy() that's running in the editor world... Annoying... Anyone done this and found a workaround?

spice vale
#

no idea... seems like a bug.

rustic rain
#

what error do you get?

spice vale
#

when I enter play mode the editor world closes, so OnDestroy is called on my system and the GameObject is destroyed, but as soon as I exit playmode the GameObject is back again

frosty siren
misty wedge
#

What the name says, it passes the job struct by ref instead of copying it

rustic rain
spice vale
#

yes

rustic rain
#

DestroyImmidiate

#

should od it

spice vale
#

I use that

rustic rain
#

you also should have gotten a warning

#

about it

spice vale
#

I know destoy doesn't work in editor

frosty siren
spice vale
#

but I use DestroyImmidiate

#

thing is, If I cache the GOs I want to destoy in a static list and delay destruction until the systems OnCreate is called once I exit play mode, they are destroyed fine.

misty wedge
#

It will load the old version would be my guess

spice vale
#

That sounds like it could be

#

Can you manually trigger serialization?

misty wedge
#

You can try marking it dirty and then saving

#

although maybe you can even skip the marking it dirty step, I think a direct call to save will do it regardless of whether or not it should

#

Ah yeah, there's even a note about it

spice vale
#

What method is that?

spice vale
#

Thanks I'll play around with this and see if i can fix it.

mild ledge
#

I'm still super confused by the entities workflow. Why would I even do anything else than schedule jobs from a system if a systems update is main thread only

misty wedge
#

Because scheduling also has overhead, sometimes it can be faster to just do it on the main thread. Also you may need some previous data to schedule your jobs

mild ledge
#

I can do that in job and schedule the next job from a dependency. I mean I get a lets say MainPlayerMove system that moves my 1 player based on input to be just a Update on the system

#

but moving the 10k zombies that chase the player needs to be a job

misty wedge
#

It's up to you really. There's also some stuff that is just easier on the main thread if it uses managed types that haven't been converted to ECS

#

e.g. input system, 2d stuff, etc

rustic rain
#

for example: player input

#

let's say player spawns entities

#

it's structural change, that can't be done in a job

#

so why create ECB, schedule it when you can instantly process input

#

and spawn entities

#

after all

#

all ECB run through main thread in the end anyway

misty wedge
#

Ideally in this case you would move your system close to another structural change

rustic rain
#

yeah

#

I have whole groups

#

dedicated to it

misty wedge
#

Yep, just letting them know that it's not super efficient to do that "between" two other structural changes

mild ledge
#

I get that. It's just most tutorials I see do for each entities in a system Update to move the enemies etc etc

#

and that seems like it should be in a job

#

input, spawning etc etc are ok on the main thread ofc

rustic rain
#

Entities.ForEach ... .Schedule()/.ScheduleParallel()
those?

#

they schedule codegened jobs

misty wedge
#

I mean the cool thing is you can always choose. e.g. IJobEntity has overloads for all types of scheduling, and can also be run on the main thread

#

So "everything" is already in a job, it just depends on how you are scheduling (or in the case of Run, not scheduling) it

mild ledge
#

" Entities.ForEach is fundamentally a job generator, and it makes it very easy to create parallel jobs. This unfortunately comes with a complexity cost and weird arbitrary constraints, which is why more explicit approaches are preferred. Those explicit approaches (IJobEntity) are covered later in this tutorial." I see

misty wedge
#

Also I would not use Entities.ForEach anymore, it is being deprecated in the next update

#

Use either the SystemAPI.Query API, or IJobEntity

#

(or IJobChunk if you want to be more explicit on what is happening)

mild ledge
#

I was talking about seeing many examples of ``` [BurstCompile]
public void OnUpdate(ref SystemState state)
{
// The amount of rotation around Y required to do 360 degrees in 2 seconds.
var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI);

    foreach (var transform in SystemAPI.Query<TransformAspect>())
    {
        transform.RotateWorld(rotation);
    }
}```
rustic rain
#

this is main thread

mild ledge
#

this is not a job at all right

misty wedge
#

Yes, it runs on the main thread

mild ledge
#

regural everyday foreach loop

misty wedge
#

Well, burst compiled, so still very fast

mild ledge
#

well yes

misty wedge
#

Also has good cache coherency due to the the way the data is layed out, and does not allocate any garbage

rustic rain
#

don't take it too close to heart, unity themselves probably still haven't figured the best way to organise systems, so ๐Ÿ˜…

#

It's probably depends heavily on project too

misty wedge
#

Regarding your example, I would probably put that in a IJobEntity

misty wedge
mild ledge
#

I think I'm going to watch the 3 hours V rIsing stream

misty wedge
#

I thought they only used DOTS, not ECS?

#

I've still not gotten around to watching it...

mild ledge
#

bro at this point I dont even know the difference.... I've been using Jobs in regular projects for a while now

#

am I using DOTS ?

#

fuck if I know

misty wedge
#

DOTS = Job, Burst, Collections, etc

#

ECS = Entities, Physics, Graphics, etc

#

(vs "normal" MonoBehaviour stuff)

mild ledge
#

ECS is part of the whole DOTS stack as far as I can tell

rustic rain
misty wedge
#

Yeah that might be better

rustic rain
spice vale
rustic rain
#

you are not required to use it

#

but ECS itself uses whole power of DOTS

mild ledge
#

but the guy in the stream starts talking about data oriented design so I guess they did ECS

misty wedge
spice vale
#

no errors

misty wedge
misty wedge
# spice vale no errors

Weird. I've never tried this, maybe you just can't save the scene while the game is already starting?

#

You could write a custom "start" script that does your cleanup stuff or something? Not the cleanest solution though...

spice vale
mild ledge
#

any official docs on how to use the new input system with ecs ?

misty wedge
#

There is no specific integration

#

So just use them separately, and modify the ECS state however you like according to your inputs

mild ledge
#

my idea was to have a InputData component that a system fills up. I'm not understanding how to get the InputActions connected to the system

misty wedge
#

Just read from them as you would normally?

mild ledge
#

from a monobehaviour ?

misty wedge
#

Why would you need a monobehaviour, just read from it in a system

rustic rain
#
  1. create a huge struct stored in NativeReference<T> and just access specific fields through pointer
#
  1. use components for every action and it's state
#

for example

#

Started<RMB>
Performed<RMB>
Cancelled<RMB>

#

for now I use second approach, I do enjoy it
But it certainly has downsides

misty wedge
rustic rain
#

it doesn't change the fact that you will access it only once

#

kek

#

allthough

#

I see what you mean

misty wedge
#

Accessing it by pointer sounds more complicated than just reading a component

rustic rain
#

well, not really

#

NativeReference<T> is easy

#

it's like native array of size 1

#

you pass it by value

misty wedge
#

Yeah but why do that

#

Just put the state in a component on an entity

rustic rain
#

and then add dependency overhead for what?

#

it's input

#

written only once before World update

#

read only in World

misty wedge
#

If you want to micro-optimize that far sure

rustic rain
#

it's not even micro-optimization

#

it's just doing it simpler way

misty wedge
#

People using unity normally are often times not very familiar with pointers in C#

rustic rain
#

NativeReference<T> is easy

#

it's certainly better

#

than getting entity query for singleton

#

and accessing it through entity manager

#

every frame

misty wedge
#

So you mean just pass the NativeReference to the job

rustic rain
#

well, considering you usually use input for one time actions

#

you are probably just going to read it in OnUpdate

#

for some boolean for example

misty wedge
#

I know, but often times when you try to explain something you skip over details, and that makes it hard to understand what you mean

rustic rain
#

and then do early return if it's not

rustic rain
#

๐Ÿค”

#

I guess

misty wedge
#

๐Ÿ˜…

#

Then yes, I agree, the approach you mentioned is easier, I originally thought you meant something completely different

#

Something I've been wondering, do ECBs do any kind of pre-processing on the requested commands? For example, if I add a component and then remove a component on an ECB, will it move that entity twice? or not at all?

rustic rain
#

but I wouldn't count on it

#

since they specifically mentioned

#

that if you destroy entity in ECB

#

and then add smth to it

#

it'll throw

misty wedge
#

Seems kind of difficult if you have multiple systems that can e.g. destroy entities in an ECB

rustic rain
#

one more headache to look for ๐Ÿ˜…

mild ledge
#

Wait so I can use the generated c# class, new it in the systems oncreate and read inputs

misty wedge
#

Yes

mild ledge
#

Why the f didnt you say so๐Ÿคฃ๐ŸคฃUnityChanThumbsUp

misty wedge
rustic rain
#

inputAction.performed += _ => em.AddComponent(inputEventEntity, performed);

#

I usually do it this way

misty wedge
#

Alternatively you could try baking InputActionReference and reading the baked references, but I just read an instance of the generated C# class

mild ledge
rustic rain
#

well, that works too

#

but I tried it

#

and it sucks for all in ECS approach

#

because it's like combing OOP with ECS

#

result is uugh

#

so instead I decided to use all those callbacks

#

to just setup state in World

#

so systems can react on it

mild ledge
#

I still dont get your aproach

rustic rain
# mild ledge I still dont get your aproach

Here's simple toggle switch for example

    [UpdateInGroup(typeof(EarlySimulationSystemGroup))]
    [BurstCompile]
    public struct ToggleMapHandler : ISystem
    {
        private Entity _requestEntity;

        public void OnCreate(ref SystemState state)
        {
            state.RequireForUpdate<Performed<ToggleMap>>();

            _requestEntity = state.EntityManager.GetOrCreateSingletonEntity<Singleton<OpenMapRequest>>();
        }

        public void OnDestroy(ref SystemState state) { }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            state.EntityManager.AddComponent<OpenMapRequest>(_requestEntity);
        }
    }
#

everytime I press ToggleMap action button

#

it creates an entity with this tag

#

and this system runs OnUpdate just once

mild ledge
#

What is Performed<ToggleMap> and what does it do ? Somehow I still dont get it, thank you for taking the time to explain

rustic rain
#

just a tag

brave field
#

๐Ÿฅฒ Sadly dots input is not a thing yet

rustic rain
#

emtpy struct

mild ledge
#

So who reads that for examole M was pressed to toggle the map ?

rustic rain
#

what it does - it exists the same frame Performed on ToggleMap action is called

rustic rain
#

state.RequireForUpdate<Performed<ToggleMap>>();

#

this makes this system run only if this component exists in world

#

and I clear all those components on end of frame

brave field
misty wedge
#

In the full release at the latest iirc

mild ledge
misty wedge
#

Not necessarily in the next one

brave field
#

๐Ÿฅฒ I still fixing compile errors of my production project. Can't enter play mode yet

rustic rain
#

Here's more complex

    [UpdateInGroup(typeof(PlayerInputGroup))]
    [BurstCompile]
    public partial struct FocusOnPlayerHandler : ISystem, ISystemStartStop
    {
        private Entity _player;
        private Entity _cameraEntity;
        private EntityQuery _playerQuery;

        public void OnCreate(ref SystemState state)
        {
            var em = state.EntityManager;

            _cameraEntity = em.GetOrCreateSingletonEntity<SpaceCameraTag>();
            state.RequireForUpdate<Pressed<FocusCameraOnPlayer>>();

            _playerQuery = state.GetSingletonEntityQueryInternal(typeof(PlayerTag));
        }

        [BurstCompile]
        public void OnStartRunning(ref SystemState state) { _player = _playerQuery.GetSingletonEntity(); }

        // [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var em = state.EntityManager;

            var pos = em.GetComponentData<LocalToWorld>(_player).Position;
            var sysID = em.GetSharedComponent<StarShared>(_player).systemID;

            em.SetCameraPosition(_cameraEntity, pos);

            // Set star system if it's not already current
            if (sysID != em.GetEntityStar(_cameraEntity))
            {
                em.SetStarSystem(_cameraEntity, sysID);
                em.FixRendering();
            }
        }


        public void OnStopRunning(ref SystemState state) { }
        public void OnDestroy(ref SystemState state) { }
    }
#

state.RequireForUpdate<Pressed<FocusCameraOnPlayer>>();
So every frame this component exists

#

System runs

#

meanwhile this component gets created in Started and gets removed in Cancelled

#

of NIS callbacks

mild ledge
#

Ok I get it.. where do you hook into the nis callbacks ?

rustic rain
#

out of OnCreate of other system

mild ledge
#

And you use the genersted c# class there ?

rustic rain
#
            var inputActionTypes = TypeUtility.GetAllAssignableFrom(typeof(IEventAction)).ToList();
            _inputExtensions = TypeUtility.InstantiateAllOfType<IInputExtension>();

            foreach (var inputExtension in _inputExtensions)
            {
                var asset = inputExtension.Asset;

                inputExtension.RegisterCustomInput(em, inputEventEntity, pressedEventEntity);
                asset.Enable();
                foreach (var inputAction in asset)
                {
                    var name = inputAction.name.ToLower();
                    foreach (var type in inputActionTypes)
                    {
                        if (!type.Name.ToLower().Equals(name)) continue;
                        if (allStarted.TryGetValue(name, out var started))
                        {
                            inputAction.started += _ => em.AddComponent(inputEventEntity, started);
                        }

                        if (allPerformed.TryGetValue(name, out var performed))
                        {
                            inputAction.performed += _ => em.AddComponent(inputEventEntity, performed);
                        }

                        if (allCanceled.TryGetValue(name, out var canceled))
                        {
                            inputAction.canceled += _ => em.AddComponent(inputEventEntity, canceled);
                        }

                        if (allPressed.TryGetValue(name, out var pressed))
                        {
                            inputAction.started += _ => em.AddComponent(pressedEventEntity, pressed);
                            inputAction.canceled += _ => em.RemoveComponent(pressedEventEntity, pressed);
                        }

                        inputActionTypes.Remove(type);
                        break;
                    }
                }
            }
rustic rain
#

I just iterate ActionMaps for InputAction

#

and automatically assign callbacks to them

#

name based

#

if type name and name of InputAction matches

#

I create all callbacks for all registered components

#

basically just for components that are used

#

but

#

I assume there's better solution

#

with just 1 giant struct

#

which contains all values for those actions

mild ledge
#

I assumed that for 1.0 at least input would work๐Ÿคฃ

rustic rain
#

because this way you'll avoid any structural changes at all

rustic rain
#

let's be glad we at least have character controlled for free

#

๐Ÿ˜…

mild ledge
#

For 0.5

rustic rain
#

well, 1.0 is not released yet to complain about it

#

kek

mild ledge
#

I can complain that there is no proper input handling in a 1.0 version even if its experimental

rustic rain
#

also no 2D, no animations, no audio

#

๐Ÿ‘ด

mild ledge
#

1.0 means all the parts should at least be there but what ever just unity things

rustic rain
#

nnnah

#

it's just ECS that will be ready

#

everything else will probably be external packages

#

because I'm certain, those things will not do well with existing dev's solutions

mild ledge
#

Wdym no audio? Dots audio has been a thing since mega city they havent expanded on that at all ? Do i need to do magic trickery to play a bullet impact sound as well ?

rustic rain
#

oh, it's scrapped

#

you can use FMOD

#

it's burst compatible

#

since it's c++ native

mild ledge
#

How do you play sounds ?

rustic rain
#

you better read FMOD about it

#

in short, you just create event instance and use method on it

#

like

#

musicEvent.Play();

mild ledge
#

Fmod has ecs documentation?

rustic rain
#

no

#

it has nothing to do with ECS

mild ledge
#

So I pass the FMODUnity.EventReference to a component from the Baker I beleive it is called now and used to be AuthoringComponent and then from a system I can call the fmod runtime manager to play the sound ?

rustic rain
#

which is pog

#
    [UpdateInGroup(typeof(InitializationSystemGroup))]
    [BurstCompile]
    public partial struct AddSoundInstanceSystem : ISystem
    {
        private EntityQuery _query;

        public void OnCreate(ref SystemState state)
        {
            _query = state.GetEntityQuery(new EntityQueryDesc
            {
                None = new[] { ComponentType.ReadOnly<SoundInstance>() },
                All = new[] { ComponentType.ReadOnly<SoundSource>() },
                Options = EntityQueryOptions.IncludeDisabled
            });
            state.RequireForUpdate(_query);
        }

        [BurstCompile] public void OnDestroy(ref SystemState state) { }

        public void OnUpdate(ref SystemState state)
        {
            var em = state.EntityManager;
            using var entities = _query.ToEntityArray(Allocator.Temp);
            using var sounds = _query.ToComponentDataArray<SoundSource>(Allocator.Temp);

            for (int i = 0; i < entities.Length; i++)
            {
                em.AddComponentData(entities[i],
                    new SoundInstance { value = RuntimeManager.CreateInstance(sounds[i].guid) });
            }
        }
    }

Smth like this

#

And then played like this

    [UpdateInGroup(typeof(InteractionSystemGroup))]
    [BurstCompile]
    public partial struct SoundInteractionSystem : ISystem
    {
        [BurstCompile] public void OnCreate(ref SystemState state) { }
        [BurstCompile] public void OnDestroy(ref SystemState state) { }

        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            state.Entities.WithAll<InteractedTag>()
                .WithAll<InteractionSound>()
                .ForEach((ref SoundInstance sound) => { sound.value.start(); })
                .Run();
        }
    }
spice vale
# mild ledge I can complain that there is no proper input handling in a 1.0 version even if i...

There is no reason to have a specific input system for dots, its not like input is a bottleneck in any game. Here is an example from unity of how to use the new input system with dots: https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/PhysicsSamples/Assets/Common/Scripts/DemoInputGatheringSystem.cs

GitHub

Contribute to Unity-Technologies/EntityComponentSystemSamples development by creating an account on GitHub.

mild ledge
#

Wait wait this is what I was looking for

viral sonnet
#

the argument is sound. i think that's also the reason why they dropped priority on audio. unity knows everyone uses fmod

mild ledge
#

Ofc unity hide the input example in the physics demos kekl

stone osprey
#

Soo not entirely dots or unity specific but im trying to replicate a pure c# archetype based ecs.
If anyone is interested let me know ^^ i think its pretty interesting, the current version is still very very basic but i already have a benchmark for the iteration performance.

rustic rain
#

๐Ÿ˜…

stone osprey
#

Yeah but tied to unity, we cant use it outside of unity right ? ^^

rustic rain
#

no you can't

#

why not just use existing C# ECS libraries?

#

why invent a bicycle? ๐Ÿ˜…

stone osprey
#

Yep thats why i made my own one and for learning purposes ^^
Couldnt find any archetype based c# ecs... only sparsesets

rustic rain
#

well, pure C# without burst will not do well if you try to do it same way as unity

#

whole reason to return to monke do unmanaged code is because Burst

stone osprey
#

The main purpose was actually learning.
Yeah, "my" version does not use unmanaged code. But i try to utilize the L1 cache atleast ^^

I mean if you want you can take a quick look at it : https://github.com/genaray/Arch
Its not that much code, pretty small currently ^^

GitHub

A C# & .NET 6.0 based Archetype Entity Component System ( ECS ). - GitHub - genaray/Arch: A C# & .NET 6.0 based Archetype Entity Component System ( ECS ).

rustic rain
#

oof

#

well, I don't favor this approach because it's way too much GC allocation

#

for every little change in archetype

#

tons of allocated data

stone osprey
#

Interesting, let me hear... what exactly do you mean ? ๐Ÿ˜„

rustic rain
#

Unity chunks are unmanaged, no Garbage Collector involved

#

managed arrays are

stone osprey
#

Are thats what you mean, well yes... the only way to make it compatible with public struct MyData{ string s } components for example was to use regular arrays.
I also played around with a chunk variant that actually is unsafe and uses manual allocation of memory... i had the idea that the archetype could just support both, based on what the types are basically. If all of the passed types are unmanaged it could use the manual allocation approach and be more efficient probably

rustic rain
#

I'd say, just use Lists

#

for every type

stone osprey
#

I just wonder... if i can really utilize the cache with the current managed array approach. Since they are... managed... but every single person on this planet has a different opinion on this, most people actually told me that they are of course cache efficient

rustic rain
#

and figure a nice approach to iterate over them

stone osprey
#

But lists destroy the whole cache utilization idea ๐Ÿ˜ฎ

rustic rain
#

no they don't?

stone osprey
#

Dont they ?

rustic rain
#

I actually tested giant array approach vs chunks approach

#

arrays won

#

List is just array with better handling

stone osprey
#

So chunks are not usefull ? Since the idea was... well... one chunk = 16kb, fits perfectly in the cache... insane iteration speed...

#

Therefore thats the iteration itself :

            ref var chunk = ref archetype.Chunks[chunkIndex];
            var transforms = chunk.GetSpan<Transform>();
            var rotations = chunk.GetSpan<Rotation>();
            
            ref var transform = ref transforms[0];
            ref var rotation = ref rotations[0];

            for (var index = 0; index < chunk.Capacity; index++) {

                ref var currentTransform = ref Unsafe.Add(ref transform, index);
                ref var currentRotation = ref Unsafe.Add(ref rotation, index);
                
                currentTransform.x++;
                currentRotation.w++;
            }
rustic rain
#

no, that's not the idea

#

I tested perfomance

#

in unmanaged context chunks are very versatile vs large arrays

#

so unless you want to hardcode access to them in your every system, just use chunks ๐Ÿ˜…

#

in managed scenario though

#

hmm

#

I'd guess your chunk can contain data about at what indices starts it's entities data in those arrays

stone osprey
#

Damn... but why ? I cant imagine a reason why one big array is faster than ๐Ÿ˜ฎ
So chunks only make sense for unmanaged memory, interesting

stone osprey
viral sonnet
#

not relates to your question though. might just give you some ideas

misty wedge
#

If I'm using native streams and want to schedule something in parallel, do I need to set the index count to Threads * Chunks? Or can I check in a thread if the writer for that thread has been set to the correct index already

#

Also, I'm still not 100% clear on the usage. Do I pass the NativeStream itself to the job, then create a writer, or do I pass the writer to the job (calling BeginForIndex on the main thread)

coarse turtle
#

not sure how it can be tied to packages

viral sonnet
#

in the job, use BeginForIndex before writing

#

i use the unfilteredChunkIndex for the index but that's up to you what you need. it's also possible to use the entity index if you need to group it per entity and not chunk

#

though that's a bit more tricky in 1.0 where IJobChunk doesn't have the entityIndex as parameter anymore

misty wedge
#

Also couldn't each thread just keep re-using the same index?

viral sonnet
#

chunkCount is enough.

misty wedge
#

I thought the indices can't be re-used? Or is that just after reading

#

Since I need to call EndForIndex after the batch is finished

viral sonnet
misty wedge
viral sonnet
#

you can write multiple times to the same index

#

yes ๐Ÿ™‚

misty wedge
#

Ah, alright. I thought you couldn't

#

That makes more sense then, thanks ๐Ÿ™‚

viral sonnet
#

that's why the reader returns a count when you start reading from an index

misty wedge
#

It just returns the same thing as RemainingItemCount right?

#

(once you set the index)

#

I'm trying to use streams more since they seem really useful for parallel operations where the total count is unknown (since the other parallel writers can't resize the underlying collection)

viral sonnet
#

yeah it does in ReadUnsafePtr, i have a while (stream.RemainingItemCount > 0) so it's fine.

rustic rain
#

๐Ÿค”

spice vale
rustic rain
#

anyone worked with BRG yet?

I'm trying to understand whether I can render into specific RenderTexture

#

oh man, this API is so bad to work with

viral sonnet
spice vale
#

sure, but after that you can't write to that index again, right?

viral sonnet
#

no, theoretically it would work but BeginForEachIndex sets the ElementCount to 0 so not with the NativeStream implementation.

spice vale
#

So basically you can write multiple times to the same index once ๐Ÿ˜†

misty wedge
#

That makes native streams really useless for IJobEntity then, unless you create a buffer for each entity which does not seem like a good idea

viral sonnet
#

correct ๐Ÿ™‚ i must be misremembering this part - i thought i did this in the past at some point. how the code looks though, 100% not the case ^^

misty wedge
#

What do you mean?

viral sonnet
#

opening an index for each entity is fine

misty wedge
#

Really?

viral sonnet
#

yeah, the memory block. m_BlockStream->Ranges is pre allocated beforehand

#

it's overhead, sure, but very small

misty wedge
#

Oh, opening an index sure, but I mean creating a native stream with that many indices

viral sonnet
#

yep, even that

misty wedge
#

Oh ok, I thought it was slow-ish due to this comment:
Using a job to allocate the buffers can be more efficient, particularly for a stream with many buffers.

#

I'm guessing using an IJobChunk with the unfilteredChunkIndex as the stream index is probably faster though

viral sonnet
#

sure it is, especially when reading then

#
        {
            long allocationSize = sizeof(UnsafeStreamRange) * forEachCount;
            m_Block->Ranges = (UnsafeStreamRange*)Memory.Unmanaged.Allocate(allocationSize, 16, m_Allocator);
            m_Block->RangeCount = forEachCount;
            UnsafeUtility.MemClear(m_Block->Ranges, allocationSize);
        }``` that's the part where the forEach ranges are allocated
#

i think 24 bytes per element

#

IJE has no chunk index? i'm very unfamiliar with it

misty wedge
#

nope

#

Maybe you can get it somehow, but it just has the read / write handles for the components normally as parameters

#

Nevermind, you can get it

rustic rain
#

yoooo, I figured how to do custom rendering now

#

๐Ÿ˜…

#
            var sys = World.GetExistingSystemManaged<EntitiesGraphicsSystem>();
            var fieldInfo = typeof(EntitiesGraphicsSystem)
                .GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
                .First(x => x.FieldType == typeof(BatchRendererGroup));
            _brg = (BatchRendererGroup)fieldInfo.GetValue(sys);
var mesh = _brg.GetRegisteredMesh(mmi.MeshID);
misty wedge
#

The BRG in it is private?

rustic rain
#

yeah

misty wedge
rustic rain
#

yeah

#

well, it's not really an issue

#

sad part

#

I didn't figure how to draw with BRG

#

so I'll use legacy system

#

Entities graphics system is 3k lines

#

hope I won't need the same ๐Ÿ˜…

viral sonnet
#

huh that's kind of weird you have to do that

rustic rain
#

wcyd

#

technically, nothing stops you from registering generic types in runtime either

#

but to do that you have to use Harmony or some other code injection hack

misty wedge
#

won't work in AOT though

rustic rain
#

yeah

#

no il2cpp in this one

viral sonnet
#

and why are you doing this?

rustic rain
#

I use selection tool which needs entities rendered

#

with new API old way of getting meshes broke

#

so

#

fixing it now

#

hehe

viral sonnet
#

ah i see

rustic rain
#

in fact

#

it seems like the whole process is actually a bit easier now

#

if it wasn't for me being pepega for so long

#

allthough I might take back my words ๐Ÿ˜…

#

so I have entities in a chunk

#

each entity might have their own meshID

#

while I need in the end nice them groupped, so I can draw same meshes batched

#

๐Ÿค”

#

I'd guess obtaining hashMap value on every entity iteration is not a good idea

misty wedge
#

Not too different from reading a component / buffer lookup

rustic rain
#

yeah, but I need it for very fast job

#

I need to collect all entities indices and transforms into 1 good looking array

#

while separated by meshID

#

but while iterating chunks I might get different indices every time

rustic rain
#

hmm

#

I'm checking at implementation of HashMaps rn

#

I need a hashmap to which I can write in a batch

#

<int,int> hashmap

#

where I need to write array of Entites as batched key,value pair

#

NativeHashMap seems like using some sort of integer between pairs

#

so that won't work

#

meanwhile UnsafeParallelHashMap makes me ๐Ÿฅด

misty wedge
#

Why do you need an unsafe collection

rustic rain
#

but it's so low level

#

I can't understand it

rotund token
#

Sounds like you want a hashmap of lists

rustic rain
#

but implementation I need is just ๐Ÿฅด

#

it used to be so cool when it was just 1 render mesh per chunk

#

now I need some complex map solution

#

I need this structure per batch:
uint meshID
float4x4[] matrices
int[] indices

#

any idea how I can implement one?

#

@rotund token

hot basin
#

any materials on BRG?

rustic rain
#

using MMI component

hot basin
rustic rain
#

you can add any to it

#

I don't use it to do selection rendering though, so

hot basin
#

?

#

I think "material" in this context may be misleading or plainly wrong. I'm asking for external sources on BRG like tutorials, articles etc.

#

something that explains it more than linked doc

rustic rain
#

ooh

#

xD

#

no idea, I only read manual

#

from Unity

#

which is...