1

I'm currently trying to create a multiplayer game using mirror! So far I've been successful in creating a lobby and set up a simple character model with a player locomotion script I've taken and learnt inside out from Sebastian Graves on YouTube (you may know him as the dark souls III tutorial guy)

This player locomotion script uses unity's package 'Input System' and is also dependent on using the camera's .forward and .right directions to determine where the player moves and rotates instead of using forces on the rigidbody. This means you actually need the camera free in the scene and unparented from the player.

Here is my HandleRotation() function for rotating my character (not the camera's rotation function):

private void HandleRotation()
    {
        // target direction is the way we want our player to rotate and move // setting it to 0
        Vector3 targetDirection = Vector3.zero;
        
        targetDirection = cameraManager.cameraTransform.forward * inputHandler.verticalInput;
        targetDirection += cameraManager.cameraTransform.right * inputHandler.horizontalInput;
        targetDirection.Normalize();
        targetDirection.y = 0;
        
        if (targetDirection == Vector3.zero)
        {
            // keep our rotation facing the way we stopped
            targetDirection = transform.forward;
        }
        
        // Quaternion's are used to calculate rotations
        // Look towards our target direction
        Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
        // Slerp = rotation between current rotation and target rotation by the speed you want to rotate * constant time regardless of framerates
        Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

        transform.rotation = playerRotation;
    }

It's also worth mentioning I'm not using cinemachine however I'm open to learning cinemachine as it may be beneficial in the future.

However, from what I've learnt and managed to find about mirror is that you have to parent the Main Camera under your player object's prefab so that when multiple people load in, multiple camera's are created. This has to happen on a Start() function or similar like OnStartLocalPlayer().

public override void OnStartLocalPlayer()
    {
        if (mainCam != null)
        {
            // configure and make camera a child of player
            mainCam.orthographic = false;
            mainCam.transform.SetParent(cameraPivotTransform);
            mainCam.transform.localPosition = new Vector3(0f, 0f, -3f);
            mainCam.transform.localEulerAngles = new Vector3(0f, 0f, 0f);

            cameraTransform = GetComponentInChildren<Camera>().transform;
            defaultPosition = cameraTransform.localPosition.z;
        }
    }

But of course, that means that the camera is no longer independent to the player and so what ends up happening is the camera rotates when the player rotates. E.g. if I'm in game and looking to the right of my player model and then press 'w' to walk in the direction the camera is facing, my camera will spin with the player keeping the same rotation while my player spins in order to try and walk in the direction the camera is facing.

What my question here would be: Is there a way to create a system using mirror that doesn't require the camera to be parented to the player object prefab on start, and INSTEAD works by keeping it independent in the scene?

(I understand that using forces on a rigidbody is another method of creating a player locomotion script however I would like to avoid that if possible)

If anybody can help that would be greatly appreciated, Thank You! =]

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
King_H
  • 11
  • 2

1 Answers1

0

With the constraint of your camera being attached to the player you will have to adapt the camera logic. What you can do is instantiate a proxy transform for the camera and copy that transforms properties to your camera, globally, every frame. The parent constraint component might do this for you. Then do all your transformations on that proxy.

Camera script with instantiation:

Transform proxy;

void Start(){
  proxy = (new GameObject()).transform;
}

void Update(){
  //transformations on proxy
  transform.position = proxy.position;
  transform.rotation = proxy.rotation;
}
  • 1
    Thank you very much for your answer! Would you be willing to provide some example syntax for this as I'm relatively new and haven't used .Instantiate(); before? I'll look into the parent constraint component. – King_H Jun 17 '22 at 18:53