banner



How To Rotate A Camera Around Object In Vuforia

[Tutorial] How to rotate the camera around an object in Unity3D

In this Unity3D tutorial you lot volition larn a simple mode to move the photographic camera around an object in the scene while always looking at it. I shared all of the code, and I added a link to where you can download the total Unity project likewise.

If y'all have tried RotateAround() and it's not working for you, you have come to the right place.

You lot can jump to the solution at the end of the post, download the total projection, or follow the tutorial in video format.

Table of contents

  1. Detecting the drag
  2. Computing the rotation
  3. Moving the camera
  4. The solution
  5. Extra credit: Alter the rotation speed

We want to program the camera so that information technology rotates around an object in the scene, while looking at information technology, responding to player input.

As you can see, the photographic camera is doing the yaw and pitch rotations.

(Annotation: The method explained in this post can be applied to movement caused by any script too, it's not restricted to user input.)

Nosotros desire that a drag from one side of the screen to the other rotates u.s. 180º around the object. How practice we do that?

The screen (the viewport rather) has a size of 1x1 in viewport coordinates.

Since a drag from left to right of the screen will have a distance of one, we take simply defined our relation:

1 unit in viewport coordinates < == > 180 degrees of camera rotation

Step 1: Discover the elevate (= user input)

For this, I created an empty GameObject in the scene (I named it "InputController"), and added a script to information technology (that I created, and named "CameraMovement"). These are the steps:

  1. Get to the Unity Editor.
  2. In the Scene hierarcy, right click.
  3. Create > Game Object > Emtpy. I named it "InputController".
  4. In the InputController's Inspector, click "Add Script".
  5. Type "CameraMovement", hit enter. This created a "CameraMovement.cs" file in your Assets folder, which contains an empty CameraMovement class that extends MonoBehaviour.

(This is the about basic setup working with an empty project. Of class you can adapt your files and classes yet you prefer.)

Open CameraMovement.cs with your editor, time to code!

public class CameraMovement : MonoBehaviour {     void Update()     {         if (Input.GetMouseButtonDown(0))         {             // Volition exist true only in the 1st frame in which information technology detects the mouse is down (or a tap is happening)         }         else if (Input.GetMouseButton(0))         {             // Will be true equally long as the mouse is downward or a touch is happening.         }     } }

In Unity games, information technology is mutual practice to employ the Update part to detect role player input. (Information technology is too skillful do not to handle it in the Update office directly, but this is the smallest of projects and we're not going to over-engineer it.)

We are using the functions Input.GetMouseButtonDown(0) and Input.GetMouseButton(0) to discover whether the user clicked/tapped or dragged the pointer over the screen.

The Input class also has a convenient mousePosition field which gives us the position of the pointer (mouse or finger) in screen coordinates. We'll apply it in the next step.

Now that we take the problem defined and the drag detected, nosotros can move the photographic camera.

Pace two: Calculate the rotation

Every frame we volition summate how much the cursor/finger moved since last frame, and translate it into how many degrees the camera should rotate according to our previously defined relation:

1 unit in viewport coordinates < == > 180 degrees of camera rotation

In guild to do that, we need to store the previous position in a individual field (previousPosition).

This is how the code looks:

public form CameraMovement : MonoBehaviour {     private Vector3 previousPosition          void Update()     {         if (Input.GetMouseButtonDown(0))         {             previousPosition = cam.ScreenToViewportPoint(Input.mousePosition);         }         else if (Input.GetMouseButton(0))         {             Vector3 currentPosition = cam.ScreenToViewportPoint(Input.mousePosition);             Vector3 management = previousPosition - currentPosition;                          float rotationAroundYAxis = -direction.x * 180; // camera moves horizontally             bladder rotationAroundXAxis = direction.y * 180; // camera moves vertically                          previousPosition = currentPosition;         }     } }

On the first frame in which the mouse is downward (or the finger touches the screen), nosotros store that position equally our previousPosition.

In each subsequent frames, we calculate management, which is the difference between the current mousePosition and previousPosition.

rotationAroundYAxis and rotationAroundXAxis are the rotations nosotros must add together to the current rotation each frame. They are calculated using this very advanced mathematical formula:

(i / 180º) = (direction / rotationAroundAxis)

In UnityEngine, the forward vector is by convention (0, 0, 1). This is why we are working with the assumption that the camera starts looking "forward", and will rotate around the X and Y axes.

At the cease of the part, don't forget to store our currentPosition as our previousPosition!

Okay, but how practise we ACTUALLY Motility THE Photographic camera?

Pace iii: Move the camera

UnityEngine's transform class has a convenient function RotateAround(Vector3 point, Vector3 centrality, float angleInDegrees). Here you would use it like this:

cam.transform.RotateAround(target.transform.position, new Vector3(ane, 0, 0), rotationAroundXAxis); cam.transform.RotateAround(target.transform.position, new Vector3(0, one, 0), rotationAroundYAxis);

Equally you can see, information technology works, but information technology probably doesn't yield the issue y'all want:

RotateAround() produces a weird motion that we can't control, awful UX, 0 stars, thumbs down. (This is due to the fact that when we rotate around 1 axis we are moving the other, and viceversa. RotateAround() works well when you only allow rotation around 1 axis.)

But don't worry! At that place's a way!

Nosotros will apply Rotate(Vector3 centrality, float angleInDegrees, Infinite relativeTo) instead.

Solution

public class CameraMovement : MonoBehaviour {     [SerializeField] private Camera cam;     [SerializeField] private Transform target;     [SerializeField] private float distanceToTarget = x;          private Vector3 previousPosition;          void Update()     {         if (Input.GetMouseButtonDown(0))         {             previousPosition = cam.ScreenToViewportPoint(Input.mousePosition);         }         else if (Input.GetMouseButton(0))         {             Vector3 newPosition = cam.ScreenToViewportPoint(Input.mousePosition);             Vector3 direction = previousPosition - newPosition;                          float rotationAroundYAxis = -management.x * 180; // camera moves horizontally             float rotationAroundXAxis = management.y * 180; // photographic camera moves vertically                          cam.transform.position = target.position;                          cam.transform.Rotate(new Vector3(i, 0, 0), rotationAroundXAxis);             cam.transform.Rotate(new Vector3(0, 1, 0), rotationAroundYAxis, Space.Earth); // <— This is what makes it work!                          cam.transform.Translate(new Vector3(0, 0, -distanceToTarget));                          previousPosition = newPosition;         }     } }

Caption

We created the following private serialized fields, that you must assign in the Unity Editor (only elevate the objects into their corresponding box):

  • cam references the camera that you want to motion.
  • target is the transform component of the gameObject around which we want to rotate.
  • distanceToTarget is the altitude from the target that nosotros want the photographic camera to exist.

What makes this method work is the fact that we are rotating around the world'south Y axis.

By default, Rotate() and RotateAround() employ the GameObject's local axes (in our case, the camera's). Since rotating around one axis messes up the other, we need to rotate around the world's centrality instead of ours.

Rotate() but rotates the object in its place. When you rotate around something, you are also translating. That's why we must call cam.transform.Interpret(). The society in which you practice information technology matters:

  • If you Rotate() first and Translate() second, you are rotating your axes, and so moving "co-ordinate" to them.
  • If you Translate() first and Rotate() second, yous are moving "according" to the world's axes, and then rotating effectually yourself in your new position.

So what we demand to do for this application is:

Each frame, we set the camera'due south position equally the target's position. So we apply the rotations. Finally, we translate the camera back distanceToTarget units in -Z.

Nosotros divers the rotation speed by the relation:

1 unit of measurement in viewport coordinates < == > 180 degrees of photographic camera rotation

While it is one that works very well, and is very intuitive from a UX perspective, yous could make the argument that 180 is a hadcoded arbitrary number.

Therefore, we tin turn the relationship into a private serialized field, so nosotros tin can edit it in the inspector:

[SerializeField] [Range(0, 360)] individual int maxRotationInOneSwipe = 180;

And the code for calculating the photographic camera rotation will look like this:

bladder rotationAroundYAxis = -direction.x * maxRotationInOneSwipe; // camera moves horizontally bladder rotationAroundXAxis = direction.y * maxRotationInOneSwipe; // camera moves vertically

Source: https://emmaprats.com/p/how-to-rotate-the-camera-around-an-object-in-unity3d/

Posted by: freyfacharnmethe.blogspot.com

0 Response to "How To Rotate A Camera Around Object In Vuforia"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel