How to properly destroy non-instantiated objects over a network?

After more than a week testing and retesting many different ways to do this and examining every post I can find here and elsewhere, I am starting to think this is not even possible via any means within unity. This not so much a code question but a concept clarification as I really just don’t get Unity’s take on networking.

Is there a way to destroy an object which was in the scene when the game was started - non-Network.Instantiate’d - and have it permanently removed from the scene so that it does not reappear for players joining later. Surely there is some way the server can do this. I have tried sending messages and RPCs in every possible combination I can think of but I just can’t make it work. It would be counter productive if I were to post the code in question because as I have said I have tried so many combinations which simply haven’t worked.

Add to this the fact of starting 2 clients and a server to check it thousands of times and I’m sure you can relate to my current state of sanity :slight_smile:

I just find it mind-boggling bizarre that Unity doesn’t seem to be able to do this. At the moment it seems like I would need to Network.Instantiate every item that might possibly be destroyed during a game. Surely that can’t be the case - can it?

Again not looking for specific code examples but conceptual de-obfuscation, any help very much appreciated. I hope I have just misunderstood or overlooked something and hopefully your response will provide a simple solution which makes me look very foolish :slight_smile:

Ok so it "should" work by sending a buffered RPC call to some function you write to destroy the objects... Sounds like you've tried to do that?

You don't. Have a scene object which acts as a comms hub and takes a parameter that identifies the object to destroy.

While I am vaguely familiar with the concept I don't understand how that will alleviate the buffer issue. I'm not being contrary, I simply don't understand the mechanism. Perhaps you could elaborate a little? Do you mean just use a single networkView on the hub object and serialise everything through that? How would I distinguish between large numbers of similar/identical objects if they don't have a networkView? Thanks for taking the time to discuss this.

I think you don't need NetworkView at all. The problem is when new player connect and level loaded, the scene is loaded with initial state (all non-network-instantiated objects alive). I think you can keep a list of objects to be destroyed, filling this list on server using RPCs from old players during of game, then, when a new player connect, send this list from server to the client and destroy the objects on the list. I didn't test such as way but I see no reasons not to work, juggling with RPCs and methods like OnPlayerConnected() and OnLevelWasLoaded().

Thank you so much whydoidoit and nastasache . You've given excellent and very useful advice here and I'm in the process of putting it into action now that I have a clearer idea of direction. I have some modelling to finish today but I will update when I've got it sorted out (probably tomorrow).

1 Answer

1

Since I have an answer that resolves from several different inputs, I will try to encapsulate the approach I took as an answer.

I used a single networkview on an empty game object and made all destructibles children of that object. I used a dictionary to store references to the destructible objects and also gave them an ID via attached script which matched the index in the dictionary. The result was that I had direct access to the object for both getting (via raycasthit - ID) and setting health (via RPC - index) with no iteration involved.

Destroy was called locally on server with RPC to others. No buffered RPCs required.

Again thanks to those who helped out with most useful guidance.