#Having issues spawning a ghost entity and getting components on it.

1 messages · Page 1 of 1 (latest)

mild bear
#

Ok I'm having two related issues here. I have a prefab with this authoring component on it:

public struct CrewMemberStub : ICleanupComponentData {
    [GhostField]
    public int LocalPlayerId;
}

[DisallowMultipleComponent]
public class CrewMemberAuthoring : MonoBehaviour
{
    class Baker : Baker<CrewMemberAuthoring>
    {
        public override void Bake(CrewMemberAuthoring authoring) {
            DependsOn(authoring.GetComponent<Rigidbody>());
            
            var entity = GetEntity(TransformUsageFlags.Dynamic);
            AddComponent<CrewMember>(entity);
            AddComponent<CrewMemberStub>(entity);
        }
    }
}```

The prefab also has the "Ghost Authoring Component" on it, set to "Owner Predicted" as the default ghost mode.

Then I have this code in a server side system to spawn this object:
```cs
            Entity player = commandBuffer.Instantiate(prefab);
            commandBuffer.SetComponent(player, new GhostOwner {
                NetworkId = networkId.Value
            });
            commandBuffer.AddComponent(player, new CrewMemberStub {
                LocalPlayerId = requestComponent.ValueRO.LocalPlayerId
            });
            commandBuffer.AppendToBuffer(reqSrc.ValueRO.SourceConnection, new LinkedEntityGroup {
                Value = player
            });
            commandBuffer.DestroyEntity(reqEntity);```

My first issue is:
- Why does this work with AddComponent instead of SetComponent for my CrewMemberStub? With SetComponent I get a System.ArgumentException here.  But AddComponent workd.

And probably related, the second issue is that the entity does spawn in both the server world and the client world, but the client world entity doesn't have the CrewMemberStub component at all. It's only there in the server world.

What am I missing, and/or what further info should I share to help debug this problem?
#

I see my CrewMemberStub component in the ghost authoring inspection component, so what's going wrong here? It's as if the server world doesn't know about this component at all in the prefab or something (but this screenshot shows that it should know since Server is enabled for it)

mild bear
#

And I just checked - if I don't include the commandBuffer.AddComponent(player, new CrewMemberStub line then my spawned entity doesn't get the CrewMemberStub component at all in either server or client world. So something is wrong with my prefab I guess?

molten notch
#

Cannot bake CleanupComponents

novel token
#

If you want to have a nice cleanup experience

#

I suggest to introduce centralized destruction pipeline in project

#

so that all it takes to destroy entity just set enabled component of some DestroyEntity enablable tag

#

and then destroy system would handle the rest

mild bear
#

I knew it had to be something stupid, thank you.

#

Make sure to add it to entities at runtime, because cleanup components cannot be baked.
What a cheeky little comment

#

I guess I'm confused as to why the ghost authoring inspection component seemed to have no problem with it.

mild bear
#

@novel token how would such a pipeline work in the context of Netcode For Entities? I can understand perhaps in a normal circumstance the server could add a "destroy" component to entities it wants to destroy and the clients can obey that. But what does the server do with entities that are owned by, say, a client that suddenly disconnects?

novel token
#

but assuming interpolated stuff

#

you simply do everything about it on server

#

as in:
something wants entity dead - it sets DestroyEntity to enabled

#

and then you have a system group somewhere in the end of system order, like CleanupSystemGroup here you schedule jobs to cleanup stuff
then you also have MainThreadCleanupSystemGroup which runs on next frame at the very beginning

#

here you make systems that want main thread cleanup (allthough probably should be avoided on server)

#

and then finally after that system group finishes - you have a single system that destroys entity

mild bear
#

What about if those entities have client-only bits that need cleaning up?

novel token
#

is it interpolated?

mild bear
#

(actually only relevant in my case for predicted entities so maybe a different story)

novel token
#

assuming it is

#

you just do exact same thing

#

oh wait...

#

netcode does not use destruction pipeline

mild bear
#

If the server marks an entity for deletion and then cleans it up all on its own side, I'm thinking there's no guarantee the client would see the "destroyed = true" state at any point

novel token
#

Sorry, a bit too used to our own network solution

mild bear
#

Alright I'll try to do some more research and maybe there's some examples about this somewhere

novel token
#

I guess one way - you need to look into internals of netcode

#

and find out how exactly it destroys entities

#

as in: when it figures which entities are meant to be destroyed

mild bear
#

It seems like such a common use case I'd be surprised if there's not an example for this somewhere

novel token
#

so if you can do it before actual destruction - then you will simply read it, and export to your DestroyEntity state

#

I'd say, unity netcode has many things that are commonly required, but actually very hard to do with netcode

mild bear
#

I'm seeing that yes 😭

novel token
#

from what I remember

#

your best bet is to be able to "disable" things

#

for predicted destruction

#

so your predicted destruction is actually not a destruction, but hiding

#

because if rollback happens - then you need a proper reinstantiation

#

which will likely cause a fps drop if you have an animator with particles here

mild bear
#

yeah that definitely makes sense

novel token
#

Hmmm, maybe dig into a direction of custom registration of cleanup? So you avoid structural changes

molten notch
#

Hot tip, let things live a bit longer than they need to, and mark them destroyed.

novel token
#

You most definitely can do "Initialization" of ghosts, where you can do things on entity once

#

so from here maybe you can register your entity and all it's archetype

#

and then when entity detected destroyed - you do the cleanup

#

but most annoying part - duplication of component data before destruction...

#

Need to dig into how unity netcode handles destructions to understand what to do aboit ig

molten notch
#

What kind of things do you need to clean up on client side though?

novel token
#

but ICleanup pattern is purely runtime and you have to do double query: one for initialization, one for destruction

#

(we ran away from it, because it's hard to maintain and scale)

novel token
molten notch
#

Also structural changes breaks importance calc stuff etc. for network rn, so better avoid it.

mild bear
#

particle systems probably in the future though

novel token
#

yeah, we have MMO project and so far we never had any need to have any cleanup networked. Everything is handled separately: server only keeps gameplay related cleanup (player that left should cleanup everything about him like quests and etc). While client cleanups only what it creates on it's own: hybrid objects (animator), visual effects from buffs and etc

#

so you probably should not worry your head about networking related cleanup

#

just destroy entities on server and let client rely purely on entity destruction

#

just gotta figure a covninient pattern to do so to avoid boilerplate