- Home /
Smartfox Multiplayer Update problem
I'm not 100% sure if this is the right place for this, but here goes: My team are on a Senior project and have to present soon. The problem is when another person connects to the server, the position of them is not updated. Here are the relevanet scripts: The Game manager
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Sfs2X;
using Sfs2X.Core;
using Sfs2X.Entities;
using Sfs2X.Entities.Data;
using Sfs2X.Entities.Variables;
using Sfs2X.Requests;
using Sfs2X.Logging;
public class GameManager : MonoBehaviour {
//----------------------------------------------------------
// Setup variables
//----------------------------------------------------------
public GameObject[] playerModels;
public Material[] playerMaterials;
public LogLevel logLevel = LogLevel.DEBUG;
// Internal / private variables
private SmartFox smartFox;
private GameObject localPlayer;
private PlayerController localPlayerController;
private PlayerController localPlayerController2;
private Dictionary<SFSUser, GameObject> remotePlayers = new Dictionary<SFSUser, GameObject>();
//----------------------------------------------------------
// Unity callbacks
//----------------------------------------------------------
void Start() {
if (!SmartFoxConnection.IsInitialized) {
Application.LoadLevel("Connection");
return;
}
smartFox = SmartFoxConnection.Connection;
// Register callback delegates
smartFox.AddEventListener(SFSEvent.OBJECT_MESSAGE, OnObjectMessage);
smartFox.AddEventListener(SFSEvent.CONNECTION_LOST, OnConnectionLost);
smartFox.AddEventListener(SFSEvent.USER_VARIABLES_UPDATE, OnUserVariableUpdate);
smartFox.AddEventListener(SFSEvent.USER_EXIT_ROOM, OnUserExitRoom);
smartFox.AddEventListener(SFSEvent.USER_ENTER_ROOM, OnUserEnterRoom);
smartFox.AddLogListener(logLevel, OnDebugMessage);
// Start this clients avatar and get cracking!
int numModel = UnityEngine.Random.Range(0, playerModels.Length);
int numMaterial = UnityEngine.Random.Range(0, playerMaterials.Length);
SpawnLocalPlayer(numModel, numMaterial);
}
void FixedUpdate() {
if (smartFox != null) {
smartFox.ProcessEvents();
/*
// If we spawned a local player, send position if movement is dirty
if (localPlayer != null && localPlayerController != null && localPlayerController.MovementDirty)
{
List<UserVariable> userVariables = new List<UserVariable>();
userVariables.Add(new SFSUserVariable("x", (double)localPlayer.transform.position.x));
userVariables.Add(new SFSUserVariable("y", (double)localPlayer.transform.position.y));
userVariables.Add(new SFSUserVariable("z", (double)localPlayer.transform.position.z));
userVariables.Add(new SFSUserVariable("rot", (double)localPlayer.transform.rotation.eulerAngles.y));
smartFox.Send(new SetUserVariablesRequest(userVariables));
localPlayerController.MovementDirty = false;
}
*/
if (localPlayer != null && localPlayer.GetComponent<VehicleControlPhysics>().MovementDirty)
{
Debug.Log("Updateing Postion");
List<UserVariable> userVariables = new List<UserVariable>();
userVariables.Add(new SFSUserVariable("x", (double)localPlayer.rigidbody.position.x));
userVariables.Add(new SFSUserVariable("y", (double)localPlayer.rigidbody.position.y));
userVariables.Add(new SFSUserVariable("z", (double)localPlayer.rigidbody.position.z));
smartFox.Send(new SetUserVariablesRequest(userVariables));
}
}
}
void OnApplicationQuit() {
// Before leaving, lets notify the others about this client dropping out
RemoveLocalPlayer();
}
//----------------------------------------------------------
// SmartFox callbacks
//----------------------------------------------------------
public void OnUserExitRoom(BaseEvent evt) {
// Someone left - lets make certain they are removed if they didnt nicely send a remove command
SFSUser user = (SFSUser)evt.Params["user"];
RemoveRemotePlayer(user);
}
public void OnUserEnterRoom(BaseEvent evt) {
// User joined - and we might be standing still (not sending position info). So lets send him our position info
if (localPlayer != null)
{
List<UserVariable> userVariables = new List<UserVariable>();
userVariables.Add(new SFSUserVariable("x", (double)localPlayer.transform.position.x));
userVariables.Add(new SFSUserVariable("y", (double)localPlayer.transform.position.y));
userVariables.Add(new SFSUserVariable("z", (double)localPlayer.transform.position.z));
userVariables.Add(new SFSUserVariable("rot", (double)localPlayer.transform.rotation.eulerAngles.y));
userVariables.Add(new SFSUserVariable("model", smartFox.MySelf.GetVariable("model").GetIntValue()));
userVariables.Add(new SFSUserVariable("mat", smartFox.MySelf.GetVariable("mat").GetIntValue()));
smartFox.Send(new SetUserVariablesRequest(userVariables));
}
}
public void OnConnectionLost(BaseEvent evt) {
// Reset all internal states so we kick back to login screen
smartFox.RemoveAllEventListeners();
Application.LoadLevel("Connection");
}
public void OnObjectMessage(BaseEvent evt) {
// The only messages being send around are
// - a remove message from someone that is dropping out
ISFSObject dataObj = (SFSObject)evt.Params["message"];
SFSUser sender = (SFSUser)evt.Params["sender"];
if (dataObj.ContainsKey("cmd")) {
switch (dataObj.GetUtfString("cmd")) {
case "rm":
Debug.Log("Removing player unit " + sender.Id);
RemoveRemotePlayer(sender);
break;
}
}
}
public void OnUserVariableUpdate(BaseEvent evt) {
// When user variable is updated on any client, then this callback is being received
// This is where most of the magic happens
ArrayList changedVars = (ArrayList)evt.Params["changedVars"];
SFSUser user = (SFSUser)evt.Params["user"];
if (user == smartFox.MySelf) return;
if (!remotePlayers.ContainsKey(user)) {
// New client just started transmitting - lets create remote player
Vector3 pos = new Vector3(0, 1, 0);
if (user.ContainsVariable("x") && user.ContainsVariable("y") && user.ContainsVariable("z")) {
pos.x = (float)user.GetVariable("x").GetDoubleValue();
pos.y = (float)user.GetVariable("y").GetDoubleValue();
pos.z = (float)user.GetVariable("z").GetDoubleValue();
}
float rotAngle = 0;
if (user.ContainsVariable("rot")) {
rotAngle = (float)user.GetVariable("rot").GetDoubleValue();
}
int numModel = 0;
if (user.ContainsVariable("model")) {
numModel = user.GetVariable("model").GetIntValue();
}
int numMaterial = 0;
if (user.ContainsVariable("mat")) {
numMaterial = user.GetVariable("mat").GetIntValue();
}
SpawnRemotePlayer(user, numModel, numMaterial, pos, Quaternion.Euler(0, rotAngle, 0));
}
// Check if the remote user changed his position or rotation
if (changedVars.Contains("x") && changedVars.Contains("y") && changedVars.Contains("z") && changedVars.Contains("rot")) {
// Move the character to a new position...
remotePlayers[user].GetComponent<SimpleRemoteInterpolation>().SetTransform(
new Vector3((float)user.GetVariable("x").GetDoubleValue(), (float)user.GetVariable("y").GetDoubleValue(), (float)user.GetVariable("z").GetDoubleValue()),
Quaternion.Euler(0, (float)user.GetVariable("rot").GetDoubleValue(), 0),
true);
}
// Remote client got new name?
if (changedVars.Contains("name")) {
remotePlayers[user].GetComponentInChildren<TextMesh>().text = user.Name;
}
// Remote client selected new model?
if (changedVars.Contains("model")) {
SpawnRemotePlayer(user, user.GetVariable("model").GetIntValue(), user.GetVariable("mat").GetIntValue(), remotePlayers[user].transform.position, remotePlayers[user].transform.rotation);
}
// Remote client selected new material?
if (changedVars.Contains("mat")) {
remotePlayers[user].GetComponentInChildren<Renderer>().material = playerMaterials[ user.GetVariable("mat").GetIntValue() ];
}
}
public void OnDebugMessage(BaseEvent evt) {
string message = (string)evt.Params["message"];
Debug.Log("[SFS DEBUG] " + message);
}
//----------------------------------------------------------
// Public interface methods for GUI
//----------------------------------------------------------
public void ChangePlayerMaterial(int numMaterial) {
localPlayer.GetComponentInChildren<Renderer>().material = playerMaterials[numMaterial];
List<UserVariable> userVariables = new List<UserVariable>();
userVariables.Add(new SFSUserVariable("mat", numMaterial));
smartFox.Send(new SetUserVariablesRequest(userVariables));
}
public void ChangePlayerModel(int numModel) {
SpawnLocalPlayer(numModel, smartFox.MySelf.GetVariable("mat").GetIntValue() );
}
//----------------------------------------------------------
// Private player helper methods
//----------------------------------------------------------
private void SpawnLocalPlayer(int numModel, int numMaterial) {
Vector3 pos;
Quaternion rot;
// See if there already exists a model - if so, take its pos+rot before destroying it
if (localPlayer != null) {
pos = localPlayer.transform.position;
rot = localPlayer.transform.rotation;
Camera.main.transform.parent = null;
Destroy(localPlayer);
} else {
pos = new Vector3(58, 2, 52);
rot = Quaternion.identity;
}
// Lets spawn our local player model
localPlayer = GameObject.Instantiate(playerModels[numModel]) as GameObject;
localPlayer.transform.position = pos;
localPlayer.transform.rotation = rot;
// Assign starting material
localPlayer.GetComponentInChildren<Renderer>().material = playerMaterials[numMaterial];
// Since this is the local player, lets add a controller and fix the camera
//localPlayer.AddComponent<VehicleControlPhysics>();
//localPlayer.AddComponent<Rigidbody>();
//localPlayerController2 = localPlayer.GetComponent<VehicleControlPhysics>();
Camera.mainCamera.GetComponent<CarCamera>().target = localPlayer.transform;
localPlayer.GetComponentInChildren<TextMesh>().text = smartFox.MySelf.Name;
Camera.main.transform.parent = localPlayer.transform;
// Lets set the model and material choice and tell the others about it
List<UserVariable> userVariables = new List<UserVariable>();
userVariables.Add(new SFSUserVariable("model", numModel));
userVariables.Add(new SFSUserVariable("mat", numMaterial));
smartFox.Send(new SetUserVariablesRequest(userVariables));
}
private void SpawnRemotePlayer(SFSUser user, int numModel, int numMaterial, Vector3 pos, Quaternion rot) {
// See if there already exists a model so we can destroy it first
if (remotePlayers.ContainsKey(user) && remotePlayers[user] != null) {
Destroy(remotePlayers[user]);
remotePlayers.Remove(user);
}
// Lets spawn our remote player model
GameObject remotePlayer = GameObject.Instantiate(playerModels[numModel]) as GameObject;
remotePlayer.AddComponent<SimpleRemoteInterpolation>();
remotePlayer.GetComponent<SimpleRemoteInterpolation>().SetTransform(pos, rot, false);
// Color and name
remotePlayer.GetComponentInChildren<TextMesh>().text = user.Name;
remotePlayer.GetComponentInChildren<Renderer>().material = playerMaterials[numMaterial];
// Lets track the dude
remotePlayers.Add(user, remotePlayer);
}
private void RemoveLocalPlayer() {
// Someone dropped off the grid. Lets remove him
SFSObject obj = new SFSObject();
obj.PutUtfString("cmd", "rm");
smartFox.Send(new ObjectMessageRequest(obj, smartFox.LastJoinedRoom));
}
private void RemoveRemotePlayer(SFSUser user) {
if (user == smartFox.MySelf) return;
if (remotePlayers.ContainsKey(user)) {
Destroy(remotePlayers[user]);
remotePlayers.Remove(user);
}
}
}
The car movement
using UnityEngine; using System.Collections;
public class VehicleControlPhysics : MonoBehaviour {
public WheelCollider frontWheel1;
public WheelCollider frontWheel2;
public WheelCollider rearWheel1;
public WheelCollider rearWheel2;
public Transform wheelFL;
public Transform wheelFR;
public Transform wheelRL;
public Transform wheelRR;
public float steer_max = 10;
public float motor_max = 20;
public float brake_max = 150;
public AudioClip EngineSound;
public float EngineSoundVolume = 0.5f;
private AudioSource EngineAudio;
private float steer = 0;
private float forward = 0;
private float back = 0;
private float motor = 0;
private float brake = 0;
private bool reverse = false;
private float speed = 0;
public bool MovementDirty {get; set;}
// Initialization
void Start () {
MovementDirty=false;
rigidbody.centerOfMass = new Vector3(0f, -0.05f, 0f);
EngineAudio = gameObject.AddComponent();
EngineAudio.clip = EngineSound;
EngineAudio.loop = true;
EngineAudio.playOnAwake = true;
EngineAudio.volume = EngineSoundVolume;
}
void Update () {
// float carSpeed = rigidbody.velocity.magnitude; // float carSpeedFactor = Mathf.Clamp01(carSpeed / 10); // EngineAudio.pitch = Mathf.Abs(carSpeedFactor);//.Lerp(0, EngineSoundVolume, carSpeedFactor);
// if(Input.GetKeyDown(KeyCode.UpArrow)){ //
// EngineAudio.Play(); // float carSpeed = rigidbody.velocity.sqrMagnitude; // float carSpeedFactor = Mathf.Clamp01(carSpeed / 10); // EngineAudio.pitch = Mathf.Abs(carSpeedFactor / motor_max) + 1.0f; // } //
// if(Input.GetKeyUp(KeyCode.UpArrow)){ //
// EngineAudio.Stop(); //
// }
}
void FixedUpdate () {
speed = rigidbody.velocity.sqrMagnitude;
steer = Mathf.Clamp(Input.GetAxis("Horizontal"),-1f, 1f);
forward = Mathf.Clamp(Input.GetAxis("Vertical"), 0f, 1f);
back = -1f * Mathf.Clamp(Input.GetAxis("Vertical"), -1f, 0f);
if(speed <= 1){
if(back > 0){
reverse = true;
}
else if(forward > 0){
// float carSpeed = rigidbody.velocity.sqrMagnitude; // float carSpeedFactor = Mathf.Clamp01(carSpeed / 10); // EngineAudio.pitch = Mathf.Abs(carSpeedFactor / motor_max) + 1.0f; //EngineAudio.pitch = Mathf.Abs(motor / motor_max) + 1.0 ; reverse = false; } //if(forward > 0) { reverse = false; } }
if(reverse) {
motor = -1 * back;
brake = forward;
EngineAudio.pitch = Mathf.Abs(motor / motor_max) + 1.0f ;
MovementDirty=true;
}
else{
motor = forward;
brake = back;
EngineAudio.pitch = Mathf.Abs(motor / motor_max) + 1.0f ;
MovementDirty=true;
}
// Torque for vehicle
rearWheel1.motorTorque = motor_max * motor;
rearWheel2.motorTorque = motor_max * motor;
rearWheel1.brakeTorque = brake_max * brake;
rearWheel2.brakeTorque = brake_max * brake;
// Steering
frontWheel1.steerAngle = steer_max * steer;
frontWheel2.steerAngle = steer_max * steer;
wheelFL.localEulerAngles = new Vector3(90, steer_max * steer * 1.5f, -90);
wheelFR.localEulerAngles = new Vector3(90, steer_max * steer * 1.5f, 90);
// Due to wheel orientations, the direction of rotation has to be
// reversed for the right-hand wheels.
wheelFL.Rotate(0f, frontWheel1.rpm * 4f * Time.fixedTime, 0f);
wheelFR.Rotate(0f, frontWheel2.rpm * -4f * Time.fixedTime, 0f);
wheelRL.Rotate(0f, rearWheel1.rpm * 6f * Time.deltaTime, 0f);
wheelRR.Rotate(0f, rearWheel2.rpm * -6f * Time.deltaTime, 0f);
}
// Speed
void OnGUI(){
GUI.Box(new Rect(0, 100, 200, 50),"km/h: "+rigidbody.velocity.magnitude * 3.6f);
}
}
I am asking the question on the Smartfox server forum there as well. any help would be appreciated!