#archived-dots

1 messages ยท Page 44 of 1

muted star
#

A parent entity (the hovercraft 'Cleaver ECS') with the cube attached to it

rustic rain
#

why not attach cube before baking?

#

in scene

#

that's the only valid option

#

aside from runtime conversion

proud jackal
#

I would like to bake children.
Children are already baked tho, like your subscene hiarchry will automatically do a bake of every contained GO. (that includes children)

#

And the Transform baking system, which should be semi-readable and it will go in and take care of the relationships for you?

muted star
#

For me the baking of the child GameObject doesn't work by default.

However, the parent entity is a prefab which might be causing problems.
I'm setting the position and rotation of the parent like this. But I think this should be fine.

[BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            foreach (
                var (realPosition, transform)
                in SystemAPI.Query<RefRO<RealPosition>, TransformAspect>()
            )
            {
                transform.Position = realPosition.ValueRO.Value.Position;
                transform.Rotation = realPosition.ValueRO.Value.Rotation;
            }
        }```
rustic rain
#

during baking?

muted star
#

The cube position and rotation is not affected by the position and rotation of its parent

muted star
rustic rain
#

try to test bake cubes

#

within cubes

#

Child transform conversion works fine by my side

muted star
#

Do you also have prefab baking set up like this?
'UnitPrefabHolder' references 'Cleaver ECS' and has this code

public class UnitPrefabHolderMono : MonoBehaviour
    {
        [Required, SceneObjectsOnly] public GameObject prefab;
    }

    public class UnitPrefabHolderBaker : Baker<UnitPrefabHolderMono>
    {
        public override void Bake(UnitPrefabHolderMono authoring)
        {
            AddComponent(new UnitPrefabDC {Prefab = GetEntity(authoring.prefab)});
        }
    }
#

UnitPrefabDC.Prefab is later instantiated

rustic rain
muted star
#

I mean the prefab is istantiated in a system

#

and here is the result

rustic rain
#

sorry, I don't really get it

muted star
#

No problem. I'll give this another try once I really need child entities.

#

Right now I can work around it

rustic rain
#

no I mean, I don't get what you mean

#

when you mention instantiating prefab

muted star
#
 var prefab = SystemAPI.GetSingleton<UnitPrefabDC>().Prefab;
 var clone = state.EntityManager.Instantiate(prefab);
rustic rain
#

how does that prefab entity looks like?

#

in hierarchy

muted star
#

In my screenshot its the hovercraft to the left above the blue terrain

rustic rain
#

so, you are trying to instantiate a prefab entity which is child of something else?

muted star
#

no I'm instantiating a prefab with a child

#

but somehow the child is broken

#

and doesn't move with the parent

rustic rain
#

does it have linked entity group?

muted star
#

As you can see in the screenshot the parent only has the child buffer

rustic rain
#

then it won't be instantiated

#

only linked entity group gets instantiated

muted star
#

Okay then I'll add LinkedEntity group to the parent

#

It still doesn't work but thanks a lot for the help anyways @rustic rain and @proud jackal
I'll give it another try once I badly need child entities

queen dome
#

How should one destroy an entity instantiated with prefab? I am having a problem where I am destroying the entity of enemy but instead of being destroyed it just moves to (0,0,0) and continues rendering there.

#

I understand that that entities are actual flat and hierarchy is kept with additional components.

#

What I do not understand is how to destroy all "child" entities, how do I even get them?

solemn hollow
viral sonnet
#

is the script a baker or a monobehaviour (awake/start/...)?

robust scaffold
#

In that screenshot, it only shifts at most 393,216 bytes of data every frame, or a 314x314 texture every frame. Basically nothing so I do it every frame.

#

And yea, i just zero out the Z translation and velocity vectors of all the bodies.

jolly palm
robust scaffold
# jolly palm Yeah that's what I was thinking. Just have all 2d objects be 3d objects with 0 Z
[BurstCompile]
private unsafe struct ConstrainJob : IJob
{
    public int Linear, Angular, World, Pos;

    public NativeArray<MotionVelocity> Velocity;
    public NativeArray<MotionData>     Data;

    public void Execute()
    {
        var vel = (MotionVelocity*)Velocity.GetUnsafePtr();

        // * Fixed zero value.
        var zC = 0;

        // * Shift pointer to access Z variable of linear velocity and zero it out.
        void* destination = (float*)((byte*)vel + Linear) + 2;
        UnsafeUtility.MemCpyStride(destination, sizeof(MotionVelocity), &zC,
            0, sizeof(int), Velocity.Length);

        // * Fixed float2 zero value.
        float2 xyC = float2.zero;

        // * Shift pointer to access XY fields of angular velocity and zero them out.
        destination = (byte*)vel + Angular;
        UnsafeUtility.MemCpyStride(destination, sizeof(MotionVelocity), &xyC,
            0, sizeof(float2), Velocity.Length);

        var dat = (MotionData*)Data.GetUnsafePtr();

        // * Shift pointer to access WorldFromMotion (RigidTransform) and then the Z variable of its position.
        destination = (float*)((byte*)dat + World + Pos) + 2;
        UnsafeUtility.MemCpyStride(destination, sizeof(MotionData), &zC,
            0, sizeof(int), Data.Length);

        // ! Body motion apparently not needed?
        // destination = (float*)((byte*)dat + Body + Pos) + 2;
        // UnsafeUtility.MemCpyStride(destination, sizeof(MotionData), &zC,
        //     0, sizeof(int), Data.Length);
    }
}```
#

Works so far. I've just been hitting spheres together so my test case isnt the most robust.

robust scaffold
# jolly palm Yeah that's what I was thinking. Just have all 2d objects be 3d objects with 0 Z
public void OnCreate(ref SystemState state)
{
    Type velType = typeof(MotionVelocity);

    _linear  = UnsafeUtility.GetFieldOffset(velType.GetField(nameof(MotionVelocity.LinearVelocity)));
    _angular = UnsafeUtility.GetFieldOffset(velType.GetField(nameof(MotionVelocity.AngularVelocity)));

    Type datType = typeof(MotionData);

    _world = UnsafeUtility.GetFieldOffset(datType.GetField(nameof(MotionData.WorldFromMotion)));
    //_body  = UnsafeUtility.GetFieldOffset(datType.GetField(nameof(MotionData.BodyFromMotion)));

    Type rigType = typeof(RigidTransform);

    _pos = UnsafeUtility.GetFieldOffset(rigType.GetField(nameof(RigidTransform.pos)));
}``` The pointer offsets are obtained by reflection at the creation of the system to ensure minimal hardcoding. I hardcoded the Z offset of the float3 though, I think that can be safely assumed.
jolly palm
robust scaffold
robust scaffold
rotund token
#

I have a list.addnativerange extension which is much faster

solemn hollow
rotund token
#

Whatever works

solemn hollow
#

your extension is in your core package?

rotund token
#

I also have a way to get access to internal list array without allocations and can reinterpret that to a native array

#

To allow me to write direct with no allocs

solemn hollow
#

ill have a look through those. i bet they come in handy. i didnt ref your assembly so i havent discovered your extensions yet

#

Atm im trying to get the NavMeshModifiers to work with something other than the default agent... I dont know how i can get the agentID from the NavMeshModifier :/
The only way to check if the modifier affects an Agent is this: public bool AffectsAgentType(int agentTypeID) { if (m_AffectedAgents.Count == 0) return false; if (m_AffectedAgents[0] == -1) return true; return m_AffectedAgents.IndexOf(agentTypeID) != -1; }

#

And it requires me to know all AgentIDs beforehand. Is there some way to get a List of all AgentIDs available?

rotund token
#

Yes you can query the mesh mesh config

#

Umm

solemn hollow
#

but that isnt available at bake time right?

rotund token
#

It is

#

Navmesh getsettingscount

#

Then just navmesh getsettingsbyindex

#

(typing on phone in bed)

#

And each settings has agent type id

solemn hollow
#

so even if i didnt bake a navmesh for an agent it still has its settings?

rotund token
#

Yes

solemn hollow
#

thank god

rotund token
#

This is just reading the settings you setup in the nav mesh window

solemn hollow
#

Id like to confirm that it works but unity is crashing/hanging constantly today :S

#

exactly what i needed though! i really dont know how you have an answer to everything..

#

works perfectly fine now!
One last question remaining about Navmeshes:
As far as i understood i need a NavMeshData per Agent. But its fine to add all those NavMeshData to one NavMeshDataInstance?

rotund token
#

Yeah you need to build 1 mesh per agent type

#

As for the setup can't remember syntax sorry, it's a bit confusing in both naming and setup

edgy fulcrum
#

how do I update code that used UnsafeList to UnsafeList<T>? Unity Collections deprecated typeless UnsafeList and one of my libraries uses it ๐Ÿ˜ฆ

rotund token
#

interesting, what's your use case?

#

you could somewhat replace it with nativestream if you need something typeless

#

though it's not the same

#

i just use nativelist<byte>

#

with a tiny wrapper/extension

edgy fulcrum
#

yeah the asset is "Obi Fluid" and it's because I'm trying to port the project to 2022.2 and entities 1.0 ๐Ÿ˜ฆ

rotund token
#
            where T : unmanaged
        {
            data.AddRange(&value, UnsafeUtility.SizeOf<T>());
        }```
edgy fulcrum
#

seems like it's not a drop-in replacement thing to get rid of UnsafeList eh

rotund token
#

