- Home /
Make camera move and look at an object over time
Hi all,
I need a script which moves a camera from the player towards an item. I want this to be achieved over time using a Lerp/Slerp.
I thought I had it but for some reason my code only works when the object is rotated 90 degrees (i.e when the up direction is the Z rather than Y).
I've been banging my head on this for a while and I really can't figure it out. I must have a misunderstanding of some of the concepts I'm trying to use. The movement seems to be fine but the rotation only works when the objects are rotated as described above (image I have a sheet of paper object which by default is stood upright with Y being the top, when the game start it falls to the ground and the Z is now facing up).
These are the two moving and rotating functions:
void RotateTowardCam (){
Vector3 relativePosition = trans.position - secondaryCam.GetComponent<Transform> ().position;
targetRotation = Quaternion.LookRotation (relativePosition, new Vector3 (0, 0, -1));
secondaryCam.GetComponent<Transform> ().rotation = Quaternion.Slerp (secondaryCam.GetComponent<Transform> ().rotation, targetRotation, Time.deltaTime * rotateSpeed);
//Debug.Log (trans.rotation + " " + targetRotation + " " + secondaryCam.GetComponent<Transform> ().rotation);
}
IEnumerator MoveCameraToward (Vector3 startPos)
{
float distCovered = 0f;
while (trans.localPosition != secondaryCam.GetComponent<Transform> ().position * offsetFromCam && secondaryCam.GetComponent<Camera>().fieldOfView != zoomFOV) {
distCovered += Time.deltaTime * lookAtSpeed;
secondaryCam.GetComponent<Transform> ().position = Vector3.Lerp (startPos, trans.position + trans.forward * offsetFromCam, distCovered);
secondaryCam.GetComponent<Camera> ().fieldOfView = Mathf.Lerp (secondaryCam.GetComponent<Camera> ().fieldOfView, zoomFOV, Time.deltaTime * lookAtSpeed);
yield return new WaitForSeconds (0.0f);
}
}
And this is the entire class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LookAtOnClick : MonoBehaviour {
private Rigidbody body;
private Collider col;
private Transform trans;
public GameObject playerCam;
public GameObject secondaryCam;
public float lookAtSpeed;
public float rotateSpeed;
public float offsetFromCam;
public float zoomFOV;
private Quaternion targetRotation;
private bool currentlyLooked;
private void Awake()
{
// Assuming a simple, flat hierarchy
body = GetComponent<Rigidbody>();
col = GetComponent<Collider>();
}
public void Start (){
trans = GetComponent<Transform>();
}
void Update(){
if (currentlyLooked) {
RotateTowardCam ();
}
}
public void HitByRay () {
//Debug.Log ("I was hit by a Ray");
LookAtItem ();
}
private void LookAtItem(){
if (Input.GetButtonDown ("Fire1")) {
secondaryCam.SetActive (true);
secondaryCam.GetComponent<Transform> ().position = Camera.main.transform.position;
secondaryCam.GetComponent<Transform> ().rotation = Camera.main.transform.rotation;
secondaryCam.GetComponent<Camera> ().fieldOfView = Camera.main.fieldOfView;
StartCoroutine (MoveCameraToward (secondaryCam.GetComponent<Transform> ().position));
currentlyLooked = true;
Camera.main.enabled = false;
EventManager.TriggerEvent ("InViewMode");
}
}
void RotateTowardCam (){
Vector3 relativePosition = trans.position - secondaryCam.GetComponent<Transform> ().position;
targetRotation = Quaternion.LookRotation (relativePosition, new Vector3 (0, 0, -1));
secondaryCam.GetComponent<Transform> ().rotation = Quaternion.Slerp (secondaryCam.GetComponent<Transform> ().rotation, targetRotation, Time.deltaTime * rotateSpeed);
//Debug.Log (trans.rotation + " " + targetRotation + " " + secondaryCam.GetComponent<Transform> ().rotation);
}
IEnumerator MoveCameraToward (Vector3 startPos)
{
float distCovered = 0f;
while (trans.localPosition != secondaryCam.GetComponent<Transform> ().position * offsetFromCam && secondaryCam.GetComponent<Camera>().fieldOfView != zoomFOV) {
distCovered += Time.deltaTime * lookAtSpeed;
secondaryCam.GetComponent<Transform> ().position = Vector3.Lerp (startPos, trans.position + trans.forward * offsetFromCam, distCovered);
secondaryCam.GetComponent<Camera> ().fieldOfView = Mathf.Lerp (secondaryCam.GetComponent<Camera> ().fieldOfView, zoomFOV, Time.deltaTime * lookAtSpeed);
yield return null;
}
}
}
Thank you for your help.