How to transform a child's position and rotation independently from their parent?

Hello!

I’m creating a 3rd person multiplayer game using Mirror and every single tutorial I’ve seen requires the camera to be parented under the player object’s prefab.

This is infuriating because my entire player movement and rotation is based on the way the camera is facing.

private void HandleRotation()
{
    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 targetRotation = Quaternion.LookRotation(targetDirection);
    Quaternion playerRotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);

    transform.rotation = playerRotation;
}

For example: 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.

Ideally, I would like to find a solution that doesn’t require me to parent the camera to the player model, however I can’t find one, so instead I’m looking to be able to move the camera’s transform independently to the player.

This is how I handle my camera rotation:

private void RotateCamera()
{
    Vector3 rotation;
    Quaternion targetRotation;

    // lookAngle = left and right input
    lookAngle += (inputHandler.cameraHorizontalInput * cameraLookSpeed);
    // pivotAngle = up and down input
    pivotAngle -= (inputHandler.cameraVerticalInput * cameraPivotSpeed);
    // limit rotation so we can't look in the ground etc.
    pivotAngle = Mathf.Clamp(pivotAngle, minimumPivotAngle, maximumPivotAngle);

    // Setting the rotation for y axis
    rotation = Vector3.zero;
    rotation.y = lookAngle;
    targetRotation = Quaternion.Euler(rotation);
    cameraHolderTransform.localRotation = targetRotation;

    // Setting the rotation for x axis
    rotation = Vector3.zero;
    rotation.x = pivotAngle;
    targetRotation = Quaternion.Euler(rotation);
    cameraPivotTransform.localRotation = targetRotation;
}

It’s worth noting as well that I am using 2 different gameObjects parented underneath the player object as a sort of camera holder for individual axis’ (One of which is a parent and the other is a child). The camera gets parented to the child gameObject on Start.

Any help with this would be greatly appreciated! Thank you <3

Hi!
It appears you are setting the transform.localRotation in your RotateCamera() method instead of using transform.rotation. This would explain why your camera is affected by your player’s transform. Assuming your RotateCamera() method is called every update, that should be the only required change.

It seems weird that your camera has to be a child of your player. Are you sure it is required, or could those tutorials have just been using it as a shortcut? I’m afraid I haven’t used Mirror, but most scenarios shouldn’t require parenting in this way.

As for alternate solutions, you can Instantiate a gameobject in world space instead of local space, which should make the position of the parent not affect the instantiated gameobject.

Instantiate(Object original, Transform parent, bool instantiateInWorldSpace);

Hope this helps!

you can set its parent to null so it will be parentless, transform.position provides parent-independent value, the transform.localPosition determines what position it is in relative to parent, same goes for rotation