entities has this internally

    unsafe struct TypelessUnsafeList
    {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
        public AtomicSafetyHandle m_Safety;
#endif
        [NativeDisableUnsafePtrRestriction] public byte* Ptr;
        [NativeDisableUnsafePtrRestriction] public int* Length;
        public int Capacity;
    }```
#

but that ain't too helpful for you

edgy fulcrum
#

yeah I will just contact the asset author for support and see what I can do to help them, thanks!

rotund token
#

oh it's not your library

#

yeah that's a little more awkward

edgy fulcrum
#

yup that's the crappy thing about upgrading unity "ahead" of my assets ๐Ÿ˜ฆ

misty wedge
#

Is schedule granularity not a thing anymore?

#

Can't find it on IJobChunk or IJobEntity

edgy fulcrum
#

yeah it's automatically codegen'd away or something like that and will be removed

misty wedge
#

Huh, that's kind of a bummer. I had a few things that would have benefitted from it

edgy fulcrum
#

yeah but tbh worrying about it means your high-level architecture is somewhat funky ๐Ÿ˜‰

misty wedge
#

Eh, it's not that crazy. For example, pathfinding scheduling benefits from it massively

#

Especially on CPUs with a lot of cores

edgy fulcrum
#

if you really need it, then there's always ParallelFor eh

misty wedge
#

Yep but that's a massive amount of boilerplate compared to IJobEntity / IJobChunk

edgy fulcrum
#

agreed, hope that's on their roadmap to bring more codegen goodies everywhere!

rotund token
#

yeah i had a few usages of it as well

#

was nice to schedule 1 navmesh generation per thread for example

#

or to ensure pathfinding was split evenly and not having a huge spike on 1 thread because all entities from 1 chunk decided to find a path on the same frame

#

i don't use it enough to really care though

#

the couple of cases i can deal with a bit of extra boilerplate and just use an IJobFor

misty wedge
#

I hope they also add the ability to set a shared component filter on an IJobEntity back in, it's so much more boilerplate now

#

Need to re-define the query each time. Might as well just use IJobChunk at that point...

#

A lot of the utility that Entities.ForEach had in general is gone now, I hope that gets added back in

#

e.g. fetching the auto-generated entity query into a variable

rotund token
#

do you do a lot of setsharedfilters?

#

think i might have used it once ever on EFE

#

IJobEntity not good for padding those code coverage numbers ๐Ÿ˜ฆ

#

i was like, i'm pretty sure i've completely tested this system but it's only 57% coverage i'd expect 95%

#

oh yeah, IJobEntity alternate paths....

#

oh i can probably add Temp to the exclude path

#

maybe that'll avoid them

#

yeah that works

misty wedge
# rotund token do you do a lot of setsharedfilters?

I use it for the weird world system I use, not sure if you can remember.
For example I'll have an entity that is a "world", and each voronoi cell is an entity that belongs to that world, and has a shared component that points to the world so they can find them, and I can more performantly access data about that cells' world in an IJobChunk

rotund token
#

ah i do vaguely remember

#

what's the need case for setsharedfilter though

misty wedge
#

How else would I know what world a voronoi cell belongs to

rotund token
#

are you iterating all worlds and scheduling separate jobs?

misty wedge
#

Sometimes yes

#

I'm trying to avoid it though

#

(for stuff that needs to be fast)

rotund token
#

with the ability to access unmanaged shared components in jobs i find little reason to do this now

#

hence the curiosity

misty wedge
#

I don't see how that changes it? My grouping component is also unmanaged

#

Or do you mean early-outing?

#

(based on the state of the shared component)

#

(instead of using a shared filter)

rotund token
#

so i can just execute in the same job in parallel instead of scheduling a bunch of jobs 1 after the other

misty wedge
rotund token
#

ah ok so it's for partial updating

#

yeah that makes sense

misty wedge
#

yeah

#

The other approach which avoids the filter is just iterating over all cells, checking the shared component, and early outing for the entire chunk if nothing needs to be done

#

Probably less code that way, but would only really work for IJobChunk

rotund token
#

so you want like an overload for schedule on IJobEntity or something?

misty wedge
#

e.g. new MyJob().WithSharedComponentFilter(...).Schedule()

#

so basically how it used to work for Entities.ForEach

rotund token
#

from a vague understanding of how the source generators are setup atm i can understand why this isn't supported

misty wedge
#

Yeah it sounds difficult

rotund token
#

it'd probably be easier if it was just in the schedule overload

misty wedge
#

wdym?

#

ScheduleWithFilter?

rotund token
#

.ScheduleWithFilter(T)

#

yeah

misty wedge
#

I'd take either ๐Ÿ˜…

rotund token
#

because schedule generator is what would generate the query

#

(probably)

misty wedge
#

I've only looked at the source-gen bits very briefly

rotund token
#

im sure it's doable either way, but who knows

#

i'd kind of like a with query out

#

personally

rotund token
#

yeah

misty wedge
#

Yeah I also miss that. There's a few nice utility things that were lost in the transition

rotund token
#

honestly that'd mostly solve the filter option as well

#

not as clean

#

but much cleaner

misty wedge
#

Yeah re-defining the query for an IJobEntity each time feels really wrong

rotund token
#

systemapi.querybuilder is pretty clean for passing queries to ijobentity

#

but i think it's error prone

#

thats what i don't like about it

misty wedge
#

Error prone in what way? If you change the signature of Execute?

rotund token
#

yeah

misty wedge
#

Yeah

#

and you can't do it inline, since SetSharedComponentFilter returns void

rotund token
#

someone looks at ijobentity

#

makes changes

#

[withall]

misty wedge
#

Yep

rotund token
#

they might never look at the scheduling code

#

and realize it's using a different query

misty wedge
#

Some other things I'm also really excited for are structural updates in Query, and support for code-gen'd type handles with SystemAPI

rotund token
#

or just some obscure case where someone edits the job and someone edits the query in separate pull requests

misty wedge
#

at least the error message is pretty clear if you mess it up, still very annoying though

rotund token
#

the larger my team gets, the more i value reducing ability to make mistakes

misty wedge
#

definitely

#

where I work we mainly use python for stuff, and it really annoys me that it's so difficult to enforce certain things

rotund token
#

the one thing i really want to focus on next project is code re-use

#

the number of different id, grouping, etc systems in our project is ridiculous

#

people just don't realize a solution already exists

misty wedge
#

Yeah that's something I'm kind of struggling with ecs, I usually just write a completely seperated system with all jobs only used by that system

#

although there usually isn't a huge deal of overlap in how they work, so I'm not sure how that would even work

#

I also try to put "smaller" operations that could be re-used inside of an already existing job instead of scheduling it separately since scheduling overhead used to be an issue...

#

@rotund token I was planning on writing a graph based ability system soon, but I'm not entirely sure how to go about storing the logic of the actually executable graph node.

My first idea was to store them in a blobarray, and each node knows the index of the next node. But the scheduling issue is then that a single job will be running all node-types, meaning it would need to grab a lot of component lookups.

The other idea was to have a job per graph node type.

Any tips?

rotund token
#

thats basically how i do my ai

#

except i didn't use blobs because i found it too painful to setup

misty wedge
#

The first or the second one

#

Ah

rotund token
#

first idea

#

but also i like the ability to edit graphs at runtime which is a bit more painful for blobs as well

misty wedge
#

The thing I was having trouble with is that an ability can basically be anything, so in theory it would require all component lookups for all things that it could modify

rotund token
#

so yeah i just serialize factories to disk and generate the graph in oncreate (or when it changes for runtime updating for testing)

rotund token
#

so anyone can extend it with any component

misty wedge
#

What does the component do?

#

I'm guessing this is a utility based system?

rotund token
#

its kind of a graph based utility sytem

misty wedge
#

But a single job runs the update logic for all components?

rotund token
#

yep

#

my ai is 1 job

misty wedge
#

What if a component needs to lookup another component?

rotund token
#
        public float Score(in EntityContext<T> entityContext, ref T context)
        {
            fixed (Scorer<T>* scorerHeader = &this)
            {
                var scorer = (void*)((IntPtr)scorerHeader + UnsafeUtility.SizeOf<Scorer<T>>());

                return this.header.ScorerType switch
                {
                    (short)Core.ScorerType.Default => UnsafeUtility.AsRef<DefaultScorer<T>>(scorer).Score(in entityContext, ref context),
                    _ => context.CustomScorers(this.header.ScorerType, new Scorers<T>(scorer), in entityContext, ref context),
                };
            }
        }```
#

every single one of these is <T> : unmanaged, IContext

#

and all the component handles are passed in the context

#

so it's re-usable in any game

rotund token
misty wedge
#

in the EntityContext?

rotund token
#

nah in ref T context

#

entity context stores default info about the current entity processing

#
        where T : unmanaged, IContext<T>
    {
        internal Graphs<T> Graphs { get; set; }

#if UNITY_EDITOR && !BL_AI_DISABLE_DEBUGGER
        internal AIDebugger AIDebugger { get; set; }
#endif

        public RandomReference Random { get; internal set; }

        public Entity Entity { get; internal set; }

        public int EntityInQueryIndex { get; internal set; }

        public int EntityIndexInChunk { get; internal set; }
    }```
misty wedge
#

And the component defines which type of lookups it needs somehow?

rotund token
#

you just implement a struct

misty wedge
#

e.g. if I need to know the health of another entity

rotund token
#

and put the handles/lookups/whatever you want

misty wedge
#

How are those populated? Reflection?

rotund token
#

no

#

you just implement the system

#
        where T : unmanaged, IContext<T>```
#

For example

    {
        /// <inheritdoc/>
        protected override AIContext CreateContext()
        {
            return new AIContext
            {
                Translations = this.GetComponentTypeHandle<Translation>(true),
                Observations = this.GetBufferTypeHandle<Observation>(true),
            };
        }
    }```
#

i have this little sneaky

        [EditorBrowsable(EditorBrowsableState.Never)]
        protected virtual GenericResolver<T> GenericResolver { get; }```
property in the base
#

that is enough to get burst/il2cpp to not bitch about generics

misty wedge
#

I see, and the T in AISystemBase is what is passed as the context to the component?

rotund token
#

yeah context is everything

#
        where T : unmanaged, IContext<T>
    {
        void InitChunk(ArchetypeChunk chunk, int batchIndex);

        float CustomScorers(short scorerType, Scorers<T> scorer, in EntityContext<T> entityContext, ref T context);

        void CustomActions(short actionType, Actions<T> action, in EntityContext<T> entityContext, ref T context);

        float CustomOptionScorers<TOption>(short scorerType, OptionScorers<T> scorer, in EntityContext<T> entityContext, ref T context, in TOption option)
            where TOption : unmanaged;
    }```
#

allows adding custom nodes as well as data

misty wedge
#

Are the type handles stored or is CreateContext called for each update?

rotund token
#

(the one thing i haven't got working here is full generic sharing for il2cpp, for some reason it just won't play nice even if i explicitly define all types)

rotund token
jolly palm
rotund token
#

but i haven't updated the samples so its still creating them per frame

rotund token
#

but there's no reason that needs to happen

misty wedge
#

Looks very cool @rotund token , and also gave me a few ideas for my stuff, thanks

rotund token
#

i wrote this like 2 years ago

#

and it's kind of just sat here

#

it was amazing at the time

#

i also found like 4 really deep obscure burst bugs

misty wedge
rotund token
#

im coming up on 5 years i think

misty wedge
#

so basically when it was announced? ๐Ÿ˜›

rotund token
#

march 2018 i think it was releasedish?

#

i think like a month or so after it was released

jolly palm
#

Tertle is literally the person i keep seeing in unity threads when i look up info on ECS

rotund token
#

i barely post on forums these days

#

i just have a lot of historic posts ^_^'

jolly palm
#

Thanks for all your contributions

rotund token
#

i find there are enough experienced users now I'm not really needed

misty wedge
#

I still have trouble wrapping my head around writing generic code for ECS, so this made it a bit more clear

misty wedge
rotund token
#

usually it just sets a bit field

#

to determine state

#

and other systems take it from there

misty wedge
#

Looks like you pre-define actions (looking at the short actiontype)?

rotund token
#

but really it can do anything

#

set targets etc

#

i try to avoid putting the update logic in there

#

like my move routine won't exist inside my AI

#

it'll just set the, follow target flag

#

and the AI will just check next frame current state, if it wants to change etc

jolly palm
#

Would you say your AI system works like a sort of AI API?

#

that other entities use in order to manage their own AI behaviour?

misty wedge
rotund token
misty wedge
#

Yes, but you'd need to store the result of AISystem.CreateContext somewhere right? And that can't return a struct

#

unless you do some unsafe stuff

rotund token
rotund token
#

Create context returns a struct

#

protected abstract T CreateContext();

#
                {
                    Context = this.CreateContext(),
                    AIUtilityGraphs = this.aiUtilityGraphs,
                    EntityHandle = this.GetEntityTypeHandle(),
                    AIHandle = this.GetBufferTypeHandle<AI>(),
                    Seed = this.GetSeed(),
                    ChunkFirstIndices = chunkFirstIndices,
#if UNITY_EDITOR && !BL_AI_DISABLE_DEBUGGER
                    DebugWriter = this.eventProducer.CreateWriter(),
#endif
                };

            this.Dependency = job.ScheduleParallelByRef(this.aiQuery, this.Dependency);```
