- Home /
Rotating a camera around a sphere to look at a specific point
I have a planet and I'd like the camera to rotate towards a specific point on the planet (rotate and transform towards). The issue I'm having is that I can't seem to tell which direction I should be rotating towards to have the camera line up correctly with the point on the planet. I'd really like to have the camera rotate around the planet instead of having the planet rotate if possible. This is the script I'm using so far. Thanks!
void RotateAroundPlanet(GameObject location)
{
Ray ray = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
RaycastHit hit;
if(Physics.Raycast(ray, out hit))
{
if(hit.collider.gameObject != location)
transform.RotateAround(planet.transform.position, Direction(hit.point, location.transform.position), Time.deltaTime * 25);
}
}
Vector3 Direction(Vector3 from, Vector3 to)
{
return (to - from).normalized;
}
Answer by randomuser · Apr 03, 2013 at 11:50 PM
Hello. I had to do the exact same thing. I solved it by adding a empty game object to the center of the planet and attaching the camera to it. I then added the rotation script to the empty game object. When you change the object at then center's rotation, the camera rotates around it and the planet. To do the transform, I would adjust the zoom of the camera, called f-stop I think. It looks like you are moving closer and is much less clumsy than moving the real camera (which should be avoided unless necessary in this situation). If you actually need to move the camera (like you were landing on the plant) this becomes much more difficult.
Answer by robertbu · Apr 04, 2013 at 12:02 AM
If you want a spherical rotation, you can use Vector3.Slerp(). Here is a bit of test code:
using UnityEngine;
using System.Collections;
public class SlerpTest : MonoBehaviour {
public GameObject goPlanet; // "Planet" to rotate around
public float altitude = 4.0f; // Height above the planet
public Vector3 v3Start = Vector3.left;
public Vector3 v3End = new Vector3(0.5f, 0.5f, -0.5f);
private Vector3 v3StartPos;
private Vector3 v3EndPos;
private float timer = 0.0f;
private float speed = 0.15f;
void Start () {
v3StartPos = v3Start.normalized * altitude;
v3EndPos = v3End.normalized * altitude;
}
// Update is called once per frame
void Update () {
if (timer <= 1.0)
transform.position = goPlanet.transform.position + Vector3.Slerp (v3StartPos, v3EndPos, timer);
timer += Time.deltaTime * speed;
if (Input.GetKeyDown(KeyCode.Space))
timer = 0.0f;
}
}
Create two game object, one to be the center of rotation, and the other to rotate around the center. Attach this script to the one that will be rotating, and drag and drop the center object onto 'goPlanet'. 'v3Start' and 'v3End' are vectors relative to the center along which the object will be placed. 'altitude' is the distance up from the center to place the rotating object.
Note if you were generating the position on the center object through a hit point, you would do something like:
v3End = hit.point - goPlanet.transform.position;
This makes v3End relative to the planet. At the end of the rotation, you will be over that point.
I guess I'm not really following this script, i tried it out and it seems to do exactly what RotateAround would do.
The difference is that you can define a start and end vector for so that you are "over" your hit point at the end of the Slerp().
Here is another example script. The setup is the same as above, but the center object must be named "Center." You can click on on the center sphere and the object will rotate so that it is overhead that point.
public class SlerpTest : $$anonymous$$onoBehaviour {
public GameObject goCenter; // Object to rotate around
public float speed = 0.35f;
private float altitude = 4.0f; // Height above the planet
private Vector3 v3StartPos;
private Vector3 v3EndPos;
private float timer = 1.1f;
void Start () {
altitude = (transform.position - goCenter.transform.position).magnitude;
}
void Update () {
if (Input.Get$$anonymous$$ouseButtonDown (0)) {
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit) && hit.collider.name == "Center") {
timer = 0.0f;
v3StartPos = transform.position - goCenter.transform.position;
v3EndPos = (hit.point - goCenter.transform.position).normalized * altitude;
}
}
if (timer <= 1.0)
transform.position = goCenter.transform.position + Vector3.Slerp (v3StartPos, v3EndPos, timer);
timer += Time.deltaTime * speed;
}
}
Your answer
Follow this Question
Related Questions
Rotate around moves object out of position, why? 1 Answer
How to limit the angle of a camera with transform.RotateAround? 1 Answer
Get the rotation of a object around a arbitrary axis. 0 Answers
Rotate Around Planet with Spaceship Face Set on Path 1 Answer
Error with transform.RotateAround when I use a variable for the last parameter... 1 Answer