Home > Enterprise >  Why isn't my attempt at making an FPS shooter zoom working?
Why isn't my attempt at making an FPS shooter zoom working?

Time:04-16

OBJECTIVE

I am using this script I got from Unity's forums to move my camera around. It works perfectly and this is exactly the style of camera I want. Here it is in action:

https://streamable.com/j7ozps

I wanted to create a zoom effect when the user holds the right mouse button.

PROBLEM

After zooming in, the aim is off by a lot. Here's what happens: https://streamable.com/8aiil0

MY ATTEMPT

void Update () {
        if (Input.GetMouseButton(1))
        {
            int layerMask = 1 << CombatManager.GROUND_LAYER; // -> public const int GROUND_LAYER = 8;
            Ray mouseClick = Camera.main.ScreenPointToRay(Input.mousePosition);                         
            RaycastHit[] hitInfos;                                                                      
            float maxDistance = 100.0f;

            hitInfos = Physics.RaycastAll(mouseClick, maxDistance,
                                            layerMask, QueryTriggerInteraction.Ignore);                

            mainCamera.fieldOfView = 10;
            mainCamera.transform.LookAt(hitInfos[0].point);
        }
        else
            mainCamera.fieldOfView = startingFieldOfView;

I also tried swapping the order of the LookAt and field of view assignment.

What am I doing wrong?

CodePudding user response:

Seems that what you want is to zoom towards the cursor position, not towards where the ray hits which are likely not the same point. To check that out you can draw a debug cube where the ray hits, to check if the point you are looking at is the one you need, like so:

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = hitInfos[0].point;

Check Camera.ScreenToWorldPoint that gives you the worldspace point created by converting the screen space point at the provided distance z from the camera plane.

What I would try:

Vector3 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
//check if this is the point you want to look at
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.position = point;
//look at it
mainCamera.transform.LookAt(point);

It should not mind if you are using the cam.nearClipPlane or the cam.farClipPlane in the ScreenToWorldPoint function, but I would play with that in case something is not working as intended.

Vector3 screenPoint = Input.mousePosition;
screenPoint.z = Camera.main.farClipPlane;
Vector3 worldPoint = Camera.main.ScreenToWorldPoint(screenPoint);
  • Related