#

literally pass it straight to the job

#

Context = this.CreateContext(),

misty wedge
#

Ah, it runs a job for each defined component?

rotund token
#

you usually only implement 1 AI system

#

in theory you could implement more

#

but there's not much reason to

#

you can attach multiple AI graphs to an entity

#
    {
        /// <summary> Gets the key to the graph. </summary>
        public int Key;

        /// <summary> Gets the number of frames between updates. </summary>
        public int UpdateEveryXFrames;

        /// <summary> Gets a value indicating whether the AI is enabled. </summary>
        public bool Enabled;

        /// <summary>
        /// How many frames before the AI should update again.
        /// To avoid updating all AI on the same frame, if you are instantiating AI from code this should be set to a random value.
        /// e.g. Random.Range(0, ai.UpdateEveryXFrames) + 1
        /// AI in a subscene are given a random value during conversion.
        /// </summary>
        public int FramesBeforeNextUpdate;
    }```
misty wedge
#

Ah, and CreateContext creates the shared context for all custom components?

rotund token
#

it's a buffer

misty wedge
#

Ah, ok. That's why I was confused. I thought each component defines its own context

#

Got it

rotund token
#

for the record, my AI system is unproven in production so I don't really recommend the huge complexities it took to setup

#

but it's a very interesting implementation

misty wedge
rotund token
#

(also if you're not intending to release as a general purpose shared library, no reason to make it generic)

#

(could save a lot of time/effort figuring that out)

jolly palm
#

I think the topic of 2nd order Systems (systems used by other systems) is still a relatively unexplored topic in ECS, so I think its interesting

misty wedge
#

Since that part also looked generic

rotund token
#

oh boy ok

#
    {
        private EntityType entityType;
        private bool not;
        private float score;

        /// <inheritdoc/>
        public float Score(in EntityContext<AIContext> entityContext, ref AIContext context)
        {
            Check.Assume(context.Observations.Length != 0, $"Entity({entityContext.Entity.ToFixedString()}) without Observation using HasEntityInMemory.");

            var observations = context.Observations[entityContext.EntityIndexInChunk].AsNativeArray();
            foreach (var obs in observations)
            {
                if (this.entityType != EntityType.Any && obs.EntityType != this.entityType)
                {
                    continue;
                }

                return this.not ? 0f : this.score;
            }

            return this.not ? this.score : 0f;
        }

        /// <summary> Factory for <see cref="HasEntityInMemory"/>. </summary>
        public class Factory : Scorer<AIContext>.Factory<HasEntityInMemory>
        {
            /// <inheritdoc/>
            public override short ScorerType => 1;

            /// <inheritdoc/>
            public override string DefaultName => "Has Entity In Memory";

            public EntityType EntityType { get; set; }

            public bool Not { get; set; }

            public float Score { get; set; }

            /// <inheritdoc/>
            protected override void Init(ref HasEntityInMemory scorer, MemoryAllocator allocator)
            {
                scorer.entityType = EntityType;
                scorer.not = Not;
                scorer.score = Score;
            }
        }
    }```
#

this is a scorer

#

Factory is what the UI graph works and what is serialized

misty wedge
#

I see. And when the factories are called, the results are added to a buffer somewhere?

rotund token
#

there is no buffer

misty wedge
#

Where is the result of the factory put at runtime then?

rotund token
#

private UnsafeParallelHashMap<int, ReferenceData> aiUtilityGraphs;

misty wedge
#

Ah I meant buffer in the more general sense of "in an array type thing"

#

versus on entities or something

rotund token
#

each node is allocated

#

and just points to each other

#

the same graph is used by all entities that use the node

#

no state is stored in it

misty wedge
#

What would you do if you needed to store state?

rotund token
#

store it on the entity

misty wedge
#

The reason I'm asking is since I need to store state for my ability stuff, so I was wondering

rotund token
#

like my entities have state, target/s etc

jolly palm
#

Huh. Having a node graph often implies data being stored in the nodes to prevent duplicate pathing calculations

rotund token
#

just think of each node as a single job

misty wedge
rotund token
#

basically what UI looks like, this is editable in runtime

jolly palm
#

Oh wait that type of node graph

rotund token
#

it also tracks X frames

#

where each entity travels

jolly palm
#

I was thinking like pathing nodes, A* or something

rotund token
#

so you can visually see what paths the AI took

misty wedge
rotund token
#

over the last X frames

misty wedge
rotund token
# misty wedge That's really neat, since utility systems are usually tricky to debug

