Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by Fewpwew130 · Feb 03, 2016 at 11:17 AM · arrayorder

[Simple Networking] Remember member order in the array

Hello! I am trying to make a simple networking solution. When a player joins the game he gets put into the spectator array (before he chooses a team). Later when another player joins the same game he should know not only that array has this and that player, but also be able to tell who joined 1st, 2nd and so on.

For example, say 4 players want to join the same room: Player A, B, C and D.

Player D enters first, our spectator array has been created and consists of 1 member so far: spectator.Length = 1 spectator[0] = D

Now another player B joins. The array looks like this: spectator.Length = 2 spectator[0] = D spectator[1] = B

C joins. spectator.Length = 3 spectator[0] = D spectator[1] = B spectator[2] = A

D joins. spectator.Length = 3 spectator[0] = D spectator[1] = B spectator[2] = C spectator[3] = A

This array should be the same across all users. So not only the 1st one who joined is able to tell who joined afterwards, but also people who came in later, can be able to tell precisely not only the content of the array and its length, but also the exact order.

I don't know exactly how to do this. Maybe the logic is flawed, maybe not. This is what I imagine is the right way to it: using RPC:

 using UnityEngine;
 using System.Collections;
 
 public class instantiate_spectator_at_runtime : MonoBehaviour {
 
 
     public GameObject[] spectors;
 
         
         // Use this for initialization
         void Start () {
 
 
         SpawnSpectator ();
         Debug.Log ("We are spectator number: ");
         Debug.Log(spectors.Length);
         }
 
     [RPC]
     void SpawnSpectator(){
         GameObject mySpawnSpot = GameObject.FindGameObjectWithTag ("SpawnSpot");
         GameObject spectator = (GameObject)Instantiate("Spectator_prefab", mySpawnSpot.transform.position, mySpawnSpot.transform.rotation, 0);
         spectator.GetComponent<NetworkView> ();
         NetworkView.RPC("Spectator_prefab", RPCMode.AllBuffered, NetworkViewID, transform.position);
 
         for (int i = 0; i < spectors.Length; i++){
             spectors[i] = this.gameObject;
         }
 
     }
         
 }
 

Can you suggest what is the right way to solve this problem? Thank you very much!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by cjdev · Feb 03, 2016 at 01:17 PM

The problem with an array in this case is that they are of a fixed size. To use one you have to declare how big it is first so that it can allot a portion of memory for it's elements. In order to use a more dynamic storage method you can use a generic List. This is (essentially) a wrapper class around an array of some type T which you specify. The nice thing about it, however, is that you can add items to the list without limitations because the class automatically remakes the array to an appropriate size to store everything needed. This is how it works:

 // using System.Collections.Generic;

 // Instantiate a list with a specific type
 List<GameObject> myList = new List<GameObject>();
 // Add each element to the list, the order is preserved
 myList.Add(nextGameObject);
 // Accessing the elements is just like an array
 GameObject goAtZero = myList[0];
Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Fewpwew130 · Feb 03, 2016 at 01:46 PM 0
Share

First of all, thank you for a quick answer! Second of all, suppose I use List ins$$anonymous$$d of array, how do I tell connected clients to reproduce the same list without some kind of RPC or serialization? Is it possible?

avatar image cjdev · Feb 03, 2016 at 02:08 PM 1
Share

The nice thing about Lists is that they come with a lot of helper methods, one of them being toArray(). So if you need to change a list to an array it's fairly simple, and to go the other way you just have to use the AddRange method.

avatar image Fewpwew130 · Feb 03, 2016 at 02:26 PM 0
Share

Thanks! But I think I am not particularly clear. With your help, I've managed to write a functioning script, but it doesn't do what I intended: using UnityEngine; using System.Collections; using System.Collections.Generic;

 public class instantiate_spectator_at_runtime : $$anonymous$$onoBehaviour {
 
 
 
     public List<GameObject> myList;
 
 
         // Use this for initialization
         void Start () {
 
 
 
         }
 
     void Update () {
 
 
 
         if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.A)) {
             Debug.Log ("Index 1" + myList [0]);
             Debug.Log ("Index 2" + myList [1]);
             Debug.Log ("Index 3" + myList [2]);
             Debug.Log ("Index 4" + myList [3]);
         }
 
         if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.W)) {
             PhotonView photonView = PhotonView.Get(this);
             photonView.RPC("addtolist", PhotonTargets.AllBuffered);
         }
     
     }
 
     [PunRPC]
     public void addtolist(){
         if (myList.Contains(this.gameObject)){
             Debug.Log("it contains");
         }
         else
         myList.Add(this.gameObject);
     }
 
         
 }
 

