Copying a transform - copy by reference?

New to Unity.

Working on a 3D scene as a learning project, I’m moving the camera around the player object when the user holds down the middle mouse button and moves the mouse.

I’m trying to limit the vertical movement so that the camera cannot go below the player (y=0).

The idea was that I would copy the camera transform, then do a RotateAround on the copy. If the result was > 0 then it would be safe to do the RotateAround on the ‘real’ transform. My thinking was that doing the operation on the real thing then resetting it to 0 if required may cause flickering or jumping.

But it doesn’t work - the RotateAround on the copy also affects the real one. Is it passing by reference when setting the copy of the transform?

        //rotate camera around player if middle mouse button pressed and mouse moved
        if (Input.GetMouseButton(2))
        {
            float rotateHorizontal = Input.GetAxis("Mouse X");
            float rotateVertical = Input.GetAxis("Mouse Y");
           
            // horizontal rotation
            transform.RotateAround(player.transform.position, -Vector3.up, rotateHorizontal * sensitivity);

            //vertical rotation
            checkTransform = transform;
            checkTransform.RotateAround(Vector3.zero, checkTransform.right, rotateVertical * sensitivity);
            if (checkTransform.position.y > 0)
            {
                transform.RotateAround(Vector3.zero, transform.right, rotateVertical * sensitivity);
            }

        }

checkTransform is defined as private Transform checkTransform;
and sensitivity is a public variable

Good opportunity to clarify the difference between a value and a reference.

In simple terms: a transform is a reference because it is an “object”. Objects can be of just about any size and therefore a reference to the block of memory where it is stored is passed around as opposed to the block of memory itself.

It is also possible to clone an object. This will give you a new and disassociated object reference with the same values as the original.

1 Like

Instead of copying the Transform component (which isn’t easy to do), you can add a serialized Transform field to your class:

[SerializeField] Transform checkTransform;

Then you can create a second empty GameObject, and drag-and-drop it into the Check Transform field that appears in the Inspector.

Might be easier to clamp it instead. This avoids testing whether y < 0 before rotation, and instead, allows the new value but clamps y > 0 using the highest/Max value of 0 and the y position. In this case, clampedPosition is a copy (value). This is modified and then the transform.position is updated.

    transform.RotateAround(player.transform.position, transform.right, rotateVertical * sensitivity);

    // Clamp the camera's Y position to ensure it doesn't go below 0
    Vector3 clampedPosition = transform.position;
    clampedPosition.y = Mathf.Max(clampedPosition.y, 0);
    transform.position = clampedPosition;
// One line instead
transform.position = new Vector3(transform.position.x, Mathf.Max(transform.position.y, 0), transform.position.z);