yeah

        {
            fixed (Action<T>* actionHeader = &this)
            {
#if UNITY_EDITOR && !BL_AI_DISABLE_DEBUGGER
                entityContext.AIDebugger.WriteNode(this.header.Guid);
#endif

                var action = (void*)((IntPtr)actionHeader + UnsafeUtility.SizeOf<Action<T>>());

                switch (this.header.ActionType)
                {
                    case (short)ActionType.Selector:
                        UnsafeUtility.AsRef<SelectorAction<T>>(action).Execute(in entityContext, ref context);
                        break;
                    case (short)ActionType.AILink:
                        UnsafeUtility.AsRef<AILinkAction<T>>(action).Execute(in entityContext, ref context);
                        break;
                    case (short)ActionType.Composite:
                        UnsafeUtility.AsRef<CompositeAction<T>>(action).Execute(in entityContext, ref context);
                        break;
                    default:
                        context.CustomActions(this.header.ActionType, new Actions<T>(action), in entityContext, ref context);
                        break;
                }
            }
        }```
#

each node has a unique ID

#

and it writes this before entering it

#

(can be compiled out as you can see)

#

i basically use fake inheritance

#

for each type of node

#

(Action is not System.Action)

misty wedge
#

Yeah I thought so, that would have been weird ๐Ÿ˜…

#

UnsafeUtility.SizeOf<Action<T>>() this works on IL2CPP?

rotund token
#

yeah

#

well

#

it doesn't need to work in il2cpp

#

since it's in burst

#

^_^'

misty wedge
#

ah

rotund token
#

but yeah so i can build il2cpp

#

as long as i don't enable full generic sharing

misty wedge
#

Are il2cpp builds working atm?

rotund token
#

not sure how to resolve it

#

yes

#

So yeah, you have to select "Faster runtime" not "Faster (smaller) builds" for this AI to work atm

jolly palm
#

cant you just give your generic type wrapper class a custom sizeof method?

rotund token
#

(which is the opposite issue that Unity had for a while with il2cpp)

rotund token
#

the issue is my deserializer and creation of the nodes at runtime

#

that il2cpp has issues with

misty wedge
rotund token
#

it's just my generic nodes

#

user generic have no issues because they're fully defined

jolly palm
#

(de)serialization issues are my nemesis

rotund token
#

my current workaround is

        where T : unmanaged, IContext<T>
    {
        [Preserve]
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected virtual GenericResolver<T> GenericResolver { get; }```
#
    [SuppressMessage("ReSharper", "UnusedMember.Global")]
    public struct GenericResolver<T>
        where T : unmanaged, IContext<T>
    {
        public AISystemBase<T>.AIJob Job { get; }

        public FirstScoreWinsSelector<T>.Factory FirstScoreWinsSelector { get; }
        public HighestScoreWinsSelector<T>.Factory HighestScoreWinsSelector { get; }
        public RandomWeightedScoreWinsSelector<T>.Factory RandomWeightedScoreWinsSelector { get; }

        public AllOrNothingQualifier<T>.Factory AllOrNothingQualifier { get; }
        public DefaultQualifier<T>.Factory DefaultQualifier { get; }
        public FixedScoreQualifier<T>.Factory FixedScoreQualifier { get; }
        public MinimumOrNothingQualifier<T>.Factory MinimumOrNothingQualifier { get; }
        public SumAllAboveThresholdQualifier<T>.Factory SumAllAboveThresholdQualifier { get; }
        public SumAllQualifier<T>.Factory SumAllQualifier { get; }
        public SumWhileAboveThresholdQualifier<T>.Factory SumWhileAboveThresholdQualifier { get; }

        public AILinkAction<T>.Factory AILinkAction { get; }
        public CompositeAction<T>.Factory CompositeAction { get; }
        public SelectorAction<T>.Factory SelectorAction { get; }

        public DefaultScorer<T>.Factory DefaultScorer { get; }
    }```
#

and this is enough to get it to run fine in both burst and il2cpp "Faster runtime"

#

but not "Faster (smaller) builds"

#

even manually defining the implementation (just for the sake of testing) didn't work for me

#

so i'm not sure how to solve this

#

i could have code-gen explicit definitions if it came to it, but it didn't help

misty wedge
#

odd

rotund token
#

i just get

#

ExecutionEngineException: An unresolved indirect call lookup failed

#

which has 0 google results

#

(try it yourself "An unresolved indirect call lookup failed")

#

so that's always a good sign i'm doing something bad ๐Ÿ˜„

jolly palm
rotund token
#

different ExecutionEngineException

misty wedge
#

For example, "cake recipes" instead of "how to make a cake."

rotund token
#

the best bit is,

in Unity 2022.1, IL2CPP no longer produces an ExecutionEngineException, eliminating a whole class of errors that are difficult to rectify.

misty wedge
#

you got pranked

rotund token
#

โ€œFaster (smaller) buildsโ€ is meant to remove these exceptions but i seem to have found an edge case

misty wedge
#

I also have an issue with il2cpp generics, but I think mine is intended

jolly palm
#

Hmmm so it perhaps it isnt registering one of your Generics as being used and therefore cant compile the correct version for intepreting the generic?

misty wedge
#

then an explicit implementation would work, but tertle mentioned that didn't work either

rotund token
#

yeah i defined the explicit implementations as a test

#

and i could get it to work only at the top level

jolly palm
#

Can you try to narrow down the problem by making the most concise test that results in this error?

misty wedge
#

Going by the article, if il2cpp can already generate code for value type generics, why does marshaling them not work?

robust scaffold
#

If anyone else here writes shaderlabs, have you gotten unorm float4 buffers to work? Ive been feeding in Color32s and I'm forced to unpack them manually (bitmask the bytes and / 255) as setting a buffer<unorm float4> Color32 doesnt unpack automatically.

#

Although unorm float4 seems to be a DX12 feature....

robust scaffold
#

ugh, 1.0-pre unity plz.

jolly palm
robust scaffold
jolly palm
#

and using something like this doesn't work?:

[MaterialProperty("_ColorBuffer")]
public struct ColorBufferPropertyOverride : IComponentData
{
    public Buffer<float4> ColorBuffer;
}
robust scaffold
jolly palm
#

Not work as in it doesnt convert, or doesnt convert correctly?

robust scaffold
#

This is what I have to do to unpack a Color32 into a float4. Since the color itself is a R8G8B8A8_UNORM float4.

#

Where Buffer<uint> LightColor;

#

I wish to be able to do Buffer<unorm float4> LightColor; and not have to do that unpacking.

jolly palm
#

Oh duh. Of course it wont work, a Color32 is the size of an int/float.
And I'm pretty sure the docs say that most conversions require the same number of bytes for the conversion to occur

robust scaffold
#

I want to feed in R8G8B8A8 which is 32 bits wide and thus size of an int for packing and just directly render it

jolly palm
#

I think i misunderstood what your shader looked like.
as part of your shader you have a Buffer<unorm float4> Colors that already convert into the correct color type, but trying to populate that data from Unity => HLSL isnt working

is that correct?

robust scaffold
#

I am attempting to use Buffer<unorm float4> Colors and I'm populating it with Color32s, which is in RGBA32 format.

#

I can use Buffer<uint> Colors then unpack it using bitshifts so the data is being transferred properly.

jolly palm
#

sorry. I don't know enough to be any more help here

robust scaffold
#

Yea, it's very very niche hlsl coding and there's only a few posts from 2010 (12 years ago) talking about it

robust scaffold
robust scaffold
robust scaffold
#

DOTS for 23.1 when?

rustic rain
robust scaffold
late mural
#

is there any way to parallel write to a native reference? Or should i just use nativearray<whatever>[0]?

late mural
pulsar jay
#

I just stumbled upon the problem that perfabs in subscenes do not get LinkedEntityGroups. How am I supposed to destroy them at runtime? Destroying the root entity always leaves the children behind.

rotund token
#

my big complaint with baking is that prefabs get LEG even if they shouldn't (they have no hierarchy)

#

how is everyone not getting LEG when my problem is I am ^_^'

#

BakedEntityData - line 824
CreateEntityForPrefab
var buffer = _EntityManager.AddBuffer<LinkedEntityGroupBakingData>(entity);

#

always adds a linked entity group to a prefab

#

are your children physics objects or something?

pulsar jay
#

I just added a cube to a sphere and it does not get a LEG:

pulsar jay
#

Maybe I should specify that by prefabs I mean prefabs placed in the subscene and not referenced prefabs

dull shell
#

Can someone explain what exactly is Project Tiny? I dont understand why description says its only for small games, like mobile games, are there some actual limitation? And why its not updating, are there any problems? Can i somehow get something from it, like ecs sprite rendering and use it in my unity project, as i understand i cant, but why?

rustic rain
#

It's been postponed till better times

dull shell
rustic rain
#

Yep

dull shell
#

isnt it main performance boost

rustic rain
#

There isn't

#

But it's irrelevant

#

You can do 2d with normal ecs

dull shell
#

ye but u have to use normal physics and sprite rendering which is kinda slow if u want to have a lot of objects, not sure about ecs performance tho, i assume physics much be optimized in some similar way at low lvl

rustic rain
#

Yeah. Sadly

#

Physics is fine though

#

It's pretty efficient on it's own

#

Bad part is that you get 2d for the price of 3d

#

You can do certain optimizations thogug

#

To make 2d rendering faster

#

Like disabling game objects that are culled

coarse turtle
# dull shell Can someone explain what exactly is Project Tiny? I dont understand why descript...

The goal of project tiny was to export games and pack them for things like web content: https://tiny.vision/demos/TinyRacing/Wasm/TinyRacing.html
Can't remember the exact final size of that project - but it was a few kb and can work nicely on mobile WebGL (it likely compiled things to wasm too). And as Issue said - it's been shelved.

You can't really use things like rendering from project tiny because it uses a different rendering/audio path than what Unity provides out of the box (it uses BGFX as its graphics backend https://github.com/bkaradzic/bgfx and miniaudio for its audio playback engine https://github.com/mackron/miniaudio.) You can probably still take a look at the package source and get some inspiration from it - doubt you can pull things out of it and use it directly in your project.

dull shell
rustic rain
#

well, since ECS was fine for small projects

#

that's probably why they didn't bother with tiny

coarse turtle
whole gyro
drowsy pagoda
#

I need to implement a dynamic navmesh, one that I can update at runtime for changes in scenery. Is there something like this for DOTS already? If so, can someone point me in the right direction?

pulsar jay
whole gyro
#

I kinda like how it gives you explicit control over whether you want the LEG, but I don't like how it's inconsistent with the prefab workflow.

pulsar jay
whole gyro
#

I know a lot of folks here would prefab that no LEG get automatically added, but I think its the right approach for new DOTS developers. Otherwise, things don't work how you expect them to. I think I'd prefer a DoNotAddLinkedEntityGroup authoring component that we can add to a prefab or game object to skip the LEG generation.

#

Same goes for the transform components. I think the TransformUsageFlags stuff in the baker is really confusing. Maybe there could be an OverrideEntityDefaults authoring component that lets you control both the transform components and LEG.

pliant pike
#

I don't suppose anyone has any insight into why this is happening, when I instantiate all these physics items

#

the irony is I want them to do something like this but in a different way, and I had a script that changed the initial linear velocity, but I removed it and reset the values to zero, but they are still flying away in this manner

robust scaffold
pliant pike
#

yeah that's what I thought it could be but I've even turned off collisions between them

robust scaffold
#

Make sure they arent colliding with the source object as well. Any clipping will cause that spray

strange jackal
#

why is clipping so vliolent

pliant pike
#

ok I found it, its colliding with an environment collider that surrounds the whole shelves, how did I not see that leahHMM thanks

robust scaffold
strange jackal
#

is there a violence setting to turn it down

pliant pike
#

yeah and its because I've got tons of colliders overlapping, it kind of makes it more difficult to remember all of them

strange jackal
#

i have little bumps in my level and it makes my ghost do so many barrel rolls

robust scaffold
#

It's also how they ensure stacking stability. If bodies just offset their positions by their calculated penetration distance, stacked boxes would be very unstable.

strange jackal
#

3:10 - 4:00 is spot on

pulsar jay
#

I tried to use generic SystemStateComponents and got the following error:
Execute() parameter 'registered' is not a supported parameter in an IJobEntity type.
Is it just not allowed to use generic in any place that uses code generation?
It didnt work with ForEach either but I got a different error

rotund token
#

But yes you can't use generics in code gen

#

If you want to use generics you need to manually write the jobs

pulsar jay
rotund token
#

Yes

pulsar jay
#

Thats sad. Just wanted to create a simple reactive framework to avoid all the boilerplate code

#

But if that means having to write every system that uses it with IJobChunk I am not sure if I will gain anything from it

robust scaffold
#

IJC isn't that bad in terms of boilerplate. If unity comes out with a SysAPI to get and update type handles, I would say it's equivalent, possibly superior, to IJE.

stone osprey
#

Sooo each chunk is 16 KB big... Archetypes do store them basically in some sort of linked list... so chunks are most likely not next to each other in memory, means that if our chunks do not contain many entities... its slower since theres more memory jumping required.

In that case, how do we deal with large entities ? Imagine something like this...

Character
- Identity{ UniqueId, name, type }
- Stats{ level, attack, defence, magicAttack, magicDefence, maxHealth, luck, agility, ... }
- Transform
- Rotation
- Mesh
- Health
- Velocity
- Collider
- Inventory
- Equipment
- AOI
- AnimationPlaying
...

As you can see the list grows and grows... and such an entity is pretty big, lets just guess we could only fit like 50 into one chunk. However there like ten thousands of them crawling around the world, so we have like hundreds or thousands of chunks.

This way the performance becomes worse since there a lot of chunks and a lot of chunk switching...

So how do we deal with such massive entities ? What are common techniques ?

rotund token
#

lets just guess we could only fit like 50 into one chunk.

#

that's optimistic with that type of structure

#

i'd estimate you'd end up with just 5-10/chunk, or less, based off experience

#

i can tell you in a work project we have 2-3 players per chunk, 5-6 normal creatures

#

and this is what happens when you don't think about/pay attention to this problem

#

so ah good you're hopefully do this ahead of time!

robust scaffold
#

If you use unity's ECS packages (physics, rendering, netcode), it's about 25 entities per chunk with no custom components.

stone osprey
#

Most likely :/

Of course we can outsource some of that data since there a few things which are not unique to each entity. Like the stats, those are allways the same for a group of entities... like each default character has the same attack, defence, maxHealth. So we could store that somewhere else and reference it.

However Most of the stuff actually can not be outsourced... inventory is unique per character... also the equipment attached. Transform/Rotation is also unique... aswell as the current animation, the current health, the mesh being used and and and...

So is the only way here to accept that this becomes slow by design ? ๐Ÿ˜„

robust scaffold
rotund token
robust scaffold
#

Or fragmenting entities and storing references in a off-chunk buffer component element (a buffer with internal buffer capacity set to 0).

rotund token
#

for example, the stat/effect library i'm super obsessed with all your stats (health, % damage increase, gravity, turn speed) are stored in a single buffer and are written to player from individual effect entities

#

so every stat in the game is just 16 bytes per entity in the archetype

#

(i've tested this at 100million stats on 10million targets at 20ms/frame)

#

(memory is much more of a problem at this extreme ^_^' 32GB min machine requirement no other feature in game)

stone osprey
#

Ah i see... that kinda makes sense ^^ however this is also kinda a dependency nightmare ๐Ÿ˜„

Im working heavily with custom networking... and such a structure would mean that i also need to synchronise effect entities with the client/server, which is again more work... and you always need to have those in mind aswell ๐Ÿ˜„

stone osprey
rotund token
#

however this is also kinda a dependency nightmare
๐Ÿ’ฏ

#

i had to plan this carefully

#

and wrote a very clearly defined life cycle management solution

#

as well as a way to cache chunk references safely for fast lookups

robust scaffold
rotund token
#

i also need to synchronise effect entities with the client/server, which is again more work
yeah already planned this out

#

most effects dont need synchronization

#

like effects are, a sword has 6 stats

#

these stats dont need to be synced to client

#

just the effect of the stats do

#

things like buffs/auras etc existing need to sync to apply visuals

rotund token
#

it's more about when a target/effect is destroyed

#

it might reference something that doesn't exist

#

i have no actual safety checks in this entire library (hascomponent/exists etc)

#

and i dont think any lookups either, at least not for regular frame operations
they're fine, i just wanted to push to extreme

robust scaffold
#

Ah, hrm.

stone osprey
#

Oh boy that sounds like a lot of fun ๐Ÿ˜„

Easiest way is to force the chip manufactures to implement like 5mb L1 Caches so that the chunk size can be increased ๐Ÿ˜„

robust scaffold
#

Nah, chunk sizes seems to be dictated by enabled component bitmasks.

#

v128 is used for enabled state. Why they didnt use v256 is beyond me.

rotund token
# robust scaffold for something less extreme but more flexible / less strict, would interlocked op...
    {
        [NativeDisableUnsafePtrRestriction]
        internal StatEffect* Effect;
    }```
