Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Syncing custom list

Discussion in 'Multiplayer' started by Vedrit, May 21, 2016.

  1. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Hi all, I'm hoping this will be a better place to find help than in the scripting section;
    I've set up a custom list
    Code (csharp):
    1.  
    2. public class ItemList {
    3.  
    4.     public string itemName { get; set; }
    5.     public int typeID { get; set; }
    6.     public int modification1 { get; set; }
    7.     public float mod1Effect { get; set; }
    8.     public int modification2 { get; set; }
    9.     public float mod2Effect { get; set; }
    10.     public int modification3 { get; set; }
    11.     public float mod3Effect { get; set; }
    12.     public float tier { get; set; }
    13.     public int stackCount { get; set; }
    14. }
    And I'm needing to sync an instance of this so it's consistent for all connected players, but I can't seem to figure it out and there isn't a whole lot of relevant information in the docs.
     
    Last edited: May 21, 2016
  2. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Any suggestions?
     
  3. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Please, some help is needed.
     
  4. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Is it even possible to sync a user-defined list?
     
  5. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    If the instance is immutable, you can use SyncListStruct. Otherwise you'll need to handle the syncing yourself
     
  6. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    I don't know what is meant by "immutable"
     
  7. Oshroth

    Oshroth

    Joined:
    Apr 28, 2014
    Posts:
    99
    Immutable means it doesn't change, i.e. you set the initial values and then you don't change them
     
  8. JasonT2012

    JasonT2012

    Joined:
    May 4, 2016
    Posts:
    5
    I have yet to find a good example of SyncListStruct being used. Can anyone provide one? They seem like they would be really useful for syncing larger amounts of data than SyncVars.

    The problem I had was understanding how I can access their elements and use them, modify an element etc.
     
  9. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    I've only started experimenting with SyncListStruct, but here's how I got things to not give errors... Not tested, so not 100% it'll work, but... No errors is progress.

    Code (csharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.Networking;
    4.  
    5. public class listTest : NetworkBehaviour
    6. {
    7.   public struct listOfItems
    8.   {
    9.     public string itemName { get; set; }
    10.     public int typeID { get; set; }
    11.     public int modification1 { get; set; }
    12.     public float mod1Effect { get; set; }
    13.     public int modification2 { get; set; }
    14.     public float mod2Effect { get; set; }
    15.     public int modification3 { get; set; }
    16.     public float mod3Effect { get; set; }
    17.     public float tier { get; set; }
    18.     public int stackCount { get; set; }
    19.   }
    20.   public class SyncListItemList : SyncListStruct<listOfItems> { }
    21.   public SyncListItemList storedItems = new SyncListItemList();
    22.  
    23. //Other stuff that this script does
    24. }
     
    Last edited: May 24, 2016
  10. JasonT2012

    JasonT2012

    Joined:
    May 4, 2016
    Posts:
    5
    Thanks Vedrit. It would be interesting to follow your progress on this.

    I am just reworking my network code on my project. The project is a simulator and has a requirement to sync a lot of data so I'm keen to get my head around sync lists.
     
  11. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Glad to know I'm not the only one having issues with SyncLists.
    I'm having issues of retrieving information from it by a different script... I can get information from the list if I do something like this
    Code (csharp):
    1. void Update()
    2.     {
    3.         if(Input.GetKey(KeyCode.K) && Input.GetKey(KeyCode.I))
    4.         {
    5.             for (var i = 0; i < storedItems.Count; i++)
    6.             {
    7.                 print("Item " + i + " is " + storedItems[i].itemName);
    8.             }
    9.         }
    10.     }
    But if I try that from any other script, I get nothing no matter how many items have been added to the list.

    Edit: I did some fiddling and when I expressly state which item I am trying to get info when doing a print or debug command from another script, then I can get the info, but not when I iterate through in a for loop. I'll try and look into it more tomorrow, since it's late as of this edit and I need to sleep.
     
    Last edited: May 24, 2016
  12. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Alright, so I don't know why it wasn't working last night. I know part of the problem I was experiencing was, for some reason, my script wasn't instantiating an object. But I've got everything working now.
    Don't forget that you'll need to have any changes to the SyncList done via commands. Here's what I've got
    (Because of my setup, the script with the list is separate but a component of whatever object the list is for) buildingStorage script
    Code (csharp):
    1.  
    2. using UnityEngine.Networking;
    3.  
    4. public class buildingStorage : NetworkBehaviour {
    5.  
    6.     public struct listOfItems
    7.     {
    8.         public string itemName { get; set; }
    9.         public int typeID { get; set; }
    10.         public int modification1 { get; set; }
    11.         public float mod1Effect { get; set; }
    12.         public int modification2 { get; set; }
    13.         public float mod2Effect { get; set; }
    14.         public int modification3 { get; set; }
    15.         public float mod3Effect { get; set; }
    16.         public float tier { get; set; }
    17.         public int stackCount { get; set; }
    18.     }
    19.     public class SyncItemList : SyncListStruct<listOfItems> { }
    20.     public SyncItemList storedItems = new SyncItemList();
    21. }
    Portion of the playerCommands script (where I put all of my client-side commands) as it relates to adding to the SyncList
    Code (csharp):
    1. [Command]
    2. public void CmdAddItem (GameObject objectWList, buildingStorage.listOfItems item)
    3. {
    4.     buildingStorage list = objectWList.GetComponent<buildingStorage>();
    5.     list.storedItems.Add(item);
    6. }
    Portion of the script player interacts with to add an item
    Code (csharp):
    1. if(buildingInv.GetComponent<SmallPlot>() != null)
    2. {
    3.     buildingStorage.listOfItems addedItem = new buildingStorage.listOfItems { itemName = newItemInfo.itemName, mod1Effect = newItemInfo.mod1Effect, typeID = newItemInfo.typeID, modification1 = newItemInfo.modification1, mod2Effect = newItemInfo.mod2Effect, mod3Effect = newItemInfo.mod3Effect, tier = newItemInfo.tier, stackCount = newItemInfo.stackCount, modification2 = newItemInfo.modification2, modification3 = newItemInfo.modification3 };
    4.     buildingInv.GetComponent<SmallPlot>().plyrCmds.CmdAddItem(buildingInv.gameObject, addedItem);
    5. }
    It really is similar to regular lists, just a couple extra hoops you have to jump through (And should be re-iterated in the docs regarding SyncLists)
    I hope this helps any other lost souls
     
    Last edited: May 25, 2016
  13. DRRosen3

    DRRosen3

    Joined:
    Jan 30, 2014
    Posts:
    683
    It seems like you're confused as to how anything "Sync____" works. Whether it be a SyncVar or a SyncListInt or a SyncListStruct, etc...etc... the server is in control of what happens to that Sync____. Because of this, if the player wants to make a change to the Sync___, yes, there would have to be a Command to be sent to the server requesting the change. However, ALL changes do not have to be made via commands. There can be code that exists to only function on the server that makes changes. For example, there could be a box on the ground that has a script on it with an OnTriggerEnter function that is set up to only execute on the server. When the player enters the trigger, the contents of that box are added to their inventory...a SyncList of some kind. Hope this clears things up for you.