UI Scrollbar limit Camera FOV change?

I want to make a zoomable camera, with a UI Scrollbar which moves left and right based on if you zoom in or out. And I want the element to limit how much you can zoom. So if the bar gets all the way to the left, you won’t be able to zoom out anymore, and same for zooming in (bar going right).

I want this to be somehow connected to a script, which will change the camera’s FOV when the person scrolls the mouse wheel. But I haven’t done much of UI work, aside from health bars, so I have no idea how I would make these two (camera and UI) communicate in code.

If someone could point me to a Unity Manual page with UI commands, that would be great. Or even better, help me figure out the logical process behind how something like that would work.

I know you’d have to check for the scrollbar’s current value, but I don’t how to stop the FOV going any further once that value is reached.

P.S. I know limiting the zoom can be achieved without the UI, but I want the player to have visual feedback on how much they can zoom.

You can connect things together in script (you asked about the UI + camera) by declaring variables that you reference.
Using those variables, you can take the input of a slider and adjust the camera’s FOV.
The slider can be limited - if you just put one in the scene you’ll see that you can set its limits.
If there’s a lower bound you want to enforce, you can easily just say : 0 (in the slider’s world) equals whatever limit you want.
If you didn’t know how to connect to variables, you should start smaller and learn some basics so you’ll feel more comfortable, in my opinion (meant to be helpful).

Personal note: When I first began, one of the things I tried was adjusting the FOV for a zoom effect, also. It may be different in your situation, but for me, the FOV was a bad means of zooming. I preferred moving the camera closer/farther. It was more what I was looking for, and partially related, I believe the FOV skewed objects in [the] view.

1 Like

The thing is, I want my camera to act as a literal camera in real life, so for me moving the Camera object back and forth would be unrealistic Also, I want that skewing effect, because it reminds the player they have a camera in front of them.

Fair enough … So long as that’s what you want, it’s all good :slight_smile:
Did the other stuff I wrote make sense to you ?

1 Like

Yeah. Thanks. :slight_smile:

Cool :slight_smile: Enjoy your project.

1 Like

I’m having some trouble.

I got to a point where I can make the scrollbar and the current camera scrolling system (which uses the mouse wheel to change the FOV) communicate.

But changing the value of the scrollbar seems to be a lot harder than I thought.

I can see this being done in two ways:

Either
The scrollbar value is controlled with the mouse wheel (and changes the FOV), until it reaches one of its limits (0 or 1), and then locks the FOV from changing any further (which would mean I’d be unable to fine-tune the FOV).
Or
The FOV is controlled with the mouse wheel (like it currently is) and changes the scrollbar value, until the value reaches its limits, and locks the FOV from going further (which would be the better option).

Either way, I still can’t figure out how to change the scrollbar’s value in any way.

Here’s the code so far:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CameraScroll : MonoBehaviour {

    Scrollbar bar;

    public float minFov = 15f;
    public float maxFov = 50f;
    public float sensitivity = 12.5f;

    void Start () {
        bar = gameObject.GetComponent<Scrollbar> ();
    }

    void Update () {
        float fov = Camera.main.fieldOfView;
        if (bar.value >= 0 && bar.value <= 1) {
            fov -= Input.GetAxis("Mouse ScrollWheel") * sensitivity;
            fov = Mathf.Clamp(fov, minFov, maxFov);
            Camera.main.fieldOfView = fov;
        }
    }
}

I put it as a component of the UI Scrollbar, so that I would have an easier time referencing and calling the “Scrollbar (Script)” component inside the Scrollbar GameObject. (The FOV changing still works this way)

The “if” statement in the Update method is just a test, to see if they are communicating (the UI and camera). Basically I can set it to check between 0 and 0.5, or something like that, and then if I set the scrollbar value to above 0.5 before running the game, I won’t be able to change the FOV, which is the expected result.

Now I just need to implement the Scrollbar’s value change inside that if statement, which will essentially become the locking mechanism for the FOV.

So as you can see I got most of the work done, I just need some help finding the last piece.

I sometimes get scrollbar and slider confused.
Here is an offer for using a Slider (which, btw, you can adjust the little sprites so it looks exactly the same if you like that look). Modified my handle so it’s square and the background so it’s the same size, and removed the fill area on mine, for example , when testing this :slight_smile:

using UnityEngine.EventSystems;
using UnityEngine.UI;
public class SliderTest : MonoBehaviour, IScrollHandler {
    public void OnScroll(PointerEventData eventData)
    {
        float f = eventData.scrollDelta.y > 0 ? 1 : -1;
        GetComponent<Slider>().value += f;
    }

