242 lines
7.7 KiB
C#
242 lines
7.7 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public class CameraController : MonoBehaviour
|
|
{
|
|
public Camera mainCamera;
|
|
public float transitionSpeed = 3f;
|
|
|
|
public float planetDistance = 15f;
|
|
public float planetHeight = 5f;
|
|
public float rotationSpeed = 100f;
|
|
|
|
public float cameraLocalX = 1.76f;
|
|
public float cameraLocalY = 1.14f;
|
|
public float cameraLocalZ = -1.51f;
|
|
public Vector3 cameraLocalRotation;
|
|
|
|
public float sunZoomSpeed = 10f;
|
|
public float sunMinZ = -200f;
|
|
public float sunMaxZ = -5f;
|
|
|
|
private Dictionary<int, GameObject> _planets = new Dictionary<int, GameObject>();
|
|
private GameObject _sun;
|
|
private int _currentIndex = 0;
|
|
private bool _isTransitioning = false;
|
|
|
|
private float _currentPlanetDistance;
|
|
private float _planetRotationY = 0f;
|
|
private float _planetRotationX = 20f;
|
|
|
|
void Start()
|
|
{
|
|
_sun = GameObject.Find("Sun");
|
|
|
|
FindPlanetByName(1, "Mercury");
|
|
FindPlanetByName(2, "Venus");
|
|
FindPlanetByName(3, "Earth");
|
|
FindPlanetByName(4, "Mars");
|
|
FindPlanetByName(5, "Jupiter");
|
|
FindPlanetByName(6, "Saturn");
|
|
FindPlanetByName(7, "Uranus");
|
|
FindPlanetByName(8, "Neptune");
|
|
FindPlanetByName(9, "Pluto");
|
|
|
|
_currentPlanetDistance = planetDistance;
|
|
|
|
ShowOverview();
|
|
}
|
|
|
|
void FindPlanetByName(int key, string planetName)
|
|
{
|
|
GameObject planet = GameObject.Find(planetName);
|
|
if (planet != null)
|
|
_planets[key] = planet;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
HandleInput();
|
|
|
|
if (!_isTransitioning && _currentIndex != 0)
|
|
HandlePlanetCamera();
|
|
|
|
if (!_isTransitioning && _currentIndex == 0)
|
|
HandleSunZoom();
|
|
}
|
|
|
|
void HandleInput()
|
|
{
|
|
if (Input.GetKeyDown(KeyCode.Alpha0) || Input.GetKeyDown(KeyCode.Keypad0))
|
|
ShowOverview();
|
|
|
|
if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1)) FocusPlanet(1);
|
|
if (Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2)) FocusPlanet(2);
|
|
if (Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3)) FocusPlanet(3);
|
|
if (Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4)) FocusPlanet(4);
|
|
if (Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5)) FocusPlanet(5);
|
|
if (Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6)) FocusPlanet(6);
|
|
if (Input.GetKeyDown(KeyCode.Alpha7) || Input.GetKeyDown(KeyCode.Keypad7)) FocusPlanet(7);
|
|
if (Input.GetKeyDown(KeyCode.Alpha8) || Input.GetKeyDown(KeyCode.Keypad8)) FocusPlanet(8);
|
|
if (Input.GetKeyDown(KeyCode.Alpha9) || Input.GetKeyDown(KeyCode.Keypad9)) FocusPlanet(9);
|
|
|
|
if (Input.GetKeyDown(KeyCode.RightArrow)) NextPlanet();
|
|
if (Input.GetKeyDown(KeyCode.LeftArrow)) PreviousPlanet();
|
|
}
|
|
|
|
void ShowOverview()
|
|
{
|
|
_currentIndex = 0;
|
|
StopAllCoroutines();
|
|
StartCoroutine(TransitionToSun());
|
|
}
|
|
|
|
void FocusPlanet(int planetNumber)
|
|
{
|
|
if (!_planets.ContainsKey(planetNumber)) return;
|
|
|
|
_currentIndex = planetNumber;
|
|
StopAllCoroutines();
|
|
StartCoroutine(TransitionToPlanet(planetNumber));
|
|
}
|
|
|
|
void NextPlanet()
|
|
{
|
|
_currentIndex++;
|
|
if (_currentIndex > 9) _currentIndex = 0;
|
|
if (_currentIndex == 0) ShowOverview();
|
|
else FocusPlanet(_currentIndex);
|
|
}
|
|
|
|
void PreviousPlanet()
|
|
{
|
|
_currentIndex--;
|
|
if (_currentIndex < 0) _currentIndex = 9;
|
|
if (_currentIndex == 0) ShowOverview();
|
|
else FocusPlanet(_currentIndex);
|
|
}
|
|
|
|
IEnumerator TransitionToSun()
|
|
{
|
|
_isTransitioning = true;
|
|
|
|
if (_sun == null)
|
|
{
|
|
_isTransitioning = false;
|
|
yield break;
|
|
}
|
|
|
|
Vector3 startPos = mainCamera.transform.position;
|
|
Quaternion startRot = mainCamera.transform.rotation;
|
|
|
|
Vector3 targetWorldPos = _sun.transform.TransformPoint(
|
|
new Vector3(cameraLocalX, cameraLocalY, cameraLocalZ)
|
|
);
|
|
Quaternion targetWorldRot = _sun.transform.rotation * Quaternion.Euler(cameraLocalRotation);
|
|
|
|
float elapsed = 0f;
|
|
float duration = 1f / transitionSpeed;
|
|
|
|
while (elapsed < duration)
|
|
{
|
|
elapsed += Time.deltaTime;
|
|
float t = Mathf.SmoothStep(0, 1, elapsed / duration);
|
|
|
|
mainCamera.transform.position = Vector3.Lerp(startPos, targetWorldPos, t);
|
|
mainCamera.transform.rotation = Quaternion.Slerp(startRot, targetWorldRot, t);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
mainCamera.transform.SetParent(_sun.transform);
|
|
mainCamera.transform.localPosition = new Vector3(cameraLocalX, cameraLocalY, cameraLocalZ);
|
|
mainCamera.transform.localRotation = Quaternion.Euler(cameraLocalRotation);
|
|
|
|
_isTransitioning = false;
|
|
}
|
|
|
|
void HandleSunZoom()
|
|
{
|
|
if (mainCamera.transform.parent != _sun.transform) return;
|
|
|
|
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
|
if (Mathf.Abs(scroll) < 0.001f) return;
|
|
|
|
cameraLocalZ += scroll * sunZoomSpeed;
|
|
cameraLocalZ = Mathf.Clamp(cameraLocalZ, sunMinZ, sunMaxZ);
|
|
|
|
mainCamera.transform.localPosition = new Vector3(
|
|
cameraLocalX,
|
|
cameraLocalY,
|
|
cameraLocalZ
|
|
);
|
|
}
|
|
|
|
IEnumerator TransitionToPlanet(int planetNumber)
|
|
{
|
|
_isTransitioning = true;
|
|
|
|
Transform planet = _planets[planetNumber].transform;
|
|
|
|
mainCamera.transform.SetParent(null);
|
|
|
|
Vector3 startPos = mainCamera.transform.position;
|
|
Quaternion startRot = mainCamera.transform.rotation;
|
|
|
|
_currentPlanetDistance = planetDistance;
|
|
Vector3 localTargetPos = new Vector3(0, planetHeight, -_currentPlanetDistance);
|
|
Vector3 worldTargetPos = planet.TransformPoint(localTargetPos);
|
|
Quaternion targetRot = Quaternion.LookRotation(planet.position - worldTargetPos);
|
|
|
|
float elapsed = 0f;
|
|
float duration = 1f / transitionSpeed;
|
|
|
|
while (elapsed < duration)
|
|
{
|
|
elapsed += Time.deltaTime;
|
|
float t = Mathf.SmoothStep(0, 1, elapsed / duration);
|
|
|
|
mainCamera.transform.position = Vector3.Lerp(startPos, worldTargetPos, t);
|
|
mainCamera.transform.rotation = Quaternion.Slerp(startRot, targetRot, t);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
mainCamera.transform.SetParent(planet);
|
|
mainCamera.transform.localPosition = localTargetPos;
|
|
mainCamera.transform.LookAt(planet.position);
|
|
|
|
_planetRotationY = 0f;
|
|
_planetRotationX = planetHeight > 0 ? 20f : 0f;
|
|
|
|
_isTransitioning = false;
|
|
}
|
|
|
|
void HandlePlanetCamera()
|
|
{
|
|
if (!_planets.ContainsKey(_currentIndex)) return;
|
|
|
|
Transform planet = _planets[_currentIndex].transform;
|
|
|
|
if (Input.GetMouseButton(1))
|
|
{
|
|
_planetRotationY += Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime;
|
|
_planetRotationX -= Input.GetAxis("Mouse Y") * rotationSpeed * Time.deltaTime;
|
|
_planetRotationX = Mathf.Clamp(_planetRotationX, -85f, 85f);
|
|
}
|
|
|
|
float scroll = Input.GetAxis("Mouse ScrollWheel");
|
|
_currentPlanetDistance -= scroll * 10f;
|
|
_currentPlanetDistance = Mathf.Clamp(_currentPlanetDistance, 3f, 100f);
|
|
|
|
Quaternion rotation = Quaternion.Euler(_planetRotationX, _planetRotationY, 0);
|
|
Vector3 localPos = rotation * new Vector3(0, 0, -_currentPlanetDistance);
|
|
|
|
mainCamera.transform.localPosition = localPos;
|
|
Vector3 direction = planet.position - mainCamera.transform.position;
|
|
mainCamera.transform.rotation =
|
|
Quaternion.LookRotation(direction, planet.up);
|
|
}
|
|
}
|