effect entity has this

```    /// <summary> The buffer sits on the owner and can be directly written from stat entities via <see cref="StatEffectApplication"/>. </summary>
    [InternalBufferCapacity(0)]
    [ChunkSerializable]
    public unsafe struct StatValueBuffer : IBufferElementData
    {
        [NativeDisableUnsafePtrRestriction]
        internal StatEffect* Effect;
    }```
whatever has stats has this
#

i.e. they share a pointer

#

so i can just write the stat directly

#

on change the thing that has the stats iterates the StatValueBuffer and calculates the actual stats

robust scaffold
#

Oh wait stat is it's own entity?

rotund token
#

effects are condition -> action

robust scaffold
#

ugh, eww

rotund token
#

action can be, add stat, create effect, enable capability

#

can have up to 8 conditions

#

conditions can be, low health, nighttime, on block etc

#

the final stat buffer is stored on the actual target

#
    public struct Stat : IBufferElementData
    {
        public float Value;```
#

simply a float buffer

#

value is calculated from all StatValueBuffer

#

the index in the buffer is the stat key

#

all stats always exist on all entities that can have a stat

#

even at 500 stats i'm ok with this memory cost

#

for the performance benefit

#

if memory is too problematic though i'll just switch to my IDynamicHashMap

robust scaffold
#

A hash map on an entity? I always wanted one.

rotund token
#

here you go then

#

basically just a wrapper for DynamicBuffer<byte> which is reinterpreted into a hashmap

robust scaffold
#

Yea, fantastic. I'll need to go back to my drawing board and see how I can use it.

rotund token
#

the pain line is htis

#

hashMapBuffer.AsHashMap<TestHashMap, int, byte>();

#

c# limitation on generics and i can't figure out how to remove the need for this explicit generics

#

i would really like it to just be

#

hashMapBuffer.AsHashMap()

#

compiler not smart enough

rustic rain
rotund token
#

native array does not have the same issue

#

it's a single generic

rustic rain
#

Or is that extension limitation?

rotund token
#

public static DynamicHashMap<TKey, TValue> AsHashMap<TBuffer, TKey, TValue>(this DynamicBuffer<TBuffer> buffer) where TBuffer : unmanaged, IDynamicHashMap<TKey, TValue> where TKey : unmanaged, IEquatable<TKey> where TValue : unmanaged

#

even though TBuffer defines TKey, Value

#

the compiler can't figure it out without you specifying the generics yourself

#

always bothered me

#

i assume it's because of inheritance

#

but with unmanaged if you specify a TBuffer type there is only 1 possibility as far as i'm aware

robust scaffold
rotund token
#

nah even without that it still requires <>

frigid crypt
#

Can I somehow get an entity reference inside of this foreach or do I have to do some weird dots voodoo magic to be able to destroy the entities I want?

robust scaffold
frigid crypt
#

Not gonna lie, I was not expecting it to be that easy

full epoch
#

Older ways to generate meshes(which were much simpler to use) do not work anymore at least i do not know how to do it that way - seems now only way is using RenderMeshUtility

rustic rain
rotund token
#

try

rustic rain
rotund token
#

you can create a very simple test case

rustic rain
#

I don't know how to declare collections ๐Ÿ˜…
Can you give me blank example?

#

hold up

#

or not?
I can see how it can be done without generics

#

but it has to be part of DynamicBuffer I think

#

which is probably not smth you want

#

or maybe of DynamicHashMap

jolly palm
#

Has anyone been able to get skinned meshes to work (SkinMatrix) as an ECS component 1.0?

Edit: Problem was my shaders didnt use the "Compute Deformation" node in the shader graph

rotund token
#

there are no collections here

#

this is just a reinterpretation of a dynamicbuffer into a hashmap

rustic rain
#

here

#

No stupid generics

rotund token
#

but this doesn't help at all?

#

DynamicBuffer<Kek<T0, T1>>
try add this to an entity

#
where T0 : unmanaged where T1 : unmanaged
    {
        public byte Value;

        public static Kek<T0, T1> AsKek(DynamicBuffer<Kek<T0, T1>> lul)
        {
            return default;
        }
    }```
#

all i'd be getting back is a single byte not a hashmap

rustic rain
#

๐Ÿฅด

rotund token
#

apart from that
public struct Kek<T0, T1> : IBufferElement
generic components aren't even allowed without attribute registering which is a no go unfortunately

#

System.ArgumentException : Unknown Type:`BovineLabs.Effects.Tests.Effects.KekTest+Kek`2[System.Int32,System.Int32]` All ComponentType must be known at compile time. For generic components, each concrete type must be registered with [RegisterGenericComponentType].

devout prairie
#

Hey folks.. just doing some initial testing piping the unity nav stuff through dots.. i have a landscape mesh that's roughly 1k width and 1k length, not too dense:

#

it's taking a few seconds to bake this - should i expect faster or does that seem about right? ( with or without dots obviously )

#

My next question was, it's also taking a few seconds to build when i add a building to the map at runtime, almost as if it's rebuilding the entire landscape mesh again.. this is my prototype update code:

rotund token
#

if your navbounds is the entire map

#

yeah it will rebuild the entire map

#

wait hmm maybe that's not true

#

been a while

#

you need your build sources list to be the same order

#

bare minimum

#

it hashes and only updates new/things out of order

devout prairie
#

yeah that's why i added the conditional to check if the source list already contains the mesh at the same position

#

so the source list should be:
Initial Build -
0 : landscape mesh
After placing building -
0 : landscape mesh
1 : building block mesh1
2 : building block mesh2
..etc..

#

tbf, it's parsing meshes not colliders, and there are around 200 meshes ( kinda 'building blocks' ) in the building

#

but it's taking an equally long time to build after placing the building as it does for the initial landscape build

rotund token
#

But yeah for that size seems about right

#

For a fresh build

#

Just have to figure out how to partial update

devout prairie
#

yeah, i think the update async isn't partially building, trying to debug that now

dense crypt
#

for IJobEntity, how do attributes prioritize when using a query for scheduling? I.E if I have [WithAll(T)] but my query I schedule with does not, what happens? Also how should I reason about which one to pick?

#

I suppose that the attributes are added on top of the query? At least that's how I understand it reading the docs

rustic rain
#

then I think attribute query options won't work

#

you should just check codegened result

dense crypt
#

For a typical Entity.ForEach I can use a field on my system that's a managed type. But in IJobEntity I'm not allowed to pass any managed types even if the job is intended to run main-thread only. Is there a workaround for this issue?
Trying to convert a ForEach in to a IJobEntity and it suddenly became very hard because of this limitation

rustic rain
#

.RunByRef()

#

this way you can have managed fields in job struct

dense crypt
#

Oh wait, this only works for IJobEntityBatch right?

proud jackal
#

Well - First question - why do you want a managed field on an IJE to begin? :3

rustic rain
#

besides, allows you to do abstracted execution

devout prairie
#

basically, when i just let it build that initial landscape mesh, so it adds only that to the list, and remove the 'requires singleton' to allow the gather/bake system to run continually, it seems to be rebaking the landscape each time

proud jackal
devout prairie
#

somehow it's not hashing the list as 'same as before' and doing a partial rebuild

dense crypt
# proud jackal Well - First question - why do you want a managed field on an IJE to begin? :3

In this exact case I'm making a job to start loading assets, it's done through addressables and as a consequence of loading I get a handle back. Since I can't store the handle in a native container (it contain's an interface field) I am storing it in plain old Dictionary. But I can't use Dictionary in IJE since it's managed.

I currently have this implemented in EForEach but I'd prefer to migrate it to IJE to future proof it (on v0.51.1 atm), planning to upgrade to 1.0

#

Perhaps I should just make this in to a function call instead? I'm not entirely sure how to approach this case

#

It's Main Thread only and non-burstable because of API usage

proud jackal
#

It seems this case is best suited for just any old function call / you could likely write a simple query.ToXXX to solve your needs :3

queen shard
#

Feels like the SortJob should use IDefer?

edgy fulcrum
#

I think it's because you use filtering you are updating the list's length thus the sortJob goes wonky

queen shard
#

Yes, but normally you use AsDeferredArray for that. And for example i can use two filter jobs after eachother

edgy fulcrum
#

mmm yeah I always use deferredArray but never did that particular sequence of jobs

trail valve
#

Hi guys, Does anyone here know how to check a entity have an IEnableableComponent(including disable)?

robust scaffold
queen shard
#

Thanks! It does work!

I just dont understand why, whats the difference between what i did?

        var handle = new FilterOdd().ScheduleFilter(indices, 32);    
        handle = indices.SortJob().Schedule(handle);
  
#

Is it the safety system that 'sees' indices is read after the FilteroOddJob, and you move it before. But how

queen shard
#

FilterOdd is an example, and uses IJobParallelForFilter

#

I dont know what you mean with IJE

rustic rain
#

IJobEntity

queen shard
#

No sorry im not using ECS per se, just the job system. Still thought this would be the most correct channel

rustic rain
#

it is

robust scaffold
# queen shard Thanks! It does work! I just dont understand why, whats the difference between ...

Sort job is an extension method of NativeArray/List that reads from the container. Once you schedule a job using a NativeContainer, you can not read or write from it from the main thread except for more scheduling. So to schedule a sort job after another job completes, you need to first create the job that sorts the NA/L then schedule it after. See if there's a ScheduleByRef() and use that for the sort job, otherwise you're good.

pulsar jay
#

I am trying to build a system that spawns entities on destruction of another entity.
Sounds simple but I am a bit stuck. I tried using SystemStateComponents.
The system correctly triggers when the entity is destroyed but I have no chance of getting its position to spawn the entities at because the LTW component has already been destroyed.
Is there any good way, besides constantly updating my state component with the position, to handle that?

rustic rain
#

which will remove entities in the end

#

so in order to get extended behaviour you just UpdateBefore destruction system

pulsar jay
rustic rain
#

just before destroying entity check whether it has Parent component

#

and maybe some kind of

#

Hierarchy entity tag

#

which would indicate that destroying children equals destroying whole hierarchy

pulsar jay
rustic rain
#

no

#

it triggers of DestroyTag

#

but before destroying entity you can check whether it has Parent component

pulsar jay
#

oh you mean I should then just add the tag to all its children too?

rustic rain
#

no

#

let's say it this way

#

foreach entity with destroy tag
{
if (em.TryGetComponent<Parent>(entity, out var parent)){
toDestroyToo.Add(parent.value);
}
}

pulsar jay
#

yeah I guess I see what you mean

#

but the problem is the parent is the one getting actively destroyed but the child is the one with the ability

#

atm the parent get destroyed and destroys all of its linked entities with it

#

but the linked entity does not have a clue that its about to get destroyed

#

It could only know if I would add the DestroyTag to the parent and all its linked entities if it dies

rustic rain
#

not really

#

does your parent know about ability?

pulsar jay
#

no

#

only via linked entity group

rustic rain
#

maybe it should?

#

at least have a tag

#

that indicates it

pulsar jay
#

the purpose of having a separate entity for the ability was to avoid overloading the root entitiy with components

rustic rain
#

but it's just a tag

pulsar jay
#

but that would create a separate archetype for each enemy with a different ability

#

so instead of having the movement code iterate over one chunk it would have to iterate over 1 chunk per enemy ability combination

rustic rain
#

why can't it be just 1 tag?

#

AblityHolder

pulsar jay
#

that would be ok. but what would that change?

rustic rain
#

because then

#

you can iterate over all destroy tag + ability holder

#

knowing that it has somewhere ability entity in hierarchy

pulsar jay
#

but right now thats the only ability that triggers on destruction. so basically it would need a HasTriggerOnDestructionAbilityTag which is pretty close to having a tag per Ability again

rustic rain
#

why can't you do with just having 1 tag per all?

pulsar jay
#

after querying for DestroyTag and AbilityHolder and getting the ability entity how would I execute the ability?

rustic rain
#

didn't you just want to spawn entity into it?

#

just do that spawn

#

and let system loop do it on next run

pulsar jay
#

The Ability entity has a SpawnOnDeath component which should spawn the specified prefab:

public struct SpawnOnDeath : IComponentData
{
    public Entity Prefab;
    public int Count;
}
#

But this could also be sth like ExplodeOnDeath

#

So the tag wont tell me what kind of ability to trigger

rustic rain
#

does it need to?
Just make a spawn on death of entity

#

and that entity will do it's job itself

#

you can have instead a buffer

#

DynamicBuffer<SpawnOnDeath>

pulsar jay
#

Oh so you mean the AbilityHolder should instantiate an AbilityPrefab which just does its stuff when it exists?

rustic rain
#

yeah

pulsar jay
#

ok now I got it ๐Ÿ˜…

#

I guess thats a good approach for the OnDeath abilities. But there are a lot of other abilities which e.g. should run each frame

rustic rain
#

it's the way ECS works

#

event entities

#

and etc

#

code execution can be delayed by 1 frame

#

but absolutely no blocking

#

for maximum CPU cache efficiency

pulsar jay
#

yeah thx for the input I will think about it

covert lagoon
#

Cool.

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.NullReferenceException: Object reference not set to an instance of an object.
covert lagoon
#

I fixed some of the missing usings in my code and it's gone now.

robust scaffold
#

Yea, unity largely removed that error in 1.0 at least. More bugs with baking though.

balmy thistle
warm haven
#

guys, does rendering static meshes using entities will be more efficent than rendering them as gameobjects?

viral sonnet
#

yes, although the workflow has to allow for it. (can't make 1 million unique meshes with different textures more efficient) - aaand, there's quite the bug right now with performance of the dots renderer that is fixed in b15

warm haven
#

kk, thanks for letting me know!

#

I am rather thinking about rendering some foliage, although I assume that the vertex animation isn't supported by now, right?

viral sonnet
#

i guess you'd do that with shadergraph? and that is supported

covert lagoon
#

I waited 30 minutes for the Rival Online FPS sample to build and it segfaults when I click "Host Game."

#

:/

#

There aren't any errors in the player logs.

#

Still segfaults.

#

I guess I'm not allowed to play with an up-to-date DOTS sample game.

signal phoenix
robust scaffold
#

This is a stretch but has anyone managed to get ComputeBuffer BeginWrite or the GraphicsBuffer version to work?

#

I can get BeginWrite to actually communicate data to the GPU but whenever I have rendering take a while, concurrent CPU writing and GPU reading causes a lot of flickering. Has anyone managed to "fence" rendering until CPU writing is completed?

#

A single post by the rendering guys who made BatchRenderingGroup say how they sync writing using an AsyncReadbackRequest but I want rendering to occur after a system in PresentationGroup to finish writing since the results in that produce updated values.

#

And I dont want to use a rotating double buffer (which didnt work anyways)

jolly palm
robust scaffold
#

I mean, there is a locking writing version, called SetData, which is very slow (relatively) and mainthread only.

#

I'm using it now and it works but I spent 8 hours today trying to get BeginWrite to work and it didnt.

jolly palm
#

What exactly are you writing to that is used by both CPU and GPU?

#

since that seems to be the problem. Its hard to synchronize writing if done by 2 separate cores with limited communication

robust scaffold
#

ComputeBuffer, a structured buffer on the shader side.

jolly palm
#

I guess i mean, why do both CPU and GPU need to write to it? Why are you unable to just use the GPU for the buffer

robust scaffold
#

I am trying to transfer data from the CPU to the GPU. By writing to this ComputeBuffer, I am transferring data from the CPU to the GPU.

#

Basically I have object positions in the CPU on Entities that I am transferring to the GPU for custom rendering. I want to do it fast but due to long rendering times on the GPU, the GPU rendering overlaps with the CPU writing job. When that happens, a race condition occurs and the screen flickers.

jolly palm
#

Oh you mean the GPU is reading from the buffer before the CPU finishes writing to it

robust scaffold
#

Yea.

jolly palm
#

I thought you meant that both the GPU and CPU were writing to it. Which is a race condition.
What you described isnt technically a race condition i dont think

robust scaffold
#

It is because since the writing is not guaranteed to be in a set order (rearranges every frame) so if you read from the buffer and halfway through the write job overwrites it, the rendering breaks.

jolly palm
#

That is an interesting problem....
I suppose ComputeBuffer.EndWrite isnt for signaling that the buffer can be read then

robust scaffold
#

No, it's very low level. Exposes basically the raw memory if possible. You dont even need to use EndWrite

jolly palm
#

Right. And a rotating buffer didn't work? I know that is often used in order to help with rendering frames faster

#

basically you would need to delay your writes until you know the frame is complete

robust scaffold
#

No. I had the CPU job write to a "future' buffer and the GPU read from a "past" buffer but that didnt seem to work.

#

The same flickering happened. And I know the CPU job is fine because if I use SetData() with identical output results, rendering works flawlessly

jolly palm
#

How many different sections are writing to this buffer. Can you just have a counting semaphore that locks next frame writes until all from the previous frame complete?
Something like how C# has Task.WhenAll?

robust scaffold
#

That's the problem. There's no way to tell if the GPU finished rendering the previous frame. That would fix the issue.

jolly palm
#

But you can tell when you start writing your next frame. And that is your timelimit

robust scaffold
#

So currently we keep track of where the GPU is using a tiny AsyncReadback per frame. It's certainly not nice but currently there is no exposed API to keep track of what frame is done on the GPU.

#

That's from the batchrenderinggroup team, aka hybrid renderer.

jolly palm
#

The way I see it you either
A. Have a job(s) each frame that write to the buffer, and you cant start the next frame's job until the previous completes
B. Any previous writes are immediately canceled when the next frame wants to write to the buffer

robust scaffold
#

GPU Execution overlaps with Systems, which is where the compute buffer data is being updated.

jolly palm
#

Oh i see what you mean, you cant time GPU execution with systems so you have no idea when the GPU reads from the buffer, which is a race condition

robust scaffold
#

And oddly no, placing the BeginWrite data upload inside the Rendering block (which I am 99% sure that it's always following completion of GPU execution) doesnt fix the problem of rendering flicking.

jolly palm
#

if thats the case, a double buffer should work then

#

since you switch it out per frame

#

or i think a triple buffer is used normally

robust scaffold
#

This is what I'm doing now, which works. Reading arrays from Systems and uploading using SetData

#

I've tried something like a double buffer that cycles. Didnt work.

jolly palm
#

My initial reaction is that you are implementing it wrong somehow.
Based on the timeline you shared, I think you either have to find a way to prevent overlap between your buffer writing and GPU reading.
Or you use multiple buffers so that you dont write to the buffer you are reading in the same frame.

robust scaffold
#

And this is all that I'm doing to calculate these arrays. Basically a simple circle distance culling.

jolly palm
#

i dont think using set buffer would work though since you are just replacing the buffer during the reads which results in the same problem.
I think you need multiple buffers on the GPU side, though i dont know what that woudl look like

robust scaffold
robust scaffold
jolly palm
#

Almost certainly a sync issue then, cause it looks like SetData() does wait for GPU sync to work

#

whereas StartWrite explicitly states that no CPU-GPU Sync occurs

#

which i know you already mentioned but wanted to be sure

robust scaffold
#

Yea. And when I reduce the rendering costs (remove 90% of the rendered objects), no flickering because GPU finishes before a new CPU write happens.

jolly palm
#

How about a single circular buffer?

#

err actually nvm

robust scaffold
#

I mean, theoretically possible? Havent tried not resetting the interlocked counter

jolly palm
#

I assume you don't have any custom processing of light in your shaders

robust scaffold
#

Objectively, SetData functions fine. There is minimal performance cost (sub 0.05ms) on the profiler to upload position data. The reason why i want to use BeginWrite is to remove the redundant 262KB NativeArrays required to collect the position data that is just immediately uploaded.

jolly palm
#

like you are just using URP/Lit or something?

robust scaffold
jolly palm
#

So you also have custom shaders to process lightmaps? OR just using standard lightmap structs and passing them to shaders

robust scaffold
#

Fully custom, i'm sending in float4s (XY is position, Z is light radius, W is light color).

#

As in I have 8 shaders and 12 draw calls to render my own lighting:

#

So I know 100% what's going on behind the scenes down to the individual pixel values. Because I wrote it myself.

jolly palm
#

Wow. Nice

#

As I see it, having these artifacts will always be a risk of not forcing CPU-GPU sync, and using SetData seems like the easiest way to enforce that sync (not sure if cheapest)

Implementing some sort of double/triple buffer would work, but I don't know how to properly implement that in Unity (unity does it automatically? I dont know how that wokrs though). Of course having 2 buffers for light frame data would have worked if you could update the data outside of the GPU buffer read, but you said you couldn't get that to work

robust scaffold
#

Yea, but that comes with an additional cost of even more memory being used. Memory is cheap but adding rotating buffers adds up quickly

jolly palm
#

right. At the end of the day its either a processing/memory cost.

If you cant get all the writing (processing) done before GPU reads start, you need more memory to compensate

#

Thinking about it, shouldn't SetData lead to frame loss since you have to wait for sync before moving data to the GPU?

robust scaffold
#

Honestly, I have no clue what it does.

#

It works and doesnt seem to have an impact on timing either.

jolly palm
#

My initial guess would be that it saves data in a separate array that gets pushed into the GPU during a safe/sync point

#

This may be exactly what you want anyways

#

Which i guess technically is a 2nd buffer it thats how it works

robust scaffold
#

Yea. I wanted to write directly to that separate data without an intermediate NativeArray.

jolly palm
#

So ideally you get the code for how SetData syncs with the GPU and use that to write data safely

robust scaffold
#

It's an internal engine API (set data is just an exposed Extern function) so I'll need to find a C++ decompiler and see how it works.

jolly palm
#

Is copying the data once that big of an issue, or does it have to copy for every shader?

robust scaffold
#

Just once. It's not an issue in terms of performance but these intermediate buffers are a quarter of a MB each (242KB) and the majority of it is not used.

jolly palm
#

This feels like the type of problem thats both really big and really small. If your entire lighting setup only ever requires an extra persistent 242KB of RAM, that sounds small. But in games with a small footprint that can be really significant

robust scaffold
#

Ehhh, this game is using the full suite of DOTS netcode, physics, and support up to 8192 (small) lights simultaneously. So it's not a small game and a quarter MB isnt much when the fluid sim portion takes up 4GB of floats so... eh

#

But every tiny bit helps. A bit of optimization here, some there, and I can halve the costs

jolly palm
#

Whatever you think works based on my (limited) experience working with OpenGL and shaders directly. I think the trade off of using SetData is worth it. You might be able to make the buffer smaller if you wrote your own GPU sync code, but thats the only benefit i see.

It might be worth looking into just to learn how to sync with GPU data though.

robust scaffold
#

There's CreateAsyncFence which just synchronizes GPU threads and of course the various mutex and locking abilities on CPU but none that cross between.

jolly palm
#

what about CommandBuffer.WaitOnAsyncGraphicsFence?

robust scaffold
#

That's the gpu fence I'm talking about. It synchronizes GPU threads to execute only after the inputted graphics fence is passed. And those fences are formed following the execution of a GPU draw call or dispatch.

jolly palm
#

on the topic of performance, do you know A good way of moving Persistent data into the ECS ecosystem?

I've been looking into using a Baker to create Blob assets, but It's still hard to find info on best practices, can the Baker seems to act at runtime for loaded scenes, which is not ideal if the blob asset requires processing to create

robust scaffold
#

The baker only runs in the editor. It generate bytecode that is the "cached" version of subscenes containing pure entities data.

jolly palm
#

Nothing is wrong with blobs or the baker. Its just not completely clear

robust scaffold
#

All subscenes do at runtime is read from that chunk of cached data and immediately translates it into entities. Very fast, no monobehaviors or GOs at runtime if you're going full ECS

#

Got any examples of data you want converted to blobs?

jolly palm
#

Right now I'm working on creating a simple workflow for Skinnedmesh animations in ECS, since Unity hasn't released their package yet

#

So I'm creating a baker that bakes AnimationClips into something ECS readable for SkinMatrix components

idle kernel
#

vertex animated textures?

jolly palm
#

Can't you just use shaders for vertex animated textures?

robust scaffold
jolly palm
#

Ugh but I dont want to wait a year

#

You are right though

#

Thats why I wanted a minimal setup, just to make sure it works

robust scaffold
#

A year passes quick. It felt like just yesterday I was slogging through IJobEntityBatch in 0.17 and trying to convert everything to ISystem.

jolly palm
#

Yeah. This reminds me of waiting for Jetpack Compose all over again

#

Great library for making android apps!

#

Now if only they had a better Dependency Injection system....

robust scaffold
#

Apparently Rival from Phil (commented above) has a animation system bundled with it as well

jolly palm
#

I need to up my searching game. This is great!

robust scaffold
#

Rival seems to be fully DOTS and free. The source isnt googlable but if you install the package, you can probably just traverse the package and find how he does animations.

#

Rival is officially supported by Unity themselves so I recommend digging through his package as that is probably Unity verified good code.

jolly palm
#

I've looked though some Unity code so I don't think that necessarily makes it quality. ๐Ÿ˜…

robust scaffold
#

Ehhhh, unity code is corporate code.

balmy thistle
#

What, it's written in COBOL?

#

Actually hip, happening corporations probably write in F# or Go or something

covert lagoon
#

I only changed this:
Platform: Linux
Configuration: Release
Scripting Backend: IL2CPP
IL2CPP Compiler Configuration: Release

#

I guess I should try removing TextMeshPro.

#

Does TextMeshPro not mix well with Entities in Linux builds for some reason?

queen shard
#

Hiya; im quite stuck with sorting a list that has been filtered.

The steps are as follows:

  1. Make a list with indices 0..8
  2. Filter out everything that is odd
  3. SortJob

However i'm noticing my sortJob gets the indices pre-filtering, eventhough its called on that List. I even added sync points and i see in the debugger that my list is correct the moment i schedule the sort.

void OnEnable()
    {
        NativeList<int> indices = new NativeList<int>(10, Allocator.TempJob);
        
        for (int i = 0; i < 8; i++)
            indices.Add(i);
        Debug.Log($"Start indices: {string.Join(',', indices.AsArray())}");
        var sortJob = indices.SortJob(new Comparer());
        JobHandle handle = default;
        
        handle = new FilterOddJob().ScheduleFilter(indices, 32);
        handle.Complete();
        Debug.Log($"After filtering: {string.Join(',', indices.AsArray())}");

        handle = sortJob.Schedule(handle);        
        handle.Complete();

        indices.Dispose();
    }
    
    [BurstCompile]
    struct FilterOddJob : IJobParallelForFilter
    {
        public bool Execute(int index) => index % 2 == 0;
    }
    
    struct Comparer : IComparer<int>
    {
        public int Compare(int x, int y)
        {
            Debug.Log($"Comparing {x} with {y}!");
            return x.CompareTo(y);
        }
    }
#

To be clear; i dont understand why my sorting is done on odd numbers. I would expect, since the indices have been filtered, only to see comparing the even numbers.

queen shard
robust scaffold
balmy thistle
signal phoenix
#

@covert lagoon Have you tried building with IL2CPP in "development" mode, or building with Mono? If successful, it might help isolating the issue.

According to the thread you linked earlier, this sounds like an issue that happens with Linux + non-dev IL2CPP builds

safe lintel
#

has anyone actually been using the RenderMeshUtility.AddComponents with a RenderMesh with 1.0? Ive tried runtime and in a baking system and neither appear to work.
Only way ive actually been able to make it work is to copy an already converted entity's RenderMeshArray and use the RenderMeshArray version of AddComponents(or manually add every component), but that seems to defeat the purpose of the whole utility.

covert lagoon
#

But when I try to close the window, the game dies without actually closing. The window stops being redrawn and both CPU and GPU usage drop to 0%.

#

Ok I killed it then launched it again and this time it closed properly.

#

Player-prev.log ends with this:

Setting up 4 worker threads for Enlighten.
Vulkan PSO: data extracted [new size=126144, old size=0, incomplete=0]
Vulkan PSO: Saved size[126144] path[/tmp/PhilippeStAmand/Rival_OnlineFPS_ClientServer/vulkan_pso_cache.bin] success=1 headerChanged=1 sizeChanged=1
malloc_consolidate(): unaligned fastbin chunk detected
Caught fatal signal - signo:6 code:-6 errno:0 addr:0x3e800004c5a
slow epoch
#

Is there a specific version of entities that I need to install depending on my unity version? I'm following up the official "Getting Started" guide but I only have error consoles no matter what I do

covert lagoon
#

Just click the button to add a package by Git name in the package manager, type com.unity.entities, press Enter, and it should install the latest version that supports the version of Unity that you're using.

slow epoch
#

Yep that's exactly what I'm doing. I have Unity 2022.2.0b8 and installing entities exactly like that, but I'm getting errors from other packages like these:

slow epoch
#

Looks like the only thing I can do is remove all 2D but that's the project I wanted to make

covert lagoon
#

I guess com.unity.2d.animation depends on an older version of com.unity.collections than com.unity.entities, and the newer version on which com.unity.entities depends is being used.

#

But shouldn't you have a different error then?

#

One about the NativeHashMap type not being found.

#

But I can't find a version where .Count is not a method.

light mason
#

Im wondering if someone could help me understand when to use IJobEntity vs IJobChunk

rustic rain
#

it's made for less boilerplate code

#

write some simple IJE and take a look at generated code

light mason
#

ok ty

dusky roost
full epoch
#

seems this doesnt work : var rendMesh = EntityManager.GetSharedComponentManaged<RenderMesh>(meshEntity);
rendMesh.mesh.GetVertices(vertices); (vertices is list of Vector3) - so how we can get list of mesh vertices manipulate it and set it back to RenderMesh?

rotund token
#

Firstly are you still on 0.51?

#

Secondly are you writing the verts back to the mesh?

full epoch
#

its 1.0 - mesh and vertices are null even material is - it seems the only way is to use RenderMeshUtility destroy entity or remove RenderMesh and then create it again using AddComponents from RenderMeshUtility? Or is there an easier way?

rotund token
#

oh thats because rendermesh isn't really what is used anymore in 1.0

full epoch
rotund token
#

i dont create my entities at runtime

#

for my procedural generation and i have infinite voxel terrain

full epoch
#

There is also this RenderMeshArray component documents say it contains meshes ...

#

Yep this worked for me in order to change vertices from the code : Mesh mesh = rma.GetMesh(MaterialMeshInfo.FromRenderMeshArrayIndices(0, 0));mesh.GetVertices(vertices); vertices[0] = new Vector3(0,-100,0);
mesh.SetVertices(vertices); >>>> This is code in Entities.ForEach(simply changes value of 1 vertex) - but to be honest i dont know exactly what means this MaterialMeshInfo need to read more docs if they exist (rma is RenderMeshArray component(inside EFE), vertices is List<Vector3> from the main thread) - now i can at least read veritices and other mesh properties previously generated xD EDIT : seems that MaterialMeshInfo simply supplies indices for lists in RenderMeshArray(which contains Lists of Meshes and Materials which we set when creating entity explained in doc in my 2nd post above - look up) so we can get proper mesh / material we want to manipulate in our code ... EDIT2 : also read this interesting post and whole thread actually : https://forum.unity.com/threads/rendermesharray-getmesh-materialmeshinfo-returns-null-why.1359493/#post-8576641

rotund token
honest plinth
vernal cypress
#

Hi everyone ! I'm currently designing a navmesh navigation system in DOTS 1.0 using NavMeshQuery.
I was wondering what would be less costly between these two option :

  1. having a single NavSystem & NavAgentComponent that handles both path Queries & part of the navigation state base (eg : RequireRouting, ComputingPath, GoingToDest, etc...)
  2. having 2 separate system NavQuerySystem & NavAgentSystem with 2 separate components NavQueryComponent & NavAgentComponent (possiblity to split NavQuerySystem into 3 subsystems StartQuery, UpdateQuery, EndQuery)

the NavQueryComponent would then need to be added only when the entities need to be computing a new path & removed upon completion. how expensive is it to add & remove components at runtime in system having design myself an ECS i know it's suppose to be the most expensive part of the ECS if it's archetype Based even though Unity has probably optimised the shit out of it.

Any thought ? thank you taking the time to read my post !

solemn hollow
#

@vernal cypress there really is no difference in you splitting the logic up into multiple systems or not. you only get the systems overhead on mainthread once per system (which is not really significant). everything else performance wise depends on your actual logic.

#

whether adding and removing components is a good idea or not depends on how frequent you do this. since you shouldnt need to request a path every third frame it should be fine to add and remove a component to start pathfinding

#

i would advise to not overanalyze your problem performance wise at this point and just implement it the most simple way possible. ecs really shines with how easy it is to modify the architecture later on

#

for example switching between removing / adding and enabling /disabling components is really easy now

vernal cypress
#

@solemn hollow Thank you for your insight ! Yeah I will try to prototype a working solution fast and refactor it later then

solemn hollow
#

i am really interested in what you end up with. i am doing navmesh stuff myself atm. though more baking than the agent

vernal cypress
#

Cool ! i'll keep you updated. feel free to share your progress with me aswell, i'm interested.

devout prairie
pliant pike
#

basic stupid question but how do I get data and write to it in an IjobEntity that isn't part of the main query

safe lintel
#

@honest plinth I spent yesterday testing this and couldnt get the RenderMesh version working during baking at all, only using RenderMeshArray would it render and still only with a subscene closed. docs for "runtime" creation definitely seem out of step with actual reality of what exists(feels like this area might still be undergoing changes?)

pliant pike
#

is ComponentDataFromEntity<>() the only way

safe lintel
#

thats probably the best way

#

now ComponentLookup for 1.0

pliant pike
#

ok cool thanks, I figured I'd check if there was a better way

safe lintel
#

you could technically get the chunks for another query on the main thread and stuff that data into the job if you were some kind of masochist

pliant pike
#

its kind of convaluted having to get the data and the entity then write backwards and forwards etc, but I guess its fine for now

devout prairie
#

Be interesting to see some comparisons, out of the handful of ways you could approach doing that common scenario, which ways are faster etc

viral sonnet
devout prairie
#

CDFE, interim container, ecb, buffer etc

pliant pike
pliant pike
devout prairie
#

If it's just one value, I'd maybe pass in a NativeReference and then assign it where it needs to go afterwards

viral sonnet
#

that commit is compatible with 0.51

devout prairie
#

So if you have say one Health float for example to write, pass in a NativeReference<float>, write to it, then afterwards write that float to your target health. Rather than opening up a CDFE of every potential Health and passing that in

pliant pike
pliant pike
edgy fulcrum
#

is there an equivalent of GetComponentLookup() for SharedComponents? I want to look up an unmanaged SCD (just an int) for a random entity in an IJobEntity...

urban ore
#

This might be a dumb question, but what's the intended way of ordering OnCreate calls when using ISystem's? In my case, I just want to make sure that one system runs before the others (the first system creates a singleton with a list and the second/third/etc. adds some static data into it). It seems like I could just use blind calls to World.GetOrCreateSystem from the subsequent/dependent systems? But surely there's a better way? I see a lot of people creating the singletons in self-disabling/ordered OnUpdate or in Baking but that doesn't seem ideal to me for this use-case?

#

Without singletons this could presumably be done by using system state. But I'm a bit nervous about that since the only way to then add to the state would be via the managed route with GetOrCreateSystemManaged.

rotund token
#

and i strictly try to avoid this

#

but in 1.0 there's a new [Create(Before|After)] attribute

    /// Apply to a system to specify a creation ordering constraint with another system in the same <see cref="ComponentSystemGroup"/>.
    /// </summary>
    /// <remarks>Create before or after a system constrains the creation order of these systems when initializing a default world.
    /// System destruction order is defined as the reverse of creation order.</remarks>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)]
    public class CreateBeforeAttribute : Attribute, ISystemOrderAttribute```
#

if you must order them

#

Baking but that doesn't seem ideal to me for this use-case

adds some static data into it

IMO baking seems ideal for your use case

urban ore
#

By which you mean baking the singleton? Because baking happens before system creation, right?

rotund token
#

well yes

#

but the entity wont exist until after system creation

#

due to having to load from subscene

#

unless you manually control the subscene/system creation ordering

urban ore
#

I'm not sure I understand. If I did that, and the singleton entity didn't exist until after system creation, I wouldn't be able to add to the singleton's list in the second system's OnCreate function?

rotund token
#

well the question is really

#

why do you need it in oncreate

#

that kind of determines what is required

urban ore
#

Sure - my goal here is to give the second system a handle to a value that's continuously computed by the first system. That relationship is set up on system creation and the computing is based on a small set of configuration data that's passed in and added to this list. So it would make sense that that handle would go in the second system's state on creation, I'd think.

#

For example, the type of the output value (the computed data) is one of a few different options. I'd like to return a strongly-typed handle for that.

#

Doing all of this in OnUpdate just seems like it's probably... too late? Or at least would be pretty complicated.

rotund token
#

What's the problem with just calling SystemAPI.GetSingleton<MyData>() in OnUpdate in the second system?

urban ore
#

This is a library, so MyData wouldn't have a member for the computed data you're looking for. Hence the handle instead.

rotund token
#

idgi

#

why can't mydata have the handle?

urban ore
#

Sorry - I misunderstood you. MyData or some other singleton in the application would probably hold the handle. Or they could hold it in system state. I don't really care. But where does the handle come from? I was planning on returning it as part of a call they make from OnCreate.

rotund token
#

in OnCreate of System1, it creates a singleton and puts the data on it

#

then any other system (System2) can read it whenever it needs

#

anyway that doesn't really solve the whole baking in time thing, that'd require setting it up in OnStartRunning etc

#

and the attribute approach i mentioned above would solve your problem anyway if that's the way you want to do it

#

(i got to bounce)

urban ore
#

Yeah, I think the attribute would probably work. My situation's kinda complicated. Thanks for the help!

edgy fulcrum
#

@rotund token your SCL is pretty awesome! Thanks for the tip ๐Ÿ™‚

#

@rotund token entityManager.GetCheckedEntityDataAccess() <-- where can I find this?

covert lagoon
#

[0.51] How do I use ComponentSystemBase.GetComponentTypeHandle with a component type inheriting from Unity.NetCode.ICommandData?

worn umbra
#

Hi guys, I have spent three days already on this, so I hope to find answers here. In my project, I'm using DOTS [1.0.0-exp.12] with Netcode for Entities [1.0.0-exp.13]. My issue is straightforward, and I need help understanding how it can be solved. I'm working on the Menu to Game transition. I have a managed script storing all prefabs and baking them into an entity. This script is in subscene (in a prefab) and has GhostComponent assigned, which means it is spawned in the Default World when the user launches the game. So it is not in "InGame" status, and Client/Server worlds don't exist yet. (tbh, I don't like this solution, and I would like to load the sub-scene instead when I host the game, but it seems it is impossible now). Later I'm trying to host the game, so I create Server and Client worlds, move to "InGame" status, and I need to access the prefabs now. I want to spawn a prefab in the multiplayer. The problem is in querying the entity with prefabs. It is listed only in the Default world, and I cannot access it in the Server world. On the Unity forum, I have found a note that the pre-spawned-ghosted entities should be spawned automatically when you enter the multiplayer, but this is not happening. They are all listed under the Disabled tag, and they are not in Server/Client world. How do you store your prefabs before you go into a multiplayer mode, and how do you simultaneously make them accessible for server and client? Thank you very much for any tip/directions. I'm losing my hair on this.

