Author Topic: Static TNObject IDs  (Read 5074 times)

nicefive

  • Newbie
  • *
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 7
    • View Profile
Static TNObject IDs
« on: February 19, 2017, 03:45:42 AM »
I am new so please appreciate that I am still learning TNet and probably post in the wrong places.  As I am not allowed email the author/seller that I just paid my money to I am posting here for the World to see.

After spending a few days slowly integrating TNet into my game  I have struggled past a number of things including player spawning, and enabling "NoDelay" but the latest and most troublesome is with TNObject IDs for placed objects.

In short, specifying an ID in the editor manually (even with the value slider/warning icon) is not an option.  There are simply too may placed objects scattered over large areas to manage.

I have tried to make a "normalise" editor script to assign IDs and even modify the custom inspector code for TNObject (which could potentially auto assign onPlaced) but the changes are not applied because of "serialization" issues and probably because my objects are prefabs.

Searches indicate that an earlier version of TNet had such a script.

cmifwdll

  • Global Moderator
  • Sr. Member
  • *****
  • Thank You
  • -Given: 0
  • -Receive: 149
  • Posts: 285
  • TNet Alchemist
    • View Profile
Re: Static TNObject IDs
« Reply #1 on: February 20, 2017, 01:51:42 PM »
Only networked objects need a TNObject. Only networked objects that exist in the scene at edit-time need an assigned TNObject.ID.

