Author Topic: Instantiate a different Gameobject for Networked Players  (Read 3968 times)

nosyrbllewe

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 1
  • Posts: 11
    • View Profile
Instantiate a different Gameobject for Networked Players
« on: August 18, 2015, 02:20:49 PM »
Hi, I am kind of new to Networking  and I am trying to convert my FPS to multiplayer using TNet. Currently I am stuck in the issue of instantiating the players. For the local player I want to instantiate a full FPS controller, while for the networked players I want to instantiate "dummy" controllers. Using your tutorials, I can get instantiating all of them same type to work, but for obvious reasons, networked players should be not using a first-person rig. So, how can I create a different object depending on if the player is local or not and get it to sync properly? Thanks.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Instantiate a different Gameobject for Networked Players
« Reply #1 on: August 18, 2015, 05:50:30 PM »
You should be instantiating the same thing, just disable sub-components as necessary.

It's most commonly done simply by existing out of your update functions early like so:
  1. void Update ()
  2. {
  3.     if (!tno.isMine) return;
  4.     // Do your stuff
  5. }

nosyrbllewe

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 1
  • Posts: 11
    • View Profile
Re: Instantiate a different Gameobject for Networked Players
« Reply #2 on: August 18, 2015, 09:52:07 PM »
Thanks for your reply, but that is currently what I am doing. To me, it feels a bit messy trying to disable most of the components on a controller. Also, I am using UFPS and for their networking using Photon, they use a simplified controller for all of the networked players and AI (with the local player scripts inheriting from the simplified ones). In testing right now I am using just the Standard Assets controller, disabling components works. But once I switch over to UFPS to actually implement it, many issues will likely appear with using the same prefab.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Instantiate a different Gameobject for Networked Players
« Reply #3 on: August 22, 2015, 02:40:19 AM »
Best practice is not to disable anything. Best practice is to use the early exit like in the example I posted. This gets you into the habit of making your game modular -- so if one player who happens to be controlling the NPC leaves, another player seamlessly takes over controlling its AI (or any other relevant logic) without any extra code on your part. Disabling things is final. It offers no easy way of going back without writing extra code. Early exit approach does, and seamlessly so.

nosyrbllewe

  • Newbie
  • *
  • Thank You
  • -Given: 2
  • -Receive: 1
  • Posts: 11
    • View Profile
Re: Instantiate a different Gameobject for Networked Players
« Reply #4 on: August 23, 2015, 03:37:59 PM »
The way my game works is that your friends join your saved game, so there is no need for another player to become host. Regarding modularity, UFPS already has it down. For example, they use a script such as vp_PlayerDamageHandler that handles base damage handling and is INTENDED for use for networked players. The local player then inherits from this script as vp_FPPlayerDamageHandler. The UFPS team has this working with Photon, so, how can I do it with TNet? They use two prefabs, one for networked players with the base scripts and one for the local player scripts and cameras. How can I instantiate the Networked prefab to work with TNet? You also can't avoid disabling things if you do it your way, as the local First-person controller has two cameras and leaving them be will only cause problems. Furthermore, with over half of the scripts on the local player not needed on the networked players it makes much more sense for them not to even be there and trying to add the tno.isMine check for some scripts is not the best solution due to the inheritance structure. So again, how can I sync two different prefabs with scripts inherited from each other as it is possible?
PS: By networked players I mean the other player prefabs on each players machine. Every player has the First-person scripts for their player on their machine, but has simplified functionality when displayed on other machines.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Instantiate a different Gameobject for Networked Players
« Reply #5 on: August 26, 2015, 11:12:08 AM »
You can't instantiate different prefabs based on whether you're player or host. It's really poor practice to complicate the code that way anyway. Just think future maintenance in mind: you have to maintain two different prefabs now and make sure they are updated at the same time instead of just one prefab. What if some new guy comes aboard and doesn't know about the two prefabs, and only updates one? Suddenly you've got issues. It's much easier if you only have one thing to work with.

In the example you mentioned where the local player has to inherit from a specific script to get this working... with TNet you don't need to inherit from a specific script. You just write your code so that parts of it will run and others won't, depending on whether you own the object or not (tno.isMine if your script inherits from TNBehaviour, GetComponent<TNObject>().isMine otherwise).

Seems to me your difficulty lies in the fact that the script you're working with was written with rather specific usage in mind. TNet is easier to work with, but it does tend to have a slightly different approach. If you're used to working with something else, your knowledge often does more harm than good when it comes to learning TNet.

Sounds to me like the easiest approach for you will be to write a script that will selectively disable components attached to the object (or maybe the opposite -- enable them) based on whether the object is yours or not.
  1. void Start ()
  2. {
  3.     if (tno.isMine) GetComponent<SomeScript>().enabled = true;
  4. }