robust scaffold
rotund token
#

Without needing to change the package

worn umbra
robust scaffold
robust scaffold
#

So the NetworkIDComponent must have the NetworkStreamInGame component added by you in the code.

#

Both on the client and server

worn umbra
viral sonnet
#

seems like b16 is the last version before 2022.2 release

robust scaffold
robust scaffold
viral sonnet
#

are the annoying asset database problems fixed? still on b9

robust scaffold
viral sonnet
#

damn, are you on b16?

robust scaffold
worn umbra
# robust scaffold Default world? The default world shouldnt be used when you're using netcode.

Well, I was saying at the main post, this entity exists before NetCode starts. The user click host / connect button and that will create ServerWorld and ClientWorld. They call it "Prespawned ghosts" at netcode documentation. It has two rules:

  • With regard to using subscenes, when placing an object in a subscene, you no longer place the ConvertToClientServerEntity component on it as being in a subscene implies conversion to an Entity. Also, it means the option of making an entity only appear on the client or server is now missing. Prespawned ghosts always appear on both client and server as they are just like a normal spawned ghost, and will always be synchronized (as configured) after the game starts.
  • Loading a new subscene with prespawned ghosts after starting (entering the game) is currently not supported.

I'm loading the subscene with prespawned ghost before starting (enterting the game) so it should be supported

robust scaffold
robust scaffold
#

My SceneManager, which is a core unity feature using full scenes not subscenes contains the subscenes and entities for gameplay.

#

And yes, that scene has prespawned ghosts in subscenes that are mirrored on client and server with proper sync

#

This is my current scene distribution

#

And of course the things that need to be networked as well

#

I just press the unload so it leaves only the launcher scene active

#

And when starting up server/client, i make sure to load SampleScene (the main scene) before starting the worlds and everything works

worn umbra
robust scaffold
worn umbra
#

Thank you for sharing the screenshots. It makes me sure about that I'm on the right track.

rotund token
#

some point up to b14 they fixed il2cpp

#

but yeah still getting corrupted subscenes in b14, haven't tried the newer ones just yet

viral sonnet
#

b15 they fixed the render stuff. i just can't stomach closing the editor on every code change ๐Ÿ˜„

#

and b9 seems to be fine on that front

rotund token
#

you never get corrupted subscenes in b9?

#

because i definitely do

#

frequency i'm not sure

#

i haven't really tested a library with subscenes in a while

#

just been writing unit tests