So only things that move or interact over the network need a TNObject. In most cases these should be instantiated at runtime anyway (using TNManager.Instantiate or whatever it's called nowadays).

If you truly do have this many networked objects at edit-time, you could write a simple editor script:
  1. using UnityEngine;
  2. using UnityEditor;
  3. public class EditorTNIDAssigner
  4. {
  5.     [MenuItem("TNet/Assign IDs")]
  6.     static void AssignIDs()
  7.     {
  8.         int counter = 0;
  9.         Debug.Log("[TNet ID Assigner] iterating selected objects...");
  10.         foreach (GameObject go in Selection.gameObjects)
  11.         {
  12.             TNObject tno = go.GetComponent<TNObject>();
  13.             if (tno == null) continue;
  14.             SerializedObject sObject = new SerializedObject(tno);
  15.             SerializedProperty spropID = sObject.FindProperty("id");
  16.             if (spropID == null)
  17.             {
  18.                 Debug.LogError("Could not find 'id' property on " + go.name);
  19.                 continue;
  20.             }
  21.             spropID.intValue = ++counter;
  22.             sObject.ApplyModifiedProperties();
  23.         }
  24.         Debug.Log("[TNet ID Assigner] Done! Assigned " + counter.ToString() + " ids");
  25.     }
  26. }
  27.  

This script could be modified to remove reliance on Selection.gameObjects. You could also hook this up to AssetModificationProcessor.OnWillSaveAssets to auto-run whenever you save the scene (though I'm not entirely sure if modifications to objects will be saved in this hook, hook may be executed too late).

I am new so please appreciate that I am still learning TNet and probably post in the wrong places.  As I am not allowed email the author/seller that I just paid my money to I am posting here for the World to see.

I don't know why you're not allowed to email. I've found this forum to be a great source of support though. ArenMook replies to PMs on here as well. One of the great things about TNet is the support.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Static TNObject IDs
« Reply #2 on: February 21, 2017, 01:03:27 PM »
I much prefer the forum as my responses here can be googled later, while private PMs and emails can't be. I check the forums as often as I check my emails, and another downside of emails is emails can sometimes be blocked by the target's provider due to an over-eager spam filter.

On the topic though, cmifwdll's suggestion is correct. There is no need to manually assign IDs unless you're creating an entirely static scene where the number of objects will always be static (which in a multiplayer game seems weird). In most cases you should dynamically instantiate objects at run-time using TNManager.Instantiate -- and that takes care of assigning IDs for you automatically so you can focus on your game.

Why do you find yourself assigning all those IDs anyway? How many static objects do you have, and do they all need a unique network ID?

nicefive

  • Newbie
  • *
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Static TNObject IDs
« Reply #3 on: February 22, 2017, 11:49:32 AM »
Hello cmifwdll, thank you for the useful code snippet, I have already adjusted it for all objects but for some reason it cannot find the "id" property, I will look into it further and post the script back here when it is working.

And hello ArenMook, I can see you are busy on here answering almost every question which is great.  The forum thing is a little restrictive as I can't post either your code or ours publicly including screenshots but I generally have no problems using it as long as I don't give too many examples.

I am working on 2 titles, the first game is much smaller and could be ready this year, it is aimed at mobile and is primarily a single player game but with support for MP coop.  There will be lots of NPCs (notably farm animals) which are directly of the gameplay as well as a loads of power ups (mostly coins).  I have a small test map with 78 placed objects and have barely started but there will be plenty of optimisation and net culling to come, it really depends on how TNet performs.

Interestingly the placed power ups could be placed with a spawner script as they may respawn so I could manage here.  The other characters and triggers/switches would need to have IDs entered unless I just instantiate everything on Awake which is longwinded.  It is especially difficult as normally have to click each object and then scroll down part lots of components to see TNObject at the bottom.

I understand that these IDs need to be set at design time as they need to match up and can see potential pitfalls if they were automatic as the same ID could be reassigned after deletion.  On the other hand I find it strange that I am having to type them in when I just expect there to be an automatic option (perhaps I am being unreasonable here).  I duplicate objects all the time too which makes it especially tricky.

The second game is Steam/Desktop/Console targeted and is much bigger.  It can only be described as a combat adventure with interactive vehicles and maps from 1 to 4KM across.  This supports single player and MP modes.

TNet's save feature is amazing, also the general the API is very well made.  I have already created a generic "NetSyncTransform" class with 4 range sliders and basic prediction that I can attach to any dynamic game object (with automatic RB detection if one is present).  As most of the objects don't move much (power ups/animals/non woken enemies) TNet looks just the ticket.  However I really could not possibly manually manage all those IDs so that editor script will sure come in handy but I will be looking carefully to see if I can somehow modify the TNObject class to auto-assign on placement.







nicefive

  • Newbie
  • *
  • Thank You
  • -Given: 3
  • -Receive: 0
  • Posts: 7
    • View Profile
Re: Static TNObject IDs
« Reply #4 on: February 22, 2017, 01:17:58 PM »
I said I would post when I got the code working to generate static tno IDs for all map objects.  This version seems to suit my needs.

  1. using UnityEngine;
  2. using UnityEditor;
  3. using TNet;
  4.  
  5. public class EditorTNIDAssigner
  6. {
  7.     [MenuItem("TNet/Assign IDs")]
  8.     static void AssignIDs()
  9.     {
  10.         int counter = 0;
  11.         Debug.Log("[TNet ID Assigner] iterating selected objects...");
  12.  
  13.         GameObject[] gameObjects = GameObject.FindObjectsOfType<GameObject>();
  14.         foreach (GameObject go in gameObjects)
  15.         {
  16.             TNObject tno = go.GetComponent<TNObject>();
  17.  
  18.             if (tno == null)
  19.                 continue;
  20.  
  21.             if (tno.parent != null)
  22.                 continue;
  23.  
  24.             SerializedObject sObject = new SerializedObject(tno);
  25.             SerializedProperty spropID = sObject.FindProperty("mStaticID");
  26.             if (spropID == null)
  27.             {
  28.                 Debug.LogError("Could not find 'id' property on " + tno.gameObject.name);
  29.                 continue;
  30.             }
  31.             spropID.intValue = ++counter;
  32.             sObject.ApplyModifiedProperties();
  33.         }
  34.         Debug.Log("[TNet ID Assigner] Done! Assigned " + counter.ToString() + " ids");
  35.     }
  36. }

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Static TNObject IDs
« Reply #5 on: February 24, 2017, 08:54:40 AM »
Note that you can do FindObjectsOfType<TNObject>() to avoid looping through all the game objects.

I'll add a button to inspector for TNObject to make this easier.