Instantiating correct object data for later connections

Options
Hello,

I am currently working with the Unity Plugin, so far I am doing good but I have now a little problem.

I have a scene that is very similar to the "Tutorial 4" of the PUN Guide that I purchased on the asset store :

The game uses "mobs" objects, that each player can attack. Theses objects have a basic AI attached to them.
For instantiation of these AIs, I manually instantiate a prefab and then attach a photon view and a network script to it. I only do that once with the master client, and use a buffered RPCs for later client connections.
It all works well, AIs are instantiated and the master are their owner. Every player that connects to the game can then see and interact with the AI.

But problem : when the AI object changes position, or gets destroyed, or whatever changes of state it encounters, players that connect AFTER this change of state don't get it, they see the object like it was brand new, and just intantiated.

For instance, let's say a player 1 connects to the game, destroy an AI (call it AI1). Every player that is connected during the attack will see the AI1 getting destroyed, no problem.

But, if a player connects afterwards, the AI1 will pop in it's game, it won't be destroyed, causing bugs like nullReferenceExceptions and stuff.

I don't really see how I could solve that easily, I could create some kind of data manager that would store the states and positions of all shared objects, but isn't there a Photon tool that already does that ?

Thank you very much !

Comments

  • Tobias
    Options
    You do use PhotonNetwirk.Instantiate and PhotonNetwork.Destroy?
    The latter is important to use to get rid of destroyed objects.
  • Raphy
    Options
    Hello,

    No I wasn't using it.

    I tried it and it seems kindda better but I am encountering new problems. I am really having a hard time managing the "scene" objects like AIs or collectables : player may not have access to manipulate it because it's not the owner. I tried to manage the object with owner only but then only the owner gets the modifications. And I realized that owner of the AIs were the players, and not the scene, which isn't acceptable.

    So I tried to use "InstantiateSceneObject" method. This gives me 2 new problems :

    - I have trouble manipulating the instantiated objects, for instance changing the transform.parent of an AI doesn't seem to work anymore.
    - The GameManager.Objects list that I used is no longer correct for the clients, so I can't interact with instantiated objects using RPCs.

    Is there some tutorial or documentation explaining the InstantiateSceneObject method and how to use it ? I am really confused.

    Thanks and sorry if my message seems a bit hazy.
  • Tobias
    Options
    If AIs are owned by individual players, then don't use scene objects. Those can only be modified by the current Master Client (who is the owner). If a player instantiates things, she becomes owner and can control an AI.
    Changing ownership is not supported at the moment (as the general case is complicated due to lag and the possibility someone might leave anytime).

    It would help me help you, if I knew a bit better what you need to achieve. At the moment, I only vaguely understand your problems but I'm not sure if it makes sense to solve them or propose a different approach.
  • Hello,

    Indeed my question was lacking of precision, sorry I wrote this a bit in a hurry.

    This is what I want to do :

    Each scene has some evil AIs. These AIs are just bots that every player in the scene can shoot to gain XP and loot, just like in thousands of other games. These AIs must persist and must be controled by the master client (the scene) and not the player.

    This is why I tried to use scene objects. But I am having a lot of troubles using them since I can't find any examples on how to use them :

    -some modifications I make to the scene object after it's instantiation. These modifications work well on the master server (understandable, the master controls the object), but I can't find how to make these modifications apply to the clients.
    For instance, if I just rename the bot : (this script is just executed on the master server)
    if (PhotonNetwork.isMasterClient) {
    newObject = PhotonNetwork.InstantiateSceneObject("Prefabs/Objects/Bots/Bot", pos, rot, 0, null) as GameObject;
    newObject.name = "Bot#"+id1;
    }

    The bot will have the right name on the master server, but on the clients it will be named "Bot (Clone)". I have the same problem when I want to change the transform parent of the object. How can I make this work ? Should I send RPCs to the clients to do this ?


    - This first issue creates another one : how I am supposed to identify or find a SceneObject on a client ? For instance, imagine I am using an RPC to transmit this message "Player 1 attacks Bot 5". Identifying "Player 1" is easy : It's just the sender of the RPC, or I can just use Photon View ID. But how am I supposed to identify "Bot 5" ? My only idea is just to send the Photon View ID of the target, but even with that, I don't know how to relate the in-scene object to this.

    I hope you understand my problems better. I would really love to solve them, since they are blocking part of my development.

    Thanks and have a nice day.
  • Tobias
    Options
    newObject.name is not a networked method. It just locally changes the name.
    You can send RPCs for this but ultimately, the name is not important for the networking of things. We use a viewId in the PhotonViews.

    Bot 5 can be identified with the PhotonView on it. You can find it and then cache the result. Make yourself a list of bots and their PhotonViews. Then you can use their IDs to access the same view on any client.
    Keep in mind: When more than one player shoots a bot, this might be destroyed before the master calculated each hit that it will receive. This way, errors happen saying "shot X didn't find target bot Y". You can work around this simply but you need to know this happens.