#archived-dots
1 messages ยท Page 271 of 1
I'm not sure where that comes from. AFAIK a system uses default instead of Dependency. I always got errors when I left it empty
so I tell everyone they should use Dependency
apparently there's some auto-magic but /shrug
hmm i think it was in a changelog or sth. i remember reading it...
yeah I remember it too but have forgotten where I read it
anyway, I think it's a bad habit to not explicitly write it out
fk auto magic
i guess as soon as you return a jobhandle from a job you should manually manage all dependencies in the system
if you only use Entities.Foreach().Schedule() without parameters and returning jobhandles it works internally with the Systems Dependency
the first example is pretty much unreadable. you'd never know the jobs run in a sequence
bruh, any tip how to solve this?
Basically I want to randomise positions of certain entities with certain rules, like "not closer than 50 units to any other certain entity".
I was thinking about simply changing Translations to some neutral position with max float value on all of them.
And then do random logic on each entity: check compare it's translation after random to translations of all other certain entities.
But here's the problem. Can I do it in same job?
var translations = GetComponentDataFromEntity<Translation>();
dep = Entities.WithAll<StarSystem.StarSystem>()
.ForEach((ref Translation translation) =>
{
var nextRandom = rnd.NextFloat2(MINRect, MAXRect);
translation.Value = new float3(nextRandom.x, nextRandom.y, 0f);
for (int i = 0; i < systems.Length; i++)
{
if (translation.Value -)
}
})
.Schedule(dep);
i agree. magic that shouldnt be there
it's just confusing. I already see how much problems devs are having with dependencies. At first it's one thing you never care about and then boom, I don't get it, what's Dependency? Why do my jobs run after each other and not in parallel, etc...
but honestly i am amazed how comparativly easy it was for me to get into dots (very early adopter). I did not have any experience whatsoever with multithreading etc and the errors guided me pretty well.
again not sure what you want to achieve. this sounds like a job for multiple systems
id say complex worldgen generally runs in steps
Can I use read/write TypeHandle in system that also has write access?
var translations = GetComponentDataFromEntity<Translation>();
dep = Entities.WithAll<StarSystem.StarSystem>()
.ForEach((ref Translation translation) =>
{
basically just this
is that legal? xD
well Transforms is an easy case. you can read from LocalToWorld.Position and write to Translation
we are talking about worldgen here too right?
kind of, this is all just 1 step of randomizing positions
potentially that would be the only world gen xD
then just only use the ComponentDataFromEntity. Its not a hot path so youd not need to squeeze out every little bit you can by liniar iteration.
yep, I'm obviously nitpicking. It's all very nice and user friendly. Granted, DOD makes multi threading a lot easier to grasp
i am teaching some students in DOTS atm and i am really amazed how much easier the entry got compared to early days too. its defininatly made progress(allbeit too slow for my taste :D)
@rustic rain ```var translations = GetComponentDataFromEntity<Translation>();
dep = Entities.WithAll<Translation>
.WithAll<StarSystem.StarSystem>()
.ForEach((Entity e) =>
{
but why can you read from translation and not from localToWorld... why is translation set at this point
if you spawn entites and you want to read from them you need to have a sync point or manage their translation data in some other fashion
i mean you could maintain an array of translations you spawned entities at in that system and make sure you spawn no other entity close to another based on that array instead of reading from not yet fully created entities
i hope i do make sense here
Another way to go about it to just spawn alot of entites and delete ones that are too close to each other. that might be more multithreadable.
yeah, that's what I'm doing rn
I can't read from LTW
because in job Z I assign Translation to some far far away
so when I do checks, it's not actually trigger by accident
and I don't wait till it's written to it
oh well, I think I crashed unity
xD
sry i still dont get the problem you are trying to solve here. generate an array of correct translations in the first place and then spawn the entites?
yes but somehow your problem seems to be that you have not yet valid entites already spawned and then want to query from them in the same system. spawn them in the right location in the first place.
nah, they are all valid
problem I was trying to solve is simple - I am pepega, who doesn't know rules of ECS
xD
I don't need for each loop
I Just need Job With code
hmm now i understand even less^^.
you want to check for each entity if there is another entity in a certain radius. so do a foreach and in that foreach iterate over the chunks of all those entites again.
can you just post some pseudo code?
.ForEach((Entity e) =>
{
float3 pos;
do
{
var nextRandom = rnd.NextFloat2(MINRect, MAXRect);
pos = new float3(nextRandom.x, nextRandom.y, 0f);
translations[e] =
new Translation() { Value = pos };
} while (CheckValid(translations, pos, systems));
})
here's what I did
private static bool CheckValid(ComponentDataFromEntity<Translation> translations, in float3 pos,
in NativeArray<Entity> systems)
{
for (int i = 0; i < systems.Length; i++)
{
if (math.distance(pos, translations[systems[i]].Value) < 50f)
{
return true;
}
}
return false;
}
it crashed kek
protip: use math.distancesq ๐
why?
square root is expensive and multiplying the needed distance by itself is fast
or can even be a constant in your case where it would be 250
did it crash or just not respond anymore
CheckValid looks okay, the other one, I don't see if the job runs on a translation query. I also don't understand why you write back to translations[e]
{
for (int i = 0; i < systems.Length; i++)
{
var e = systems[i];
Start:
var nextRandom = rnd.NextFloat2(MINRect, MAXRect);
var pos = new float3(nextRandom.x, nextRandom.y, 0f);
translations[e] = new Translation() { Value = pos };
for (int j = 0; j < i; j++)
{
var s = systems[j];
var dist = math.distance(translations[s].Value, pos);
if (dist < 50f) goto Start;
}
}
})
hes randomly generating positions until he finds a place thats ok
wtf....
well, no need to write it back to chunk. leave the random position in stack until you know it's valid and then write back
true
dear lord, a goto. that the day will ever come that i see such code
ngl, it seems so good
id kill my coworkers for that ๐
that's just shameless ๐
saves me 50 lines of code
?!
instead of having do while loop
i can probably do it with a while and a bool
I just do goto
saving so many lines
and making it extremely more readable
dep = Entities.WithAll<StarSystem.StarSystem>()
.ForEach((Entity e) =>
{
float3 pos;
do
{
var nextRandom = rnd.NextFloat2(MINRect, MAXRect);
pos = new float3(nextRandom.x, nextRandom.y, 0f);
translations[e] =
new Translation() { Value = pos };
} while (CheckValid(translations, pos, systems));
})
.Schedule(JobHandle.CombineDependencies(posDep, dep));
dep.Complete();
}
private static bool CheckValid(ComponentDataFromEntity<Translation> translations, in float3 pos,
in NativeArray<Entity> systems)
{
for (int i = 0; i < systems.Length; i++)
{
if (math.distance(pos, translations[systems[i]].Value) < 50f)
{
return true;
}
}
return false;
}
Just compare this and
this
dep = Job.WithCode(() =>
{
for (int i = 0; i < systems.Length; i++)
{
var e = systems[i];
Start:
var nextRandom = rnd.NextFloat2(MINRect, MAXRect);
var pos = new float3(nextRandom.x, nextRandom.y, 0f);
for (int j = 0; j < i; j++)
{
var s = systems[j];
var dist = math.distance(translations[s].Value, pos);
if (dist < 50f) goto Start;
}
translations[e] = new Translation() { Value = pos };
}
})
.WithDisposeOnCompletion(systems)
.Schedule(dep);
you can inline in the first way too lol
I didn't even know goto was a thing in C#. TIL
kill it with fire
but why
why is goto bad? assembler also uses it?
i guess a single one is not too bad readability wise. thing is you dont have good formatting anymore
ok, I'm just bored because webgl takes 11 minutes to export
I like both these perspectives: kill it with fire and assembler uses it
i'm just trolling, kill it with fire!
I don't get the hate
compilers have a hard time with it. any optimisation is gone
oh
That's a good point. Coding according to the conventions of the compilers
Dammit, thought my time machine finally worked
it's not about readability, in that sense goto would win over pretty much anything. you could write gotos instead of loops. but yeah, to tell the real difference you'd have to look at the assembly. the goto one should always look much worse.
@rustic rain report back on how that worldgen in conversion worked out for you. ill need to implement something similiar soonish
works fine, it does randomises positions xD
public void RandomizeWorld(uint seed)
{
var rnd = new Random();
rnd.InitState(seed);
var translations = GetComponentDataFromEntity<Translation>();
var systems = _starSystemQuery.ToEntityArrayAsync(Allocator.TempJob, out var dep);
dep = Job.WithCode(() =>
{
for (int i = 0; i < systems.Length; i++)
{
var e = systems[i];
Start:
var nextRandom = rnd.NextFloat2(MINRect, MAXRect);
var pos = new float3(nextRandom.x, nextRandom.y, 0f);
for (int j = 0; j < i; j++)
{
var s = systems[j];
var dist = math.distance(translations[s].Value, pos);
if (dist < 50f) goto Start;
}
translations[e] = new Translation() { Value = pos };
}
})
.WithDisposeOnCompletion(systems)
.Schedule(dep);
dep.Complete();
}
so the thing with spawning gameobjects early on worked?
ah ok
also the most fun
eh, I have more fun when I know what I want to do
figuring out what to do is fun when you have people to discuss it with
lots of trial and error when you don't have people with lots of experience
@viral sonnet are you actively working on your ability system or is it just a casual sideproject? We recently talked about abilities and i later stumbled upon a short post of your system. I was wondering how you add new behaviours to your abilities.
pretty active ๐
Do you have extra components that handle the movement of the projectiles for example?
from the looks of it we have quite similar options.
i have 2 projectile types, virtual and physical. physical has collisions and a direction, virtual is just following the player until it hits
and how you handle thrown projectiles that move in an arc or projectiles circling a player?
right now I don't. If I would add it would be another comp in addition to physical
ah ok. i split my ability system in basically 2 parts. AbilityBehaviours and AbilityEffects. Effects are the things that effect other entities (targets) and behaviours are the things the ability itself does. RN i have building blocks of behaviour that stack to form whatever movement you want combined with the targeting component. So a projectile + heading component + non static target becomes a homeing missile. A projectile + parabola component + static target becomes a projectile traveling in an arc towards a position the target was when it was thrown
im not too happy with the authoring atm cause i have too many possible combinations :S
but this way its very easy to extend...
my projectile is just an archetype. particles are its own comp with own system that's a GO that just follows the entity
sadly i have to do the same because of sprite renderers and Particle systems beeing hybrid.
but where we differ i guess is that i convert the authored projectiles too
So you are probably developing it for the asset store?
that's the plan ๐
ill watch out for it! very curious
thanks ๐ I've just taken a look at my loader system: ```public partial class ParticlePrefabLoaderSystem : SystemBase
{
public Dictionary<int, GameObject> particlePrefabs;
protected override void OnCreate()
{
particlePrefabs = new Dictionary<int, GameObject>();
var lala = Resources.LoadAll("Particles");
foreach (var p in lala)
{
Debug.Log("loaded " + p.name + " " + p.GetType().ToString());
particlePrefabs.Add(p.name.GetHashCode(), (GameObject)p);
}
}
protected override void OnUpdate()
{
}
}``` it's really dumb but effective for hybrid. that way I can circle around the problem of having SharedComponentData and GameObject references
I need to go back to particles once I've finished another part. See if it will hold up
Right now I'm designing a way to have linear memory buffers for entities that work like a DynamicBuffer as array and hashmap
If I can manage to write it, it will be pretty dope
because I can't stress enough and @rotund token will correct me on that but DBs suuuuuck ... haha
access times are just ass
overall time:
none: 22ms
only boss: 24.66ms (250k entities on 1 DynamicHashMap, 250k lookups no writes in the measured time)
only casters: 56.21ms (1 entity on 250k DynamicHashMap, 250k lookups no writes in the measured time)
both: 62ms
a test I did yesterday, has to do with a dynamic hashmap that has data which entities are in combat with other entities
250k attack one boss monster
160ns per lookup is slow ๐ฉ
eh, could be 16 ๐
What is that loader? Looks gross =D
its still really impressive to me how many entities you guys are really try to get running at once xD
loader for hybrid particles. that way I can only reference an int and spawn the correct one from entity
true, it's gross. what's even more gross is to have no animations or particles in ecs, so ... ๐
It kind of loads all particles into memory permanently
yeah, for now. obviously has to be refined but the gist stays the same I think
I really wish they provided an unmanaged visual effect graph
The actual visual effect script is pretty much just a wrapper for native code so I don't think it's be too hard
yeah, everything hybrid sucks right now
(also this is only the second time I've seen use goto used in c#, kill it with fire)
๐ท ๐ฎ ๐ต
such a letdown when they had a dots vfx graph on the roadmap as in progress for months, then changed it to under consideration
I was under the impression that all I'm writing are for loops. Now I'm under the impression that all I'm writing are hashmaps ๐คฃ
ok what. I have an entity being changed elsewhere, i can see the correct data reflected in the inspector when it should be, but when I get that same entity via query the data is wrong
maybe it's overwritten?
@rotund token reduced it from 66ms to 31ms. key lookup is now through a hashset with prime hashed entity1+entity2. write is done via NativeStream and a single threaded job builds the hashset and the multiHashMap. even with 500k items it just takes 1ms to build.
I have to say, the combination is pretty nice. Especially because I don't have to set the Capacity of the hashmaps which is a pain to know beforehand. If I manage this better the hashmap build job could even be faster. Only thing that's missing is to set the blockSize of the NativeStream that's allocated. 4k is okay but I could need some more ๐
thanks! ๐
I have only single writes right now. Don't know how I could batch them which seems like a requirement for the WriteLarge extensions, right?
yes thats the point
if you need to write more than 4088 per allocate
nativestream is a lot faster if you can batch your writes
huh, I have overlooked errors because safety checks were turned off. I set the chunk count as the ForEachCount for the writer and use the batchIndex of the IJobEntityBatch. seems pretty default usage to me. I could supress it with [NativeDisableParallelForRestriction] but I'm wondering what's wrong in the first place
yeah you basically have to disable parallel writing safety if not using ijobfor
Ah I see, I remember having to do that once but never quite figured out why. With IJobChunk and the entityIndexInQuery it was pretty straight forward. Seems like it's built for that
I don't think so, the inspector still has everything correct even if i switch away and refresh it
the inspector shows only the values from the end of the frame. you could read the value somewhere in between. I dunno, the question is, why should it be different? It's either overwritten or you read the wrong thing
Can't think of much more causes tbh
break point on it?
look at the speed!
655360 elements
WriteLargeBurst - 0.03ms
WriteBurst - 0.86ms
damn!
Ok so how do I properly work with entity queries, because some of these get the right data while others do not. im very confused and I don't even know where to begin debugging this.
EntityQueryDesc desc = new EntityQueryDesc
{
None = new ComponentType[]
{
typeof(PlayerTag),
typeof(ChestTag),
typeof(DoorTag)
},
All = new ComponentType[]
{
typeof(LocalToWorld),
typeof(RefIDComponent)
}
};
EntityQuery q = eManager.CreateEntityQuery(desc);
float3 pPos = PlayerInventory.pInventory.gameObject.transform.position;
NativeArray<Entity> matchedEntities = q.ToEntityArray(Unity.Collections.Allocator.Temp);
print((eManager.HasComponent<MobTag>(e)) + ", " + cInScene.inScene);
foreach (var e in matchedEntities)
{
RefIDComponent cRefID = eManager.GetComponentData<RefIDComponent>(e);
InSceneComponent cInScene = eManager.GetComponentData<InSceneComponent>(e);
LocalToWorld cLTW = eManager.GetComponentData<LocalToWorld>(e);
WorldComponent cWorld = eManager.GetComponentData<WorldComponent>(e);
BaseIDComponent cBaseID = eManager.GetComponentData<BaseIDComponent>(e);
Like here I try to print both if it has a certain component and if it is in the scene, which prints what I believe is correct data, but then when I go into an if statement over cInScene.inScene and check again it never prints anything
To be clear I am trying to read
ummm, try explaining this again?
- what you tried
- expected result
- actual result
- This is in a Monobehaviour, looping through entities that fit a certain query, and reading data from them. In this case, I was going to perform some action on an entity if it had a
MobTagcomponent and iftruewas in the attachedInSceneComponent. - It was supposed to do an if/else on
InSceneComponent.InScene, and for debug purposes it is printing whether it has the tag or not. - Even when both conditions I am looking for are true, such as
print((eManager.HasComponent<MobTag>(e)) + ", " + cInScene.inScene);printing true, in the if/else loop it never prints the right thing. Also, it seems as though sometimes it printsFalsefor the InScene variable even if I can see in the inspector that it is true
i wonder if I could debug.log a get; set; in a component, to see if i'
m secretly setting it somewhere
is that allowed
I think you are a bit stuck in your train of thought...
What you should do is make 2 minimum examples in code to compare
e.g.
Always works:
print((eManager.HasComponent<MobTag>(e)) + ", " + cInScene.inScene);
Never works:
if(cInScene.inScene){
print((eManager.HasComponent<MobTag>(e)) + ", " + cInScene.inScene);
}
Now also, what is cInScene?
Seems pretty important but there is no information in your question showing exactly how it comes to be (other than it being some component data)
To me it looks like the entity query is fine, but maybe you have some issues with this InSceneComponent
That's what I have done. Also, what do you mean, how it comes to be?
(Also I tested my Get Set idea to make sure it wasnt secretly being set every frame. It wasn't.)
Your original question was about entity queries but from your post there is nothing to suggest that the entity query shown plays any part in your issue.
So it seems that you are getting lead down the garden path by your train of thought.
If you can reduce the number of possibilities you will be able to figure it out easier.
This is just some advice to help you get to solutions quicker.
If those above snippets I posted are your issue then then only things it can be are:
- the whole block of code isn't getting called, in which case, why?
cInScene.inSceneis false, in which case why is it false (i.e. how does it come to be)?
In the inspector and in the debug Get Set the inScene should be true.
The code block is being called, if I put something in there it floods the console.
but InScene seems to be false in the code block
also the get set reveals that it is never set to false
The odd thing is when 1 prints true, true, which means 2 and 3 should pass, 4 never prints
print((eManager.HasComponent<MobTag>(e)) + ", " + eManager.GetComponentData<InSceneComponent>(e).inScene); //1
if (eManager.GetComponentData<InSceneComponent>(e).inScene) //2
{
if (eManager.HasComponent<MobTag>(e)) //3
{
print("Mob in scene"); //4
print(cRefID.refID);
print("---");
}
yep you're right, so there is something else going on
is it sequential like this or in separate functions
What do you mean, like when is it changed?
I believe the only place it is changed in earlier in this function. This is a loop that processes certain events in the world and changes some entity data, and then this section of the loop checks the newly updated data and sees if the object needs to be despawned, spawned, etc
What the difference between EntityManager.CreateEntityQuery() and SystemBase.GetEntityQuery() ?
1st creates new, 2nd gets cached or creates new
Any tip what are my options to restore Entity connections during save/load worlds?
I assume I can restore randomly generated positions through random seeds
but what about entities data
how do I know, which one is which
give them an ID or index?
ok so I have this code:
foreach (var e in matchedEntities)
{
RefIDComponent cRefID = eManager.GetComponentData<RefIDComponent>(e);
InSceneComponent cInScene = eManager.GetComponentData<InSceneComponent>(e);
LocalToWorld cLTW = eManager.GetComponentData<LocalToWorld>(e);
WorldComponent cWorld = eManager.GetComponentData<WorldComponent>(e);
BaseIDComponent cBaseID = eManager.GetComponentData<BaseIDComponent>(e);
NativeArray<ComponentType> types = eManager.GetComponentTypes(e); //get all component types
print((eManager.HasComponent<MobTag>(e)) + ", " + eManager.GetComponentData<InSceneComponent>(e).inScene); //1
if (eManager.GetComponentData<InSceneComponent>(e).inScene) //2
{
if (eManager.HasComponent<MobTag>(e)) //3
{
print("Mob in scene"); //4
print(cRefID.refID);
print("---");
}
These are entities being read during a LateUpdate loop.
The odd thing is when 1 prints true, true, which means 2 and 3 should pass, 4 never prints. What?
What is the idiomatic way to get the camera (or its translation) into an ECS system every frame? I have a float3 camerasPosition property in my system (:BaseSystem) but I'm trying to figure out how to pass a reference to or retrieve the camera's position since the System is auto started. Is it better to not create the system manually in my MonoBehavior or is there another idiomatic way to pull data out of the rest of your scene?
Add a CopyTransformFromGameObject component to get transform from a gameobject to an entity, with convert and inject mode on your camera you should have an Entity created with the position binded to your Camera gameobject.
How would it know which GameObject to copy the transform from? Also, I need the position in a system.
why not do vice versa? Write position to camera from ECS?
the object you want to copy the transform from has be "Hybrid" so Convert and Inject to have both of them, the component is for the entity
they is a https://docs.unity3d.com/Packages/com.unity.entities@0.9/api/Unity.Transforms.CopyTransformToGameObject.html too, so I bet you could go through an hybrid setup too
What I mean is that this is recommended way
to communicate with GO from ECS, not other way around
Yes okay so after that I have some entity C that has a component with the camera transform in it. How do I get the value of that component into a system that by default queries for the entities at play here?
yes this recommended way
other can be painfull ^^
@gusty comet add en empty component to easy tag as "cameraEntity" for query this entity
the position of this entity can be saved as camera like that
So to be clear, this is the full context :
- Have a main camera in the hierarchy
- I have some GO that as one of its serialized fields has a reference to that camera
- I have 10k entities for which one of the systems queries for a tag "billboard"
- Matching entities are rotated towards the assigned camera
I get from the above how to turn a GO value into an entity component but does that mean the above system would have to first query for the camera tag, get that value, then query for the entities it's actually interested in to do the actual iteration?
So basically if I understand correctly after doing the convert on a GO with the camera I end up with this situation :
- 1 entity with a camera tag
- 10k entities that need rotating
Issue got it
Yes I get that
But how do I get that into a system that is querying for other entities.
Or well, I clearly don't get it.
aaaand grab that value before doing your 10k loop job
A system according to the docs should query for one specific set of entities.
The above would break that pattern/suggestion/idiom
for the system part, you will have to get organized to filter your queries by tags
it can become very custom depend of your "tag"component" and the design of a game
I think you mean you have to break a job to get the camera transform stored in the entity, but no
there is some job than can be executed with specifics orders
I still think we're disconnecting here or I have a fundamental misunderstanding ๐
I'll have 1 "camera" entity, and 10000 "billboard" entities, for a total of 10001 entities. The "billboard system" is tasked to query for the "billboard" tagged entities and rotate them towards "camera". If I understand idiomatic ECS correctly I shouldn't use a single system to query for two different collections of entities (if I even can). So the "billboard system" is not every querying for the camera tagged entity because it's only allowed one "query". Again, if the idiom is to be followed. I get I can force the issue but that seems horrible software design.
When you load save and create your new entity, you just setup a hash map mapping old entity to be one. Then go through your components and remap your references
Create a single entity that represents the camera. The billboards look at that entity not the gameobject. The camera has a 1:1 link to that entity.
[BurstCompile]
public partial struct BillboardJob : IJobEntity
{
public float3 cameraPosition; // <-- I need this to be set or some way to get it into the below
void Execute(ref Rotation rotation, in Translation translation, in Billboard billboard)
{
float3 position = translation.Value;
float3 forward = cameraPosition - position;
float3 up = new float3(0, 1, 0);
quaternion lookAtCameraQuaternion = quaternion.LookRotation(forward, up);
rotation.Value = lookAtCameraQuaternion;
}
}
See above. I get that I can have an entity with a camera transform. How do I get it into a system that's not querying for that entity, though.
GetSingletonEntity
btw, does it cause sync point?
yes or a job that look for the only "camera entity" and stored it
I just started to wonder, whether using all that is even safe to avoid sync points
Is there really no such thing as a formal inter-system data exchange?
You exchange data between systems using entities and queries
Yes but idiomatic ECS apparently doesn't want you to make systems that executes multiple queries within the same system.
Yeah that's bs
I think I will write you an exemple for tomorrow morning @gusty comet if it can help, i am sleepy
That'd be much appreciated but I think tertle pretty much helped me on my way with his last comment.
Unfortunately running tiny systems in entities is terrible for performance
The expectation is I invoke a single query to just get the entity with a camera tag, then pass the translation component of that into the next one.
@rotund token btw, do you happen to know if it's possible to have a conversion system that runs before GOs are registered?
Basically I want to generate all GOs hierarchy through code in conversion system, so then it all converts it as if I created them by hand.
I tried to make it update in that first group before entities are created
but it seems like new GOs aren't registered or smth
so... no conversion is run, nor entities are created.
Thanks for input all. I shall continue my hacking and forehead rubbing.
you are right
so just chain your two query here to share the float 3
I think someone else tried to do this and I don't believe it's possible
Yeah I'm using IJobEntity but that should be roughly the same.
so, the only way - creating entities by hand?
Whole point of conversion is to convert game objects, if you don't have game objects to convert why not just create the Entities directly yourself?
well, because conversion through GOs is easier
not only most things are attached themselves
but also you have easier time with authoring components
and all that stuff
@gusty comet if it can reassure you, they is exemple from Unitys staff with a lot of queries shared data
Anyway, it doesn't work because your original game object had to exist for live linking etc
Oh? Happen to have a link?
If you just create a ghost go it just breaks that
Just look at transform system or rendering or physics etc they all use multi queries
I'll have to create all entities myself, while also generating them by attaching to that original game object?
Sounds like it. Though this also sounds like a terrible 1.0 workflow!
this is a disgusting workflow
I have learned a lot using/modifying the 3rd person controller Scene of this exemple https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/PhysicsSamples
If you can generate go's, why not just generate go's but outside of conversion?
Wait. So this isn't subscene conversion?
@rustic rain you are killing me it's like to reverse enginering the world haha
Well you can't do conversion like this outside editor
Basically I have this:
I need about 70-80 rooms (star systems)
about 10 of them will be totally unique and authored in editor.
While everything else should be randomly generated upon starting new game.
Sooo, I'm basically figuring out my options
@gusty comet GetComponentDataFromEntity<CameraTag>() on top of your job
I've read this a few times from you now. I've never read that recommendation. Any source?
to define the job to run after the one who sync with the GameObject use a header which look like [UpdateAfter(typeof(CopyTransfromFromGameObject)] or a thing like that
I need to tag the camera (Main Camera in my case) with the Camera tag component. I've added the ConvertToEntity component to the camera but if I understand you correctly I should do the above in yet another job to listen for this conversion and then add this CameraTag: IComponentData component then?
@viral sonnet thats tertle's recommendation - which I agree with ๐
Anyone use adressables with dots?
yes add this component with the camera convertion and get it from the camera like that
Alright, cheers. I suspect that's all I need to progress. I'll either make it work or throw my PC out of the window. Whichever happens first.
it will act as a tag for you to get easy this entity position from a query
this is true
Ah ok, thought a Unity dev made that recommendation. np, I also agree, just think there are exceptions
we had a horrible time communicating in reverse at work. completely shit show of lifecycle management.
From ECS to GO is the way to go
Otherwise you do not have the proper controls over scheduling
And it makes the ECS->Simulation, GO->Presentation flow a lot easier
having no strict direction can quickly start to get you into trouble.
I see mainly 2 problems, - where is my code? - scheduled jobs that suddenly need a sync point because some MB wants to read/write something
this is a comment from source
ha nice, there really is a unity statement ๐ nice find
I need to rewrite some interface elements to achieve that rule. As GOs don't really work in subscenes, we'd need to use Convert and Inject in a scene, right?
the schedule overhead didn't get you in any trouble? I don't have hard facts but I'd say a sync point + MB updates for individual components, as in 1-2 entity count in a system, are faster than a schedule.
our client is 80% mb ๐ข
basically taken from before it was converted to dots (and multiplayer)
just a mess
and you'd also recommend convert & inject? my target frame is still a lazy MB that gets the components of health/resource/etc...
no
i do not think anyone should use those conversion scripts
borderline deprecated
so create an entity and AddComponentObject in a conversion MB?
agree with turtle for one object or one component it's ok but don't sync mass thing like that
just create the go presentation at runtime
WithNone<MB>.WithAll<MBC>.CreateGO
they dont work with netcode for example
Hm, I have to think about that. creating at runtime sounds horribly annoying for interface elements
@last ridge I have it mostly working now except that the Translation component of the camera tagged entity is not bound to the GO transform (so, I can move the camera without the component value changing). Do I need to wire something up?
@rotund token hmm, do your "conversion" during normal runtime for things that cant fit in subscenes?
no, i only convert in subscenes
i actually put all my authoring in editor only asmdef
to stop anyone doing it at runtime
@gusty comet try to add in the camera gameobject in the inspector's tab, a new component on the object, look for CopyFrom..
its will feed the component during the convertion for you
is that some pseudo code or some extension I don't know about?
i mean for things that would otherwise require Convert&Inject?
@gusty comet you should see the new component (copyfromgo) on the entity, in the entity debugger
I have this added. But that doesn't see to affect it the Translation instance.
Ahh, it's a new component rather than it setting the Value on Translation component?
Ok
yes
and a job will modify the entity translation for yoyu
as it use this component as a Tag to act on Translation
thats just pseudo code of an entitiesforeach
yes ECS foreach or a scheduled job
why would I do that over a conversion script? I mean it's nice to keep and edit things in the editor. Especially some UI scene
ah UI
are you talking about runtime conversion?
Okay so that's added but it doesn't seem to sync (or at least, not if I move the tagged camera in the scene view). Is it expected to work when you mod the GO in scene view?
if you have hit play?
a) because runtime converison is incredible slow
b) it doesn't let you do ecb.Instantiate(entity)
c) runtime conversion doesn't work with packages like netcode
Yes. I can move the camera but the translation isn't being synced with the camera.transform.position value. I do see the GO copy tag on the camera.
hmm there must be something I have forget
I'll try to open my hybrid project tomorrow then I get back to you powcode, hope to help further
ah look for the local to world
Ah that'd be great, no worries.
It does not, no
ok we will found why
but apart from that enzi
Warning: Although there are APIs that you can use to convert GameObjects to Entities at runtime (such as GameObjectConversionUtility), these will be deprecated in the future because you should never use them in runtime code. They are far, far too slow. As such, you should convert authoring data to runtime data in the Unity Editor during the build process, and Unity should load and use only the runtime data at runtime.
they'll be going away
@rotund token wait how do you handle animated gameobjects? just dont convert them?
oula animation
i only convert the entity, i just instantiate presentation gos at runtime when required
its become a mess to sync transform at some point
@rotund token yeah, I totally get the point ๐ Just trying to figure out how to best apply that to my UI elements
I have cry with VFX graph added on weapons
Cheers. I can't even find a single example on Google for this workflow but I'll try other sources.
ah ok
{
public GameObject Prefab;
public CopyModes CopyMode;
}```
i just reference the GO during conversion and then i instantiate GOs at runtime (on client only for example, ignored on server. but i can also have thin client worlds for testing and ignore it in those thin worlds)
yes this is not very nicely documented, I have put a lot of time to resolve camera myself
yeah im seeing this would potentially ease certain things for me
I look forward to your insights. Ironically I only need a camera reference to manually rotate quads towards the camera to act as billboards which seems like a huge workaround for just wanting to draw camera facing rect quads in the first place ๐
why don't you go for a simple shader so?
which could like process rotation regarding camera angle
or even more tricky, use a VFX graph Bilboard that fetch some position
but it go out of DOTS channel sorry
Hm, well, if that's possible I'd be open to it. I have my entities in DOTS/ECS but the actual rendering is essentially a glorified particle system. I just wasnt sure how to efficiently get 10k-100k-ish entity positions and colors on the screen.
Meaning, my first inclination was to dynamically generate a mesh and render the entire cloud with a single draw call, then I got distracted by looking into instanced draws and...well...here we are.
(so, I'd have a CloudMeshCompilerJob that'd convert all queried entities into a point mesh of some sort and just render that, but seemed suboptimal)
If there's a good way to get the entity component data for the position and color components efficiently on the GPU side for a shader solution that'd be nice(r).
yes like materials property block, i guess
but you shall keep it on GPU side only, entity should not have to inject camera properties
a shader can fetch camera position
directly
exactly, I think it's just the blit from cpu to gpu for the positions and colors would be prohibitively slow. And I can't easily keep the position data in gpu memory and manipulate it there given the amount of logic needed to adjust those positions each frame.
In shader world the camera position is given so that'd be a non issue thankfully.
Well, bedtime for me. Thanks for all the input.
I may have to conclude I'm just in way over my head with all this ๐
ur welcome
oof 200 unread messages. sometimes its quite busy here ๐
I wonder about that recommendation with writing from ECS to GameObjects. Unitys statement is based on Companion Gameobjects not on normal unlinked monobehaviours. I believe having a query with managed components generates garbarge. im not so sure if it might be better to poll a singleton entity from a monobehaviours update to avoid that garbage
We have to find out about the garbage
im already in bed. ill check it tomorrow. i think i have that problem in one of my systems right now
And yeah, I'm never too sure about absolute rules. I have written a new system for some UI value updates but now I can't really figure out how I would continue creating the reference. Canvas or UIElements can't be in a subscene. Right now I'm trying a subscene object that references the UI Elements then. But then the UI already has to be in the scene. I dunno, it's just annoying right now. Guess I'll just go back to reading from entities ๐
anyone have any ideas
i have 1 system per 'panel'
the system is responsible for loading the asset and writing to it
the UI has no knowledge of what is writing to it
why would it? it's presentation
if your UI is reading your entities you've fallen back into the old go trap of coupling your model and presentation!
in fact im not even sure where you're reading your entity data from if you're using UIElements
UIelements doesn't use a gameobjects (except the root document) so where is your script attached?
I'm still on canvas. How are you placing the interface elements? Do you reference an anchor?
each 'panel' is independent
usually only 1 panel is shown at a game but it's not a requirement
can certainly have them layering
whole thing is just mostly just setup via uxml
instantiated in the system
and the elements that require updates and just kept as references in the system whenever something changes
most UI rarely needs updating
ah so yours already uses UIElement? Guess that works a little better with xml layouts
yes i use uielements
it works much much much better with dots projects
because you dont need gameobjects!
if you really want to be gross, you can use Marshal.GetFunctionPointerForDelegate to write to them much easier from burst jobs as well
can you dispel the myth that companion objects in ForEach generates garbage?
no idea
it's not 2012 anymore and i don't work on mobile devices, i care a lot less about garbage these days so i rarely profile for it
(mostly because it requires making a build and i cbf)
they still do @viral sonnet
well the companion transform update system does
I hate it, its a linear increase for the amount of companion gameobjects you have
down with companion gameobjects! ๐ข
just going to make a game style with no animations
problem solved
or like 1 basic animation loop i can do with a shader
im reworking animated characters for I think the 5th or 6th time, I feel that its like trying to push a square peg into a round hole
at least making it with dots๐ก
ok, gonna test later when I make a build. The targetFrameSystem also generates garbage for me now. Is this a bug or something not really supported? I can't keep references from a subscene object to the GOs from the scene where the subscene is in. It's only working once and when I go out of play mode they are gone.
can you rephrase ๐
are you saying you have a subscene with references to another scene?
i should have made a space game! ๐ฅฒ
hehe, sure. pictures are better I guess
yeah you cant do that
well this is why every panel is separate for me is handled individually
my entities just reference the prefab and instantiate it at runtime (onto the document or canvas)
kind of? it's on my settings components
let me load up my project
on my navmesh project atm
wrote this ui stuff 18+ months ago and havent really touched it since
in my case, I can't even set an anchor with no references working where I could instantiate to as parent
it's just worked perfectly for me, but i can't remember exactly how its setup so let me look
thanks! ๐
and yeah, as stated previously. this really comes down to right now for having no layout outside of the scene hierachy
ok thats right
so my entire game only has 2 gameobjects in the scene
a directional light, and a uidocuments
i have a single settings file with all my panels (in this demo only 2 but you get the idea)
literally stored in a single component just for reference
{
public VisualTreeAsset[] Assets;
}```
this is only accessed once to instantiate
it's never queried per frame
in my UISystemBase I just have this to start instantiating
{
if (this.panelElement == null)
{
var windows = this.EntityManager.GetComponentObject<UIAssets>(this.GetSingletonEntity<UIAssets>());
var asset = windows.Assets[this.StateKey];
Assert.IsNotNull(asset, $"No UI asset set for {this.StateKey}");
this.panelElement = asset.CloneTree();
this.panelElement.name = this.StateInstanceComponent.ToString();
this.panelElement.pickingMode = PickingMode.Ignore;
this.panelElement.AddToClassList(RootClassName);
this.OnLoad(this.panelElement);
}
this.OnShow(this.panelElement);
this.AddToParent(this.documentSystem, this.panelElement, this.Priority);
}```
so i set it up once per play and that's it
every panel has it's own system that instantiates what it owns
i have a whole state system i use in my project to handle what panel is visible when etc
pretty elegant so far. how are values updated?
panels implement OnLoad
(as you see above)
and just get all the elements they need to write to
and then they just write on query when data changes if required
i avoid writing unless data has actually changed - this is mostly a habit from UGUI
which is super slow to update values
i think uielements is much better at handling this but i just avoid it from habit
do you achieve this with DidChange filter or some tag?
depends what i'm writing
the system can store the past state if it needs, it can be a separate component
it can be change filters
i can simply read the current UI value
depends entirely on the situation
alright, thanks a lot. got to invest into UIElements it seems ๐
oh its hell in 2020.3 though ๐
i am dying for 2021
every time i load my project i get compile errors and have to reimport files to fix it
ah right, we talked about this once. I remember that was what was holding me back ๐
it also breaks burst building in development builds for some reason
well it makes burst build like it's release even when development is set
so if you have condition #if UNITY_DEVELOPMENT tags in there bad things happen
yeah the way they implemented it in 2020 is problematic with their dll replacement stuff
thankfully all fixed in 2021 and working nice
it was a sad downgrade though
not many weeks now until Q2 ends ๐
looking forward to the day I can ditch 2020.3 for good. Never used a version for that long
most of the time unless i need a specific feature i like to stick to lts these days
but yeah i also like to switch when a new lts comes out
what do you think of that? ```public class UpdateUIValue_Authoring : MonoBehaviour
{
public UpdateUITargetType targetType;
public UpdateUIValueType valueType;
public TMP_Text tmpText;
public Slider slider;
private void Awake()
{
var barrier = World.DefaultGameObjectInjectionWorld.GetExistingSystem<EndSimulationEntityCommandBufferSystem>();
var commandBuffer = barrier.CreateCommandBuffer();
var entity = commandBuffer.CreateEntity();
commandBuffer.AddComponent(entity, new UpdateUIValue()
{
targetType = targetType,
valueType = valueType,
tmpText = tmpText,
slider = slider
});
Destroy(this);
}
}```
it works but it isn't very flexible
i mean if it's just for your own project or sample it's fine
but this doesn't really work for a multiplayer game
if this was part of say a library
that said, not even sure why you bother with ECB here
just create it with EM?
I'm alright with that for now, multiplayer is a long way off. Well I figured so it can never run into any scheduling problems
is this not just happening once though at start of game?
pretty much, unless some jobs are running while the interface is loading on transitions
any downsides of the ecb?
ecb is bad mkay
anything less dogmatic? ๐
Oh UIElements does that for you too? Iโm glad Iโm not the only one
{
// Using a custom bootstrap that returns false lets you set extra data (such as the total address space you want to reserve for ECS Chunks) before worlds are default initialized.
public bool Initialize(string defaultWorldName)
{
// ICustomBoostrap runs for all scenes in a project, so to gate this sample to a particular scene, we have to use this hack that checks the active scene's name.
//if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "DemoScene")
EntityManager.TotalChunkAddressSpaceInBytes = (1024UL * 1024UL * 16UL) * 4;
return false;
}
}``` does this actually work for anyone?
@rotund token @white island does this fix it https://forum.unity.com/threads/ui-toolkit-migration-guide.1138621/#post-7405538 I was also getting an error on loading, but slapping an asmdef in there fixed mine
oh i can fix it by simply making a build
for some reason that fixed it for me
all my code is in asmdef though
what do you mean by works?
the chunk size stays at 16k. in game and in editor
this doesn't change chunk size
the default value here is 1GB, haven't you just shrunk it?
/// The total reserved address space for all Chunks in all Worlds.
/// </summary>
public static ulong TotalChunkAddressSpaceInBytes```
` static readonly ulong DefaultChunkAddressSpaceInBytes = 1024UL * 1024UL * 1024UL;`
that said, s_TotalChunkAddressSpaceInBytes doesn't seem to be used anywhere atm anyway
lol, my bad ๐ the sample name threw me off. not sure what it's for then when it's not used
anyway, I read some long time ago that chunk size could be changed with an ICustomBootstrap
public const int kChunkSize = 16 * 1024; computer says no
what is this funky thing? in EntityComponentStore
hm, this seems like a long array of pointers to the chunks
Who said that?
no one, I misremember ๐
Sooo, in order to restore entity-data connection during save/load I need some kind of unique identifier for entities in components?
I have a question regarding the [BurstCompile] attribute and job system
When using methods inside the Job, e.g. an overloaded == from a custom struct, do I also have to attach [BurstCompile] to this method?
As in:
public struct CustomStruct
{
[BurstCompile] // <---- Is this neccessary?
public static bool operator ==(...) { ... }
}
but those ID's will be mixed upon next subscene load
no
anything called from burst code is bursted
hmm
What about entities that will be created during runtime?
thanks ๐
I guess I'll need to recreate them somehow
๐ this is what i spent 4 weeks developing for my save system
to handle all these cases
turns out there are a lot
but i think i got them all
will have it's own method for that
subscene entities, instantiated from entity prefab, instantiated from subscene reference, etc
so, how do you handle saving entities created during runtime?
managed to set the the whole thing up through the same conversion system
and setup them different depending on their state
the prefab has the same save component setup
and it just instantiates from the same prefab on load
you can make changes to prefab etc between save sessions to change it
and it'll all be reflected
by prefab i mean entity prefab
I get it
it's just that in my case, those entities will be let's say AI ships
NPCs
hmmm
maybe prefab is enough
to handle component recreation
anyway saving is complex and people leave it way too late
I want to start on it rn
hence i wanted to build a complex and complete save + migration system before i had even started building game
so yeah props to you
most people wait like 3 years about to release
and realize they have to refactor their entire gmae to do it
it gives me errors that it tries to access classic Input
unsolvable
I guess I'll have to just enable classic input
rip perfomance
you're using the wrong input thingy
I use New Input
I even removed Library
i assume old input system was disabled from project settings
hmm just keep the old one enabled at the same time maybe?
any harm in just leaving it on while you develop in 2020.3
yeah, but that rips perfomance for some reason
btw
could you suggest a pattern with UI documnets?
how do you handle different screens? Switching between them?
i only have 1 ui document
I am so lost, no manual gives any detail into this
i actually reported a bug when i used to use multiple
and ui guys were like, wtf do you have more htan 1 ๐
i had a second because i wanted a universal console that i could just drop in a project ok!
no
i have a lot of panels each their own uxml
and they just all get added to the UIDocument
the base panels all use absolute positioning
each with its own system
each system sets up and maintains its own panel
but I don't like it at all
i actually went through it a bit this morning
i really like how i've set it up
what concerns you?
requires to set up manager to enable/disable screens
i have a state system i use for a lot of things
and even then perfomance is eaten by disabled screens for some reason
i dont turn off visibility of panels that are hidden
i remove them from the uidocument
so i only ever have visible panels
/// <param name="visualElement"> The panel to add. </param>
/// <param name="priority"> The draw priority. </param>
public void AddPanel(VisualElement visualElement, int priority = 0)
{
var e = new OrderedElement(visualElement, priority);
this.elements.Add(e);
this.elements.Sort();
var index = this.elements.IndexOf(e);
this.view.Insert(index, visualElement);
}
/// <summary> Removes a panel from the UI. </summary>
/// <param name="visualElement"> The panel to remove. </param>
public void RemovePanel(VisualElement visualElement)
{
var index = this.elements.IndexOf(new OrderedElement(visualElement, 0));
if (index < 0)
{
Debug.LogError($"Removing {visualElement} that isn't added.");
}
else
{
this.elements.RemoveAt(index);
this.view.Remove(visualElement);
}
}```
hmm
not the most ideal way of managing order/priority but it works
so your World keeps those panels outside of UI render component
and upon need it adds it to hierarchy?
that's interesting
ahem, that's a weird one
these systems running depending on my state tag component which is handled by a completely different state system
i've realized you can kind of use systems as state machines ๐คฃ
you handle it through RequireSingletonToUpdate()?
i used to
i have a state group system now
that prevents requiring checks on each system
but yeah pretty much that was the first approach until recently
and fundamentally that's still how it works i just dont have to do all checks for each system
really an over optimization
let me load my states
this.UIStateSet(K<UIStates>.NameToKey("menu"));
for example my client menu state looks like this
{
/// <inheritdoc/>
public override uint StateKey { get; } = K<ClientStates>.NameToKey("menu");
/// <inheritdoc/>
public override ComponentType StateInstanceComponent { get; } = typeof(StateMenu);
/// <inheritdoc/>
protected override void OnCreate()
{
this.RequireSingletonForUpdate<StateMenu>();
}
/// <inheritdoc/>
protected override void OnStartRunning()
{
this.UIStateSet(K<UIStates>.NameToKey("menu"));
}
/// <inheritdoc/>
protected override void OnUpdate()
{
}
private struct StateMenu : IComponentData
{
}
}```
very simple, not much happens in my menu
so the actual 'game' level state doesn't need to do much
but say if the join game button is hit in my menu it runs this
{
var state = this.GetSingleton<ClientState>();
state.Value = new BitArray256 { [K<ClientStates>.NameToKey("join-game")] = true };
this.SetSingleton(state);
}```
which triggers my jonigamestatesystem
// Copyright (c) BovineLabs. All rights reserved.
// </copyright>
namespace Shattered.Game.States
{
using BovineLabs.Core;
using BovineLabs.Game.App;
using BovineLabs.Game.States;
using BovineLabs.Game.UI;
using Unity.Entities;
using Unity.NetCode;
using Unity.Networking.Transport;
public class JoinGameStateSystem : ClientStateSystemBase
{
/// <inheritdoc/>
public override uint StateKey { get; } = K<ClientStates>.NameToKey("join-game");
/// <inheritdoc/>
public override ComponentType StateInstanceComponent { get; } = typeof(StateGoInGame);
/// <inheritdoc/>
protected override void OnCreate()
{
this.RequireSingletonForUpdate<StateGoInGame>();
}
/// <inheritdoc/>
protected override void OnStartRunning()
{
this.SetSingleton(default(UIState)); // TODO this is just to hide the menu, we need to show in game UI but that doesn't exist
this.ClientStateSet(K<ClientStates>.NameToKey("build")); // TODO
var network = this.World.GetExistingSystem<NetworkStreamReceiveSystem>();
var ep = NetworkEndPoint.LoopbackIpv4;
ep.Port = 7979;
network.Connect(ep);
}
/// <inheritdoc/>
protected override void OnUpdate()
{
}
private struct StateGoInGame : IComponentData
{
}
}
}
which triggers new ui state (this demo project has no in game UI)
but then if i want to enter my build game state
{
this.RegisterPhysicsRuntimeSystemReadOnly();
this.UIStateEnable(K<UIStates>.NameToKey("build"));
this.InputEnable("build");
}
shows the build UI and enables the build keys
etc
i've really fallen for my application level state machines
but yeah, i dont have time to actually develop games because i spend my whole time experimenting with and designing architecture for dots apps ^_^'
kek, weird approach ngl
The next step in the DOTS roadmap right now is 0.51 right?
yep
ok sounds good
that's pretty interesting.. could learn a thing or two from your code tbh ๐
so essentially a kind of custom layer on top of systems that allow you to group switch them on/off like states
yeah i basically wrote application level state machines out of systems
things like, UI, Input, current game state
i don't use this for anything except high level stuff
i've been away from dots for a few months and just looking at 0.5 now, was attempting to port the old physics ragdoll demo and just realised the physics samples have actually been updated
i'm curious also if the skinned character samples actually work, afaik mesh deformation is still active in AR2, but the animation package isn't supported ( in 0.50 )
i wonder if anybody has manually ported the animation package to work in 0.50
I think thelebaron tried but get furious against it ๐
the next release of animation package, I would like to have the animation package aligned with graph foundation package : in some first release of animation, I was pretty close to get a nice DOTS state machines, made with the nodal viewport (they were few nodes for animation packages available) but it was acting nicely overall, I have even scripted a Nblend Node Drawer to get some advanced stuff working because there was only linear Blend node available basically. With all that stuff, with all the nodes available in a cleaned Animation package and graph tool aligned, I will forget about hybrid for good and get my animation in dots for Main Characters
yeah that'll still take years^^
Yeah that's kinda the dream really.. Hoping not 'years' but, it could be
it's still at least a year before 1.0 releases and work on animation only resumes after that
I would consider the option of continuing your custom extension of the old animation package, personally i think it's worth it.. although i'm not sure what headaches are involved in porting Animation to 0.50 compatibility
i'm not sure it makes a lot of sense investing time into that. animation will probably have a big api redesign
i would guess at least
yeahh.. i'm pretty certain it will.. just wondering in the meantime 'what would it take to get the old package working again'
not sure
i wonder if lebaron did attempt it
i've only extracted parts of it because some of my code was using AnimationCurve
i didn't have to change anything to make that work
i think maybe the clips and graph stuff could have some entanglements
yeah graph foundation package getting too old, unfortunatly, it only work with very old version of animation, and dots packages so..
I let it in a corner get some dust
what graph package was it exactly, there's so many different graphs around unity at this point i have no idea what is what
visual scripting graph, vfx graph etc
playable graph
it was a drawer to hold GUI component that came from DOTS, it was use to draw node in the DOTS visual scripting, before it get kill
editor.graphs
it was playablegraph+ some stuff i think
was it a graph written just for dots or
ah right
to me, it would make sense just for all graphs in all contexts just to refer to one single graph package
too much confusion
but they are fundamentally different to each other
noone talking about DreamingImLatios animation package?
?
i'd always take native over 3rd party
there's no native, so?
will in the future
We are asking for
what was that package called?
i do remember there was a custom physics thing by someone
? no idea
ah sorry i replied to the wrong comment, meant Enzo's comment
ah yeah that was the same one, Latios Framework
seems he's working on skinned animation for it
if one guy can do this..
but then, he's not dealing with LTS and four thousand different package and editor versions etc
I'm quite sure he's hardworking on this and not getting much sleep
i'd say so yeah
I am having an issue with collisions. I have read the documentation and I can't seem to figure this out that feels really simple... What is the correct way to add a Tag to an entity when it collides with another... in Entities 0.50
Did you try through an ECB in a collision event job ?
I don't think it's even documented
download and look at the physics samples
I feel confused and concerned that one of the most basic and the main things people do with a physics system is not documented...
it's not difficult
For example in this snippet https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/7b7b2ae8dc24e11856fd32fab72a0e30a808a903/PhysicsSamples/Assets/Demos/2. Setup/2d. Events/Scripts/CollisionEventImpulseAuthoring.cs#L56
They're not adding a tag, just storing impulse data on a component for later use
but should give you a better idea how it's done
Come back when 1.0 is released if you're not ready to experiment and dig on your own
That's when they'll start on better documentation
exactly
and better samples and so on
i just hope 0.51 releases soon
To be fair, the docs explain doing casts but there's no mention of how you'd do something like the old OnCollisionEnter, but yeah it's in the samples
That's what confused me there seems to be lots of documentation on casting but no mention of collisions at all not even a hey if you want collisions go look in the samples
It makes it sound like it's only a raycasting lib
yeah it is pretty annoying.. the samples do cover a LOT of ground though which is nice
if you do download the samples, i think you'll have to use a Git client in order to also get the scene files and assets..
Unless you just want to look at the code, which you could just do by looking at the code on github
Im with my friend did same thing. Also i released VR game which use our technology. It was about almost 3 years ago
if i attach a link to steam with game it will probably look like an ad
I think it's ok to do that, i'd be interested to see it
That looks really cool..
So you created a custom animation/skinning system for DOTS for this?
Audio also?
Yes. For audio we used FMod
Nice.. you said 'Im with my friend did same thing' - do you mean DreamingImLatios created it with your friend, or am i misreading it?
I meant that we made our own similar animation/skinning system for DOTS. We have nothing to do with DreamingImLatios
Haha sorry okay, was just clarifying.. That is great, have you considered sharing the system or even selling as an asset?
Because i'm thinking, if devs have access to all the juice of DOTS, but it's another two years or something until an official Animation package becomes available, that's a pretty big gap to fill
we made it and put it on the shelf in fact. So I'm unlikely to be able to provide this in some form of asset
it's fairly easy to do your own solution as there are quite a few samples you can base on
Yeah i'm sure it's doable, but just is additional time
yeah this is true also
any way to exclude gameobjects from conversion or destroy their converted entities before conversion ends?
You can destroy entity in authoring
eh how
dstManager.DestroyEntity(entity);
thanks, i dont remember this working earlier? a bit funky with a hierarchy though ๐
works just fine
as long as you don't try to access PrimaryEntity afterwards
I gotta say, NativeStream proofs to be a beast in my tests. What throws me off is that a temp allocated NativeList with chunk.Count as capacity is slower than a NativeStream. I don't get that TBH. Write amount is the same. The list is filled to the max and yet it's behind NativeStream that is allocating in small blocks (I think 4k)
My next step is to persist data to storage. I used to use Newtonsoft when it was strictly MB. What is an optimal json serializer for DOTS?
......any.....json serializer? they all work more or less the same
i solely use System.Text.Json these days
Ok. Thanks for input.
InvalidOperationException: The previously scheduled job SpellCastSystem:SpellCastJob writes to the Unity.Collections.NativeStream SpellCastJob.JobData.createSpellsStream. You must call JobHandle.Complete() on the job SpellCastSystem:SpellCastJob, before you can read from the Unity.Collections.NativeStream safely. What's going on here? This happens on the first schedule. The static method gets called by a job that writes to the stream, I reference the given jobHandle yet it keeps on telling me I've to complete the job first. Completing the handle indeed fixes the problem and everything works fine then. Anyone sees the issue?
oh wow, it's the forEachCount. huh, I thought was set on the nativestream init
well, it's not. mb then ๐
hi guys, basic quesiton but.. Burst error BC1349: Invalid argument. Expecting a string literal or a string.Format or a fixed string. how do i debug.log a string in a job method?
Debug.Log($"This is a message that ouputs {variable1}");
how do i get my data wjhen OnUpdate is called on a system?
chatmessagesystem.GetComponent<ChatMessageEvent>(b).MessageType.ToString()
is that right?
What are you trying to do?
@rustic rain get the messagetype
UnhollowerBaseLib.Il2CppException: System.ArgumentException: Unknown Type:ProjectM.ChatMessageSystem All ComponentType must be known at compile time.
For generic components, each concrete type must be registered with [RegisterGenericComponentType].
is ChatMessageEvent a IComponentData?
you have to register all generic types if you want to use generics
yeah so you cant 'GetComponent<>()' it
no? that has not really anything to do with chatmessageevent
chatmessageevent is NOT an IComponentData, so you can't GetComponent<>() it
mhh
@haughty rampart if its not an IComponentData how come GetEntityQuery(ComponentType.ReadOnly<ChatMessageEvent>()) returns something
you can return a lot of things that aren't icomponentdata in queuries
you can even return gameobjects etc
how can i get the component's data attached to that entity then
if i dont know the type
if you dont know the type, what are you getting?
i have that entity that i know is the one i need to get my data
i just dont know how to grab the data from here
then inspect the entity and find out what it has
oh tell me more. i've been dying to know how to make a ECS game moddable
(or any game really)
oh i think mindstyler is talking more official
they make it pretty simple to use, i just dont know much about C# or Unity
because ecs games using bepinex/melon tbh kind of sucks
too hard to inject burst/jobs imo
why?
yeah
you really want the game to officially support loading them
im just modding the server, try to add a !command system to the chat
just can't get to read the chat
what game is it anyway? there are not so many ecs games out there yet
V Rising
ah
just came out
sad not my game ๐
so maybe inject some code to view the entity archetype and go from there?
so is there a way to know what type of component an entity goes with?
yeah i just got no idea how to do that
sec
NativeArray<ComponentType> components = this.EntityManager.GetChunk(entity).Archetype.GetComponentTypes();
lets try that
ive been stuck on this for way too long
[Message: Unity] FromCharacter
[Message: Unity] NetworkEventType
[Message: Unity] ChatMessageEvent
[Message: Unity] ReceiveNetworkEventTag
ChatMessageEvent is in there...
doesn't make sense
i think its attached as a component object
like not ECS style?
try entitymanager.getcomponentobject<ChatMessageEvent>(entity)
ive never considered attaching a struct as a componentobject
but i assume it'd just box and work fine
[Message: Unity] Exception UnhollowerBaseLib.Il2CppException: System.ExecutionEngineException: Attempting to call method 'Unity.Entities.EntityMana
ger::GetComponentObject<ProjectM.Network.ChatMessageEvent>' for which no ahead of time (AOT) code was generated.
same ๐ฆ
well that's too bad
seems you have to patch that one in too. maybe if that's possible
IIRC there was some Stop component to prevent propagation of GO conversion downwards on the hierarchy
i dont get why im getting this error
can i just dump the content of the components i get from the archetype list?
see whats in them
see this list
they are componenttypes right?
you can get the data from the component type
i mean i just tried..
{
var entitymanager = v.GetExistingSystem<ChatMessageSystem>().EntityManager;
var chatmessagesystem = v.GetExistingSystem<ChatMessageSystem>();
EntityQuery m_Group = chatmessagesystem.GetEntityQuery(ComponentType.ReadOnly<ChatMessageEvent>());
var entities = m_Group.ToEntityArray(Allocator.TempJob);
Debug.Log($"Entities: {entities.Length}");
foreach(var entity in entities)
{
try
{
Debug.Log($"Entity: {entitymanager.GetDebugName(entity)}");
Debug.Log($"EntityType: {entity.GetType()}");
NativeArray<ComponentType> components = __instance.EntityManager.GetChunk(entity).Archetype.GetComponentTypes();
foreach (var component in components)
{
Debug.Log("Current Component Type:" + component.ToString());
ChatMessageEvent message = entitymanager.GetComponentObject<ChatMessageEvent>(entity);
Debug.Log("Text:" + message.MessageText.ToString());
}```
yeah component object wont help
var dynamicHandle = this.EntityManager.GetDynamicComponentTypeHandle(componentType);
var typeInfo = TypeManager.GetTypeInfo(componentType.TypeIndex);
NativeArray<byte> a = chunk.GetDynamicComponentDataArrayReinterpret<byte>(dynamicHandle, typeInfo.ElementSize);```
will you get you the raw bytes
but what i've just realized is
the struct doesn't seem to have any data
hmm, so if I upload dll through AppDomain will that do?
before creating world
for modding
I wonder if you can harmony patch bursted methods btw
BEWARE AppDomain is deprecated in future .net versions
afaik, (haven't researched a whole lot about it yet) it's gonna be with assembly load context iirc. (which people say is even nicer for mod purposes)
Oh my god, imagine spending a day to make some system just to realise it won't work
I do feel relieved that I realised it sooner than later though xD
Anyone familiar with this? ArgumentException: NativeStream.Writer must be passed by ref once it is in use I have a struct container with 5 NativeStream.Writers and when writing to those I get this error message. Is this somehow not allowed? The container is passed by ref
hm, maybe internal struct gets changed once you use it?
kind of like how buffers become dirty during structural changes
lol, I think I just forgot to BeginForEachIndex
yeah, that was it, just an odd error message
nah, that was not it, error is back once I fixed some other broken code.
well that's weird. I can't use ref in a container struct
had to use pointers to get around that :/
Why can't you pass the container struct by ref or use a ref return on the struct to get the stream
But yes native containers must be passed by ref, they write local data to themselves
looks like this right now. so you say with a method that returns them as a ref it would work without pointers?
Ah
Are you passing that to a parallel job?
If so that's going to break
Each job needs its own unique instance
It stores its current state in the local container and only writes it in on end index
I build that struct in the Execute of a parallel job. It's just so I don't have to pass each own to the method
Well ok of your building it in the execute that's fine
But yes it's you just passed them by ref it'd work
Just like the error says =D
Yeah, some safety complains even when it's technically still correct.
well I'm just testing if I can get rid of the NativeListExtended blockWrite method but the perf really tanks sadly :/
a part that should work out pretty great isn't ๐ฆ the rest seems better than expected. odd behaviour. I write to several NativeStream.writers now instead of the list and timing has nearly doubled from around 48ms overall to 105ms
eh, damn safety checks were on. still 90ms
It's not correct
From what you said you passed the outer container by ref
Then probably used the actual native stream locally
This check on the native stream I'm pretty sure is always valid
no, I still use the writer from the container but the address which is checked in this safety check changes of course because I put it in the container.
it's okay though, I'm glad the check is in place. would be a lot more troublesome if it weren't
I hope the write speed is better in builds. 90-130ms is really not great to the 50ms. Must be the allocations. If that's it I'll test a custom NativeStream where I can set the allocation size
at least I could bring it down to 1-2 allocations in one Execute. That would already be a lot better
zero difference loooots of FallbackAllocations
From using native stream a lot the cost is checking if it needs to allocate more then the allocations
Hence the large allocator I wrote, still allocates the same but 100x faster
For a first-person shooter, should I make players be kinematic physics bodies and manually implement basic physics for them using collision queries?
The terrain is blocky and I won't have to handle angular velocity or slopes
the question is if you want to bother writing your own character controller
otherwise, yeah, fps controllers are kinematic
huh, really. the check seems pretty tame but of course I trust your experience with it.
Implementing walking, jumping and collisions shouldn't take much more than a day, should it?
how new are you to this?
I took a quick look at the DOTS sample's character controller code
That's about it
you can have something functional pretty quick but overall it's quite the rabbit hole. takes several weeks
I did study how to make basic AABB physics 2 years ago
For now I really just need walking, jumping and not falling through terrain nor falling slower when going against walls
I would recommend you take a look at the Rival asset if you want to stay with dots or modify the DOTS sample character.
the dots character controller sample should take that simplicity to heart ๐
code is such a mess
yeah i accidently halved the performance of my eventstream at one point by simply adding an integer write to a pointer during this check
this isn't working out ๐ฆ I would need a NativeStream with persistent memory layout that can be cleared and then an Indexable NativeStream so I don't have to create an array and from that a NMHM
although there isn't a lot missing. eh, I'll keep trying for a while ๐
@rotund token Did you ever write a NativeStream with persistent block memory that can just be cleared?
I use chunkIndex. Thought about that being a bad idea and I should just use threadIndex
you can't really use threadindex
you can't start the same index again
you'll override the previous threadindex data
ah yeah, right.
if you want to use thread index get my eventstream
from my eventsystem
that uses thread index, you don't need to do BeginForEachIndex
(or pass by ref)
that said it is marginally (few %) slower by the extra write
so wont really help that performance of yours
I don't mind, chunkIndex. I'm currently studying the code to find out which implications the forEachIndex has on writing. Answer is none. it's just for writing data back in EndForEach
well you dont want to use like entity index
because then you are allocating 4k per entity
instead of 4k per chunk
but yeah chunk index is usually fine
as long as you aren't running like 2 entities per chunk ๐
see that's what I want to find out right now. If any usage screws with the block amount but they use MaxJobThreadCount anyway
so a bad forEachCount is only relevant for the allocated UnsafeStreamRange
and subsequent reading. but blocks stay the same parallelized 128
I quickly tried with other block sizes. 8k seems like a sweet spot for me. even 16k gives some boost. at 32k it gets slower
what I want to find now is the sanest way to keep the allocated blocks persistent. I can clear the UnsafeStreamRange. It's even easier when they don't have to be maintained
native stream was really not designed to be persistent
you'd basically have to pool the blocks
and you'd still not be able to change the foreach index, anytime your chunk count changed it'd break
I mean, I'm talking about a total rewrite of NativeStream from scratch. Probably wouldn't even use the ForEachCount concept and just threadIndex. Even with NativeStream, I don't see the problem of the foreach index. The block data and Ranges data is decoupled and just referenced with pointers. What am I missing?
what I read from the code is that 2 or more ForEach indices can even be in one block as long as there's enough space
if you're doing that seriously look at my eventwriter
it's like exactly what you're talking about (except without memory reuse)
yeah, thanks. I have the UnsafeParallelBlockList as baseline
this is my channel
@rotund token that was pretty much a success. 53ms with ExtendedList 57ms with persistent block list
thats still a long time ๐ฌ
overall thread time ๐
i'm dealing with some insane load here. if I manage to ever get this to 60fps you can really call me king of performance. right now I'm in ~30fps land
this method has the advantage of not overshooting like the block reserve in NativeList when the overall count is unknown. and it's better than 100-130ms nativestream. you said yourself the extendedList method is pretty much the fastest thing you can do, so I think it's pretty cool. I'm not looking for your approval. But I also don't need snarky comments. If you're not interested, just say so, I don't mind.
im not trying to be snarky
im just pointing out 57ms is <20 fps which was concerning
ok then, I'm just taking the overall times now because thread times don't mean as much. It's 6.9ms multi threaded.
dont suppose anyone else noticed if joint conversion changed from 0.6 to 0.50? my character/configurable joints dont appear to get set any limits ๐ฌ
definitely not converting properly, sigh https://gfycat.com/incompatiblerareiberianbarbel
still love the video ๐ bug aside, looks cool
ah ok yeah that's much more what i'd expect! did you end up going with an approach similar to dreaming UnsafeParallelBlockList?
yeah, it's built on his code. it was easier than I thought. Just the enumerator gave me some trouble ๐
I'm curious, any other Australian DOTS devs out there?
i am
Is there a managed alternative to NativeMultiHashMap?
I need to store this kind of data NativeMultiHashMap<Entity, IComponentData>
nvm, I figured this will do new Dictionary<Entity, List<IComponentData>>();
yeah that's pretty much what NativeMultiHashMap replaced
hmm, any tip regarding what kind of pattern to use for saving?
as in, where do I put that interface
ISavable
that returns serialized data
rn I choose between: Systems, Authoring
not really sure what your interface is
i detailed my saving pretty thoroughly on the forum
could you share a link?
GetDynamicComponentDataArrayReinterpret
huh, didn't know it was possible
nice
I have this idea:
For each piece of data I want to save, I'll create a new system, with only method - return managed list of serialised data and jobHandle.
So this way I potentially can make bursted saving.
The only question - how to handle component types