- Home /
Camera on circular path, following object movement
Hi, I need to create this camera movement/behaviour:
][1]
A: the camera should follow the vertical movement of the object (the blue cube, which is moving freely around an arbitrary object in the center [the big cylinder]), thus always keeping it's Y position aligned with the Y position of the object
B: the camera should follow the horizontal movement of the object, but it should be constrained on a circular path
C: the camera should also be able to zoom in/out under certain circumstances
I tried different approaches but none of them is currently working. For example, I tried to modify the MouseOrbit script in order to recreate the circular movement of the camera; but while in the original script it's moving with the "Mouse X" input, I couldn't find a way to link the camera to the horizontal movement of the object (the blue cube):
using UnityEngine;
using System.Collections;
public class MouseOrbitImproved : MonoBehaviour
{
public Transform target;
public float distance = 50.0f;
public float xSpeed = 2.0f;
float x = 0.0f;
// Use this for initialization
void Start ()
{
Vector3 angles = transform.eulerAngles;
x = angles.y;
}
void LateUpdate ()
{
if (target)
{
// Mouse X
//x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
// Move along with target
// ???
Quaternion rotation = Quaternion.Euler(0, x, 0);
Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
Vector3 position = rotation * negDistance + target.position;
transform.rotation = rotation;
transform.position = position;
}
}
}
Answer by EHogger · Aug 03, 2013 at 03:55 PM
If the cylinder is always in the center, you can use that as a reference to find the position of the camera. (I'm sure there are other ways to do this, but I think this is simplest)
using UnityEngine;
using System.Collections;
public class MouseOrbit : MonoBehaviour {
public Transform target;
public Transform cylinder;
float cameraDistance = 50;
void Start () {
}
void LateUpdate () {
if (target) {
// First, lets match the vertical position:
transform.position = new Vector3(transform.position.x, target.position.y, transform.position.z);
// Now find the direction of the Target from the cylinder.
// We Want to ignore the vertical position of each:
Vector3 targetXZ = target.position;
Vector3 cylinderXZ = cylinder.position;
targetXZ.y = 0;
cylinderXZ.y = 0;
// Now find the direction:
Vector3 targetDirection = (targetXZ - cylinderXZ).normalized;
//Now we have the direction, we can find the position for the camera relative to the Target:
transform.position = target.position + (targetDirection * cameraDistance); //Editted this line to fix mistake.
//Now we just have to rotate it to look at the target:
transform.LookAt(target);
}
}
}
You could then use Lerp or Slerp to smooth the movement if you wanted. I haven't tested this, so let me know if it works :)
Wow, thank you very much. It's almost working. The only thing that is a bit off is the vertical position; it looks like the camera is not aligned with the Y position of the target object. Everything else is working as expected.
I had to change these lines:
targetXZ.y = target.position.y;
cylinderXZ.y = target.position.y;
because you were setting the Y to 0.
Oh, and if you want to zoom in and out, just modify the cameraDistance variable
Well spotted. Actually I meant to put target.position ins$$anonymous$$d of targetXZ on the final position setting.