    public void SliderChange(float f)
    {
        print("Slider is now: " + f.ToString());
    // I didn't use the camera in the script but just add a variable at the top and adjust the camera's FOV here.
    }
}

The Slider’s values can be set to “Min = 15, Max = 50” and use only whole numbers. :slight_smile:
** Though, if you wanted fractional numbers, You could just add the scrolldelta directly (modified by a value or not…just depends how much fine grain control ya want).
This setup works okay with moving the slider by hand, too.

Edit: Oh, right… this particular code only works if you scroll while over the object, so if you wanted it to work anywhere, then Update() is the way to go :wink:

1 Like

Would I just need to put the whole OnScroll method into an update method?

If you wanted it in your update method, you’d just use something similar to what you had before:

sliderVar += Input.GetAxis("Mouse ScrollWheel") * sensitivity; // whatever works for ya here.

SliderChange in my code was a UnityEvent assigned in the inspector, btw, if I didn’t say that (if you want to let them change it by dragging the slider).

You just no longer have to manually clamp it… and whatever value the slider is (within the range you set in the inspector) can be applied to the camera’s FOV upon its OnChange event.

Okay so this is what I got from my understanding of it.

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class SliderTest : MonoBehaviour, IScrollHandler {

    public float minFov = 15f;
    public float maxFov = 50f;
    public float sensitivity = 12.5f;
    public float sliderVar = 50;

    void Update () {
            float fov = Camera.main.fieldOfView;
            if (Slider.value >= 0 && Slider.value <= 1) {
                fov -= Input.GetAxis("Mouse ScrollWheel") * sensitivity;
                sliderVar += Input.GetAxis("Mouse ScrollWheel") * sensitivity;
                fov = Mathf.Clamp(fov, minFov, maxFov);
                Camera.main.fieldOfView = fov;
                GetComponent<Slider>().value += f;
            }
    }

    public void SliderChange(float f) {
        print("Slider is now: " + f.ToString());
        // I didn't use the camera in the script but just add a variable at the top and adjust the camera's FOV here.
    }
}

In MonoDevelop, the “f” on line 19 is red, so I’m clearly doing something wrong.

Here let me try to help fix that…

void Update() {
   int f = Input.GetAxis("Mouse ScrollWheel");
   if(f != 0) {
      f *= sensitivity;   // multiply by -1 if this isn't the direction you want :)
      GetComponent<Slider>().value += f;
      }
   }
public void SliderChange(float f) {
   Camera.main.fieldOfView = f;
   }

Set the slider values, and the clamping will be done (for you?) :slight_smile:
You didn’t respond about wanting the option to change it by dragging the slider or not, so this would do that…
if you don’t care about that, you could move the camera fieldOfView change into the Update area above/below the ().value part.

1 Like

I assumed that by asking

I stated that I wanted it to be movable wherever.

Guess I need to stop assuming.

Oh, no, no … sorry you’re right, I had temporarily forgotten :slight_smile:

That working okay like that?

I’m getting 3 errors, but there’s nothing being highlighted or anything, within the actual code.

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class SliderTest : MonoBehaviour, IScrollHandler {

    public float sensitivity = 12.5f;

    void Update () {
        int f = Input.GetAxis ("Mouse ScrollWheel");
        if(f != 0) {
            f *= sensitivity;
            GetComponent<Slider> ().value += f;
            Camera.main.fieldOfView = f;
        }
    }
}

Edit: Solved the last of the 3 errors.

typo/my bad… : float f = ... etc (not int)

I tried changing the “int f” to a “float f”. And that fixed the errors, but when I test it, and scroll with my mouse wheel, the fov goes insanely small (huge zoom in), and I can’t set it back aside from canceling the test run, but the slider moves just fine.

It like zooms in to the absolute max, and then stays zoomed in. When I try to zoom out, the fov changes for a split second and then goes back to fully zoomed in.

Try to use the code I wrote a little ways back, where it doesn’t adjust the fieldOfView in update but does so in the interface implementation instead. I tested the code, re-written to use Update() for the Scroll Wheel and my code is working properly.
Also, be sure you’re setting the Min Max values in the inspector.

May have mixed up a few of my words… Apologies. here’s what I have (removed the interface).

using UnityEngine;
using UnityEngine.UI;
public class SliderTest : MonoBehaviour {
    [SerializeField]
    Camera mCam;
    Slider mSlider;
    private void Awake()
    {
        mSlider = GetComponent<Slider>();
    }
    private void Update()
    {
        float f = Input.GetAxis("Mouse ScrollWheel");
        if (f != 0) mSlider.value += f;
    }
    public void SliderChange(float f)
    {
        print("Slider is now: " + f.ToString());
        mCam.fieldOfView = f;
    }
}