I have been working on single player about 4 years and wanted to improve. Now i started to work on multiplayer with netcode.
I have a script that i control camera zooming and rotating. Zooming works both for host and client but rotating not working on anyone. I wanted to rotate camera around player when i pressed scrool then move mouse, it will remain constant in other cases. It was working like a charm when its single player but when i try to convert it to multiplayer it got broken. Here is the script I’m talking about.
Waiting for help, thanks !
using Cinemachine;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
public class CameraMovement : MonoBehaviour
{
[SerializeField] CinemachineVirtualCamera virtualCamera;
CinemachineComponentBase componentBase;
float cameraDistance;
[SerializeField] float sensivity = 10f;
public Transform PlayerCameraRoot;
private Vector3 _cameraOffset;
[Range(0.01f, 100.0f)]
public float SmoothFactor;
public bool LookAtPlayer = false;
public bool RotateAroundPlayer = true;
public float RotationSpeed = 5f;
public bool pressedScroolButton;
void Start()
{
_cameraOffset = transform.position - PlayerCameraRoot.position;
}
void Update()
{
//if(virtualCamera.Follow == null)
// {
// virtualCamera.Follow = GameObject.Find("Player(Clone)").transform;
// }
Debug.Log(Input.GetAxis("Mouse X"));
if(PlayerCameraRoot == null)
{
PlayerCameraRoot = GameObject.Find("PlayerCameraRoot").transform;
}
if (componentBase == null)
{
componentBase = virtualCamera.GetCinemachineComponent(CinemachineCore.Stage.Body);
}
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
cameraDistance = Input.GetAxis("Mouse ScrollWheel") * sensivity;
if (componentBase is CinemachineFramingTransposer)
{
(componentBase as CinemachineFramingTransposer).m_CameraDistance = Mathf.Clamp(((componentBase as CinemachineFramingTransposer).m_CameraDistance), 5, 10);
(componentBase as CinemachineFramingTransposer).m_CameraDistance -= cameraDistance;
}
}
CheckPressedScrool();
if (RotateAroundPlayer && pressedScroolButton)
{
Quaternion camTurnAngle = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * RotationSpeed, Vector3.up);
_cameraOffset = camTurnAngle * _cameraOffset;
}
Vector3 newPos = PlayerCameraRoot.position + _cameraOffset;
transform.position = Vector3.Slerp(transform.position, newPos, SmoothFactor);
if (LookAtPlayer || RotateAroundPlayer)
{
transform.LookAt(PlayerCameraRoot);
}
}
private void CheckPressedScrool()
{
if (Input.GetMouseButton(2))
{
pressedScroolButton = true;
}
else
{
pressedScroolButton = false;
}
}
}
Your code relies on GameObject.Find(“Player(Clone)”) which makes the naive assumption that this will be the player’s name. This and all other Find assumptions you have to put on the table. Generally, don’t use Find. It’s inherently brittle and slow. You want to use Inspector references or find by tag or component type.
Your class derives from MonoBehaviour so it isn’t network-aware to begin with. You can’t make this work without using NetworkBehviour and doing appropriate checks like if(IsOwner) because some code needs to be owner-specific. If you use the PlayerPrefab reference in NetworkManager then the owner is guaranteed to be the locally controlling player.
Every player prefab should include its own Camera and Cinemachine virtual camera components. These get enabled only for the IsOwner player to make sure each player is affecting only its own, local camera components.
Since you already use Cinemachine I’m a little confused why you want to script the rotation with a FramingTransposer. The transposer isn’t made for 3rd person, there’s an actual 3rd person mode built into Cinemachine virtual cameras. If set up correctly the mouse rotation should just work automatically. You may want to check out Unity’s free Third Person Starter Asset in the store for a template.
Sorry thats my first time using Unity Forum thanks for the code tag information.
When I examined your answer, I realized that my information about the logic of network objects was incomplete or incorrect. So I am looking forward to your answer and explain to me.
In my opinion, I did not make cameras network objects because the position or rotation value of the cameras has no effect on the game or other players. So, I thought that making them network objects would be an unnecessary burden for the server.
But as far as I understand, you are saying i need to turn my cameras toNetwork Objects ?
It seemed strange to me that zoom was working but rotation was not, because everything was working in single player.
Clients are taking control of the correct cameras because when I look at the camera following the player, they are on the correct ones. This shows that the GameObject.Find() line is working correctly, the problem should not be there but I understand the logic of your advice, thank you.I have this line inside my ThirdPersonController.cs;
This project is already built based on Unity’s Third Person Starter Asset.
And there is also an interesting situation, a problem that does not exist in single player. As the characters walk around, the camera’s position changes suddenly and keeps changing (even if I never press the mouse wheel and try to rotate it). Maybe it will help you pinpoint the source of the problem.
I will send a video of the single player version of the game. Everything was working. What I want to adapt to multiplayer is exactly the same.