#RPC Spawning/Despawning Issues

67 messages · Page 1 of 1 (latest)

golden flower
#

The current issue I'm facing, is that when I spawn a "FloatingText" nob to represent damage or healing, every client is attempting to spawn their own "FloatingText" nob.

The "FloatingTextManager" responsible for spawning "FloatingText" nob for damage or text, exists on every client, but calls RPCs to the server to spawn the "FloatingText" nob.

Posting the relevant code below:

FloatingTextManager:

https://pastebin.com/ey1xmnUY

FloatingText - nob

https://pastebin.com/W4h7tB1i

SpawnManager

https://pastebin.com/zTx7v7ik

#

Also worth noting, the numbers aren't the same on the client and the clients not taking damage/using items.

#

Any help would be greatly appreciate per usual!

small helm
#

Hey, your code pastes are all private

golden flower
#

Oof

#

Let me fix that real quick

small helm
#

And preferably not in code blocks, otherwise I cannot click them on mobile,. Which is actually why I forgot about this post 😅

golden flower
#

Ohhhh gotcha.

#

I just made them unlisted, so they should work now. I'll remove the code blocks so the links work.

#

There we go. Should be all straightened out now.

#

Thanks for taking a look! Time has been pretty limited lately on what I can dedicate to the project, so any help is greatly appreciated!

#

I'd be happy to provide additional code/context as well if needed.

small helm
#

So what do you mean?

every client is attempting to spawn their own "FloatingText" nob

golden flower
#

So, when a player or NPC attacks or heals via any source, it makes a call to the "DamageManager" which calculates the damage and sends it to the player.

When the damage is calculated and sent to the player, it then makes a call to the "FloatingTextManager" to spawn the "FloatingText" nob presenting a visual for the the damage to clients.

#

For some reason, it's spawning two "FloatingText" nobs every time a client sends or receives damage.

#

I would assume the number of nobs would scale with the number of clients.

small helm
golden flower
#

I'm attempting to yeah. I was thinking the ServerRpc attribute would handle it only being called from the server. Which I'm assuming it must be since it's not throwing predicted spawning errors.

#

That's why I was asking if both clients having the managers spawned on them would be an issue...was a bit worried about that.

#

But without both clients having the managers, there would be no way to make the calls to the servers relating to managers. 😅

golden flower
#

Hm, I might need to add the "IsOwner" check or something on the managers if they are being called multiple times.

#

So close but so far to getting these systems converted. lol

small helm
golden flower
#

True. Both NPC's/Host and Clients make the calls though, so if the Client was hosting, wouldn't they have the same IP?

small helm
#

Well, the IP isn't really relevant for this. The NetworkConnections would be different

golden flower
#

Ah, I see. Sorry still a bit hazy on all the details on how those conditionals work.

#

So, I just tested, when I use an item, that call is made one time. I turned on debugging for both the client and client/host, and when I use an item, it's only called once.

small helm
#

So the SpawnObjectAtPosition method only runs once on the server, correct?

#

And it's somehow creating multiple FloatingText game objects? On the server or client side?

golden flower
#

Oh wait, putting a stopper there fires off the SpawnObjectAtPosition twice. Interesting. So it must be being called on the host and client/host.

#

The "UseItem" is only being called once, but the spawning is being called twice. Hm.

#

The "IsServerInitialized" just checks if it's initialized on the server right? Not if the server is running it?

#

I added this bit here to try and prevent the Client from spawning the nob...but it is still called twice:

    [ServerRpc(RequireOwnership = false)]
    public void RPC_SpawnDamageNumber(NetworkObject target, int amount)
    {
        if (!IsServerInitialized) return;
        // Call the observers RPC to spawn the damage number on the target client
        SpawnDamageNumber(target, amount);
    }
    
    private void SpawnDamageNumber(NetworkObject target, int amount)
    {
        Scene targetScene = target.gameObject.scene;
        Color textColor = amount >= 0 ? Color.green : Color.red;
        floatingTextObject.RPC_SetText(amount.ToString(), textColor);

        SpriteRenderer spriteRenderer = target.GetComponent<SpriteRenderer>();
        float spriteHeight = spriteRenderer.bounds.size.y;
        Vector3 topPosition = target.transform.position + new Vector3(0, spriteHeight * 1.25f, 0);

                            SpawnManager.Instance.RPC_SpawnObjectAtPosition(floatingTextObject.gameObject, targetScene, topPosition);
}
small helm
golden flower
#

Right, hm...so I guess the client/host would count as the server?

#

As well as the server?

small helm
#

You mean a hosting client (server+client) as well as a dedicated server? Yes, they both count as a server

golden flower
#

Right now there's no dedicated server. Just a Client acting as the host and a player, and then a seperate client joining as just a player.

small helm
golden flower
#

That was my understanding as well, but I wanted to be safe since it was still running twice somehow.

#

This attribute should prevent the prevent the client from running the code, but allows the client to tell the server to do it correct?

[ServerRpc(RequireOwnership = false)]

small helm
#

Yes, a client needs to call it, and it will then run on the server

golden flower
#

Oh dang, I think I found it.

#

It's not something you'd be able to see, since I didn't post the code, but it was in the DamageManager. It had an ObserverRpc on NotifyClientsOfDamage.

#

I think that's what was causing it to fire off for each client.

small helm
#

ah gotcha 🤞

golden flower
#

ObserverRpc cause something to be called on all clients observing an object right?

small helm
#

Yep

#

It's called on the server and runs the body on all observing clients

golden flower
#

Gotcha. Is it necessary to split up my methods like I'm doing for RPCs? Where the RPC then calls the method the RPC is meant to perform?

I'm not sure where I saw that at, but it might be a bit redundant based on what we've discussed.

small helm
#

Nope that's not necessary, unless you need to be able to call the method as a non RPC

golden flower
#

Well dang. Time to do some code cleanup today too then. lol

golden flower
#

Have you seen this error before? Now that I've made the server be the only one spawning the FloatingText nob, when I try to set the text and color, I'm getting this warning:

Cannot complete action because client is not active. This may also occur if the object is not yet initialized, has deinitialized, or if it does not contain a NetworkObject component.

Shortly after that it spawns with the default value. I tried adding a delay before updating the text, but it doesn't seem to help.

    [ServerRpc(RequireOwnership = false)]
    public void RPC_SpawnFloatingTextAtPosition(GameObject prefab, Scene scene, Vector2 position, string text, Color color)
    {
        NetworkObject networkObject = networkManager.GetPooledInstantiated(prefab, position, Quaternion.identity, true);
        networkManager.ServerManager.Spawn(networkObject, null, scene);

        FloatingText floatingText = networkObject.GetComponent<FloatingText>();
        floatingText.RPC_SetText(text, color);
    }
small helm
golden flower
#

Ah, yeah that'd do it. Lol

#

exactly what's going on there.

#

That one is going in the notebook. Lol

#

I messed with that for like an hour, and decided it was time to pack up and hit the gym to reset. Lol

small helm
golden flower
#

For sure. It's such a good mental reset for coding

golden flower
small helm
#

Yep, quite right

golden flower
#

I think I'm finally getting a good grasp of how this stuff works. 🥲

#

Thanks @small helm for all the help per usual! Excited to show you the results soon since you've helped me so much with the learning process!

small helm