#archived-dots
1 messages ยท Page 207 of 1
Definitely a false positive then
My client build doesn't seem to be working much on the networking side tho
Wass I missing any components in the build conf above?
Can you connect locally in the editor?
How does your connection script look like?
{
ecb.AddComponent<NetworkStreamInGame>(ent);
var req = ecb.CreateEntity();
ecb.AddComponent<GoInGameRequest>(req);
ecb.AddComponent(req, new SendRpcCommandRequestComponent { TargetConnection = ent });
}).Schedule();```
var playerPrefab = GetSingleton<PlayerPrefab>().entity;
Entities.WithNone<SendRpcCommandRequestComponent>().ForEach((Entity reqEnt, ref GoInGameRequest req, ref ReceiveRpcCommandRequestComponent reqSrc) =>
{
ecb.AddComponent<NetworkStreamInGame>(reqSrc.SourceConnection);
int networkId = GetComponent<NetworkIdComponent>(reqSrc.SourceConnection).Value;
var player = ecb.Instantiate(playerPrefab);
ecb.AddComponent(player, new GhostOwnerComponent() { NetworkId = networkId });
ecb.AddBuffer<PlayerInput>(player);
ecb.SetComponent(reqSrc.SourceConnection, new CommandTargetComponent { targetEntity = player });
ecb.DestroyEntity(reqEnt);
}).Schedule();```
That's not your connection script, all that happens after you have connected.
Both ๐
{
EntityManager.DestroyEntity(initEntity);
foreach (var world in World.All)
{
var network = world.GetExistingSystem<NetworkStreamReceiveSystem>();
if (world.GetExistingSystem<ClientSimulationSystemGroup>() != null)
{
// Client worlds automatically connect to localhost
NetworkEndPoint ep = NetworkEndPoint.LoopbackIpv4;
ep.Port = 7979;
network.Connect(ep);
}
#if UNITY_EDITOR
else if (world.GetExistingSystem<ServerSimulationSystemGroup>() != null)
{
// Server world automatically listens for connections from any host
NetworkEndPoint ep = NetworkEndPoint.AnyIpv4;
ep.Port = 7979;
network.Listen(ep);
}
#endif
}
}```
Hmm, that should be fine. In fact, even if your build doesn't have the UNITY_CLIENT define, it should still only work as a client
Because of the #if UNITY_EDITOR
Yeah exactly, I see my player prefab is instantiated on the server, but nothing is moving on the build client
Is there only the one prefab on the server?
Or are there 2, with one not moving?
player*, not prefab
I run the editor client/server, there I'm able to move my player, once the build connects as the second client, he sees nothing moving, but his prefab is instantiated on both the first client and server
Okay it works, but only when the build client is launched first
Oh, I see. Does the build also see its own player? Even if it's not moving?
What do you mean by "initially"?
Either way, the connection is not an issue then. I think the issue more lies with your movement code
Kinda sounds like you are moving more than the clients own player on each client
It's very smooth on the editor, less so in the build
How does your movement script look like?
I think it's fine it seems to be smooth now, is it normal if there's like a warmup time? I,ll try restrating and see if it's not smooth again
Definitely not normal
My movement is pretty standard
So it's definitely problematic that the build only works if it's launched first
Yeah, I'm guessing it's something related to how you move your players
I can show but there's a few systems involved
This is the gist of it ``` var deltaTime = Time.DeltaTime;
var tick = gpsg.PredictingTick;
Entities.WithNone<Stopped>().ForEach((Entity ent, ref Translation translation, ref Direction direction, in PredictedGhostComponent prediction, in Destination destination, in Stats stats) =>
{
if (!GhostPredictionSystemGroup.ShouldPredict(tick, prediction))
return;
var deltaToTarget = destination.value - translation.Value;
var remainingDistance = math.length(deltaToTarget);
var directionToTarget = math.normalize(deltaToTarget);
var travel = GetComponent<Current>(stats.speed).Value * deltaTime;
if (remainingDistance <= travel)
{
translation.Value += deltaToTarget;
direction.Value = directionToTarget;
ecb.AddComponent<Stopped>(ent);
} else
{
translation.Value += directionToTarget * travel;
direction.Value = directionToTarget;
}
}).Schedule();```
Direciton is set through input
It's click to move
What about the CommandTargetComponent, where do you handle that on the client?
I have a LocalPlayerInitializerSystem
Can I see it? ๐
Entity lookingForLocalPlayerEntity = GetSingletonEntity<LookingForLocalPlayer>();
Entity connection = GetSingletonEntity<CommandTargetComponent>();
Entity camera = GetSingletonEntity<Camera>();
Entities.ForEach((Entity localPlayer, ref GhostOwnerComponent ghost) =>
{
if (ghost.NetworkId == localPlayerId)
{
//Flag as local player singleton
ecb.AddComponent<LocalPlayer>(localPlayer);
//Instantiate input buffer
ecb.SetComponent(connection, new CommandTargetComponent { targetEntity = localPlayer });
ecb.AddBuffer<PlayerInput>(localPlayer);
//Attach camera
ecb.AddComponent(camera, new Parent() { Value = localPlayer });
ecb.AddComponent<LocalToWorld>(camera);
ecb.AddComponent<LocalToParent>(camera);
//Disable system
ecb.DestroyEntity(lookingForLocalPlayerEntity);
}
}).Schedule();```
Hmmmm. The only thing that stands out to me is that GhostOwnerComponent is added through scripts instead of added as part of the prefab. That's the biggest difference I can see that I do
Of course still have to use SetComponent for the NetworkId
I'm assuming that system also has a RequireSingletonForUpdate<LookingForLocalPlayer>() yes?
Yeah :p I'll see maybe setting it instead of adding
How does the prefab look like for the ghost component?
Yeah, then you can just change it to SetComponent, but that should be fine too.. ๐ค
I'll have to continue digging tomorrow, thanks a lot for the help I appreciate it!
I'll let you guys know what the error was when I figure it out
What happens if we have a MASSIVE IComponentData? Over the 16kb chunk size
if it is taht big, best is to store it in a blob asset and reference it from a component. there is no benefit of using that as a component directly. Of course if you can divide it into smaller components, like hell lot smaller.
Ok but it's proper game data
Eg voxel data for a chunk
Obviously have smaller chunk size so it fits but I was wondering what happens if it's too big :p
i dont think it lets you
I have gameobject conversion system which should convert objects during run time
public class AssetsConversationSystem : GameObjectConversionSystem
{
protected override void OnUpdate()
{
Debug.Log("ViewBlobAssetRefStorage = "+ViewStorage.ViewBlobAssetRefStorage.Count());
Entities.ForEach((AssetConverterPrefabReference prefabReference) =>
{
var entity = GetPrimaryEntity(prefabReference);
ViewStorage.ViewBlobAssetRefStorage.Add(prefabReference.ObjectClassId,new ViewObjectItemBlobAsset
{
ViewId = prefabReference.ViewId,
Prefab = entity
});
});
}
}
but its doesn't execute. First assets bundles downloaded and then AssetConverterPrefabReference attach to dowloaded gameobjects and this systems not execute also i can't see it in Entity Debugger
conversion systems aren't designed to execute at runtime - only edit-time
I would recommend using IConvertGameObjectToEntity instead of conversion systems. I tried both and IConvertGameObjectToEntity was much more straight forward. Maybe this might solve your problem
But I think they do convert at runtime as long as you have a ConvertToEntity component attached to it. At least the deafault conversion system should run and execute the IConvertGameObjectToEntity components
ty. i need something to control conversation because store entities in HashMap and i need place where can i add them
@half jay what are you trying to achieve as I guess I might be trying sth similar atm?
I am currently trying to use addressables with entities so they only load and convert once and I can reference them by their address
Soo we have custom web admin panel where load "Blocks"( our assets) by unique Id. This id used in path of storage on server and also in game logic. Thats why we use AssetsBundles because we need atomic changes of every Block. So during game user can get new Block for him and download (asset during runtime) . Downloaded asset converted to entity prefab and we store it in HashMap by this unique Id(this im trying to solve). And then user place block into scene selecting block from inventory by Id and getting needed asset from HashMap to instantiate View of this block.
yeah sounds pretty similar to what I am trying to do besides me using addressables
I use GameObjectConversionUtility.ConvertGameObjectHierarchy to manually convert the entities btw
Although there was a thread by eizenhorn somewhere that it is better to use a ConvertToEntity componenent as you can potentially convert mutltiple prefabs at once
GameObjectConversionUtility.ConvertGameObjectHierarchy will setup the whole conversion World etc. for each conversion
im using now MonoBehaviour and IConvertGameObjectToEntity and in Convert method add entity to HashMap
ahh found it: #archived-dots message
but I am currently stuck with using addressables from jobs. As I cannot return AsyncOperationHandles from jobs (even mainthread) as they are not blitable. So I have no clue how to keep a reference to the entity I loaded and instantiated as I cannot get any kind of reference out of a job
@pulsar jay If we have Addressables something like this. Is it possible to setup every block as single asset with its own URL and in future update only one of them. I mean build only one of them and then upload addresable file into server with its unique url where Id will be include also in game logic and forming this url.
we use assets bundles now because its proven way
Yeah thats what addressables are built for. Although they usually use one AssetBundle for mutliple assets (You can patch them if only some assets change) and addressables know which bundles / dependencies need to be downloaded in order to provide that asset
Yeah could be simpler to just use asset bundles in your case
Addressables just add an extra layer of abstraction/indirection
problem that i read documentation and didn't find info how to properly setup it. So also our problem that it will be thousands of blocks in theory
may be i need to read docs one more time ๐
I also have another project where I used plain asset bundles because I didnt take the time to read the whole addressables docs
Now that I basically recreated editor asset bundle simulation thing addressables is using I wonder if it might have been a better idea to use addressables from the start
But I think both is a pain to get to work properly with entities because there is no official proper way to handle prefabs
would be great if you could just build convert to entities at edit time and put the result in asset bundles
which should theoretically be possible
I just encountered a problem where my Entities spawned with EntityManager.Instantiate just dont exist. Did this ever happen to anybody?
I even checked in the debugger that it is being created but it does not show up in the entities window or entity debugger
Maybe it has sth to do with calling it from a lambda callback?
AddressableEntities.LoadEntityAsync(address.ToString()).Completed += handle =>
{
var instance = EntityManager.Instantiate(handle.Result);
...```
hello I need help on unity I do not understand where to download the engine itself
Thats the wrong channel then. Please try #๐ปโunity-talk
am trying to implement some custom networking atm
does it make sense to make all packets structs? would save not having to pool anything but I don't know how to deal with optional data
serializing/deserializing wise I check bitflags whether it has that data and that all works, but I mean for game logic with classes I'd just check != null if it has that, but with value types can't really do that
also these packets would be used outside ECS too so can't just 'not add component'
wonder how dots networking handles it, haven't used it yet
@trail burrow tagging because you know a lot about networking and also can't dm you
ยฏ_(ใ)_/ยฏ
There's a #archived-networking channel ๐
yea but that might as well be called #photon ๐
My first thought is that you're destroying it somewhere ๐ค
True
Unity.netcode uses two main pieces of data for network transfer. There's some other stuff for setup and whatever but I'll skip over those. It uses a command component which you can add to anything and that command will be sent over the network. The other thing it can use is a buffer component where it stores the data for different frames in different indexes of the buffer. So as you're doing prediction you can grab the data from whatever frame you need. @hollow sorrel
I'm not sure what you'd be checking for null exactly
ooo i see
but what if your command can contain optional things?
like data that you sometimes wanna send but sometimes don't need to, and is part of the same command
When an entity's Rotation.Value is assigned to, does it wait until the TransformSystemGroup to update the related variables such as LocalToWorld?
Because I am having some issues with setting rotation values. If one system uses LocalToWorld's rotation and translation for its calculations and sets the rotation or position, then another system uses LocalToWorld, wouldn't the second system be using old values?
Its really just a simple system instancing an entity each frame. I dont destroy them at all ๐ค
They do delta compression, meaning that they won't send data that hasn't changed.
I was just thinking that some other system might accidentally delete the entity
Oh wow you are right there was a cooldown system running somewhere instantly destorying the entities because the cooldown time wasnt set
yea but I mean how do you know what's changed on the client
like if you have a big packet that contains other structs that may or may not be present
NativeArray etc has a .IsCreated you can use, but what about your own structs
thinking of wrapping optional structs in a Nullable<T> maybe
like maybe you want to send a position as part of another packet but sometimes it won't be present so you don't have to update it
can't just compare it to default(T) because 0,0,0 might be valid position
What I usually do with Unity netcode is just get the previous tick and compare it to current tick for any variable
Hmmm... i wanna display a list of recipes to craft items. Each recipe basically only has some sort of visible condition, a craftable condition and some sort of required items and an output. Is it worth to implement this as an entity ?
wouldn't you just do a recipecrafting system with perhaps some recipedata with all the recipes in it?
If the rest of your game is in ECS, then yes. All you need to do is bring that data to the UI (which currently isn't DOTS yet)
@sturdy rune Well there many ways ^^ @bright sentinel Hmmm... thats right, i actually try not to overuse the ECS architecture. Not everything should be an entity, when there simpler solutions... The problem is that im always undecided between ECS and OOP
Specifically for an inventory system in a singleplayer game, I think you'd be better off creating that in OOP. There will only ever be one of them, so having it multithreaded will not really give you any benefit. OOP can also be a bit easier so you can use inheritance, which is really useful for item types. Of course you could also do this through composition with both ECS and OOP, it's just whatever you like the most.
True - I guess my idea of crafting is Factorio which suffers at cpu level haha
@pulsar jay have you tried loading subscenes from addressables?
Is that even possible yet?
Oh if it's that kind of crafting, definitely go with entities. In fact I think Factorio uses an ECS architecture
Alright thanks ^^ well its actually more the multiplayer kind of crafting ๐ RPG like
With the new conversion system, in netcode, there's no way to have some entities only on the server or client like before right?
What should I do with spawner entities that are only used by the server?
Leave them on the client anyway?
Could you move them to a subscene that you only load on the server? That's how I handle that.
Haaa see I knew there was something about that but where do I specifiy which scenes load how? In the build settings...
๐คช
So like, every level/scene should have 2 or 3 subscenes; client, server, client and server?
I dont think netcode already has something for that.
One way to archive this is by disabling auto load on the subscene and adding it to a list which you manually load on client/server systems.
What about the scene list in the build configuration? Since I have a build config for client and server, I can include only the appropriate scenes in each
Ehhh
But then I have to do it manually for each scene
I think you need to create a subscene mono behaviour so the scene is actually built
@fluid kiln I'm not using netcode but building my own that's very similar
What I do is I have a server/client system that 'strips' off components
Eg on server I have a system that removes render mesh
What I would prefer is a way to generate extra subscenes from one, eg your 'main' authoring subscene actually generates 2 subscenes, one for clients and another for servers, but subscenes are a pain to extend atm
Yeah I liked the old way where I could tag entities as Client, Server or ClientServer and they would be deleted during runtime. I don't feel like doing it myself so I'll probably just wait for a netcode implementation or do what Script said
Yea that's my plan, a editor tool to mark where the component can exist, atm I just code is all manually
I think netcode already strip some components like Render Mesh, god I hope so
Guys, can i somehow use companion workflow and avoid terrible execution time of CompanionGameObjectUpdateTransformSystem ?
Well the whole issue with it is that it can't be bursted or multithreaded, so probably not.
What's the easiest way to rotate an entity relative to world rather than the parent? I understand I have to use LocalToWorld, but do I really have to reconstruct the TRS matrix?
No didnt try that yet as we dont really use subscenes atm
Omg, i have looked into CompanionGameObjectUpdateTransformSystem code and now i understand why it is so bad
Soooooo... I have a torch. Theres the stick and the flame both are pure ecs. So we have some sort of hierarchy. The Stick has a parent component pointing to the flame. And the flame points to the stick. The flame depends on the stick. How do we make them communicate ? For example the stick should tell the flame to activate. I read somewhere that we need some sort of message system... and it should be pretty flexible. How would we do that ?
I just use simple event entities, create a singleton entity component to start(the systems have RequireSingletonforupdate<>() and then destroy it when its over
it works, it doesn't need to be majorly complicated you could have a singelton buffer for queued events
Hmmm... But the event should get passed to all childs. Like those mono behaviours do. Parent sends a message, child receives and does something with it.
Furthermore such a event entity require its own "system" or loop to apply the logic. But theres no safety... Entities.ForEach(EnableFlame flame {}) so every event would require its own system... Is kinda bloated
you have one system though that would receive that message?
personally I wouldn't think of dots in parents and children, I'd think of it in just the components that you want to calculate on
How would my system receive that message ? By looping over the event ? Or is there some cool new api ?
Well its not always possible... Imagine a car with weels. 0-n
Some sort of long car
Very long
with RequireSingeltonforUpdate<>()
Hmmm... Ok, im gonna search for some examples thanks ^^ and theres no other cool way we could pass those messages between parents and childs ?
wheels only need to be childs with a single component Translation
I think there is a childcomponent type though
LocaltoParent might be what you want
Why doesn't Unity.Mathematics have support for short? Can shorts not be vectorized or something?
Anyone know why LocalToParent doesn't have .Rotation like LocalToWorld does?
I am calculating statistics and now I want to display them as text. Can I do this with an entity?
I am currently playing around with NativeQueue as a kind of command buffer.
Is this a bad idea:
public void PlayVFX(VFXCommand command)
{
var commandWriter = this.Commands.AsParallelWriter();
commandWriter.Enqueue(command);
}
I guess using this in another Systems ForEach would lead to each iteration creating its own parallel writer,
which is a bad thing I suppose?
I dont know of any means of displaying text via entities yet. I usually just use regular gameObject UI which pulls data from entities via MonoBehaviours
OK thanks ๐
is float3.magnitude a thing? I can't seem to get it working
math.length
Is there a good way to prevent 'Attempt to access invalid address.' when assigning to entities? I do an entity null check but still seems to happen every once in a while.
Can anyone see anything wrong with this main thread system? The statistics entity is not being recognised by the system for some reason
are there any entities from "Gather statistical components" query?
I'm not quite sure what you mean, as in if I do a query does it return the statistics entity?
The statistics entity works in a test syste,
This is your Atom query. All entities which has Atom, LastFreeTime and LastFreeTime...Twice...? Maybe that is a problem. Entity can only have one component of the same type
The results of your second job depends on your first. Have you verified your first job is working how you expect?
oh ahaha thank you
Ok I think changing the query to the right component fixed it, thanks all.
if you want have multiple values of the same component on entity you can use IBufferElementData which can be accessed by Entities.ForEach(DynamicBuffer<T> buffer)
Hey guys. Just upgraded to latest entities, and it seems that calling Dispose on the DefaultGameObjectInjectionWorld always raises a warning. "Unloading the last loaded scene Assets/TestScenes/Scene1.unity(build index: 6), is not supported. Please use SceneManager.LoadScene()/EditorSceneManager.OpenScene() to switch to another scene."
Do you guys have any info about? What I'm doing is disposing the world in order to do a fresh scene load.
Where MonoBehaviour are executing in dots update loop? in which system group ?
AFAIK its independent of the ecs update loop. But you could easily test it with some debug logs in a monobehaviour and some systems
From the naming I would derive that update happens somwhere around the update group and LateUpdate happens after PreLateUpdate group
ty, i need control that i do something in ECS world and should show in UI some result which made with MonoBehaviour and want to know how to do it for one frame
If you use schedule you have to be aware that it does run multithreaded und you cannot be sure from MB when the job is being finished
Does anyone have a snippet of setting the world rotation of a child object through LocalToWorld?
I just have the approach that I really dont care if the UI shows this or last frames data
yes but after sync system
yeah that would work if the MB gets updated after that
Or is there any way to unbind the rotation of a child without unbinding the transform? I thought of removing LocalToParent but that would make it stop following the parent :/
Is it possible to use NativeQueue.AsParallelWriter in multiple Systems/Jobs at once? It seems to cause an "The previously scheduled job ... :OnUpdate_LambdaJob0 writes to the Unity.Collections.NativeQueue"
Just happened to stumble upon this: https://medium.com/@5argon/details-of-the-execution-order-of-ecs-in-conjunction-with-normal-scripts-with-updatebefore-1977de86e920
I detached the children from the parent and moved them myself for the billboards.
I ended up overriding the transform system for these entities.
public class FollowParentSystem : SimulationSystem
{
protected override void OnUpdate(EntityCommandBuffer ecb)
{
var localToWorlds = GetComponentDataFromEntity<LocalToWorld>();
Entities.WithAll<FollowParent>().ForEach((Entity entity, ref LocalToParent localToParent, in Translation translation, in Rotation rotation, in Parent parent) =>
{
localToParent.Value = float4x4.TRS(translation.Value, rotation.Value, new float3(1f, 1f, 1f));
LocalToWorld localToWorld = localToWorlds[entity];
localToWorld.Value = float4x4.TRS(localToWorlds[parent.Value].Position + translation.Value, rotation.Value, new float3(1f, 1f, 1f));
ecb.SetComponent(entity, localToWorld);
}).Schedule();
}
}```
I looks like this but I have a small delay that's noticeable since it's the camera that's following the player
I'm stuck again with the problem of not being able TO READ the parent's LocalToWorld and write to the ref of the child's LocalToWorld
That forces me to use the EntityCommandBuffer, but I'd really like to directly write into the localToWorld.Value
Any idea how I can achieve this?
Hey, I am making a grid based game and not sure how to store and check for items in a certain tile in an non-OOP way
Has anyone seen/used the Titanfall ECS clone sample project? OpenFall https://wirewhiz.com/category/tutorials/openfall/
Was going to play with that this weekend and see what I learn - like the concept and lots of overlap with what I would like to do with my project
What do you mean by items here? Like you want to check if a tile is occupied by an object?
so the rules for a tile
that it can store 1 type of item
and a mob
but every item could be unique
so for example you can store 10 hammers in 1 place
but every hammer have their own data
normally I would put the reference to the object in a container and check
Does each tile have an entity?
and I would have that container in the Tile object
well atm I made a tile archtype
which has a type component
so I can setup the map
Well, I would probably just attach a component to the tile if it has an object. This component could be named something like TileItemData and contain an entity reference to the item (e.g. hammer). That entity would then have all the data it needs.
Is that ecs friendly?
What do you mean by that?
well I thought I shouldn't treat entity as an object
and that it should contain only simple data types
because technically the tile knowing that is has an item is not needed
but some other system must know
that place is occupied
Well, how do you then ensure that there is only one item attached to that tile?
It's fine to use entity references on components
It's not too efficient to access the data on that entity from the tile
But that will happen pretty rarely anyways, no?
it is like stockpile
but I can query for the item
in the entity manager
so this part is only for checking empty spots or whether an item or mob can be moved into that tile
If you don't care about what that item is from a tile, then you can just attach a tag to the tile without any data
But then how would you interact with that item or mob?
You could use a shared component that has a value of the tile ID and then just
query using that shared component for all of the items in that tile
I meant that when eg a worker looks for a stone
for a building I wouldn't look into the tiles
but look for a stone in the entities
so I don't access them from the tile
Sure, that's all fine and good if you don't need to know what tile the stone is on
But if you're gonna do any pathfinding of sort, then you'll need to know that
true
The item could also store which tile it is attached to
That's what I meant yeah each item would just have a shared component which is basically a hashed index into a sub collection of all the components in that archetype
That's not literally how ECS stores it but it's one way of looking at it
Why a shared component?
Because you can filter all of the entities returned for an archetype based on the value of the shared component
I guess I can do this for mobs and walls, etc
So you don't have to loop through all entities in that archetype you only have to do a hashing algorithm then you only look at the subset that you care about in the actual tile you care about
I'm having a hard time understanding what half the sentence even means lol
I'm a bit smooth brained here
What is a hashed index?
XD no worries
so a shared component needs to implement GetHashCode and IEquatable
when you do a query you can create an instance of a shared component and populate the values on that instance and pass that in to filter the query
each shared compoonent value is only stored once per chunk
every entity in that architype has the same shared component value
if you change the value on that shared component, the backend moves that entity to a new or existing architype with the value you've specified
so
when you pass in the shared component value to filter by, it only returns architypes that have that same shared component value, by hashing (gethashcode) the shared component and looking it up in a hashtable
so it doesn't have to O(n) through every architype that has a shared component value
it's going to O(1) (although a hash algo is a bigger 1 than each n would be in the other case)
and return only the architypes with the value you specified
obv this is terrible if you only have like 1 item in each tile. you're doing a hashing algo when you could instead loop through 10 items in your entire world
Right, that all makes sense. But how does it solve the issue at hand?
but if it's a performance problem and you need to not be doing O(N), this can help you
Because I want to store more items
so on each item you put a shared component that points to the tile
then you query for all items and filter by the shared component value, which is the tile
the entity query will return you only the items in the tile without iterating or processing any other items
plus this works if I want to make chests
Wait, won't that mean you'll have an archetype for each new item that is not on the same tile?!
yup, just like you might store arrays of items in a hashmap keyed by the tile id
except each element of the hashmap is a static sized allocation (chunk) to improve allocator performance
it's just storing an array in a hashmap
but using EcS ApIs
But this is from the docs:
Avoid too many shared components and values on the same archetype. Since each combination of values, whether in the same component type or in different shared components, is stored in different chunks, too many combinations can lead to poor chunk utilization.
yup
they have 1 shared component
And since he wants a single item on each tile, isn't this going to be horrible?
which is tile id
if you're just putting like 1 item in each chunk and have 10,000 chunks then 10,000 * O(hash) is wayyyyyyyyy slower than O(10,000)
better to just loop through all of them and find the one with the right ID if that's the case
but those are really the only 2 solutions. loop through a list, or index the list somehow
another way to index the list would be to have some coordinate system
like if your map was static
then you could have static arrays
and index into them directly instead of using a hashing algo to find your data
but if your hash is fast, then maybe that's not really much better
but yeah it depends on the case
It just seems in this case it's not the correct solution
Over just storing the tile on a normal component?
ok sorry. I didn't see he wanted to do one item. I did say it was bad with few items above too
storing the tile?
never mind sorry
the tile is like any sim game like dwarf fortress, rimworld
so I just want to store 1 or more items
but most cases probably not a lot
oof yeah sorry my way is bad. I thought u meant tile like.... i imagined like a room or something sorry
my way will use 16kb of memory per architype per tile
which probably isn't viable for u
probably no
ECS doesn't have a way to index data in ways other than that hashing I don't think
I think to get around that you'd probably just have to use your own NativeCcollections
so should I have a NativeList of the items inside the tile archtype?
point to existing item entities so you ccan still process things of similar architype efficiently
no i meant like collections on a system
indexing data stored outside of ecs
some way to look up an entity based on whatever the thing that needs to access that rock has
you can do like what ecs does with entities where each tile is an index into an array. then that array element points to another array of items. each item value is an entity which you can get from ECS.
that way you're not doing a hash
then reuse empty slots or something depending on requirements of your game I dunno
Do you guys know of any way to write directly into a component when I need to get the same component from the parent?
Since I can't do GetComponent when I have the same type as ref in my ForEach
it sounds like you have the ref variable named the same thing as the variable set by GetComponent. you should just be able to name them different variable names. or am I missing something?
No because when you have a certain component in your ForEach lambda, you can't do GetComponent on the same type but another entity
Take this for example: protected override void OnUpdate(EntityCommandBuffer ecb) { Entities.WithAll<FollowParent>().ForEach((Entity entity, ref LocalToParent localToParent, ref LocalToWorld localToWorld, in Translation translation, in Rotation rotation, in Parent parent) => { localToParent.Value = float4x4.TRS(translation.Value, rotation.Value, new float3(1f, 1f, 1f)); localToWorld.Value = float4x4.TRS(GetComponent<LocalToWorld>(parent.Value).Position + translation.Value, rotation.Value, new float3(1f, 1f, 1f)); }).Schedule(); }
oh
oh you want to access 2 components of the same entity?
I want to write into the child's LocalToWorld, but I also need to Get the parent's LocalTOWorld
And I don't want to use a command buffer
do
var blah = GetComponentDataFromEntity<PhysicsVelocity>()
above the query
then
But then I can't write in it can I?
uhh no you're right that's for foreground hmm
Isn't there a SetComponent?
SetComponent is main thread only
GetComponent wouldn't let you change things anyway
you'd need to do multiple queries and pass them to your job
I know Unity uses GetComponentDataFromEntity to do the exact same thign in their Transform systems
the query syntax doesn't support this I guess
unless theres something I dont know
Ijobchunkentity something something
I forget
can you do a query inside a query?
No :/
my understanding is that this is what the query uses in the background
I think you can customize the things you want if you query this way but I don't know a shit ton about it sorry
I'm not familiar with jobs ๐ฆ
me either ๐ฆ
I just saw ppl usin this earlier for complex queries
was highly praised I dunno enough about it tho
I'm thinking of creating a temporary component, one system could set it to the parent's value
Then another system takes thgis temp component and writes to it
That actually makes sense even tho it dupplicates data
no
1 sec
EntityCommandBuffer buffer = new EntityCommandBuffer(Unity.Collections.Allocator.Temp);
Entities
.ForEach((
Entity entity,
ref MovableObjectPhysicsComponent simulated,
ref LocationDataComponent location) =>
{
buffer.SetComponent(simulated.PhysicsEntity, new Translation { Value = location.Translation });
buffer.SetComponent(simulated.PhysicsEntity, new Rotation { Value = location.Rotation });
buffer.SetComponent(simulated.PhysicsEntity, new PhysicsVelocity
{
Angular = location.AngularVelocity,
Linear = location.LinearVelocity,
});
}).Run();
buffer.Playback(EntityManager);
buffer.Dispose();```
Yeah but i kindof need the change to happen immediately, not in the command buffer
so rather than making temp components, just cache the "temp components" in an entity command buffer and play it back when it's done
but the temp components wont happen immediately either tho rite?
It should since it'll already exist on the entity, I'll only write to it
ah ic what u mean
If you use GetComponent or SetComponent inside a ForEach in a system base it will work, it gets converted into CDFE during codegen
wew nice
Even with Schedule? I remember it not working but maybe htat was an older version?
(what is CDFE?)
Yes, it works in bursted jobs. But only in a ForEach, not if you write a custom job
ComponentDataFromEntity
ah gotcha
Ooh well let me try this then
Well I'll be damned, I've been working for months thinking SetComponent couldn't be used in a bursted job
Smhhhhhh
I was wondering why I was using EntityCommandBuffer soooo much
Very clutch Mr. Sark thank you
It won't work in Parallel jobs for safety reasons though, you may need to use a command buffer in those cases
Got you, well everything is .Schedule for now so I'll rethink that at some other time I guess ^^
Other question atm I have variables for the meshes of ground types in a mono object and I use these to assign the meshes to the tile entity is there a better way to do this?
@midnight sonnet #include doesn't seem to work, it still wants to go line by line :/
@slim nebula NativeCcollections work for entites?
because then I can just store the entities in the tile for when I need to check them
You can use a buffer
is that better?
Better than a mono object? Probably yeah
oh you meant for the meshes?
Idk I was answering that
Okay that was for how I should store the items that are on a tile
If tiles are entities and items are entities, I would store the items in a DynamicBuffer on the tile, and also parent them for a nicer hierarchy.
Eeeh depends what kind of lookup
You could also use an unsafe nativecollection on a component
Well I want to able to look for specific items/ objects( like a wall or a character, moster, etc)
Well you can do queries at the time that's needed
I'd use a foreach for the lookup WithAll<Item, Sword>() but idk your project
But then I would make the items as components?
An item should probably be an entity with multiple components that define it unless they are very simple
In my case (rpgish) an item in an entity that has components like Item, Damage, etc...
yeah but WithAll looks for components
Yes, a tag compopnent would define what type the item is
A component Wall, Monster, Character
yeah I got that
but how would you check if a tile is occupied
so example
rimworld
you have a tile with wood
and you cannot drop a gun there
but you can add more wood there
So assuming you know what tile you're standing on, maybe the Tile has a tag <Occupied> and that means that when you go to drop the item, if the TIle has the tag Occupied then it can't drop there
In that case,
Before dropping I would look through the dynamic buffer of items, if it contains an item of the same type i'm tryuing to drop, allow it
Otherwise, don't
yeah that make sense
but then you want to know where is the wood stack
and path find the worker to the stack
if I query for the wood
I get the wood entity
Then I'd make it so that every item on the ground, has a reference to the tile it's on
I guess I can use the position
Then you can doa Foreach like WithAll<Wood>().ForEach((ParentTile tile) => {});
so the tile has dynamic buffer component
and the item has a reference to the tile
Something like that yeah, you'll definitely have to adjust depending on exactly what you're trying to do
But if everything is defined through components, then it's easy to query basically anything :p
At least I do a lot, I have tons of component that simply hold reference to other components
I mean if I store a reference to a tile , I could use it to store the holder entity
eg if someone has the item I would be able to locate that entity
whether it is a tile or a monster, character
Yup ;p
thanks that helped with the direction a lot
Hey guys, quick question. Is that normal a mesh converted to entity (URP + ConvertAndDestroy), doesn't take spotlights into account?
So I've overriden the transform system so that my parented entities follow the parent without rotation. It looks like this:
{
float3 scale = HasComponent<Scale>(entity) ? GetComponent<Scale>(entity).Value : HasComponent<NonUniformScale>(entity) ? GetComponent<NonUniformScale>(entity).Value : new float3(1f, 1f, 1f);
quaternion rotation = HasComponent<Rotation>(entity) ? GetComponent<Rotation>(entity).Value : quaternion.identity;
float3 translation = HasComponent<Translation>(entity) ? GetComponent<Translation>(entity).Value : float3.zero;
localToParent.Value = float4x4.TRS(translation, rotation, scale);
LocalToWorld parentLocalToWorld = GetComponent<LocalToWorld>(parent.Value);
SetComponent(entity, new LocalToWorld()
{
Value = float4x4.TRS(translation + parentLocalToWorld.Position, rotation, scale)
});
}).Schedule();```
But the camera stutters while following the player
I know the player is not stuttering
Has anyone done something similar who'd know what causes the stutter?
Maybe, either way you should use subscenes instead of ConvertToEntity from now on
can you guys edit Unity.Entities code without moving package from Library/PackageCache to Packages ?
No you have to move it there
Hmmm, terrible CompanionGameObjectUpdateTransformSystem performance or 1900 files in git ๐ค
Is there a reason why it doesn't suit your needs?
Don't want to see all of this
No I mean is there anything specific in the system that makes it exceptionally bad?
Yes. You have no tool to prevent system update ALL your entities with CompanionLink. Also it allocates NativeArray with Persistent allocator every frame and Transform[] array with same length. Next it iterates for all entities and access CompanionLink for each entity and fill tranform array with Link.Companion.transform. Only after that it schedules bursted job.
So i have few ways to go
- Don't use companion at all, means no HybridComponents and ConvertAndDestroy mode
- Rewrite it
- Don't use this system and write my own but with extra components for transform sync, because CompanionLink is private
Well yeah, that's the point of the whole system. You can't really do that much differently.
You can go either way tho
You can't do much of bursted stuff here though, since there's a lot of managed stuff here
Rewriting works perfectly, just few lines of code, extra query and extra component
yeah, i understand. System works with managed data, it can't be super performant
but even assuming that system is so bad
Well if you can make a better solution, go for it! I'd also encourage you to post it on the DOTS forums if you do it ๐
I can direct the devs to it if you do ๐
it's already described in this thread
https://forum.unity.com/threads/companiongameobjectupdatetransformsystem-is-very-slow-on-large-scenes.1016305/
Ah perfect!
Although I'm not sure whether this system will be improved
It's likely not something they want to encourage
And rewriting is really simple. In this thread author solved a problem by adding CopyTransformToGameObject tag to query. It's enough to fix bad performance on large scenes.
https://forum.unity.com/threads/need-copytransformfromgameobject-for-companionlink.912002/#post-5979113
Well if you don't want the transform synced, then why are you using the companion system anyways?
I havent really looked at it, so I don't know what else it does
Because i have a lot static stuff in game, that i want sync rare frames and a lot of stuff that i want to be synced every frame
And convertion now is so simple, you can just have whatever gameobject, and if it has SpriteRenderer for example conversion will produce entity with CompanionLink and new hided from hierarchy window gameobject
And all is fine, but it all goes to this system
Ah, so the problem is if you have an entity with a SpriteRenderer it will automatically add the CompanionLink component, which then runs very inefficiently?
Yeah, but also automatically running the transform system is not nice
of course
I'll tell the devs, shouldn't be an issue to add that to the entity package
It would be great, thank you ๐
Literally my job ๐
Also it might take a while for it to get in there, so for now it would be best to do it yourself - either by not using the conversion or by embedding the package
Maybe i don't understand some basics but...
Since we started talking about problems... I recently faced with strange convertion behaviour. I was trying to switch from ConvertAndDestrroy to ConvertAndInject mode. So to test it i create GO with SpriteRenderer and ConvertToEntity (with ConvertAndInject mode) components. And after conversion i got actually two gameobjects. 1st is original one still in scene as expected, and a 2nd one that linked to entity by CompanionLink and hided from hierarchy window as it happens when ConvertToEntity switched to ConvertAndDestroy.
It's totally ok that ConvertAndIject can produce CompanionLink, it's fine, but doubling gameobject is not.
I found out that it happens when there is GameObjectConversionSystem which do AddHybridComponent(). I have such systems in project and tried to turn it off. For example my Light2DGameObjectConversionSystem which simply do AddHybridComponent(Light2D) produce this behaviour with doubling gameobjects, but when it turned off, gameobject with just Light2D converting perfectly.
Also i found out that this kind of GameObjectConversionSystem for SpriteRenderer is in HybridRenderer package which i'm not actually use, so i removed it. And then all starts to convert fine.
I rewrite my GO conversion system in a way they can check if ConvertToEntity component switched to ConvertAndInject mode. Described it in this thread https://forum.unity.com/threads/solved-convertandinjectgameobject-strange-behaviour.1077644/
Having a transform and a float, anyone knows how can I calculate the point from the transform.position to the float in the transform.forward direction?
what is "point from transform.position to the float int the transform.forward direction"?
Same thing ๐คท
It's not computed by my shader (robot) or by the default lit urp one (ground)
You're using hybrid renderer v2 right?
yeap, urp shaders doesn't work otherwise
Just wanted to rule out the obvious ๐
oh though you were gonna say it's a know issue then x)
I wish ๐
and I have the same result removing all post process and ligthing settings ๐คท just an empty scene with camera lights and the two meshes
on 2020 LTS with an URP new project
expected result (mono)
Oh you are also baking the light right?
I don't think so, mode realtime for both lights and auto generate lighting is disabled (but it was on at some point).
Never really checked about light baking cause always worked on procedural stuff
I'm pretty sure spotlights really only are supported with baked lighting?
Oh wait nvm, that's just the bouncing
mb
Is the light in your subscene?
tried both, same result. So this is not something that should happen? Maybe I should try with a new project just in case
Hm yeah, probably a good idea. Otherwise report a bug, seems like it should work
how to change time scale in DOTS physics ?
Is Unity panning to keep the old workflow by using DOTS as the backend ?
It's possible right now
Ok i think i saw that somewhere but i'm not sure
where is the entery point for ecs phyiscs ? what creates the simulation and drives it ? im trying to look at the source to find how to manually set time scale
if i want to set a global gravity scale factor , then i would need to add accessors in the following classes ( might be more then this )
PhysicsStep, PhysicsStepAuthoring, SimulationStepInput, StabilizationData, PhysicsGravityFactor
this seems like an overkill
Just wondering, did someone made a performance test between Unity Jobs and C# Task? (I'm talking outside DOTS and without Burst Compiler). I mean, the raw cost of scheduling a Unity Job vs a C# Task
@lean raptor https://www.jacksondunstan.com/articles/4926
JacksonDunstan.com covers game programming
job > task
Thanks
Question, if I do:
JobHandle.CombineDependencies(new Job1(...).Schedule(), new Job2(...).Schedule()).Schedule().Complete()
Will Job1 and Job2 run in two different threads or will they be executed on the main thread?
depends on what the job system decides
but typically yes
they'll run on different threads
but they wont run at the same time.
job2 will run AFTER job1 finishes.
no matter which thread job1 finishes
job2will run AFTERjob1finishes.
Why?Job2doesn't depend onJob1, but actually the third job (.CombineDependencies) depends on bothJob2andJob1
Hrmmmmm just checked the docs, sorry you're right. I haven't touched jobs in a long while
ok
there's no guarantee to tell where your scheduled jobs will run, or if they'll be executed by two different threads. If you had 4 threads and 3 were busy doing other heavy workload, the remaining one would do both job1 and job2. You can use Run with IJobs and IJobFors instead of schedule to run a job on the main thread though
Hey Hey. Quick Question: in order to make a system run After an other system i just need to add the [UpdateAfter(typeof(InputSystemH))] to the system right? Cuz that does not work in my case. Also: Does it maybee not work on systems operating with monobehaviors? Thanks
That's all you need to do, yes. It causes one system's OnUpdate function to run after another's
If your first system is scheduling jobs maybe that's why it seems off to you
thanks for your answer. actually i have no job runing i am just getting started so i just the simple Entities.ForEach loop.
What's happening that makes you think they aren't running in the order you expect?
they give me Debug.Logs in wrong order
Can you show the code?
yes i can. wait a second
ehm sorry where do you guys share code? ๐ i kinda dont get how hastbin works
You can use hatebin or code tags. https://www.wepc.com/how-to/discord-text-formatting/#:~:text=Discord supports code blocks with,the text%2C as shown below.
Hmm, maybe it doesn't work with ComponentSystem? If you're 100% sure you're seeing "43" printed before "42" then that's all I can assume, otherwise I don't see what the problem would be
ComponentSystem is pretty old at this point and it's been replaced by SystemBase
So hows Unity DOTS doing atm?
hm yes:
i can try to replace with SystemBase an look what thats doing
hm same error, i mean same order of logs
https://hatebin.com/wtyhguqbno looks like that now
Are you sure an entity exists for that first system to match against before the second system runs?
Ahhhh damm i know why
i wrote a helper class that helps to convert child s of "ConvertToEntity" with InjectGameObject. It does that while adding "ConverToEntity" to the childobjects first and to the parent objects in the next frame
and the Input Object is a parent of the CameraObject in the heriacy
so in the first frame the camera Object is converted but the input object not.
That sounds like a good way to constantly be fighting against the conversion system
I did that because the normal "ConvertToEntity" did not work on child objects of other "ConvertToEntity". Objects
it worked with conversion mode "Convert and Destory" but not with "Convert and inject Gameobject"
so yeah ๐ looks like that is my real problem
You should consider using hybrid components if you can, they make this kind of thing a lot simpler
Instead of bothering with "ConvertAndINject". I've always ended up regretting it when I try to use that
how do i use hybrid components?
I am still yet to figure out why clients are able to connect ONLY if they are ran before the server. It's completely mind boggling to me. If I make a client build, run it, then run the server it works. If I run the server, then run the client, the player is instantiated on the server but no message is received by the client.
In my head it cannot be anything else than the behavior of my systems once a connection request in received.
[UpdateInGroup(typeof(ClientInitializationSystemGroup))]
[UpdateBefore(typeof(GhostInitializationSystemGroup))]
public class ConnectedClientSystem : InitializationSystem
{
protected override void OnUpdate(EntityCommandBuffer ecb)
{
Entities.WithNone<NetworkStreamInGame>().ForEach((Entity ent, ref NetworkIdComponent id) =>
{
ecb.AddComponent<NetworkStreamInGame>(ent);
var req = ecb.CreateEntity();
ecb.AddComponent<GoInGameRequest>(req);
ecb.AddComponent(req, new SendRpcCommandRequestComponent { TargetConnection = ent });
}).Schedule();
}
}
[UpdateInGroup(typeof(ServerInitializationSystemGroup))]
[UpdateBefore(typeof(GhostInitializationSystemGroup))]
public class ConnectedServerSystem : InitializationSystem
{
protected override void OnUpdate(EntityCommandBuffer ecb)
{
var playerPrefab = GetSingleton<PlayerPrefab>().entity;
Entities.WithNone<SendRpcCommandRequestComponent>().ForEach((Entity reqEnt, ref GoInGameRequest req, ref ReceiveRpcCommandRequestComponent reqSrc) =>
{
ecb.AddComponent<NetworkStreamInGame>(reqSrc.SourceConnection);
int networkId = GetComponent<NetworkIdComponent>(reqSrc.SourceConnection).Value;
var player = ecb.Instantiate(playerPrefab);
ecb.SetComponent(player, new GhostOwnerComponent() { NetworkId = networkId });
ecb.AddBuffer<PlayerInput>(player);
ecb.SetComponent(reqSrc.SourceConnection, new CommandTargetComponent { targetEntity = player });
ecb.DestroyEntity(reqEnt);
}).Schedule();
}
}```
thanks for your help so far, i gues i have to overthing some things now ๐
Are those of you working with netcode able to connect a client to an existing server? If yes, do you do something different than above? Do you know what could cause this?
When is that ecb played back?
In the ClientServerInitializationSystemGroup
I've just tried removing the ecb, and just having the buffer immediately on the entity prefab
Still doesn't work
Unless.... it's other parts of the ecb you,re referring to?
EndInitializationEntityCommandBufferSystem
You are on netcode version 0.6?
Yeah
Could it be that ecb is too late or too early? I know in the getting started guide they use the entity manager instead
Are you not receiving any messages from the server?
The server spawns the player prefab, the client does not receive ANY message
In 0.5 the connection flow broke when adding it (NetworkStreamInGame) during the simulation system group
Don't know if they fixed that
Exactly, it's exactly like the doc... could a problem like this originate from somewhere else? Say during the connection?
{
EntityManager.DestroyEntity(initEntity);
foreach (var world in World.All)
{
var network = world.GetExistingSystem<NetworkStreamReceiveSystem>();
if (world.GetExistingSystem<ClientSimulationSystemGroup>() != null)
{
// Client worlds automatically connect to localhost
NetworkEndPoint ep = NetworkEndPoint.LoopbackIpv4;
ep.Port = networkPort;
network.Connect(ep);
}
#if UNITY_EDITOR
else if (world.GetExistingSystem<ServerSimulationSystemGroup>() != null)
{
// Server world automatically listens for connections from any host
NetworkEndPoint ep = NetworkEndPoint.AnyIpv4;
ep.Port = networkPort;
network.Listen(ep);
}
#endif
}
}```
You said that the server is actually spawning the prefab so I would say no
I'm gonna try to derive directly from InitializatioNSystemGroup
Anything else touching that NetworkStreamInGame component?
Nope only references are in these two systems
Let me get my IDE up and look what my connection flow looks like
https://pastebin.com/bf6nHz8D
That's the stripped down version of a simple connection flow that I made some time ago
Client connecting late logs
Can you log the amount of ghost components that exist on the client?
Or how do you currently determine that the client doesn't receive anything?
I try the opposite, so building a server, running the editor as client only
No PlayerPrefab is instantiated on the client
There's no networkid entity
Why would it work if the server doesn't exist, but not if it does
It makes no sense ๐
Your code uses a lot of elements I'm not familiar with
You say "We wait until all subscens are loaded before we go in game this is a requirement of..."
I don't do that but it actually makes a lot of sense
If the client is runnign for a few seconds before the server comes online, the client has time to load the subscenes
If it tries to log in immediately, then it goes online before the subscenes are loaded ๐ฎ
I think it throws errors if the server tries to spawn an entity that wouldn't exist on the client
The subscene check I have there is for pre-spawned entities, entities that already exist inside a subscene and aren't spawned through code
And by the time we're here "SendGoInGameRequestClient ", I should have my NetworkId, you're right
That's not it
So the client is able to communicate with the server, but the server is not able to communicate with the client?
And only if the server has been launched first
Oop- It only happens when there's already a client connected on the server ๐ค
Further investigation: the prefab of the 2nd client is instantiated on the server, but the networkidcomponent is not
Pretty sure it was me ๐
the answer was a fail safe with a RequireSingletonForUpdate
Oh
Usually these fails are logged in the console no?
IIRC it was the ghostcollection maybe
nah it was a silent nasty one, and not reproductible 100 percent (the dude had it, I didnt)
๐ฎ
lemme boot my IDE I'll check that
Maybe that's why you dont see your player instanciated
the fix was confirmed by a unity dev
might find a trace of that in the forums
Uuggh that sounds like my problem but I haven't been using the ghostprefabcollection
(don't mind the ComponentSystem, I didn't bother to update yet)
Nor any requiresingletonforupdate for that matter
you dont use ghosts ? custom solution ?
I use ghost but the ghostprefabcollection isn't necessary anymore
I have an entity singleton that holds the player prefab in reference
oh didnt see 0.6 got rid of ghostcollection
The server receives the connection, that I'm 100% sure, but it never instantiates a NetworkClientId for that client.
But for it to instantiate a player prefab, it needs to find a networkidcomponent
Maaan what the hell
How the hell does your server listen after the client connects ? You launch editor then standalone build ?
foreach (var world in World.All)
{
var network = world.GetExistingSystem<NetworkStreamReceiveSystem>();
if (world.GetExistingSystem<ClientSimulationSystemGroup>() != null)
{
// Client worlds automatically connect to localhost
NetworkEndPoint ep = NetworkEndPoint.LoopbackIpv4;
ep.Port = networkPort;
network.Connect(ep);
}
#if UNITY_EDITOR
else if (world.GetExistingSystem<ServerSimulationSystemGroup>() != null)
{
// Server world automatically listens for connections from any host
NetworkEndPoint ep = NetworkEndPoint.AnyIpv4;
ep.Port = networkPort;
network.Listen(ep);
}
#endif
}```
It just comes first in the code ^^
So the server creates a NetworkdIdComponent for the second client, but it is IMMEDIATELY destroyed.
What causes a connection to be destroyed?
Some tomfoolery is deleting my connection as soon as it's created
Do you think it could be related to your LAN ?
That's what I'm starting to think. Because I paused the game as soon as I got the connection request from the client, moved a few frames to notice that the connection is in fact created and attached to the spawned entity. And when i resumed the game the client was well connected p.p
So it only happens when everything happens too quickly I guess? It's strange but I think I'll ignore it for now. It doesn't impede my work and might truly be completely unrelated to my code
Hello guys. I gotta pick my mom up from work, her car giving issues. Plz message personally how to get rid of that one error. Sorry no time for proper intro. ๐
did IJobForEach get replaced?
well they havent yet released the direct replacement though its deprecated
So I can't mark objects static? How do I bake my lightmaps?
Hey all. If I have a managed component like this (has to be managed to easily store a NativeArray, right?):
public class SpriteLibrary : IComponentData
{
public NativeArray<Entity> SpriteEntities;
}
and I want to make a singleton with one of these on it from a MonoBehaviour, would this be the proper way to do it?
private void CreateLibrarySingleton()
{
EntityManager manager = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity entity = manager.CreateEntity(ComponentType.ReadOnly<SpriteLibrary>());
manager.GetComponentData<SpriteLibrary>(entity).SpriteEntities = spriteEntities;
}
And then later, in some system's OnUpdate:
protected override void OnUpdate()
{
NativeArray<Entity> spriteEntities = this.GetSingleton<SpriteLibrary>().SpriteEntities;
Entities
.ForEach((Entity entity, int entityInQueryIndex, in WhateverComponent whatever) =>
{
// ...
Entity toUse = spriteEntities[someIndex];
// ...
}).ScheduleParallel();
}
That would be okay usage, even though it's a managed component, right?
Alternatively, if anyone could recommend a better way, if there is one, of getting a NativeArray from one system to another (or from a MonoBehaviour to a system), I'd appreciate it. I tried just storing it statically but Unity seems to do something weird with accessing static managed data in OnUpdate.
Why not use a dynamic buffer instead
Can a dynamic buffer be a singleton?
Yes
Can you access them by index? I can't find much about them.
If you mean the elements of the buffer, yes
My concern about that is, what if I need a NativeHashMap or something stored in a singleton as well? DynamicBuffers seem a little limited.
That's why I was leaning towards a managed component. Then I could just store whatever in there.
If you need something other than a resizable list then yeah you can't use a dynamic buffer
Managed-component singletons are a thing, since there's extension methods for them, I'm just not sure how to create one from a MonoBehaviour.
There's also dependency issues to consider when you're manually passing native containers into jobs. You should strongly prefer using dynamic buffers when you can
It will save you headaches
What do you mean create one from a Monobehavior?
An entity?
The entity containing the singleton in question yeah.
See CreateLibrarySingleton() above. That's inside a MonoBehaviour.
But that doesn't seem to work. Actually, it crashes Unity.
Basically, what I'm trying to do is, at an arbitrary time after the game starts up (after systems are created), I want to crunch some assets and prepare a library of data for various systems to use.
var em = World.DefaultGameObjectInjectionWorld.EntityManager;
var component = new SpriteLibrary
{
SpriteEntities = new NativeArray(10, Allocator.Persistent);
};
var e = em.CreateEntity();
em.AddComponentData(e, component);
Should be more or less what you want
Basically, I'm having trouble structuring how to get that data to the systems.
Okay, let me try this.
And I assume you know that you need to manually dispose that native array before you entity gets destroyed/before your game ends or you will leak memory
Yeah, that's handled by the MonoBehaviour that actually owns the array.
Generally speaking though, is there a better way to do this? I need more complex data structures than just arrays eventually.
To store basically static read-only game data for systems to access globally.
I had thought that a managed singleton component would be the way to go.
Pretty sure that's what BlobAssets are for, I haven't messed with them much myself
Those only have built in support for arrays as well though, but they can do nested arrays without resorting to unsafe code, unlike regular native arrays
Oh it can hold strings, that's nice.
So this would then go in an unmanaged component singleton I guess?
They can be stored in regular components
Well if that's the intended way to do global config data then I'll certainly look into it.
It just gives you references to static immutable data that won't cause dependency headaches when shared between jobs
And as mentioned above gives you a bit more flexibility in how you structure your data compared to normal native containers
Gotcha yeah. Looking at this it makes sense how this is intended to be used https://coffeebraingames.wordpress.com/2020/11/29/getting-started-with-blob-asset/. I think I'll go with these then, thanks.
Does it make sense for a dependency to be propagated for a query which is empty?
I'm paying a high price for the scheduling of my jobs and I'm saving a considerable amount by wrapping them in if(!someQuery.IsEmptyOrIgnore)... .ScheduleParallel(Dependency) - just wondering if this is going to trip me up for some reason?
Your jobs shouldn't be scheduled at all if there are no entities that matches the query.
So it must be something else that's going on here
According to the profiler I think it still adds the types into the dependency chain
Hmm, seems like a bug tbh
But I don't think there's any issue in having that if-statement
But I'd definitely report it as a bug
An empty query really shouldn't have any overhead
yea.. bit surprised tbh but it's pretty dramatic - will post on the forums and see if I'm missing something
I am trying to get entity component data onto a gameobject so I can display some relevant text. I have two gameobjects, one converts to an entity and one is just the gameobject that will be updated from the entity. I want to reference the entity but I am not sure what is the best way to do this?
^ To reference the entity in a monobehaviour script that runs on the gameobject
Simplest way is World.DefaulyGameObjectInjectionWorld.EntityManager.GetSingletonEntity<CompData> inside Awake in the not converted script. Or if you want to to have your text easily respond to changes in your data you can do something like https://forum.unity.com/threads/dots-and-ui.1018159/#post-6598195
On the same subject, what would be the best way to have a UI button event communicate with a system?
it's not the best for answering you directly but thye have source code: https://forum.unity.com/threads/showcase-pure-dots-ui-system-detailed-description-feedback.688531/
source code released: https://forum.unity.com/threads/source-code-dotsui-open-source-ui-project-for-dots.715880/
Motivation
The current Unity UI...
has an event handler
Anyone know how to get a reference to a compute shader into a system?
Like, I guess for game objects you'd make it a public field and then drag the shader it into that slot
Ah ok thanks, I have tried that and I am getting this error. Sorry in advance when this is something stupid
Oh right GetSingleton is a query/system function. So you'd have to create a query from the entity manager and use GetSingleton from that
I know this doesn't work but is this close?
Is it possible to retrieve an array which contains all elements from all entities that have a specific dynamic buffer?
To avoid X-Y problem: I want to pass this array as a computebuffer to compute shader.
Has anyone managed to use SceneSystem.LoadScene(guid)? I get Loading Entity Scene failed because the entity header file couldn't be resolved. This might be caused by a failed import of the entity scene. Please take a look at the SubScene MonoBehaviour that references this scene or at the asset import worker log in scenePath=Assets/Scenes/Test World/Test World guid=2ebf75e5a674adf44982871f7a38d189
Yeah that's what I'm using
And I use the get scene id from path first
Weird
I'm not doing anything special
I'm not in a build yet tho
I'll try with get scene id from path
What I'm trying to do is weird cause I'm trying to make a menu in my MP game. But if I run the editor, it loads the current scene. So no way to test "entering in game"
My menu is a full scene
And make sure the subscene is closed or something
Should I use subscene instead?
Not sure
I feel like in DOTS it makes more sense to have only 1 scene so maybe that's that
Basically I have the default world all setup normally
I throw in a singleton entity and that triggers the start of my networking
Opening the 'lobby' if your the host
People connect then when host starts new world is created for client/server and I load the start scene
That start scene actually should be a list of scenes and 1of them will be the game map
I'll probably have a older normal unity scene for the UI and other stuff too
And more subscenes for things like prefabs
@fluid kiln not sure if netcode let's you start networking in the default world
It creates new server client worlds as soon as you start it I think
Yeah it does :/
You should be able to get a 'lobby' system working fine tho, as your gameplay systems won't run without entities
Well maybe, I guess it depends on how your systems are setup
It's just in the editor the problem. When I run I want the client to be on the main menu scene and the server to be on the game scene. But when I run it loads the opened scene on both. And I'm unable to change the scenes on the server
I am trying to get an entity reference in a monobehaviour script but I am getting the following error:
The entity does exist and the query is over components it contains. The only thing I can think of is that the monobehaviour awake() is called before the entity is created? It is created from a gameobject.
Definitely that
If not, make sure wherever you're using GetSingletonEntity from is in the same world as that entity
Because when you think about it, for the conversion to happen, the GOs are created first.
So awake probably comes before the entity
Well I think I would try not to use GetSingletonEntity from monobhavior
Is it for UI?
yeah to start with but then I want to use the gameobject for data visualiation
I think that will be easier than using an entity
You can turn your UI into a hybrid component, and have an Entity foreach query on it
i am collecting stats onto a statistics entity and then just getting that data onto a gameobject
To update it
I think I need to be compatible with project tiny
hybrid components aren't I don't think
Oh I just put the getSingletonEntity stuff in LateUpdate and that worked!
Thanks for the help ๐
Hi guys! Don't know if anyone remembers me, but I hope you're all staying sane ๐
I was curious, if Unity has updated the Physics system to allow RaycastCommand to return more than one result yet? (ex: a ray that punches through multiple things)
Last I checked in Nov, it only returned the first hit, and then stopped
(pure Jobs, not ECS)
Damn entities aren't named when you load a scene during runtime ๐จ
Anyone know specifically what minimum set of components I need to manually add to an entity to make it work with the HybridRenderer?
Can you check with a prefab or prespawned go?
Not easily, it seems. There's a lot of components on there and I'm not sure they're all necessary.
I need to make a renderable entity in code.
At runtime, the Hybrid Renderer processes all entities that have LocalToWorld, RenderMesh and RenderBounds DOTS components. Many HDRP and URP features require their own material property components. These components are added during the MeshRenderer conversion. Processed entities are added to batches. Unity renders the batches using the SRP Batcher.
Note that if you add entities to your Scene at runtime, it is better to instantiate Prefabs than to create new entities from scratch. Prefabs are already converted to an optimal data layout during DOTS conversion, which results in improved performance. Converted prefabs also automatically contain all the necessary material property components for enabling all supported HDRP and URP features. As we are frequently adding new features to the hybrid renderer, we recommend using the conversion pipeline and prefabs instead of manually building entities from scratch, to avoid compatibility issues when updating to new hybrid renderer package versions.
Thanks, I'll try that out.
These components are added during the MeshRenderer conversion.
Mm, that's what concerns me.
Since I can't really do conversion in this case.
At least, not with a huge amount of pain.
Unless someone knows how a system can refer to a GameObject prefab in the project browser.
You can have a singleton
That has to be a created entity.
There's a chicken and egg problem here where I need to know what entity to create to create it, but the only way I can know what entity to create is by creating an entity.
Since there's no other way to get serialized data into a system.
I'm not sure I'm following 100% but you can refer a gameobject prefab from the project browser by dragging it into an entity field of an component
Right but I can't then refer to that component directly.
Like, how does the system get to that prefab?
So you have a component called PrefabHolder that has 1 field of type Entity. You add a GO in your hierarchy with that component and drag your prefab into the field. Then from any system you can call GetSingleton<PrefabHolder>().prefab
That's... painful.
Depends how many you need but it's not so different from good old oop unity
In a normal MonoBehavior context I just point the MB to the prefab I want to spawn and spawn it.
This has to form like a chain.
Can that primordial entity be marked as a prefab? Like can you have it automatically get the Prefab component?
If not maybe you can add an authorgin component that adds the Prefab component?
Obviously your use case is much more complicated than anything I've done yet so idk if that's the best solution
There's a hybrid renderer helper method for runtime rendering entity creation
It will handle setting all those components
๐
Oh perfect, thanks.
It's always a nice surprise when the docs have exactly what we want :p
I really hope they figure out a way for systems to just be able to have serialized data.
Singleton entitys is the plan I believe
The whole "create an entity just to forcefeed a system the data it needs then destroy it" pattern is not pleasant to use and has a lot of code smell.
Tho I agree, system only data can be useful
What I did is have a Dependancy injection that would inject scriptable objects
Worked very well but was too much effort to use
Was pretty easy
Used addressables to load the SO via a label
Then was injected based on type
Bit of reflection
I'm sorry but the fact that all of that is necessary just to accomplish what [SerializeField] does for MonoBehaviours is crazy.
But all that ended up being too many steps, each system that wanted data needed to create a SO (code) then in editor would create a asset of it, then needed to mark and configure addressables ... Was too much
True but I perfer the systems being as they are, almost pure code
So we can create and destroy them as we like
They aren't though. Look at the HybridRenderer. It stores a ton of stateful data inside of it.
And couldn't function efficiently without doing so.
I'm heavy into muti worlds, and I even have a group of systems I dynamicly create for things
Maybe there needs to be a "scriptable system"? Option
If they were truly committed to having systems be completely pure they would be functions, not classes.
Its a Separate option, exists as a asset so you can use the serialize field
There's no reason for OnCreate, OnDestroy etc. to exist without systems being stateful.
You could probably implement it now using ISystemBase
Stateful is fine, it's connecting systems to unity 'stuff' that's painful
Which, it shouldn't be.
I'm just gonna gripe about it on the forums I guess.
:p
Yeah
Nothing else to really do about it.
I keep bouncing between Unity ECS and bevy.
Every update gets better, just it's slow
Unity ECS has all the nice Unity things and a much more mature engine, but bevy has a much more sensible ECS system.
No ideal world unfortunately.
Did you try the older versions :p soooo rough
What we have now is amazing in comparison
And by the time it 1.0's should be even better
Well they said they won't release 1.0 before it is as easy to use as monobehaviour so...
Exactly
That's... an ambitious goal at this rate.
I struggle to think of use cases for unity data (assets) in a system tho
Well, mine is I need to load textures and generate a quad for each sprite on it.
Yea I remember now
And store that in a library that I can then use for making entities.
The rendering batch thing
I stepped back from the rendering batch thing. I can actually use sprite entities now.
Hybrid?
The problem is generating a library of them at the right time (and that timing is very important).
Hybrid renderer, yeah.
It's complicated because my world space is double, not float, but someone gave me a very simple solution I wish I had thought of for that.
Like I literally smacked my forehead when I read it.
What was it?
So I was going through this whole thing of having separate entities, one for the gameplay entity and one for the renderable sprite entity.
And how that sucked because I had to link them all and eat all these cache misses copying data over between them.
And then I looked into batching the gameplay entities and rendering them myself, and so on.
But the suggestion I got, the "duh" one, was to just have both representations on the same entity.
So each entity has its real double-sized game world position in a component, but also has the render transform and all the hybrid rendering data, and I just pass over each entity once per frame in a very easy-to-parallelize way with minimum possible cache misses and update the transform from the world position and the camera position to make it camera-relative in float precision.
And then it's just down to culling, which I would have had to do anyway.
You could do it with fixed point representation as well, or any really. It's probably the most efficient way to do it.
Hence the forehead-smacking "why didn't I just think of that a week ago" moment.
@stable siren yes
6 irrc
ah
But you can make more
how?
Not sure but I've seen it in the docs
Something about creating a delegate matching the parameters you want
Ok, ill just do two foreach loops, its on the main thread anyway
Smaller foreachs are better performance wise I think
Usually if you have more than 6, you can split up your operations in smaller queries
Actually that is weird cause in the screenshot I sent I think there are only 6
is there an analogue to GetComponentData for buffers?
Do you mean GetBuffer?
oh yeh that is perfect thanks
Does anyone know how to add EntityCache to the git ignore?
I don't suppose anyone knows of a good way to delay the running of a system?
[DisableAutoCreation] ?
yeah I figured the only way was to manually do it from other external systems
it doesn't matter that much I just wanted to see if I could cache some data in OnStartRunning, but it seems the Systems run before entities are converted and moved into the default world
neh mind I was wrong, I can do that
Am I stupid or is there no easy way to compare two float3s? It gives me a bool3 and there's no method .AllTrue
math.all / any
So you guys know how you can instantiate prefabs in NetCode and attach them to players. How do I go about populating these prefabs with player specific data and synchronizing this data across all clients?
Simplest example is a component with player name
The prefab doesn't know the player name at instantiation
I wouldn't want to use a ghostfield for that right?
RPC? Sounds finicky
Unless GhostField is synchronized only on value change which would be super helpful but it's nowhere documented if it is
Dots Netcode only sends data around if it changes. And if it changes it compresses the data relative to a snapshots the client already has.
Only for ghost fields, that isn't in any way related to rpcs
Awesome that's what I was looking for. Although now I'm wondering about more complex data. Like say a player is a complex RPG character. The server saves into a database the class, race, stats, buffs, debuffs it had when it last logged out. Once it logs in, how do I stream this data to all client? Considering some of it is expressed through components rather than ghostable fields.
(Buffs for example would probably be a dynamic buffer of entities)
The current implementation doesn't sync Add/Remove of components as far as I'm aware.
But you can add references to other ghosts on the Character.
Which is something that I personally do.
Where I have one Character which references a state machine (which is a ghost entity) based upon the 'role' the character has.
So components with entity fields are synchronizable now?
I guess I'm overthinking it, thanks for the guidance!
I'll cross that bridge when I get there haha
You can mark the Entity value on a component as a GhostField which will sync the reference. This only works if the Entity is a ghost tho
Gotchu, I didn't know that!
Why does this crash on the first line?
protected override void OnUpdate()
{
var ecb = _barrier.AsParallelWriter();
var typeIndex = _typeIndex;
Dependency = Entities
.WithName("AddSystemTag")
.WithNone<AgentSQTypeSystemTag>()
.WithAll<AgentTag>()
.WithAll<SpatiallyQueryableTypeBE>()
.ForEach((int entityInQueryIndex, Entity entity) =>
{
ecb.AppendToBuffer(entityInQueryIndex, entity, new SpatiallyQueryableTypeBE()
{
value = typeIndex,
});
ecb.AddComponent<AgentSQTypeSystemTag>(entityInQueryIndex, entity);
})
.Schedule(Dependency);
Dependency = Entities
.WithName("RemoveSystemTag")
.WithAll<AgentSQTypeSystemTag>()
.WithNone<AgentTag>()
.ForEach((int entityInQueryIndex, Entity entity, in DynamicBuffer<SpatiallyQueryableTypeBE> spatiallyQueryableTypeBuffer) =>
{
ecb.RemoveComponent<AgentSQTypeSystemTag>(entityInQueryIndex, entity);
//removebuffer
})
.Schedule(Dependency);
}
@dark cypress where do you set _barrier?
Nope
does a roadmap exist yet?
Not that I've seen :(
oof
trying to get up to date on dots stuff, I'm stuck on 2019 for awhile
how has it been on 2020/2021
Feels to me like there hasn't been too many major changes beyond the conversion system. More importantly though the editor is a lot faster now
That's not necessarily related to dots but it's a good reason to update imo
that must be nice lol
I've changed it to a separate command buffer system, but now it crashes with "Writing to the command buffer that's being written to elsewhere".
Shouldn't that be handled automatically by passing Dependency into the jobs?
I have to wait on openxr maturity before I can even switch
var ecb = _barrier.CreateCommandBuffer();
var typeIndex = _typeIndex;
Dependency = Entities
.WithName("AddSystemTag")
.WithNone<AgentSQTypeSystemTag>()
.WithAll<AgentTag>()
.WithAll<SpatiallyQueryableTypeBE>()
.ForEach((Entity entity) =>
{
ecb.AppendToBuffer(entity, new SpatiallyQueryableTypeBE()
{
value = typeIndex,
});
ecb.AddComponent<AgentSQTypeSystemTag>(entity);
})
.Schedule(Dependency);
Dependency = Entities
.WithName("RemoveSystemTag")
.WithAll<AgentSQTypeSystemTag>()
.WithNone<AgentTag>()
.ForEach((Entity entity, in DynamicBuffer<SpatiallyQueryableTypeBE> spatiallyQueryableTypeBuffer) =>
{
ecb.RemoveComponent<AgentSQTypeSystemTag>(entity);
//removebuffer
})
.Schedule(Dependency);
iirc the auto job handle dependency shouldn't be written to, just used as a input job handle
you might want to manually chain these two jobs, instead of dependency
var job1 = Entities...Schedule(dependency)
var job2 = Entities...Schedule(job1)
The code they posted is already doing that
its overwriting the struct
which I dont trust the code generator to handle that right
But you don't need to, it would do that implicitly if you just exclude Dependency
thats true
still used to the old job system days I guess
explicit > implicit for documentation reasons
True, it's nice to have a clear idea of what's going on if you're not already familiar with SystemBase
systembase is nice, when you already know what its doing for you. but I always worry about new users getting used to the crutch
Not sure what that error would be from but your previous example looks like a strange way to be using command buffers. Might be related to that if you're trying to do something other than what's shown in the docs examples
tbh reading the code, I'm not even sure what your doing
looks like two distinct queries to add a type index then a tag component?
I'm just trying to implement a simple SystemStateComponent handling.
Guess I'll go copy from the docs for that.
oh systemstate component?
I usually do two distinct systems, CreateXSystem and add the state and unique id there in one foreach
then a DestroyXSystem that queries State, exclude everything else, and removes the component
Yeah, I'm trying to avoid system bloat. As I keep adding more and more, it just gets worse to manage.
Related question. Can I combine 2 queries for "RequireForUpdate"?
Like this.
Seems to be working, but there's no proper way of doing it like EntityQuery.Combine, or something.
That looks like the proper way to me
It does, but I'm concerned, since I'm defining the query in 2 places(here and in the ForEach).
So I would've expected there to be a Combine method for queries, because ForEach can give you its query.
The query you get from WithStoreEntityQueryInField isn't a combined query though
That's what I'm saying. I wish there was a way to combine 2 queries that I get from the 2 ForEach's that are in this system, so that I don't have to define both of them in the OnCreate again.
WithStoreEntityQueryInField works during codegen, so you can use the queries it assigns inside OnCreate
You shouldn't need to recreate them
If I do that, the system never runs.
RequireForUpdate(_addQuery);
RequireForUpdate(_removeQuery);
Presumably because of the different ways it combines the queries, as they conflict with eachother.
I see what you mean, those are EntityQuery and not EntityQueryDesc
Surely there's a way to get the EntityQueryDesc from the queries
Hmm, I'm not seeing an obvious way from the api docs
You might be stuck doing it the way you were. Once we're able to pass our own queries into a ForEach you could avoid recreating it that way
Not sure there's a way right now though
I find personally system bloat is nothing to manage, if you just name them proper and use nested namespaces + folders to keep things isolated
plus system state create/destroy systems are like 40 lines at most
write once/forget till you need to modify
Is there a way to find a existing system(s) via interface?
Also can we have a System without OnUpdate?
I have this simple system
[DisableAutoCreation]
public class DestroyDespawningSystem : SystemBase
{
EndSimulationEntityCommandBufferSystem system;
protected override void OnCreate()
{
system = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
}
protected override void OnUpdate()
{
var ecb = system.CreateCommandBuffer();
Entities.ForEach((Entity entity, in DespawningEntity despawningEntity) =>
{
ecb.DestroyEntity(entity);
}).Run();
}
}
{
But it causes this log to pop up
"Internal: JobTempAlloc has allocations that are more than 4 frames old - this is not allowed and likely a leak"
Any ideas ?