Sunday, July 1, 2012

Unity Scripts & Game Objects

Unity is a powerful game engine that caters to the needs of programmers of any skill level. Its ability to create object prefabs and graphically place them using the Unity Editor is arguably the most used feature. There is another way, however, to place objects in a scene: via a script. In this post I'll discuss how to use Smart Fox Server and Unity to create a player object and update there locations.

If you've been reading this blog from the first post, then you already have a basic understanding of how to develop an infrastructure for your multiplayer game. You've looked closely at the First Person Shooter example for Unity available here http://docs2x.smartfoxserver.com/ExamplesUnity/fps and you understand that by creating a custom extension you can allow the server to correspond with your game.

To get things running, attach Network Manager and Player Manager as components of the main camera in your game scene. You should have a login scene that that connects the user to the zone and room, and that scene will then save the connection into the static class SmartFoxConnection and load your game scene.

Most games that you have developed probably have the player already added into the scene. The challenge of creating a networked, multiplayer game is that no character should already be in the scene. Rather, when the Unity client starts the game scene, it sends a request to the server extension to create that player on their client and every other client connected to the same room.

In my previous post I discussed the different classes that you will need to develop in Unity. Another important aspect is to create player prefab objects. For the most basic implementation, you'll want two kinds of objects in Player Manager. Create two prefabs: myPlayer and otherPlayer. Add the character controllers and animations as you normally would to a character. On the otherPlayer prefab, make sure to remove any code that would respond to input from the user's keyboard. Instead, you want to add a Network Transform Receiver script onto that prefab.  Then, add NetworkTransformSender.cs to the otherPlayer prefab. You'll need to have this code in your Player Manager and save.
public GameObject playerPrefab;
public GameObject guestPrefab;
Then, look at your main camera in the Unity property inspector. You'll see these two objects by the Player Manager script that you added to the camera. Click the small circle to the right of playerPrefab and select your myPlayer prefab. Then, do the same for guestPrefab except select the otherPlayer prefab. Use any naming convention you like, just make sure it's obvious which is which.

Make sure you've followed the guidlines of the FPS demo and enabled UDP. The game sends user transforms with UDP because it is much faster and, though less reliable than TCP, UDP will function well enough for sending transforms.

//SendTransform is a function in NetworkManager.cs
public void SendTransform(NetworkTransform nTransform)
{
 Room room = smartFox.LastJoinedRoom;
 ISFSObject data = new SFSObject();
 nTransform.ToSFSObject(data);
 // True flag = UDP
 ExtensionRequest request = 
  new ExtensionRequest("sendTransform", data, room, true);
 smartFox.Send(request);
}

Let's explore the code in the picture above. Send Transform is called in the SendTransformHandler after each period of time as set by the sendingPeriod variable. When called, it determines the client's current room and serializes the transform in an ISFSObject (used to efficiently transmit data across the network). Then it creates a new Extension Request which it labels "sendTransform". You might recall the init function in your extension.java file has the line addRequestHandler("sendTransform", SendTransformHandler.class) So, when this request reaches the server the SendTransformHandler.class is called and will in turn send a request back to all the other clients.

Adding the data variable to request is self-explanatory. The room specifies the exact room to target, however, it also limits your extension to only function as a room extension and NOT as a zone extension (otherwise to transmit to the zone, replace room with false). Last but not least is the value true. This means that this request will be transmitted using UDP.  So make sure that somwhere in the login script that connects to your server you have called this function:  smartFox.InitUDP(serverName, serverPort) or the UDP request will not transfer.

Finally, in Player Manager you will need to maintain a dictionary of all the otherPlayer Game Objects and Network Transform Receivers in order to manage each of their locations.Once you've created them, you'll want functions like these in your Player Manager class. Creating your SpawnPlayer class does not require a dictionary, and I will leave creating it as an exercise for you to figure out on your own. One thing I haven't figured out yet is how to have the main camera target the transform of your player object after it has been created.  But, this is how you can manage all the other players.

public void SpawnGuest(int id, NetworkTransform nTransform, string name)
{
 GameObject guestObj = GameObject.Instantiate(guestPrefab) as GameObject;
 guestObj.transform.position = ntransform.Position;
 guestObj.transform.localEulerAngles = ntransform.AngleRotationCC;
 
 guests.Add(id, guestObjt);
 receivers.Add(id, guests[id].GetComponent());
}

public NetworkTransformReceiver GetRecipient(int id)
{
 if(guests.ContainsKey(id)
 {
  return receivers[id];
 }
 
 return null;
}

Feel free to leave me a comment or contact me through www.GuitarRpg.com

No comments:

Post a Comment