It creates an array and adds old item to it. So when second player logs in to the server, it already has the 1st player. But it fails to distinguish between those items, when second player tries to add this.gameobject to the array - the array says it already contains it! (since objects are prefabs and are the same for all network clients). $$anonymous$$aybe it is needed to compare via NetworkViewID ?

avatar image cjdev · Feb 03, 2016 at 10:29 PM 1
Share

When you're getting "this" it means a reference to the current Script so each time you get it you're still getting the same thing. I think you want to Instantiate a new GameObject for each player and then put that in the List ins$$anonymous$$d, although I'm not really familiar with the PhotonView API.

avatar image Fewpwew130 cjdev · Feb 04, 2016 at 11:53 AM 0
Share

Fixed! Thanks!

I've wrote another scripts - works almost perfectly, but ins$$anonymous$$d of instantiating spectator prefab once on every client, it instantiates as many times as there are clients.

So if we are the only person on the server it spawns one spectator every time. If there are 2 people connected - every time it spawns 2 on EVERY client, and so on.

I created an object in the scene, gave that object a PhotonView and attached this script. using UnityEngine; using System.Collections; using System.Collections.Generic;

 public class instantiate_spectator_at_runtime : $$anonymous$$onoBehaviour {
 
 
 
     public List<GameObject> myList;
     public PhotonView photonView;
     public GameObject[] spawnSpots;
     public GameObject myPlayerGO;
         // Use this for initialization
 
         void Start () {
         photonView = this.gameObject.GetComponent<PhotonView> ();
         }
 
     void Update () {
 
         if (Input.Get$$anonymous$$eyDown ($$anonymous$$eyCode.W)) {
 
             //spawn spectators for the others clients
             photonView.RPC("addtolist", PhotonTargets.OthersBuffered);
 
             //spawn spectators for our client
             spawnSpots = GameObject.FindGameObjectsWithTag("SpawnSpot");
             GameObject mySpawnSpot = spawnSpots[ Random.Range (0, spawnSpots.Length) ];
             myPlayerGO = (GameObject)PhotonNetwork.Instantiate("spectator", mySpawnSpot.transform.position, mySpawnSpot.transform.rotation, 0);
             myList.Add(myPlayerGO.gameObject);
         }
 
     }
 
     [PunRPC]
     public void addtolist(){
 
         //spawn spectator
         spawnSpots = GameObject.FindGameObjectsWithTag("SpawnSpot");
         GameObject mySpawnSpot = spawnSpots[ Random.Range (0, spawnSpots.Length) ];
         myPlayerGO = (GameObject)PhotonNetwork.Instantiate("spectator", mySpawnSpot.transform.position, mySpawnSpot.transform.rotation, 0);
 
         //add spectator to list
         if (myList.Contains (myPlayerGO.gameObject)) {
 
             for (int i = 0; i < myList.Count; i++){
                 if(myList[i].gameObject.GetComponent<PhotonView>().viewID == myPlayerGO.gameObject.GetComponent<PhotonView>().viewID){
                 Debug.Log("it's the same");
                     PhotonNetwork.Destroy(myPlayerGO);
                     myPlayerGO = null;
                     break;
                 }
                 else
                     myList.Add(myPlayerGO.gameObject);
             }
 
             }
             else
             myList.Add(myPlayerGO.gameObject);
     }
 
         
 }

Is there any idea, how to fix it? And again - thank you for your time and helpful advice.

avatar image cjdev cjdev · Feb 04, 2016 at 01:41 PM 1
Share

Again, I'm not really familiar with the PhotonNetwork stuff but I think the problem might be in this block of code:

 if (myList.Contains (myPlayerGO.gameObject)) {
     for (int i = 0; i < myList.Count; i++){
         if(myList[i].gameObject.GetComponent<PhotonView>().viewID == 
            myPlayerGO.gameObject.GetComponent<PhotonView>().viewID){
             Debug.Log("it's the same");
             PhotonNetwork.Destroy(myPlayerGO);
             myPlayerGO = null;
             break;
         }
         else
         myList.Add(myPlayerGO.gameObject);
     }
 }
 else
     myList.Add(myPlayerGO.gameObject);

It's checking if the GameObject's in the list and then iterating through to see if there's a match in order to destroy it. The problem could be that after destroying it, the loop continues but since the original was destroyed and there's no check for any new ones, the else statement will keep making copies.

avatar image Fewpwew130 cjdev · Feb 04, 2016 at 06:53 PM 0
Share

Thank you again! This is not a complete solution, but I will mark it as an answer, if you change it from a comment.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

42 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Array Order Changes After Build 0 Answers

Spawn prefabs from array in specific order given the size of prefab 1 Answer

Creating an array of objects in the order they are in a folder? 0 Answers

Using arrays of vector3s to avoid new 1 Answer

Texture2D to Plane: Array Index is Out of Range 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges