NetCode for Game Objects returns GameObject after I move it in script

Multiplayer works in my driving game, except:

When I spawn or reset a vehicle, or try to move the GameObject through transform.position or networkTransform.position, the vehicle jumps to the position but on the very next frame returns to where it was.

I’m trying to update the network position so that it stays where I moved it, but nothing I’ve tried works.

No dedicated server, just host and clients. Happens on both, to both. I literally cannot spawn anything anywhere except (0,0,0) and they stack up on top of each other.

Current code attempt:

public void MoveToLocation(Vector3 newPosition) { Debug.Log("UserControl::MoveToLocation: Moving " + name + " to Location: " + newPosition);
	if (IsServer)
	{
		// On the server, just set the position
		Debug.Log("UserControl:MovePosition: Setting transform.");
		UpdatePositionServerRpc(newPosition);
	}
	else
	{
		// On the client, request a teleport
		Debug.Log("UserControl:MovePosition: Requesting Teleport.");
		netTransform.Teleport(newPosition, transform.rotation, transform.localScale);
	}
}

[ServerRpc]
public void UpdatePositionServerRpc(Vector3 newPosition)
{
	transform.position = newPosition;
	UpdatePositionClientRpc(newPosition);
}

[ClientRpc]
public void UpdatePositionClientRpc(Vector3 newPosition)
{
	if (!IsServer) // Avoid double-updating on host
	{
		transform.position = newPosition;
	}
}

Confirmed through debugs that transform.position, and also networkTransform.position were getting set, then changing back to zero.

Any help?

Are you making the transform change through the “authority” (owner) of the network transform? By default, NetworkTransform can only be modified by the server (host). You can implement a ClientNetworkTransform or with NGO 2.0 you can set it in Inspector to make the component owner authoritative.

If that isn’t the issue you have to have some other code that updates the transform. Possibly, and commonly overlooked, is the fact that perhaps all clients send an RPC when you meant only for the owner to send a given RPC.

You needn’t make that check. Instead use the Rpc attribute which lets you specify SendTo.NotServer.

@CodeSmile I’m still struggling to get these concepts. I basically just want to spawn at locations, but everything is spawning directly on top of each other and the origin.

In my OnNetworkSpawn, I’m trying to call MoveToLocation, which confirms this is the server, and then moves the transform to the location.

public override void OnNetworkSpawn()
	{
		MoveToLocation(locationIndex);
	}	

public void MoveToLocation(int index)
    {
		if (IsServer)
		{
			// On the server, just set the position
			Debug.Log("UserControl::MoveToLocation: The server is Moving " + name + " to Location[" + index + "]: " + missionController.GetLocations()[index].GetPosition());
			transform.position = missionController.GetLocations()[index].GetPosition();
		}
	}

But since this isn’t working, clearly it’s not right. I thought I could do this through some combination of IsServer, IsLocal, IsOwner. I’m using a Host, not a dedicated Server, but that shouldn’t make a difference, right?

Can you drop me a simple piece of code that will take the recently network spawned prefab and move it? It just keeps moving back.

UserControl::MoveToLocation: The server is Moving Cabbie McCabberson to Location[0]: (564.55, 0.15, -1837.96)

I figured out what the problem was. And for anyone reading this, I hope this helps.

I was using a Character Controller that moved things around using physics! So, moving the transform didn’t affect it.

I changed…

to…

And it works! No different code for Host/Server or Client. Not if thens. Just moved the rigidbody and everyone updates. Same as when the controller moves the body in-game.

(in case you can’t see the code, instead of changing transform.position, I call rigidBody.MovePosition(newPosition);

1 Like