I have a problem when playing 3D person Shooter project.
I'm playing good when using local IP 127.0.0.1. BUT:
In "login" scene, i use Servername is "113.161.77.183". I nonuse UDP protocol in LoginGUI.cs
I can join the game, i can see Enemy, when enemy move i can see Enemy animated, but transform's Enemy non change.
I change NetworkManager script to:
Code: Select all
public void SendTransform(NetworkTransform ntransform) {
Room room = smartFox.LastJoinedRoom;
ISFSObject data = new SFSObject();
ntransform.ToSFSObject(data);
ExtensionRequest request = new ExtensionRequest("sendTransform", data, room); // True flag = UDP >>>> I remove true flag
smartFox.Send(request);
}
but nothing change.
Here is my code change :
LoginGUI.cs
Code: Select all
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using Sfs2X;
using Sfs2X.Core;
using Sfs2X.Entities;
using Sfs2X.Requests;
using Sfs2X.Logging;
public class LoginGUI : MonoBehaviour {
private SmartFox smartFox;
private bool shuttingDown = false;
public string serverName = "127.0.0.1";
public int serverPort = 9933;
public string zone = "BasicExamples";
public bool debug = true;
public GUISkin sfsSkin;
private string username = "";
private string loginErrorMessage = "";
/************
* Unity callback methods
************/
void OnApplicationQuit() {
shuttingDown = true;
}
void FixedUpdate() {
smartFox.ProcessEvents();
}
void Awake() {
Application.runInBackground = true;
// In a webplayer (or editor in webplayer mode) we need to setup security policy negotiation with the server first
if (Application.isWebPlayer) {
if (!Security.PrefetchSocketPolicy(serverName, serverPort, 500)) {
Debug.LogError("Security Exception. Policy file load failed!");
}
}
if (SmartFoxConnection.IsInitialized) {
smartFox = SmartFoxConnection.Connection;
} else {
smartFox = new SmartFox(debug);
}
// Register callback delegate
smartFox.AddEventListener(SFSEvent.CONNECTION, OnConnection);
smartFox.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
smartFox.AddEventListener(SFSEvent.LOGIN, OnLogin);
//smartFox.AddEventListener(SFSEvent.UDP_INIT, OnUdpInit);
smartFox.AddEventListener(SFSEvent.ROOM_JOIN,OnJoinRoom);
smartFox.AddLogListener(LogLevel.DEBUG, OnDebugMessage);
smartFox.Connect(serverName, serverPort);
}
void OnGUI() {
GUI.skin = sfsSkin;
// Determine which state we are in and show the GUI accordingly
if (smartFox.IsConnected) {
DrawLoginGUI();
}
else {
string message = "Waiting for connection";
if (loginErrorMessage != "") {
message = "Connection error. "+loginErrorMessage;
}
DrawMessagePanelGUI(message);
}
}
/************
* GUI methods
************/
// Generic single message panel
void DrawMessagePanelGUI(string message) {
// Lets just quickly set up some GUI layout variables
float panelWidth = 400;
float panelHeight = 300;
float panelPosX = Screen.width/2 - panelWidth/2;
float panelPosY = Screen.height/2 - panelHeight/2;
// Draw the box
GUILayout.BeginArea(new Rect(panelPosX, panelPosY, panelWidth, panelHeight));
GUILayout.Box ("FPS Example", GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
GUILayout.BeginVertical();
GUILayout.BeginArea(new Rect(20, 25, panelWidth-40, panelHeight-60), GUI.skin.customStyles[0]);
// Center label
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.BeginVertical();
GUILayout.FlexibleSpace();
GUILayout.Label(message);
GUILayout.FlexibleSpace();
GUILayout.EndVertical();
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.EndArea ();
GUILayout.EndVertical();
GUILayout.EndArea ();
}
// Login GUI allowing for username, password and zone selection
private void DrawLoginGUI() {
// Lets just quickly set up some GUI layout variables
float panelWidth = 400;
float panelHeight = 300;
float panelPosX = Screen.width/2 - panelWidth/2;
float panelPosY = Screen.height/2 - panelHeight/2;
// Draw the box
GUILayout.BeginArea(new Rect(panelPosX, panelPosY, panelWidth, panelHeight));
GUILayout.Box ("Login", GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
GUILayout.BeginVertical();
GUILayout.BeginArea(new Rect(20, 25, panelWidth-40, panelHeight-60), GUI.skin.customStyles[0]);
// Lets show login box!
GUILayout.FlexibleSpace();
GUILayout.BeginHorizontal();
GUILayout.Label("Username: ");
username = GUILayout.TextField(username, 25, GUILayout.MinWidth(200));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Server Name: ");
serverName = GUILayout.TextField(serverName, 25, GUILayout.MinWidth(200));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Server Port: ");
serverPort = int.Parse(GUILayout.TextField(serverPort.ToString(), 4, GUILayout.MinWidth(200)));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Invert Mouse Y: ");
OptionsManager.InvertMouseY = GUILayout.Toggle(OptionsManager.InvertMouseY, "");
GUILayout.EndHorizontal();
GUILayout.Label(loginErrorMessage);
// Center login button
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Login") || (Event.current.type == EventType.keyDown && Event.current.character == '\n')) {
Debug.Log("Sending login request");
smartFox.Send(new LoginRequest(username, "", zone));
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
GUILayout.FlexibleSpace();
GUILayout.EndArea ();
GUILayout.EndVertical();
GUILayout.EndArea ();
}
/************
* Helper methods
************/
private void UnregisterSFSSceneCallbacks() {
// This should be called when switching scenes, so callbacks from the backend do not trigger code in this scene
smartFox.RemoveAllEventListeners();
}
/************
* Callbacks from the SFS API
************/
public void OnConnection(BaseEvent evt) {
bool success = (bool)evt.Params["success"];
string error = (string)evt.Params["error"];
Debug.Log("On Connection callback got: " + success + " (error : <" + error + ">)");
loginErrorMessage = "";
if (success) {
SmartFoxConnection.Connection = smartFox;
} else {
loginErrorMessage = error;
}
}
public void OnConnectionLost(BaseEvent evt) {
loginErrorMessage = "Connection lost / no connection to server";
UnregisterSFSSceneCallbacks();
}
public void OnDebugMessage(BaseEvent evt) {
string message = (string)evt.Params["message"];
Debug.Log("[SFS DEBUG] " + message);
}
public void OnLogin(BaseEvent evt) {
bool success = true;
if (evt.Params.Contains("success") && !(bool)evt.Params["success"]) {
// Login failed - lets display the error message sent to us
loginErrorMessage = (string)evt.Params["errorMessage"];
Debug.Log("Login error: "+loginErrorMessage);
} else {
// Startup up UDP
if(smartFox.RoomManager.ContainsRoom("vProject Room"))
{
smartFox.Send(new JoinRoomRequest("vProject Room"));
}else{
RoomSettings settings = new RoomSettings("vProject Room");
//settings.GroupId = "games";
//settings.IsGame = true;
settings.MaxUsers = 40;
//settings.MaxSpectators = 0;
settings.Extension = new RoomExtension(NetworkManager.ExtName, NetworkManager.ExtClass);
smartFox.Send(new CreateRoomRequest(settings, true));
}
Debug.Log("Login ok" + serverName);
smartFox.InitUDP(serverName, serverPort);
}
}
public void OnLoginError(BaseEvent evt){
print ("Login error"+(string)evt.Params["errorMessage"]);
}
public void OnUdpInit(BaseEvent evt) {
// if (evt.Params.Contains("success") && !(bool)evt.Params["success"]) {
// loginErrorMessage = (string)evt.Params["errorMessage"];
// Debug.Log("UDP error: "+loginErrorMessage);
// } else {
// Debug.Log("UDP ok");
//
// On to the lobby
loginErrorMessage = "";
UnregisterSFSSceneCallbacks();
Application.LoadLevel("game");
//}
}
public void OnJoinRoom(BaseEvent evt){
Room room = (Room)evt.Params["room"];
print ("Room "+room.Name+" joined successfully");
Application.LoadLevel("game");
}
}
NetworkManager.cs
Code: Select all
using System;
using System.Collections;
using UnityEngine;
using Sfs2X;
using Sfs2X.Core;
using Sfs2X.Entities;
using Sfs2X.Entities.Data;
using Sfs2X.Requests;
using Sfs2X.Logging;
// The Neywork manager sends the messages to server and handles the response.
public class NetworkManager : MonoBehaviour
{
private bool running = false;
public readonly static string ExtName = "fps"; // The server extension we work with
public readonly static string ExtClass = "dk.fullcontrol.fps.FpsExtension"; // The class name of the extension
private static NetworkManager instance;
public static NetworkManager Instance {
get {
return instance;
}
}
private SmartFox smartFox; // The reference to SFS client
void Awake() {
instance = this;
}
void Start() {
smartFox = SmartFoxConnection.Connection;
if (smartFox == null) {
Application.LoadLevel("login");
return;
}
SubscribeDelegates();
SendSpawnRequest();
TimeManager.Instance.Init();
running = true;
}
// This is needed to handle server events in queued mode
void FixedUpdate() {
if (!running) return;
smartFox.ProcessEvents();
}
private void SubscribeDelegates() {
smartFox.AddEventListener(SFSEvent.EXTENSION_RESPONSE, OnExtensionResponse);
smartFox.AddEventListener(SFSEvent.USER_EXIT_ROOM, OnUserLeaveRoom);
smartFox.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
}
private void UnsubscribeDelegates() {
smartFox.RemoveAllEventListeners();
}
/// <summary>
/// Send the request to server to spawn my player
/// </summary>
public void SendSpawnRequest() {
Room room = smartFox.LastJoinedRoom;
ExtensionRequest request = new ExtensionRequest("spawnMe", new SFSObject(), room);
smartFox.Send(request);
}
/// <summary>
/// Send local transform to the server
/// </summary>
/// <param name="ntransform">
/// A <see cref="NetworkTransform"/>
/// </param>
public void SendTransform(NetworkTransform ntransform) {
Room room = smartFox.LastJoinedRoom;
ISFSObject data = new SFSObject();
ntransform.ToSFSObject(data);
ExtensionRequest request = new ExtensionRequest("sendTransform", data, room); // True flag = UDP
smartFox.Send(request);
}
/// <summary>
/// Send local animation state to the server
/// </summary>
/// <param name="message">
/// A <see cref="System.String"/>
/// </param>
/// <param name="layer">
/// A <see cref="System.Int32"/>
/// </param>
public void SendAnimationState(string message, int layer) {
Room room = smartFox.LastJoinedRoom;
ISFSObject data = new SFSObject();
data.PutUtfString("msg", message);
data.PutInt("layer", layer);
ExtensionRequest request = new ExtensionRequest("sendAnim", data, room);
smartFox.Send(request);
}
/// <summary>
/// Request the current server time. Used for time synchronization
/// </summary>
public void TimeSyncRequest() {
Room room = smartFox.LastJoinedRoom;
ExtensionRequest request = new ExtensionRequest("getTime", new SFSObject(), room);
smartFox.Send(request);
}
/// <summary>
/// When connection is lost we load the login scene
/// </summary>
private void OnConnectionLost(BaseEvent evt) {
UnsubscribeDelegates();
Screen.lockCursor = false;
Screen.showCursor = true;
Application.LoadLevel("login");
}
// This method handles all the responses from the server
private void OnExtensionResponse(BaseEvent evt) {
try {
string cmd = (string)evt.Params["cmd"];
ISFSObject dt = (SFSObject)evt.Params["params"];
if (cmd == "spawnPlayer") {
HandleInstantiatePlayer(dt);
}
else if (cmd == "transform") {
HandleTransform(dt);
}
else if (cmd == "notransform") {
HandleNoTransform(dt);
}
else if (cmd == "anim") {
HandleAnimation(dt);
}
else if (cmd == "time") {
HandleServerTime(dt);
}
}
catch (Exception e) {
Debug.Log("Exception handling response: "+e.Message+" >>> "+e.StackTrace);
}
}
// Instantiating player (our local FPS model, or remote 3rd person model)
private void HandleInstantiatePlayer(ISFSObject dt) {
ISFSObject playerData = dt.GetSFSObject("player");
int userId = playerData.GetInt("id");
int score = playerData.GetInt("score");
NetworkTransform ntransform = NetworkTransform.FromSFSObject(playerData);
User user = smartFox.UserManager.GetUserById(userId);
string name = user.Name;
if (userId == smartFox.MySelf.Id) {
PlayerManager.Instance.SpawnPlayer(ntransform, name);
}
else {
PlayerManager.Instance.SpawnEnemy(userId, ntransform, name);
}
}
// Updating transform of the remote player from server
private void HandleTransform(ISFSObject dt) {
int userId = dt.GetInt("id");
NetworkTransform ntransform = NetworkTransform.FromSFSObject(dt);
if (userId != smartFox.MySelf.Id) {
// Update transform of the remote user object
NetworkTransformReceiver recipient = PlayerManager.Instance.GetRecipient(userId);
if (recipient!=null) {
recipient.ReceiveTransform(ntransform);
}
}
}
// Server rejected transform message - force the local player object to what server said
private void HandleNoTransform(ISFSObject dt) {
int userId = dt.GetInt("id");
NetworkTransform ntransform = NetworkTransform.FromSFSObject(dt);
if (userId == smartFox.MySelf.Id) {
// Movement restricted!
// Update transform of the local object
ntransform.Update(PlayerManager.Instance.GetPlayerObject().transform);
}
}
// Synchronize the time from server
private void HandleServerTime(ISFSObject dt) {
long time = dt.GetLong("t");
TimeManager.Instance.Synchronize(Convert.ToDouble(time));
}
// Handle player killed
// Synchronizing remote animation
private void HandleAnimation(ISFSObject dt) {
int userId = dt.GetInt("id");
string msg = dt.GetUtfString("msg");
int layer = dt.GetInt("layer");
if (userId != smartFox.MySelf.Id) {
PlayerManager.Instance.SyncAnimation(userId, msg, layer);
}
}
// When someone reloaded the weapon - play corresponding animation
private void HandleReload(ISFSObject dt) {
int userId = dt.GetInt("id");
if (userId != smartFox.MySelf.Id) {
SoundManager.Instance.PlayReload(PlayerManager.Instance.GetRecipient(userId).audio);
PlayerManager.Instance.SyncAnimation(userId, "Reload", 1);
}
else {
GameObject obj = PlayerManager.Instance.GetPlayerObject();
if (obj == null) return;
SoundManager.Instance.PlayReload(obj.audio);
obj.GetComponent<AnimationSynchronizer>().PlayReloadAnimation();
}
}
// When a user leaves room destroy his object
private void OnUserLeaveRoom(BaseEvent evt) {
User user = (User)evt.Params["user"];
Room room = (Room)evt.Params["room"];
PlayerManager.Instance.DestroyEnemy(user.Id);
Debug.Log("User "+user.Name+" left");
}
void OnApplicationQuit() {
UnsubscribeDelegates();
}
}
So, How to SynchronizerTransform when i playing game on Internet? What is wrong in my code?
Thanks
Deviros