Server player movement running same on all clients
in Photon Bolt
I am a newbie in bolt.
So I made my own simple movement scripts which doesn't use server authoritative movement and uses rigidbody to move the player around.
The problem is I can't move or rotate the clients individually, but when I move or rotate the server player, all clients also does same. They move and rotate with server player.
I will explain my Setup so far:
I used the same scripts from advanced tutorial of spawning the player by creating server or client player, etc. In addition to that I made a singleton prefab - "GameManagerController" whose job is to look for objects with tag "SpawnPoint" and store them in array. Then get the random spawn point for spawning the player.
Here are the codes:
Player Controller (this class takes input from player):
So I made my own simple movement scripts which doesn't use server authoritative movement and uses rigidbody to move the player around.
The problem is I can't move or rotate the clients individually, but when I move or rotate the server player, all clients also does same. They move and rotate with server player.
I will explain my Setup so far:
I used the same scripts from advanced tutorial of spawning the player by creating server or client player, etc. In addition to that I made a singleton prefab - "GameManagerController" whose job is to look for objects with tag "SpawnPoint" and store them in array. Then get the random spawn point for spawning the player.
Here are the codes:
Player Controller (this class takes input from player):
public class PlayerController : Bolt.EntityBehaviour<ISniperPlayerState> { [SerializeField] private float moveSpeed = 10f; [SerializeField] private float lookSensitivity = 3f; PlayerMotor motor; private void Awake() { motor = GetComponent<PlayerMotor>(); } public override void Attached() { state.SetTransforms(state.Transform, transform); } public override void SimulateOwner() { //Movement region #region float _xMov = Input.GetAxis("Horizontal"); float _zMov = Input.GetAxis("Vertical"); Vector3 _moveHorizontal = transform.right * _xMov; Vector3 _moveVertical = transform.forward * _zMov; //Final Movement Vector3 _velocity = Vector3.zero; _velocity = (_moveHorizontal + _moveVertical) * moveSpeed; //Apply movement motor.Move(_velocity); #endregion //Rotation region #region var _yRot = Input.GetAxis("Mouse X"); var _xRot = Input.GetAxis("Mouse Y"); var _rotation = new Vector3(0f, _yRot, 0f) * lookSensitivity; motor.Rotate(_rotation); var _cameraRotationX = _xRot * lookSensitivity; motor.RotateCamera(_cameraRotationX); #endregion } }PlayerMotor (this class applies motion by taking input from player controller):
[RequireComponent (typeof(Rigidbody))] public class PlayerMotor : MonoBehaviour { private float cameraRotationX = 0f; private float currentCameraRotationX = 0f; [SerializeField] private float cameraRotationLimit = 85f; Vector3 velocity = Vector3.zero; Vector3 rotation = Vector3.zero; Rigidbody _rb; [SerializeField] Camera cam; private void Awake() { _rb = GetComponent<Rigidbody>(); cam = CameraController.instance.myCamera; } public Vector3 Velocity { get { return _rb.velocity; } } public void Move(Vector3 _velocity) { velocity = _velocity; } public void Rotate(Vector3 _rotation) { rotation = _rotation; } public void RotateCamera(float _cameraRotationX) { cameraRotationX = _cameraRotationX; } private void FixedUpdate() { PerformMovement(); PerformRotation(); } void PerformMovement() { if (velocity != Vector3.zero) _rb.MovePosition(_rb.position + velocity * BoltNetwork.frameDeltaTime); //rb.AddForce(jumpForce /* * Time.fixedDeltaTime*/, ForceMode.Impulse); } void PerformRotation() { _rb.MoveRotation(_rb.rotation * Quaternion.Euler(rotation)); if (cam != null) { //cam.transform.Rotate(-cameraRotation); //New Camera Rotation code currentCameraRotationX -= cameraRotationX; currentCameraRotationX = Mathf.Clamp(currentCameraRotationX, -cameraRotationLimit, cameraRotationLimit); cam.transform.localEulerAngles = new Vector3(currentCameraRotationX, 0</f, 0f); } } }Here is how I spawn my player:
[BoltGlobalBehaviour(BoltNetworkModes.Server, "Prototype_Level1")] public class NetworkCallbackTest : Bolt.GlobalEventListener { void Awake() { SniperPlayerRegistry.CreateServerPlayer(); } public override void Connected(BoltConnection connection) { SniperPlayerRegistry.CreateClientPlayer(connection); } public override void SceneLoadLocalDone(string map) { GameManagerController.Instantiate(); GameManagerController.instance.SetupSpawnPoints(); SniperPlayerRegistry.ServerPlayer.Spawn(); //GameObject spawnPoint = GetRandomSpawnPoint(); //BoltNetwork.Instantiate(BoltPrefabs.SniperPlayer, spawnPoint.transform.position, spawnPoint.transform.rotation); } public override void SceneLoadRemoteDone(BoltConnection connection) { SniperPlayerRegistry.GetPlayer(connection).Spawn(); } }
0
Comments
-
For non authoritative you need to spawn the local player on the client like in the Getting Started docs0
-
Okay thanks, that works.
Here is the latest code:[BoltGlobalBehaviour] public class NetworkCallbackTest : Bolt.GlobalEventListener { GameObject spawnPoint; BoltEntity character; public override void SceneLoadLocalDone(string map) { GameManagerController.Instantiate(); GameManagerController.instance.SetupSpawnPoints(); if (GameManagerController.instance != null) spawnPoint = GameManagerController.instance.FindRandomSpawnPoint(); character = BoltNetwork.Instantiate(BoltPrefabs.SniperPlayer, spawnPoint.transform.position, spawnPoint.transform.rotation); character.TakeControl(); } }
Is the calling of TakeControl() method correct or some conditions needs to be checked first?
One more question, how do I get the camera per player? Because playermotor script is dependent on camera to rotate around. Since CameraController is another singleton prefab spawned per player.
My CameraController:using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraController : BoltSingletonPrefab<CameraController> { [SerializeField] Transform Cam; public Camera myCamera { get { return Cam.GetComponent<Camera>(); } } private readonly string newName = "PlayerCamera"; void Awake() { DontDestroyOnLoad(gameObject); } // Setup the camera with the default view public void Configure(BoltEntity entity) { Debug.Log("Configure Called on player camera"); Transform CameraPos = entity.transform.Find("CameraPos"); gameObject.transform.name = newName; gameObject.transform.parent = CameraPos; gameObject.transform.position = CameraPos.position; gameObject.transform.rotation = CameraPos.rotation; //gameObject.transform.localPosition = new Vector3(0, 100, 0); //gameObject.transform.localRotation = Quaternion.Euler(90f, 0, 0); } }
This is how PlayerMotor tries to access the camera:cam = CameraController.instance.myCamera;
0 -
You don't need to use TakeControl or anything related to control if you're not using commands ie not server authoritative
"how do I get the camera per player?"
Not sure what you mean. All movement logic of the player you own is on your client, you just use the local singleton camera.0 -
If I don't use TakeControl the CameraController is spawned at the middle of map and not assigned as child of player. I call the CameraController Configure() method from ControlofEntityGained() method or something like that called.
About camera lets say by example. One player starts a server, then comes the client player. The Client's playermotor is trying to access the camera from the server player and not it own child camera.
0