Hello! So I’m new with networking and i want to make a game where two players are stuck in a sub like ship. There are two seats one for driver and one for a navigator. I am trying to implement the driver seat and i have simple code that will let a player drive the ship. Trying to sync it i added a NetworkTransform and a NetworkIdentity to the ship. If the Host gets into the driver seat the controls work fine, but if a client tries to drive the ship will jitter in place. I should also mention that only one player should be in the driver seat at a time and both players can drive it.
I suspect that the host is just overriding the position so it goes no where. I’m ust unsure how to handle it.
i have tried using a Command to handle inputs but that didnt help nor do i think thats how it is supposed to be handled.
Here is my ShipController script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class ShipController : NetworkBehaviour
{
public float spd;
public float rotateSpd;
public GameObject ship;
public Transform DriverSeat;
public Transform OutOfSeat;
public Transform targetTransform;
private void OnEnable()
{
ship = GameObject.Find("Ship");
DriverSeat = ship.transform.Find("DriversSeat");
OutOfSeat = ship.transform.Find("OutOfSeat");
targetTransform = DriverSeat.transform;
}
void Update()
{
transform.position = targetTransform.position;
moveShip();
if (Input.GetKeyDown(KeyCode.E))
{
GetComponent<PlayerControlHandler>().exitDriverSeat(OutOfSeat);
}
}
public void moveShip()
{
if (Input.GetKey(KeyCode.W))
{
ship.transform.localPosition += ship.transform.forward * spd * Time.deltaTime;
}
if (Input.GetKey(KeyCode.S))
{
ship.transform.localPosition -= ship.transform.forward * spd * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A))
{
ship.transform.Rotate(new Vector3(0, -rotateSpd, 0) * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D))
{
ship.transform.Rotate(new Vector3(0, rotateSpd, 0) * Time.deltaTime);
}
}
}
Sending commands to the server was the correct way of thinking though. You will want the server to always determine position of the transform and then just sync the current position back to the client.
If you only want one player to have “control” look into the concept of Authority. i.e. only the player who has the current authority should be able to send the server commands on where the ship is supposed to go:
Ok so i tried added assigning authority and using the commands. when the player enters the driver seat i try to add authority to the local player. i got an error saying that that needs to be done on the server so i added it to a command, but now it doesnt seem like it was running i assume i need to have authority to run commands so i make the command not require authority and it still doesnt seem like it gets run. So then i try to make a command for the movement so i give my input then run a command that is the logic for moving the ship, but when i tested it host runs fine but now the client is kicked out of the game with no errors. I apologize i feel like im making this harder than it needs to be.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class ShipController : NetworkBehaviour
{
public float spd;
public float rotateSpd;
public GameObject ship;
public Transform DriverSeat;
public Transform OutOfSeat;
public Transform targetTransform;
private Vector3 shipPos;
private void OnEnable()
{
CmdAssignAuthority(this.GetComponent<NetworkIdentity>());
ship = GameObject.Find("Ship");
DriverSeat = ship.transform.Find("DriversSeat");
OutOfSeat = ship.transform.Find("OutOfSeat");
targetTransform = DriverSeat.transform;
}
void Update()
{
transform.position = targetTransform.position;
moveShip();
if (Input.GetKeyDown(KeyCode.E))
{
CmdRemoveAuthority(ship.GetComponent<NetworkIdentity>());
GetComponent<PlayerControlHandler>().exitDriverSeat(OutOfSeat);
}
}
public void moveShip()
{
if (isOwned)
{
if (Input.GetKey(KeyCode.W))
{
CmdMoveShipForward();
}
if (Input.GetKey(KeyCode.S))
{
CmdMoveShipBackward();
}
if (Input.GetKey(KeyCode.A))
{
ship.transform.Rotate(new Vector3(0, -rotateSpd, 0) * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D))
{
ship.transform.Rotate(new Vector3(0, rotateSpd, 0) * Time.deltaTime);
}
}
}
[Command(requiresAuthority = false)]
private void CmdAssignAuthority(NetworkIdentity player)
{
Debug.Log("Assigning Authority");
player.AssignClientAuthority(connectionToClient);
}
[Command(requiresAuthority = false)]
private void CmdRemoveAuthority(NetworkIdentity player)
{
player.RemoveClientAuthority();
}
[Command]
private void CmdMoveShipForward()
{
Debug.Log("Forward");
ship.transform.localPosition += ship.transform.forward * spd * Time.deltaTime;
}
[Command]
private void CmdMoveShipBackward()
{
Debug.Log("Backward");
ship.transform.localPosition -= ship.transform.forward * spd * Time.deltaTime;
}
}