Client Playerobject Sync Issue

Hi,

I’m comparatively new to Unity still, but seem to be muddling through without too much issue. I have however come across one particularly infuriating issue I’m finding myself unable to resolve.

I have a player prefab object that gets spawned into the world when a new player joins the game. The issue is that client-controlled prefabs, aren’t sending their position to the server.

The server host’s player object is correctly synced.
Any additional clients created on the host machine are also synced.
3rd party clients (on different machines) can see and follow the host objects without issue and see the game correctly.
No-one else can see the movement of these 3rd party playerobjects.

I really am at a loss as to why a client on the same machine as the host (aka 2 copies of the game) works, but a separate machine does not.

To move the player, I’m using the standard transform command after checking for isLocalPlayer. There are no errors in compiling.

To sync the objects, they have the network transform and network identity as below:

Any ideas or assistance would be greatly appreciated!

For completeness sake, here’s the movement control code:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class characterController : NetworkBehaviour {

public float speed = 10.0F;
float lastJump = 0.0F;
public Texture2D crosshair;

public Transform cubetemplate;

public console console;

void OnGUI() {

if (!isLocalPlayer) {
return;
}

float xMin = (Screen.width / 2) - (crosshair.width / 2);
float yMin = (Screen.height / 2) - (crosshair.height / 2);

GUI.DrawTexture (new Rect (xMin, yMin, crosshair.width, crosshair.height), crosshair);

}

void Start () {
Cursor.lockState = CursorLockMode.Locked;
if (!isLocalPlayer) {
Destroy(transform.GetComponentInChildren ());
Destroy(transform.GetComponentInChildren ());
}
}

void Update () {
if (!isLocalPlayer || console.InputEnabled) {
return;
}
float translation = Input.GetAxis (“Vertical”) * speed;
float straffe = Input.GetAxis (“Horizontal”) * speed;
float jump = Input.GetAxis (“Jump”);
translation *= Time.deltaTime;
straffe *= Time.deltaTime;

Rigidbody rb = GetComponent ();

rb.position = rb.position + transform.TransformDirection (new Vector3(straffe, 0, translation));

if (Input.GetKeyDown (“`”)) {
Cursor.lockState = CursorLockMode.None;
}

if (jump > 0 && lastJump == 0) {
RaycastHit hit;
if (Physics.SphereCast (transform.position, 0.5f, -transform.up, out hit, 1.2f)) {
if (rb.velocity.y * rb.velocity.y / 2 < 2) {
rb.AddForce (transform.up * 7, ForceMode.Impulse);
}
}
}
lastJump = jump;
}

//additional non-movement based code
}

NetworkTransform only syncs positions from the server to the clients. So if your clients are locally moving their objects, but you are not then pushing that back up to the server, no one is going to see it. You might want to just send the move commands to the server and do all the movement there too.

Thank you very much, I’ll give that a shot. After reading the tutorials, it appeared to me that making it a ‘local player authority’ would cause the client who owned it to send the updates, hence the confusion.

The “has authority” thing really means that that object has the authority to send messages to the host/server, via Commands. Non-authoritative objects don’t get to do this.

1 Like

Ah, right, that makes sense. Thank you very much for your assistance!

I’ve implemented a solution that sends updated positions to the server whenever the character moves a certain distance or turns a certain amount and it seems to work great!

Small though the project may be, if interested, you can get to it at Timothy Gentle - Computer Software Expert