3d camera control

I have a camera that is used like an overhead camera and i want to be able to use it in three dimensions. I would like to be able to zoom in and out with the mouse wheel and if i click down the middel mouse button i can rotate the camera. something like a homeworld kind of camera or black and white. how can i do this?

What you can do is apply the preset MouseOrbit script to your camera (in Camera-control section of the components drop-down). This will give you a basis for rotating around a target. However, we don't want to use the script as is, because it will be actively rotating your view with the mouse all the time, and you can't zoom yet.

We'll add the zoom function first. I'm assuming we probably want to be able to zoom even when we're not rotating, so we'll put that separate from the rotation code (this is all javascript).

Open your mouseorbit script and add the following variables to the variable list:

var maxDist : float = 200;
var minDist : float = 30;
var zoomSpeed : float = 5;

We'll use these to prevent our players from zooming in way too close or off into space, and to control the rate of zooming. You can adjust them in the inspector to fine tune. Next, scroll down to the late update function and add the following code:

    if (Input.GetAxis("Mouse ScrollWheel") < 0 && distance < maxDist){           
           distance += zoomSpeed;                             
           transform.Translate(Vector3.forward * -zoomSpeed); 
    }

Adding the above conditions will allow us to zoom OUT with the mousewheel. The GetAxis retrieves a positive or negative number, depending on which way we're scrolling the wheel. A negative number mean's we're scrolling down. We don't want to move the camera back more if we're at our maximum distance, so we make sure distance is less than maxDist before changing it. If it is, we add the zoomspeed to distance, which is used while we're rotating, and we translate our camera backward the same amount, because we want to zoom out even when we're not rotating. If we don't adjust these the same amount, the camera will 'pop' when you start to rotate it, using whatever 'distance' is set to. This code makes sure that we'll always be at that distance before we rotate.

Next we add the similar condition to zoom IN:

   if (Input.GetAxis("Mouse ScrollWheel") > 0 && distance > minDist){     
               distance -= zoomSpeed;                             
               transform.Translate(Vector3.forward * zoomSpeed); 
}

When the Mousewheel is moving the other direction: distance is checked against the minimum instead of the maximum, and we're lowering the distance variable and moving the camera forward this time, not backward.

Now to make sure it rotates when we want it to. The script currently is set to do its thing only when it has a target, as shown in the next line:

   If (target) {

We can add the mouse button requirement here. The middle mouse is mouse button 2, so we turn this line into:

   If (target && Input.GetMouseButton(2)) {

Now our camera will only rotate around an object if it has a target and the middle mouse button is down.

In the inspector you can adjust the maximum and minimum Y to make sure the camera doesn't rotate underground or too high for your game.

What I recommend now is nesting your Camera in an empty game object that you'll use as the view target. If you move this object around the map, it will move the camera with it, and you'll always be ready to rotate the camera, even without a unit to look at. You can have this parent object go to unit positions when you want to view those units, and even make the units the parent of this 'camera crane', if they're moving.

To make sure the first rotation doesn't pop into place, you should make sure that your camera is the same distance away from the viewpoint as the distance variable. There are a couple ways to do this, I find the easiest way is to run the program and allow it to pop, then look at the camera position in the inspector, and have that be the camera's start position. If you have a specific position you want the camera to start at, you'll want to detect the distance to viewpoint and adjust the 'distance' variable to match.

As you get comfortable with the script, you might consider using a form of LERP to zoom more smoothly. However, this method of zooming should do nicely for most applications.

I hope this helped!

Hi friend, i try this code and works fine, ill let you the complete code here (MouseOrbit.js with changes), and thanks to the user who assist us with this code!:


// Codigo con parametros aumentados para hacer zoom in y zoom out con el scroll del mouse:

var target : Transform;
var distance = 10.0;

var xSpeed = 250.0;
var ySpeed = 120.0;

var yMinLimit = -20;
var yMaxLimit = 80;

// Aumentado esto:
var maxDist : float = 200;
var minDist : float = 30;
var zoomSpeed : float = 5;
// hasta aca

private var x = 0.0;
private var y = 0.0;

@script AddComponentMenu("Camera-Control/Mouse Orbit")

function Start () {
    var angles = transform.eulerAngles;
    x = angles.y;
    y = angles.x;

    // Make the rigid body not change rotation
    if (rigidbody)
        rigidbody.freezeRotation = true;
}

function LateUpdate () {
    if (target && Input.GetMouseButton(2))  {
        x += Input.GetAxis("Mouse X") * xSpeed * 0.02;
        y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02;

        y = ClampAngle(y, yMinLimit, yMaxLimit);

        var rotation = Quaternion.Euler(y, x, 0);
        var position = rotation * Vector3(0.0, 0.0, -distance) + target.position;

        transform.rotation = rotation;
        transform.position = position;
    }
    // Aumentado esto:
      if (Input.GetAxis("Mouse ScrollWheel") < 0 && distance < maxDist){           
           distance += zoomSpeed;                             
           transform.Translate(Vector3.forward * -zoomSpeed); 
    }
    // hasta aca
    // Aumentado esto:
     if (Input.GetAxis("Mouse ScrollWheel") > 0 && distance > minDist){     
               distance -= zoomSpeed;                             
               transform.Translate(Vector3.forward * zoomSpeed); 
}
// hasta aca
}

static function ClampAngle (angle : float, min : float, max : float) {
    if (angle < -360)
        angle += 360;
    if (angle > 360)
        angle -= 360;
    return Mathf.Clamp (angle, min, max);
}

I need a code to make zoom in and out in the depth field, like using binoculars to see far away, anybody knows how to do this?, Thank you.