I’m creating a game in Unity3D that requires the player to be in control of a planet. I want the camera to move around the planet and rotate in the vector direction of the mouse when the player is holding down the right click anywhere on the screen. I have code written out. However, the player is only able to rotate the camera around the planet if the mouse is on the planet, and throws a “InvalidOperationException: Nullable Object must have a value” error if it is off the planet. How do I change it so that the camera will rotate around the planet even if the mouse is not on the planet? Also, I need the camera to zoom in and out using the scroll on the mouse, and I’m not entirely sure how to do that? Thank you in advance.
public class NewCameraScript : MonoBehaviour {
private Vector3? mouseStartPosition;
private Vector3? currentMousePosition;
[Header("Settings")]
public float planetRadius = 100f;
public float distance;
public float zoomSensitivity;
public float maxZoom;
public float minZoom;
public float slowZoomValue;
public GameObject planet;
void Start()
{
// Cameras initial position
Camera.main.transform.position = new Vector3(planet.transform.position.x, planet.transform.position.y, planet.transform.position.z - distance);
Camera.main.transform.LookAt(planet.transform.position);
}
private void LateUpdate()
{
if (Input.GetMouseButtonDown(1))
mouseStartPosition = GetMouseHit();
if (mouseStartPosition != null)
DragPlanet();
if (Input.GetMouseButtonUp(1))
StaticPlanet();
}
private void DragPlanet()
{
currentMousePosition = GetMouseHit();
RotateCamera((Vector3)mouseStartPosition, (Vector3)currentMousePosition);
}
private void StaticPlanet()
{
mouseStartPosition = null;
currentMousePosition = null;
}
private void Zoom()
{
}
private void RotateCamera(Vector3 dragStartPosition, Vector3 dragEndPosition)
{
//normalised for odd edges
dragEndPosition = dragEndPosition.normalized *planetRadius;
dragStartPosition = dragStartPosition.normalized * planetRadius;
// Cross Product
Vector3 cross = Vector3.Cross(dragEndPosition, dragStartPosition);
// Angle for rotation
float angle = Vector3.SignedAngle(dragEndPosition, dragStartPosition, cross);
//Causes Rotation of angle around the vector from Cross product
Camera.main.transform.RotateAround(planet.transform.position , cross, angle);
}
private static Vector3? GetMouseHit()
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
{
return hit.point;
}
return null;
}
}