Let's face it -- sometimes the generic TNManager.Create functions aren't enough. Sometimes it's useful to be able to pass custom data along. For example, creating a unit and wanting to assign its team. With Unity's objects it's easy -- Instantiate returns a game object that you can then modify, but with the creation having to go through proper synchronization, things get... tricky.
Well,
TNet 1.8.0 aims to change that.
Adding a custom creation callback is now as simple as adding a new RFC call. In fact, the syntax is very similar as well.
The first thing you will want to do is to have a
MonoBehaviour script attached to the same game object as your
TNManager, or one of its children. This way TNManager will be able to find the function you are about to add. If you have a
Game Manager, I'd suggest you add the following code there.
If you don't want to add the script under your TNManager, then you will need to register it with the TNManager by calling
TNManager.AddRCCs<YourScriptType>();. TNet will check the script and add all of its RCCs automatically.
Next, add the actual RCC (remote creation call) function to your script. To do that, simply create a prototype for it. The function prototype for it is:
[RCC(#)] GameObject FunctionName (GameObject prefab, ...); -- where "#" is the ID (10 to 255 range, inclusive), and "..." can be your custom parameters -- whatever you want them to be. For example, here's a function that expects a name to be passed along with position and rotation:
[RCC(10)]
static GameObject OnCreate (GameObject prefab, Vector3 pos, Quaternion rot, string unitName)
{
GameObject go = Instantiate(prefab, pos, rot) as GameObject;
go.name = unitName;
return go;
}
Note that the function then returns the game object you've created so that TNet can do some other work with it (namely setting the TNObject IDs, if needed).
The last step is to call the new
TNManager.CreateEx function somewhere. You can call it directly if you wish, but it's probably easier to create a wrapper function for it next to your RCC call and so that it's easy to find later:
static public void Create (GameObject prefab, Vector3 pos, Quaternion rot, string unitName, bool persistent = true)
{
TNManager.CreateEx(10, persistent, prefab, pos, rot, unitName);
}
Note that the first 2 parameters passed to TNManager.CreateEx must be the
ID of your RCC function and the
persistent flag (whether the object will remain behind if the player leaves). The following parameters should match your RCC function's parameters.
As you probably guessed, calling your custom
GameUnitManager.Create(...) function will indeed create your object as if you called TNManager.Create, except that your custom function will be doing the work -- including setting the name of the object.
Here is the complete script, for your convenience:
using UnityEngine;
using TNet;
public class GameUnitManager : MonoBehaviour
{
/// <summary>
/// Step 1: Use this function instead of TNManager.Create when you want to create a new unit.
/// </summary>
static public void Create (GameObject prefab, Vector3 pos, Quaternion rot, string unitName, bool persistent = true)
{
TNManager.CreateEx(10, persistent, prefab, pos, rot, unitName);
}
/// <summary>
/// Step 2: Create a function that will be called when the unit creation packet arrives.
/// Make sure that this script is attached to the same game object as TNManager or one of its children,
/// or that you registered this MonoBehaviour by calling TNManager.AddRCCs!
/// </summary>
[RCC(10)]
static GameObject OnCreate (GameObject prefab, Vector3 pos, Quaternion rot, string unitName)
{
GameObject go = Instantiate(prefab, pos, rot) as GameObject;
go.name = unitName;
return go;
}
}