Initial commit

This commit is contained in:
2026-03-17 13:40:09 +02:00
commit 91fb7fdad5
1055 changed files with 388166 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AirTrailController : MonoBehaviour
{
[SerializeField] private TrailRenderer trail;
private bool _active;
void Awake()
{
trail.emitting = false;
trail.Clear();
}
void LateUpdate()
{
if (!_active) return;
}
public void Activate(Vector3 startPos)
{
transform.position = startPos;
trail.Clear();
trail.emitting = false;
trail.emitting = true;
_active = true;
}
public void Deactivate()
{
_active = false;
trail.emitting = false;
trail.Clear();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c4fc423f8b56a3c49b0465f34ef591fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Billboard : MonoBehaviour
{
private Transform _parentObject;
public float heightOffset = 1.5f;
void Start()
{
_parentObject = transform.parent;
transform.SetParent(null);
}
void LateUpdate()
{
if (_parentObject == null) return;
if (Camera.main == null) return;
transform.position = _parentObject.position + Vector3.up * heightOffset;
transform.LookAt(Camera.main.transform);
transform.Rotate(0, 180, 0);
}
void OnDestroy()
{
if (_parentObject == null)
{
Destroy(gameObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c82cf7b3ebf181e4599af2d56540458b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using System;
public class Calendar : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI monthText;
[SerializeField] private Transform daysParent;
[SerializeField] private GameObject dayPrefab;
private DateTime _currentDate;
private List<GameObject> _currentMonthButtons =
new List<GameObject>();
private int _lastMonth = -1;
private int _lastYear = -1;
public void SetDate(DateTime newDate)
{
_currentDate = newDate;
if (_currentDate.Month != _lastMonth ||
_currentDate.Year != _lastYear)
{
_lastMonth = _currentDate.Month;
_lastYear = _currentDate.Year;
GenerateCalendar();
}
else
{
UpdateVisual();
}
}
private void GenerateCalendar()
{
for (int i = daysParent.childCount - 1; i >= 0; i--)
{
Destroy(daysParent.GetChild(i).gameObject);
}
_currentMonthButtons.Clear();
monthText.text = _currentDate.ToString("MMMM yyyy");
DateTime firstDay =
new DateTime(_currentDate.Year,
_currentDate.Month,
1);
int daysInMonth =
DateTime.DaysInMonth(_currentDate.Year,
_currentDate.Month);
int startDayOfWeek =
((int)firstDay.DayOfWeek + 6) % 7;
DateTime prevMonth =
_currentDate.AddMonths(-1);
int daysInPrevMonth =
DateTime.DaysInMonth(prevMonth.Year,
prevMonth.Month);
for (int i = startDayOfWeek; i > 0; i--)
{
int dayNumber =
daysInPrevMonth - i + 1;
GameObject dayObj =
Instantiate(dayPrefab, daysParent);
dayObj.GetComponentInChildren<TextMeshProUGUI>()
.text = dayNumber.ToString();
Image img =
dayObj.GetComponent<Image>();
img.color = Color.gray;
}
for (int day = 1; day <= daysInMonth; day++)
{
GameObject dayObj =
Instantiate(dayPrefab, daysParent);
dayObj.GetComponentInChildren<TextMeshProUGUI>()
.text = day.ToString();
_currentMonthButtons.Add(dayObj);
}
UpdateVisual();
}
private void UpdateVisual()
{
int today = _currentDate.Day;
for (int i = 0; i < _currentMonthButtons.Count; i++)
{
Image img =
_currentMonthButtons[i]
.GetComponent<Image>();
Transform marker =
_currentMonthButtons[i]
.transform.Find("CurrentData");
int dayNumber = i + 1;
if (dayNumber < today)
{
img.color = Color.gray;
if (marker != null)
marker.gameObject.SetActive(false);
}
else if (dayNumber == today)
{
img.color = Color.white;
if (marker != null)
marker.gameObject.SetActive(true);
}
else
{
img.color = Color.white;
if (marker != null)
marker.gameObject.SetActive(false);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0280349c718ed9246a7ea331113f1dc6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,156 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public enum PlanetType
{
Mercury,
Venus,
Earth,
Mars,
Jupiter,
Saturn,
Uranus,
Neptune,
Pluto
}
public class CalendarManager : MonoBehaviour
{
[SerializeField] private Calendar calendar;
[SerializeField] private PlanetSpin planetSpin;
[SerializeField] private PlanetType planetType = PlanetType.Earth;
private DateTime _currentDate;
private float _timer = 0f;
private float _planetDayProgress = 0f;
private float _baseRotationSpeed;
private Dictionary<PlanetType, float> _planetDayLength =
new Dictionary<PlanetType, float>()
{
{ PlanetType.Mercury, 58.6f },
{ PlanetType.Venus, 243f },
{ PlanetType.Earth, 1f },
{ PlanetType.Mars, 1.03f },
{ PlanetType.Jupiter, 0.41f },
{ PlanetType.Saturn, 0.44f },
{ PlanetType.Uranus, 0.72f },
{ PlanetType.Neptune, 0.67f },
{ PlanetType.Pluto, 6.39f }
};
private Dictionary<PlanetType, float> _baseRotationSpeeds =
new Dictionary<PlanetType, float>()
{
{ PlanetType.Mercury, 0.26f },
{ PlanetType.Venus, -0.025f },
{ PlanetType.Earth, 15f },
{ PlanetType.Mars, 14.6f },
{ PlanetType.Jupiter, 36.4f },
{ PlanetType.Saturn, 33.6f },
{ PlanetType.Uranus, -20.9f },
{ PlanetType.Neptune, 22.4f },
{ PlanetType.Pluto, -2.35f }
};
void Start()
{
_currentDate = DateTime.Now;
ApplyPlanetSettings();
if (calendar != null)
calendar.SetDate(_currentDate);
}
void Update()
{
CheckResetInput();
if (planetSpin == null) return;
if (Mathf.Abs(_baseRotationSpeed) < 0.0001f) return;
float currentSpeed = planetSpin.RotationSpeed;
float speedRatio = currentSpeed / _baseRotationSpeed;
if (Mathf.Abs(speedRatio) < 0.0001f) return;
float secondsPerEarthDay = 1f / Mathf.Abs(speedRatio);
_timer += Time.deltaTime;
if (_timer >= secondsPerEarthDay)
{
_timer = 0f;
float planetMultiplier =
1f / _planetDayLength[planetType];
_planetDayProgress += planetMultiplier;
if (_planetDayProgress >= 1f)
{
int daysToAdd =
Mathf.FloorToInt(_planetDayProgress);
_currentDate =
_currentDate.AddDays(daysToAdd);
_planetDayProgress -= daysToAdd;
if (calendar != null)
calendar.SetDate(_currentDate);
}
}
}
public void ChangePlanet(PlanetType newPlanet)
{
planetType = newPlanet;
ApplyPlanetSettings();
}
private void ApplyPlanetSettings()
{
_baseRotationSpeed =
_baseRotationSpeeds[planetType];
if (planetSpin != null)
planetSpin.SetRotationSpeed(
_baseRotationSpeed);
_planetDayProgress = 0f;
_timer = 0f;
}
private void CheckResetInput()
{
for (int i = 0; i <= 9; i++)
{
if (Input.GetKeyDown(KeyCode.Alpha0 + i) ||
Input.GetKeyDown(KeyCode.Keypad0 + i))
{
ResetToBaseSpeed();
break;
}
}
}
private void ResetToBaseSpeed()
{
if (planetSpin == null) return;
planetSpin.SetRotationSpeed(
_baseRotationSpeed);
_timer = 0f;
_planetDayProgress = 0f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 417b78b32d1a42443891caffbd20b9bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,241 @@
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);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 09215415902ffb443a9218882c828949
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraManager : MonoBehaviour
{
[Header("Cameras")]
[SerializeField] private Camera planetCamera;
[SerializeField] private Camera zodiacCamera;
[Header("Modes")]
public bool planetsMode = true;
public bool zodiacMode = false;
void Start()
{
ApplyMode();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.P))
{
planetsMode = true;
zodiacMode = false;
ApplyMode();
}
if (Input.GetKeyDown(KeyCode.Z))
{
planetsMode = false;
zodiacMode = true;
ApplyMode();
}
}
public void ApplyMode()
{
if (planetCamera != null)
planetCamera.enabled = planetsMode;
if (zodiacCamera != null)
zodiacCamera.enabled = zodiacMode;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 18092287e6b14e74ea4080a9936907b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CelestialCalendarController : MonoBehaviour
{
[System.Serializable]
public class PlanetCalendar
{
public GameObject planet;
public GameObject calendar;
}
[SerializeField] private List<PlanetCalendar> planetCalendars;
private GameObject _activeCalendar;
private Camera _activeCamera;
void Start()
{
foreach (var item in planetCalendars)
{
if (item.calendar != null)
item.calendar.SetActive(false);
}
UpdateActiveCamera();
}
void Update()
{
UpdateActiveCamera();
if (_activeCamera == null)
{
return;
}
for (int i = 0; i <= 9; i++)
{
if (Input.GetKeyDown(KeyCode.Alpha0 + i) ||
Input.GetKeyDown(KeyCode.Keypad0 + i))
{
HideActive();
return;
}
}
if (!Input.GetMouseButtonDown(0))
return;
Ray ray = _activeCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (!Physics.Raycast(ray, out hit))
{
HideActive();
return;
}
foreach (var item in planetCalendars)
{
if (item.planet == null) continue;
if (hit.collider.gameObject == item.planet ||
hit.collider.transform.IsChildOf(item.planet.transform))
{
ToggleCalendar(item.calendar);
return;
}
}
HideActive();
}
void UpdateActiveCamera()
{
Camera[] cameras = Camera.allCameras;
foreach (var cam in cameras)
{
if (cam.enabled && cam.gameObject.activeInHierarchy)
{
_activeCamera = cam;
return;
}
}
_activeCamera = null;
}
void ToggleCalendar(GameObject calendar)
{
if (calendar == null) return;
if (_activeCalendar == calendar)
{
HideActive();
return;
}
HideActive();
calendar.SetActive(true);
_activeCalendar = calendar;
}
void HideActive()
{
if (_activeCalendar != null)
{
_activeCalendar.SetActive(false);
_activeCalendar = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d8a2451b673893c4da97804e208be5a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,196 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Constellation : MonoBehaviour
{
[Header("Режим малювання")]
public bool editMode = false;
[Header("Максимальна кількіссть зірок")]
public int maxStars = 10;
[Header("Матеріали")]
[SerializeField] private GameObject starPrefab;
[SerializeField] private Material lineMaterial;
[Header("Відстань")]
[SerializeField] private float planeDistance = 8f;
[Header("Розміри")]
[SerializeField] private float starScaleMin = 0.06f;
[SerializeField] private float starScaleMax = 0.14f;
[SerializeField] private float lineWidth = 0.02f;
private readonly List<Transform> _stars = new List<Transform>();
private readonly List<LineRenderer> _lines = new List<LineRenderer>();
private Transform _root;
private Camera _cam;
private void Awake()
{
EnsureCameraAndRoot();
}
private void Update()
{
if (!editMode) return;
EnsureCameraAndRoot();
if (_cam == null)
{
return;
}
if (Input.GetMouseButtonDown(0))
{
TryAddStarByClick(Input.mousePosition);
}
UpdateAllLines();
}
private void EnsureCameraAndRoot()
{
if (_cam == null || !_cam.enabled)
{
_cam = FindEnabledCamera();
}
if (_cam != null && (_root == null || _root.parent != _cam.transform))
{
if (_root == null)
{
GameObject go = new GameObject("ConstellationRoot");
_root = go.transform;
}
_root.SetParent(_cam.transform);
_root.localPosition = new Vector3(0f, 0f, planeDistance);
_root.localRotation = Quaternion.identity;
_root.localScale = Vector3.one;
}
}
private Camera FindEnabledCamera()
{
Camera[] cams = Camera.allCameras;
for (int i = 0; i < cams.Length; i++)
{
if (cams[i] != null && cams[i].enabled && cams[i].gameObject.activeInHierarchy)
return cams[i];
}
if (Camera.main != null && Camera.main.enabled)
return Camera.main;
return null;
}
private void TryAddStarByClick(Vector3 screenPos)
{
Ray ray = _cam.ScreenPointToRay(screenPos);
Plane plane = new Plane(_cam.transform.forward, _cam.transform.position + _cam.transform.forward * planeDistance);
if (!plane.Raycast(ray, out float enter))
{
return;
}
Vector3 worldHit = ray.GetPoint(enter);
Vector3 localHit = _root.InverseTransformPoint(worldHit);
GameObject starGo = Instantiate(starPrefab, _root);
starGo.name = "Star_" + _stars.Count;
Transform starT = starGo.transform;
starT.localPosition = localHit;
float rndScale = Random.Range(starScaleMin, starScaleMax);
starT.localScale = Vector3.one * rndScale;
_stars.Add(starT);
if (_stars.Count >= 2)
{
CreateLine(_stars[_stars.Count - 2], _stars[_stars.Count - 1]);
}
}
private void CreateLine(Transform a, Transform b)
{
if (a == null || b == null) return;
GameObject lineGo = new GameObject("Line_" + _lines.Count);
lineGo.transform.SetParent(_root);
lineGo.transform.localPosition = Vector3.zero;
lineGo.transform.localRotation = Quaternion.identity;
lineGo.transform.localScale = Vector3.one;
LineRenderer lr = lineGo.AddComponent<LineRenderer>();
if (lineMaterial != null)
{
lr.material = lineMaterial;
}
else
{
Material fallback = new Material(Shader.Find("Unlit/Color"));
fallback.color = new Color(0.7f, 0.85f, 1f, 1f);
lr.material = fallback;
}
lr.useWorldSpace = false;
lr.positionCount = 2;
lr.startWidth = lineWidth;
lr.endWidth = lineWidth;
lr.numCapVertices = 6;
lr.numCornerVertices = 6;
_lines.Add(lr);
lr.SetPosition(0, a.localPosition);
lr.SetPosition(1, b.localPosition);
}
private void UpdateAllLines()
{
int needed = Mathf.Max(0, _stars.Count - 1);
if (_lines.Count < needed) return;
for (int i = 0; i < needed; i++)
{
LineRenderer lr = _lines[i];
if (lr == null) continue;
Transform a = _stars[i];
Transform b = _stars[i + 1];
if (a == null || b == null) continue;
lr.SetPosition(0, a.localPosition);
lr.SetPosition(1, b.localPosition);
}
}
public void ClearAll()
{
for (int i = 0; i < _lines.Count; i++)
{
if (_lines[i] != null) Destroy(_lines[i].gameObject);
}
for (int i = 0; i < _stars.Count; i++)
{
if (_stars[i] != null) Destroy(_stars[i].gameObject);
}
_lines.Clear();
_stars.Clear();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88f4e4721ea8d144cac21d732d053f30
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ConstellationManager : MonoBehaviour
{
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8357f6bd3c528a4479c2717bd97bf93f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,156 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CustomCursor : MonoBehaviour
{
[Header("Курсори")]
[SerializeField] private Texture2D normalCursor;
[SerializeField] private Texture2D targetCursor;
[SerializeField] private Vector2 hotspot = new Vector2(16, 16);
[Header("Підняття")]
[SerializeField] private Camera cameraMain;
[SerializeField] private float pickupDistance = 5f;
[SerializeField] private float holdDistance = 3.4f;
[SerializeField] private Vector3 holdOffset = new Vector3(0, 0.5f, 0);
[SerializeField] private float moveSpeed = 15f;
[Header("Кидання")]
[SerializeField] private float throwForwardForce = 5f;
[SerializeField] private float throwUpForce = 3f;
[SerializeField] private KeyCode throwKey = KeyCode.Mouse0;
private GameObject _heldObject;
private Rigidbody _heldObjectRb;
private AirTrailController _currentTrail;
private void Start()
{
if (cameraMain == null)
cameraMain = Camera.main;
Cursor.SetCursor(normalCursor, hotspot, CursorMode.Auto);
}
private void Update()
{
Ray ray = cameraMain.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (_heldObject != null)
{
if (Input.GetKeyDown(KeyCode.E))
{
PlaceObject();
return;
}
if (Input.GetKeyDown(throwKey))
{
ThrowObject();
return;
}
}
else
{
if (Physics.Raycast(ray, out hit, pickupDistance))
{
if (hit.collider.CompareTag("Target"))
{
Cursor.SetCursor(targetCursor, hotspot, CursorMode.Auto);
if (Input.GetKeyDown(KeyCode.E))
PickupObject(hit.collider.gameObject);
}
else
{
Cursor.SetCursor(normalCursor, hotspot, CursorMode.Auto);
}
}
else
{
Cursor.SetCursor(normalCursor, hotspot, CursorMode.Auto);
}
}
}
private void FixedUpdate()
{
if (_heldObject != null)
HoldObjectAtCursor();
}
private void PickupObject(GameObject obj)
{
_heldObject = obj;
_heldObjectRb = obj.GetComponent<Rigidbody>();
_heldObjectRb.useGravity = false;
_heldObjectRb.velocity = Vector3.zero;
_heldObjectRb.drag = 10f;
_heldObjectRb.angularDrag = 10f;
_currentTrail = _heldObject.GetComponentInChildren<AirTrailController>();
if (_currentTrail != null)
{
_currentTrail.Deactivate();
}
}
private void PlaceObject()
{
bool isMoonObject = _heldObject.GetComponent<MoonGravity>() != null;
_heldObjectRb.useGravity = !isMoonObject;
_heldObjectRb.drag = 0f;
_heldObjectRb.angularDrag = 0.05f;
_heldObjectRb.velocity = Vector3.zero;
if (_currentTrail != null)
{
_currentTrail.Deactivate();
}
_heldObject = null;
_heldObjectRb = null;
_currentTrail = null;
}
private void HoldObjectAtCursor()
{
Ray ray = cameraMain.ScreenPointToRay(Input.mousePosition);
Vector3 targetPos = ray.GetPoint(holdDistance) + holdOffset;
Vector3 dir = targetPos - _heldObject.transform.position;
_heldObjectRb.velocity = dir * moveSpeed;
}
private void ThrowObject()
{
if (_currentTrail != null)
{
Vector3 tailStart = _heldObject.transform.position - cameraMain.transform.forward * 0.3f;
_currentTrail.Activate(tailStart);
}
ObjectPhysicsInfo earthInfo = _heldObject.GetComponent<ObjectPhysicsInfo>();
if (earthInfo != null) earthInfo.OnRelease();
MoonObjectInfo moonInfo = _heldObject.GetComponent<MoonObjectInfo>();
if (moonInfo != null) moonInfo.OnRelease();
bool isMoonObject = _heldObject.GetComponent<MoonGravity>() != null;
_heldObjectRb.useGravity = !isMoonObject;
_heldObjectRb.drag = 0f;
_heldObjectRb.angularDrag = 0.05f;
Vector3 throwDir = cameraMain.transform.forward * throwForwardForce + Vector3.up * throwUpForce;
_heldObjectRb.velocity = throwDir;
_heldObject = null;
_heldObjectRb = null;
_currentTrail = null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d42e0f8a5176e34e8c5a5ec7717d56e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroCameraController : MonoBehaviour
{
[Header("Íàëàøòóâàííÿ ìèø³")]
[Range(1f, 10f)]
[SerializeField] private float _mouseSensitivityX = 2f;
[Range(1f, 10f)]
[Tooltip("×óòëèâ³ñòü ìèø³ ïî âåðòèêàë³")]
[SerializeField] private float _mouseSensitivityY = 2f;
[Range(0f, 0.5f)]
[SerializeField] private float _smoothTime = 0.1f;
[Header("Îáìåæåííÿ êóò³â")]
[SerializeField] private float _minVerticalAngle = -75f;
[SerializeField] private float _maxVerticalAngle = 45f;
[Header("Ïîñèëàííÿ")]
[SerializeField] private Transform _controller;
private float _xRotation = 0f;
private float _yRotation = 0f;
private Vector2 _currentMouseDelta;
private Vector2 _currentMouseVelocity;
private void LateUpdate()
{
HandleCameraRotation();
}
private void HandleCameraRotation()
{
Vector2 targetMouseDelta = new Vector2(
Input.GetAxis("Mouse X") * _mouseSensitivityX,
Input.GetAxis("Mouse Y") * _mouseSensitivityY
);
_currentMouseDelta = Vector2.SmoothDamp(
_currentMouseDelta,
targetMouseDelta,
ref _currentMouseVelocity,
_smoothTime
);
_yRotation += _currentMouseDelta.x;
_xRotation -= _currentMouseDelta.y;
_xRotation = Mathf.Clamp(_xRotation, _minVerticalAngle, _maxVerticalAngle);
transform.localRotation = Quaternion.Euler(_xRotation, 0f, 0f);
if (_controller != null)
{
_controller.rotation = Quaternion.Euler(0f, _yRotation, 0f);
}
}
public void SetSensitivityX(float sensitivity)
{
_mouseSensitivityX = Mathf.Clamp(sensitivity, 1f, 10f);
}
public void SetSensitivityY(float sensitivity)
{
_mouseSensitivityY = Mathf.Clamp(sensitivity, 1f, 10f);
}
public void SetSmoothTime(float smoothTime)
{
_smoothTime = Mathf.Clamp(smoothTime, 0f, 0.5f);
}
public void SetSensitivity(float sensitivity)
{
_mouseSensitivityX = Mathf.Clamp(sensitivity, 1f, 10f);
_mouseSensitivityY = Mathf.Clamp(sensitivity, 1f, 10f);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7670a57d9592c0e4d9cb3fa85786b01a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,72 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeroController : MonoBehaviour
{
[Header("Øâèäê³ñòü ðóõó")]
[Range(1f, 20f)]
[SerializeField] private float _movementSpeed = 5f;
[Header("Ïðèñêîðåííÿ ðóõó")]
[Range(1f, 5f)]
[SerializeField] private float _runMultiplier = 2f;
[Header("Ãðàâ³òàö³ÿ")]
[SerializeField] private float _gravity = -9.81f;
[Header("Ñèëà ñòðèáêó")]
[Range(1f, 20f)]
[SerializeField] private float _jumpHeight = 2f;
private CharacterController _characterController;
private Vector3 _controllerVelocity;
void Start()
{
_characterController = GetComponent<CharacterController>();
}
void Update()
{
HandleMovement();
HandleGravity();
HandleJump();
}
private void HandleMovement()
{
float moveX = Input.GetAxis("Horizontal");
float moveZ = Input.GetAxis("Vertical");
Vector3 movement = transform.right * moveX + transform.forward * moveZ;
float currentSpeed = _movementSpeed;
if (Input.GetKey(KeyCode.LeftShift))
{
currentSpeed *= _runMultiplier;
}
_characterController.Move(movement * currentSpeed * Time.deltaTime);
}
private void HandleGravity()
{
if (_characterController.isGrounded && _controllerVelocity.y < 0)
{
_controllerVelocity.y = -2f;
}
_controllerVelocity.y += _gravity * Time.deltaTime;
_characterController.Move(_controllerVelocity * Time.deltaTime);
}
private void HandleJump()
{
if (Input.GetButtonDown("Jump") && _characterController.isGrounded)
{
_controllerVelocity.y = Mathf.Sqrt(_jumpHeight * -2f * _gravity);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 28e7b6caa53e8b34eaed9f45728ba640
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,161 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MarsmoonsOrbit : MonoBehaviour
{
public Transform mars;
public MoonType moonType = MoonType.Phobos;
public bool autoCalculateOrbit = true;
public float manualOrbitRadius = 9.4f;
public float orbitInclination = 1.08f;
public float startAngleDegrees = 0f;
public float timeScale = 10f;
public bool showDebugInfo = false;
private const float MARS_RADIUS_KM = 3390f;
private const float PHOBOS_DISTANCE_KM = 9376f;
private const float PHOBOS_PERIOD_HOURS = 7.65f;
private const float DEIMOS_DISTANCE_KM = 23463f;
private const float DEIMOS_PERIOD_HOURS = 30.3f;
private float orbitRadius;
private float angularSpeed;
private float currentAngle = 0f;
private float orbitCount = 0f;
private float debugTimer = 0f;
public enum MoonType
{
Phobos,
Deimos
}
void Start()
{
if (mars == null)
{
mars = GameObject.Find("Mars")?.transform;
if (mars == null)
{
enabled = false;
return;
}
}
CalculateOrbit();
SetInitialPosition();
}
void CalculateOrbit()
{
float marsRadius = mars.localScale.x / 2f;
if (autoCalculateOrbit)
{
if (moonType == MoonType.Phobos)
{
orbitRadius = marsRadius * (PHOBOS_DISTANCE_KM / MARS_RADIUS_KM);
float period = PHOBOS_PERIOD_HOURS * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
orbitInclination = 1.08f;
}
else
{
orbitRadius = marsRadius * (DEIMOS_DISTANCE_KM / MARS_RADIUS_KM);
float period = DEIMOS_PERIOD_HOURS * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
orbitInclination = 1.79f;
}
}
else
{
orbitRadius = manualOrbitRadius;
float period = (moonType == MoonType.Phobos ? PHOBOS_PERIOD_HOURS : DEIMOS_PERIOD_HOURS) * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
}
}
void SetInitialPosition()
{
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
UpdatePosition();
}
void Update()
{
if (mars == null) return;
currentAngle += angularSpeed * Time.deltaTime;
if (currentAngle >= 2f * Mathf.PI)
{
currentAngle -= 2f * Mathf.PI;
orbitCount++;
if (showDebugInfo)
{
Debug.Log(moonType + " orbit " + orbitCount);
}
}
UpdatePosition();
if (showDebugInfo)
{
debugTimer += Time.deltaTime;
if (debugTimer >= 10f)
{
debugTimer = 0f;
float progress = (currentAngle / (2f * Mathf.PI)) * 100f;
Debug.Log(moonType + ": R=" + orbitRadius.ToString("F2") + " P=" + progress.ToString("F1") + "%");
}
}
}
void UpdatePosition()
{
float x = Mathf.Cos(currentAngle) * orbitRadius;
float z = Mathf.Sin(currentAngle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
transform.position = mars.position + new Vector3(x, y, z);
}
void OnDrawGizmos()
{
if (mars == null) return;
Gizmos.color = moonType == MoonType.Phobos ? new Color(1f, 0.5f, 0.5f, 0.5f) : new Color(0.5f, 0.7f, 1f, 0.5f);
int segments = 64;
Vector3 prevPos = GetOrbitPoint(0);
for (int i = 1; i <= segments; i++)
{
Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments);
Gizmos.DrawLine(prevPos, newPos);
prevPos = newPos;
}
}
Vector3 GetOrbitPoint(float angle)
{
float x = Mathf.Cos(angle) * orbitRadius;
float z = Mathf.Sin(angle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
return mars.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88294a843778ac649973a306a1c356d4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class MassTarget
{
[Header("Назва")]
public string ukrainianName;
[Header("Rigidbody обʼєкта")]
public Rigidbody rigidbody;
[HideInInspector]
public float baseMass;
}
public class MassInspectorController : MonoBehaviour
{
[Header("Список обʼєктів")]
public List<MassTarget> targets = new List<MassTarget>();
private void OnValidate()
{
for (int i = 0; i < targets.Count; i++)
{
if (targets[i] == null) continue;
if (targets[i].rigidbody == null) continue;
if (targets[i].baseMass <= 0f)
targets[i].baseMass = targets[i].rigidbody.mass;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e883c09c525351e49a1618558df234e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MassSliderController : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 88bd81e4a6167454ba115b8ba06aa071
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonGravity : MonoBehaviour
{
private Rigidbody _rb;
private void Awake()
{
_rb = GetComponent<Rigidbody>();
_rb.useGravity = false;
}
private void FixedUpdate()
{
_rb.AddForce(Vector3.down * 1.62f, ForceMode.Acceleration);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d410bad46ab98044b782c737e5b183a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonGravityForce : MonoBehaviour
{
[Header("Швидкість обертання навколо Землі")]
[Range(0f, 100f)]
[SerializeField] private float orbitSpeed = 0.55f;
[Header("Нахил осі Місяця")]
[Range(0f, 180f)]
[SerializeField] private float axialTilt = 6.68f;
private PlanetSpin _parentSpin;
private Transform _parentTransform;
void Start()
{
_parentTransform = transform.parent;
_parentSpin = _parentTransform.GetComponent<PlanetSpin>();
transform.localRotation = Quaternion.Euler(0f, 0f, axialTilt);
}
void Update()
{
float parentRotationSpeed = _parentSpin != null ? _parentSpin.RotationSpeed : 0f;
float compensatedOrbit = orbitSpeed - parentRotationSpeed;
transform.RotateAround(
_parentTransform.position,
Vector3.up,
compensatedOrbit * Time.deltaTime
);
transform.LookAt(_parentTransform.position);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1219dc08a36c7914c94a80ac0d2be6b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class MoonObjectInfo : MonoBehaviour
{
public TextMeshProUGUI infoText;
private Rigidbody _rb;
private float _startTime;
private float _startHeight;
private bool _isFalling = false;
private bool _hasLanded = false;
private float _startMass;
private const float moonGravity = 1.62f;
void Start()
{
_rb = GetComponent<Rigidbody>();
_startMass = _rb.mass;
if (infoText != null)
infoText.text = "";
}
void Update()
{
if (infoText != null)
{
infoText.transform.parent.LookAt(Camera.main.transform);
infoText.transform.parent.Rotate(0, 180, 0);
}
}
public void OnRelease()
{
_startTime = Time.time;
_startHeight = transform.position.y;
_isFalling = true;
_hasLanded = false;
if (infoText != null)
infoText.text = "";
}
void OnCollisionEnter(Collision collision)
{
if (_isFalling && !_hasLanded && collision.gameObject.CompareTag("Ground"))
{
_hasLanded = true;
_isFalling = false;
float fallTime = Time.time - _startTime;
float dropHeight = _startHeight - transform.position.y;
float impactSpeed = _rb.velocity.magnitude;
float mass = _rb.mass;
float gravityForce = mass * moonGravity;
float theoreticalTime = Mathf.Sqrt((2 * dropHeight) / moonGravity);
if (infoText != null)
{
infoText.text =
$"Висота: {dropHeight:F2} м\n" +
$"Час падіння: {fallTime:F2} с\n" +
$"Швидкість удару: {impactSpeed:F2} м/с\n" +
$"Маса: {mass:F2} кг\n" +
$"Сила тяжіння: {mass:F2} × {moonGravity} = ?? Н\n" +
$"Прискорення: {moonGravity} м/с² (Місяць)";
}
AirTrailController trail = GetComponentInChildren<AirTrailController>();
if (trail != null)
{
trail.Deactivate();
}
Invoke("ClearText", 15f);
}
}
void ClearText()
{
if (infoText != null)
infoText.text = "";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e37c77ea429da2c48b3bb501598e8101
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,216 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonOrbitJupiter : MonoBehaviour
{
public Transform jupiter;
public JupiterMoonType moonType = JupiterMoonType.Io;
public bool autoCalculateOrbit = true;
public float manualOrbitRadius = 10f;
public float orbitInclination = 0.04f;
public float startAngleDegrees = 0f;
public float timeScale = 10f;
public bool showDebugInfo = false;
private const float JUPITER_RADIUS_KM = 69911f;
private const float IO_RADIUS_KM = 1821f;
private const float IO_DISTANCE_KM = 421700f;
private const float IO_PERIOD_HOURS = 42.5f;
private const float EUROPA_RADIUS_KM = 1560f;
private const float EUROPA_DISTANCE_KM = 671100f;
private const float EUROPA_PERIOD_HOURS = 85.2f;
private const float GANYMEDE_RADIUS_KM = 2634f;
private const float GANYMEDE_DISTANCE_KM = 1070400f;
private const float GANYMEDE_PERIOD_HOURS = 171.7f;
private const float CALLISTO_RADIUS_KM = 2410f;
private const float CALLISTO_DISTANCE_KM = 1882700f;
private const float CALLISTO_PERIOD_HOURS = 400.5f;
private float orbitRadius;
private float angularSpeed;
private float currentAngle = 0f;
private float orbitCount = 0f;
private float debugTimer = 0f;
public enum JupiterMoonType
{
Io,
Europa,
Ganymede,
Callisto
}
void Start()
{
if (jupiter == null)
{
jupiter = GameObject.Find("Jupiter")?.transform;
if (jupiter == null)
{
enabled = false;
return;
}
}
CalculateOrbit();
SetInitialPosition();
}
void CalculateOrbit()
{
float jupiterRadius = jupiter.localScale.x / 2f;
if (autoCalculateOrbit)
{
switch (moonType)
{
case JupiterMoonType.Io:
orbitRadius = jupiterRadius * (IO_DISTANCE_KM / JUPITER_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (IO_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.04f;
break;
case JupiterMoonType.Europa:
orbitRadius = jupiterRadius * (EUROPA_DISTANCE_KM / JUPITER_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (EUROPA_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.47f;
break;
case JupiterMoonType.Ganymede:
orbitRadius = jupiterRadius * (GANYMEDE_DISTANCE_KM / JUPITER_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (GANYMEDE_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.20f;
break;
case JupiterMoonType.Callisto:
orbitRadius = jupiterRadius * (CALLISTO_DISTANCE_KM / JUPITER_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (CALLISTO_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.51f;
break;
}
}
else
{
orbitRadius = manualOrbitRadius;
float period = GetPeriod() * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
}
}
float GetPeriod()
{
switch (moonType)
{
case JupiterMoonType.Io: return IO_PERIOD_HOURS;
case JupiterMoonType.Europa: return EUROPA_PERIOD_HOURS;
case JupiterMoonType.Ganymede: return GANYMEDE_PERIOD_HOURS;
case JupiterMoonType.Callisto: return CALLISTO_PERIOD_HOURS;
default: return IO_PERIOD_HOURS;
}
}
void SetInitialPosition()
{
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
UpdatePosition();
}
void Update()
{
if (jupiter == null) return;
currentAngle += angularSpeed * Time.deltaTime;
if (currentAngle >= 2f * Mathf.PI)
{
currentAngle -= 2f * Mathf.PI;
orbitCount++;
if (showDebugInfo)
{
Debug.Log(moonType + " orbit " + orbitCount);
}
}
UpdatePosition();
if (showDebugInfo)
{
debugTimer += Time.deltaTime;
if (debugTimer >= 10f)
{
debugTimer = 0f;
float progress = (currentAngle / (2f * Mathf.PI)) * 100f;
Debug.Log(moonType + ": R=" + orbitRadius.ToString("F2") + " P=" + progress.ToString("F1") + "%");
}
}
}
void UpdatePosition()
{
float x = Mathf.Cos(currentAngle) * orbitRadius;
float z = Mathf.Sin(currentAngle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
transform.position = jupiter.position + new Vector3(x, y, z);
}
void OnDrawGizmos()
{
if (jupiter == null) return;
Color gizmoColor = Color.white;
switch (moonType)
{
case JupiterMoonType.Io:
gizmoColor = new Color(1f, 0.9f, 0.3f, 0.5f);
break;
case JupiterMoonType.Europa:
gizmoColor = new Color(0.8f, 0.9f, 1f, 0.5f);
break;
case JupiterMoonType.Ganymede:
gizmoColor = new Color(0.7f, 0.6f, 0.5f, 0.5f);
break;
case JupiterMoonType.Callisto:
gizmoColor = new Color(0.5f, 0.5f, 0.5f, 0.5f);
break;
}
Gizmos.color = gizmoColor;
int segments = 64;
Vector3 prevPos = GetOrbitPoint(0);
for (int i = 1; i <= segments; i++)
{
Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments);
Gizmos.DrawLine(prevPos, newPos);
prevPos = newPos;
}
}
Vector3 GetOrbitPoint(float angle)
{
float x = Mathf.Cos(angle) * orbitRadius;
float z = Mathf.Sin(angle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
return jupiter.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7d9f13d9ad753643b82e5a6011ab53d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonOrbitNeptune : MonoBehaviour
{
public Transform neptune;
public NeptuneMoonType moonType = NeptuneMoonType.Triton;
public bool autoCalculateOrbit = true;
public float manualOrbitRadius = 10f;
public float orbitInclination = 156.8f;
public float startAngleDegrees = 0f;
public float timeScale = 10f;
public bool showDebugInfo = false;
private const float NEPTUNE_RADIUS_KM = 24622f;
private const float TRITON_RADIUS_KM = 1353f;
private const float TRITON_DISTANCE_KM = 354759f;
private const float TRITON_PERIOD_HOURS = 141.0f;
private float orbitRadius;
private float angularSpeed;
private float currentAngle = 0f;
private float orbitCount = 0f;
private float debugTimer = 0f;
public enum NeptuneMoonType
{
Triton
}
void Start()
{
if (neptune == null)
{
neptune = GameObject.Find("Neptune")?.transform;
if (neptune == null)
{
enabled = false;
return;
}
}
CalculateOrbit();
SetInitialPosition();
}
void CalculateOrbit()
{
float neptuneRadius = neptune.localScale.x / 2f;
if (autoCalculateOrbit)
{
switch (moonType)
{
case NeptuneMoonType.Triton:
orbitRadius = neptuneRadius * (TRITON_DISTANCE_KM / NEPTUNE_RADIUS_KM);
angularSpeed = -(2f * Mathf.PI / (TRITON_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 156.8f;
break;
}
}
else
{
orbitRadius = manualOrbitRadius;
float period = GetPeriod() * 3600f;
angularSpeed = -(2f * Mathf.PI / period) * timeScale;
}
}
float GetPeriod()
{
switch (moonType)
{
case NeptuneMoonType.Triton: return TRITON_PERIOD_HOURS;
default: return TRITON_PERIOD_HOURS;
}
}
void SetInitialPosition()
{
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
UpdatePosition();
}
void Update()
{
if (neptune == null) return;
currentAngle += angularSpeed * Time.deltaTime;
if (currentAngle <= -2f * Mathf.PI)
{
currentAngle += 2f * Mathf.PI;
orbitCount++;
if (showDebugInfo)
{
Debug.Log(moonType + " orbit " + orbitCount + " (retrograde)");
}
}
UpdatePosition();
if (showDebugInfo)
{
debugTimer += Time.deltaTime;
if (debugTimer >= 10f)
{
debugTimer = 0f;
float progress = (Mathf.Abs(currentAngle) / (2f * Mathf.PI)) * 100f;
Debug.Log(moonType + ": R=" + orbitRadius.ToString("F2") + " P=" + progress.ToString("F1") + "% RETROGRADE");
}
}
}
void UpdatePosition()
{
float x = Mathf.Cos(currentAngle) * orbitRadius;
float z = Mathf.Sin(currentAngle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
transform.position = neptune.position + new Vector3(x, y, z);
}
void OnDrawGizmos()
{
if (neptune == null) return;
Color gizmoColor = new Color(0.4f, 0.7f, 1f, 0.5f);
Gizmos.color = gizmoColor;
int segments = 64;
Vector3 prevPos = GetOrbitPoint(0);
for (int i = 1; i <= segments; i++)
{
Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments);
Gizmos.DrawLine(prevPos, newPos);
prevPos = newPos;
}
}
Vector3 GetOrbitPoint(float angle)
{
float x = Mathf.Cos(angle) * orbitRadius;
float z = Mathf.Sin(angle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
return neptune.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14332449173ef1340b37742922c8ca0f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,164 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonOrbitPluto : MonoBehaviour
{
public Transform pluto;
public PlutoMoonType moonType = PlutoMoonType.Charon;
public bool autoCalculateOrbit = true;
public float manualOrbitRadius = 10f;
public float orbitInclination = 0.08f;
public float startAngleDegrees = 0f;
public float timeScale = 10f;
public bool showDebugInfo = false;
private const float PLUTO_RADIUS_KM = 1188f;
private const float CHARON_RADIUS_KM = 606f;
private const float CHARON_DISTANCE_KM = 19591f;
private const float CHARON_PERIOD_HOURS = 153.3f;
private float orbitRadius;
private float angularSpeed;
private float currentAngle = 0f;
private float orbitCount = 0f;
private float debugTimer = 0f;
public enum PlutoMoonType
{
Charon
}
void Start()
{
if (pluto == null)
{
pluto = GameObject.Find("Pluto")?.transform;
if (pluto == null)
{
enabled = false;
return;
}
}
CalculateOrbit();
SetInitialPosition();
}
void CalculateOrbit()
{
float plutoRadius = pluto.localScale.x / 2f;
if (autoCalculateOrbit)
{
switch (moonType)
{
case PlutoMoonType.Charon:
orbitRadius = plutoRadius * (CHARON_DISTANCE_KM / PLUTO_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (CHARON_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.08f;
break;
}
}
else
{
orbitRadius = manualOrbitRadius;
float period = GetPeriod() * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
}
}
float GetPeriod()
{
switch (moonType)
{
case PlutoMoonType.Charon: return CHARON_PERIOD_HOURS;
default: return CHARON_PERIOD_HOURS;
}
}
void SetInitialPosition()
{
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
UpdatePosition();
}
void Update()
{
if (pluto == null) return;
currentAngle += angularSpeed * Time.deltaTime;
if (currentAngle >= 2f * Mathf.PI)
{
currentAngle -= 2f * Mathf.PI;
orbitCount++;
if (showDebugInfo)
{
Debug.Log(moonType + " orbit " + orbitCount);
}
}
UpdatePosition();
if (showDebugInfo)
{
debugTimer += Time.deltaTime;
if (debugTimer >= 10f)
{
debugTimer = 0f;
float progress = (currentAngle / (2f * Mathf.PI)) * 100f;
Debug.Log(moonType + ": R=" + orbitRadius.ToString("F2") + " P=" + progress.ToString("F1") + "%");
}
}
}
void UpdatePosition()
{
float x = Mathf.Cos(currentAngle) * orbitRadius;
float z = Mathf.Sin(currentAngle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
transform.position = pluto.position + new Vector3(x, y, z);
}
void OnDrawGizmos()
{
if (pluto == null) return;
Color gizmoColor = new Color(0.7f, 0.7f, 0.7f, 0.5f);
Gizmos.color = gizmoColor;
int segments = 64;
Vector3 prevPos = GetOrbitPoint(0);
for (int i = 1; i <= segments; i++)
{
Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments);
Gizmos.DrawLine(prevPos, newPos);
prevPos = newPos;
}
}
Vector3 GetOrbitPoint(float angle)
{
float x = Mathf.Cos(angle) * orbitRadius;
float z = Mathf.Sin(angle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
return pluto.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9f8500565a110f4b94b56329e24c0cc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,204 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonOrbitSaturn : MonoBehaviour
{
public Transform saturn;
public SaturnMoonType moonType = SaturnMoonType.Mimas;
public bool autoCalculateOrbit = true;
public float manualOrbitRadius = 10f;
public float orbitInclination = 0f;
public float startAngleDegrees = 0f;
public float timeScale = 10f;
public float orbitScaleMultiplier = 4f;
public bool showDebugInfo = false;
private const float SATURN_RADIUS_KM = 58232f;
private const float MIMAS_DISTANCE_KM = 185539f;
private const float MIMAS_PERIOD_HOURS = 22.6f;
private const float ENCELADUS_DISTANCE_KM = 237948f;
private const float ENCELADUS_PERIOD_HOURS = 32.9f;
private const float TETHYS_DISTANCE_KM = 294619f;
private const float TETHYS_PERIOD_HOURS = 45.3f;
private const float DIONE_DISTANCE_KM = 377396f;
private const float DIONE_PERIOD_HOURS = 65.7f;
private const float RHEA_DISTANCE_KM = 527108f;
private const float RHEA_PERIOD_HOURS = 108.4f;
private const float TITAN_DISTANCE_KM = 1221870f;
private const float TITAN_PERIOD_HOURS = 382.7f;
private const float IAPETUS_DISTANCE_KM = 3560820f;
private const float IAPETUS_PERIOD_HOURS = 1903.7f;
private float orbitRadius;
private float angularSpeed;
private float currentAngle;
public enum SaturnMoonType
{
Mimas,
Enceladus,
Tethys,
Dione,
Rhea,
Titan,
Iapetus
}
void Start()
{
if (saturn == null)
{
saturn = GameObject.Find("Saturn")?.transform;
if (saturn == null)
{
enabled = false;
return;
}
}
CalculateOrbit();
SetInitialPosition();
}
void CalculateOrbit()
{
float saturnRadius = saturn.localScale.x / 2f;
if (autoCalculateOrbit)
{
switch (moonType)
{
case SaturnMoonType.Mimas:
orbitRadius = saturnRadius * (MIMAS_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (MIMAS_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 1.57f;
break;
case SaturnMoonType.Enceladus:
orbitRadius = saturnRadius * (ENCELADUS_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (ENCELADUS_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.02f;
break;
case SaturnMoonType.Tethys:
orbitRadius = saturnRadius * (TETHYS_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (TETHYS_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 1.09f;
break;
case SaturnMoonType.Dione:
orbitRadius = saturnRadius * (DIONE_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (DIONE_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.02f;
break;
case SaturnMoonType.Rhea:
orbitRadius = saturnRadius * (RHEA_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (RHEA_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.35f;
break;
case SaturnMoonType.Titan:
orbitRadius = saturnRadius * (TITAN_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (TITAN_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.33f;
break;
case SaturnMoonType.Iapetus:
orbitRadius = saturnRadius * (IAPETUS_DISTANCE_KM / SATURN_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (IAPETUS_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 15.47f;
break;
}
orbitRadius *= orbitScaleMultiplier;
}
else
{
orbitRadius = manualOrbitRadius;
float period = GetPeriod() * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
}
}
float GetPeriod()
{
switch (moonType)
{
case SaturnMoonType.Mimas: return MIMAS_PERIOD_HOURS;
case SaturnMoonType.Enceladus: return ENCELADUS_PERIOD_HOURS;
case SaturnMoonType.Tethys: return TETHYS_PERIOD_HOURS;
case SaturnMoonType.Dione: return DIONE_PERIOD_HOURS;
case SaturnMoonType.Rhea: return RHEA_PERIOD_HOURS;
case SaturnMoonType.Titan: return TITAN_PERIOD_HOURS;
case SaturnMoonType.Iapetus: return IAPETUS_PERIOD_HOURS;
default: return MIMAS_PERIOD_HOURS;
}
}
void SetInitialPosition()
{
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
UpdatePosition();
}
void Update()
{
currentAngle += angularSpeed * Time.deltaTime;
UpdatePosition();
}
void UpdatePosition()
{
float x = Mathf.Cos(currentAngle) * orbitRadius;
float z = Mathf.Sin(currentAngle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
transform.position = saturn.position + new Vector3(x, y, z);
}
void OnDrawGizmos()
{
if (saturn == null) return;
Gizmos.color = Color.white;
int segments = 64;
Vector3 prevPos = GetOrbitPoint(0f);
for (int i = 1; i <= segments; i++)
{
Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments);
Gizmos.DrawLine(prevPos, newPos);
prevPos = newPos;
}
}
Vector3 GetOrbitPoint(float angle)
{
float x = Mathf.Cos(angle) * orbitRadius;
float z = Mathf.Sin(angle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
return saturn.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99fc8b42758bbdb4384937e769a73dce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,230 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoonOrbitUranus : MonoBehaviour
{
public Transform uranus;
public UranusMoonType moonType = UranusMoonType.Miranda;
public bool autoCalculateOrbit = true;
public float manualOrbitRadius = 10f;
public float orbitInclination = 4.34f;
public float startAngleDegrees = 0f;
public float timeScale = 10f;
public bool showDebugInfo = false;
private const float URANUS_RADIUS_KM = 25362f;
private const float MIRANDA_RADIUS_KM = 236f;
private const float MIRANDA_DISTANCE_KM = 129900f;
private const float MIRANDA_PERIOD_HOURS = 33.9f;
private const float ARIEL_RADIUS_KM = 579f;
private const float ARIEL_DISTANCE_KM = 190900f;
private const float ARIEL_PERIOD_HOURS = 60.5f;
private const float UMBRIEL_RADIUS_KM = 585f;
private const float UMBRIEL_DISTANCE_KM = 266000f;
private const float UMBRIEL_PERIOD_HOURS = 99.5f;
private const float TITANIA_RADIUS_KM = 789f;
private const float TITANIA_DISTANCE_KM = 436300f;
private const float TITANIA_PERIOD_HOURS = 209.0f;
private const float OBERON_RADIUS_KM = 761f;
private const float OBERON_DISTANCE_KM = 583500f;
private const float OBERON_PERIOD_HOURS = 323.1f;
private float orbitRadius;
private float angularSpeed;
private float currentAngle = 0f;
private float orbitCount = 0f;
private float debugTimer = 0f;
public enum UranusMoonType
{
Miranda,
Ariel,
Umbriel,
Titania,
Oberon
}
void Start()
{
if (uranus == null)
{
uranus = GameObject.Find("Uranus")?.transform;
if (uranus == null)
{
enabled = false;
return;
}
}
CalculateOrbit();
SetInitialPosition();
}
void CalculateOrbit()
{
float uranusRadius = uranus.localScale.x / 2f;
if (autoCalculateOrbit)
{
switch (moonType)
{
case UranusMoonType.Miranda:
orbitRadius = uranusRadius * (MIRANDA_DISTANCE_KM / URANUS_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (MIRANDA_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 4.34f;
break;
case UranusMoonType.Ariel:
orbitRadius = uranusRadius * (ARIEL_DISTANCE_KM / URANUS_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (ARIEL_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.04f;
break;
case UranusMoonType.Umbriel:
orbitRadius = uranusRadius * (UMBRIEL_DISTANCE_KM / URANUS_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (UMBRIEL_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.13f;
break;
case UranusMoonType.Titania:
orbitRadius = uranusRadius * (TITANIA_DISTANCE_KM / URANUS_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (TITANIA_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.08f;
break;
case UranusMoonType.Oberon:
orbitRadius = uranusRadius * (OBERON_DISTANCE_KM / URANUS_RADIUS_KM);
angularSpeed = (2f * Mathf.PI / (OBERON_PERIOD_HOURS * 3600f)) * timeScale;
orbitInclination = 0.07f;
break;
}
}
else
{
orbitRadius = manualOrbitRadius;
float period = GetPeriod() * 3600f;
angularSpeed = (2f * Mathf.PI / period) * timeScale;
}
}
float GetPeriod()
{
switch (moonType)
{
case UranusMoonType.Miranda: return MIRANDA_PERIOD_HOURS;
case UranusMoonType.Ariel: return ARIEL_PERIOD_HOURS;
case UranusMoonType.Umbriel: return UMBRIEL_PERIOD_HOURS;
case UranusMoonType.Titania: return TITANIA_PERIOD_HOURS;
case UranusMoonType.Oberon: return OBERON_PERIOD_HOURS;
default: return MIRANDA_PERIOD_HOURS;
}
}
void SetInitialPosition()
{
currentAngle = startAngleDegrees * Mathf.Deg2Rad;
UpdatePosition();
}
void Update()
{
if (uranus == null) return;
currentAngle += angularSpeed * Time.deltaTime;
if (currentAngle >= 2f * Mathf.PI)
{
currentAngle -= 2f * Mathf.PI;
orbitCount++;
if (showDebugInfo)
{
Debug.Log(moonType + " orbit " + orbitCount);
}
}
UpdatePosition();
if (showDebugInfo)
{
debugTimer += Time.deltaTime;
if (debugTimer >= 10f)
{
debugTimer = 0f;
float progress = (currentAngle / (2f * Mathf.PI)) * 100f;
Debug.Log(moonType + ": R=" + orbitRadius.ToString("F2") + " P=" + progress.ToString("F1") + "%");
}
}
}
void UpdatePosition()
{
float x = Mathf.Cos(currentAngle) * orbitRadius;
float z = Mathf.Sin(currentAngle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
transform.position = uranus.position + new Vector3(x, y, z);
}
void OnDrawGizmos()
{
if (uranus == null) return;
Color gizmoColor = Color.white;
switch (moonType)
{
case UranusMoonType.Miranda:
gizmoColor = new Color(0.9f, 0.85f, 0.8f, 0.5f);
break;
case UranusMoonType.Ariel:
gizmoColor = new Color(0.95f, 0.95f, 0.9f, 0.5f);
break;
case UranusMoonType.Umbriel:
gizmoColor = new Color(0.4f, 0.4f, 0.4f, 0.5f);
break;
case UranusMoonType.Titania:
gizmoColor = new Color(0.8f, 0.75f, 0.7f, 0.5f);
break;
case UranusMoonType.Oberon:
gizmoColor = new Color(0.7f, 0.7f, 0.65f, 0.5f);
break;
}
Gizmos.color = gizmoColor;
int segments = 64;
Vector3 prevPos = GetOrbitPoint(0);
for (int i = 1; i <= segments; i++)
{
Vector3 newPos = GetOrbitPoint(i * 2f * Mathf.PI / segments);
Gizmos.DrawLine(prevPos, newPos);
prevPos = newPos;
}
}
Vector3 GetOrbitPoint(float angle)
{
float x = Mathf.Cos(angle) * orbitRadius;
float z = Mathf.Sin(angle) * orbitRadius;
float inclinationRad = orbitInclination * Mathf.Deg2Rad;
float y = z * Mathf.Sin(inclinationRad);
z = z * Mathf.Cos(inclinationRad);
return uranus.position + new Vector3(x, y, z);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5fa6b567046ab6a478f19625610abf20
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjectAirProperties : MonoBehaviour
{
[Header("Âëàñòèâîñò³")]
public float crossSectionArea = 0.05f;
public float dragCoefficient = 0.47f;
void Start()
{
AnalyzeObject();
}
void AnalyzeObject()
{
Renderer renderer = GetComponent<Renderer>();
if (renderer == null) return;
Bounds bounds = renderer.bounds;
Vector3 size = bounds.size;
float[] dimensions = new float[] { size.x, size.y, size.z };
System.Array.Sort(dimensions);
System.Array.Reverse(dimensions);
float largest = dimensions[0];
float middle = dimensions[1];
float smallest = dimensions[2];
float ratio1 = middle / largest;
float ratio2 = smallest / largest;
if (ratio1 > 0.8f && ratio2 > 0.8f)
{
DetectSphereOrCube(bounds);
}
else if (ratio2 < 0.3f)
{
crossSectionArea = largest * middle;
dragCoefficient = 1.28f;
}
else if (ratio1 > 0.7f && ratio2 < 0.7f)
{
float radius = Mathf.Max(largest, middle) * 0.5f;
crossSectionArea = Mathf.PI * radius * radius;
dragCoefficient = 0.82f;
}
else
{
crossSectionArea = Mathf.Max(
size.x * size.y,
size.x * size.z,
size.y * size.z
);
dragCoefficient = 1.05f;
}
}
void DetectSphereOrCube(Bounds bounds)
{
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter != null && meshFilter.sharedMesh != null)
{
int vertexCount = meshFilter.sharedMesh.vertexCount;
if (vertexCount > 100)
{
float radius = Mathf.Max(bounds.size.x, bounds.size.y, bounds.size.z) * 0.5f;
crossSectionArea = Mathf.PI * radius * radius;
dragCoefficient = 0.47f;
}
else
{
crossSectionArea = Mathf.Max(
bounds.size.x * bounds.size.y,
bounds.size.x * bounds.size.z,
bounds.size.y * bounds.size.z
);
dragCoefficient = 1.05f;
}
}
else
{
crossSectionArea = Mathf.Max(
bounds.size.x * bounds.size.y,
bounds.size.x * bounds.size.z,
bounds.size.y * bounds.size.z
);
dragCoefficient = 1.05f;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f9961d795d590eb4c816e070425a736b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ObjectPhysicsInfo : MonoBehaviour
{
public TextMeshProUGUI infoText;
private Rigidbody _rb;
private float _startTime;
private float _startHeight;
private bool _isFalling = false;
private bool _hasLanded = false;
private float _startMass;
void Start()
{
_rb = GetComponent<Rigidbody>();
_startMass = _rb.mass;
if (infoText != null) infoText.text = "";
}
void Update()
{
if (infoText != null)
{
infoText.transform.parent.LookAt(Camera.main.transform);
infoText.transform.parent.Rotate(0, 180, 0);
}
}
public void OnRelease()
{
_startTime = Time.time;
_startHeight = transform.position.y;
_isFalling = true;
_hasLanded = false;
if (infoText != null) infoText.text = "";
}
void OnCollisionEnter(Collision collision)
{
if (_isFalling && !_hasLanded && collision.gameObject.CompareTag("Ground"))
{
_hasLanded = true;
_isFalling = false;
float fallTime = Time.time - _startTime;
float dropHeight = _startHeight - transform.position.y;
float impactSpeed = _rb.velocity.magnitude;
float mass = _startMass;
float gravityForce = mass * 9.8f;
float theoreticalTime = Mathf.Sqrt((2 * dropHeight) / 9.8f);
if (infoText != null)
{
infoText.text =
$"Висота: {dropHeight:F2} м\n" +
$"Час падіння: {fallTime:F2} с\n" +
$"Швидкість: {impactSpeed:F2} м/с\n" +
$"Маса: {mass:F2} кг\n" +
$"Сила тяжіння: {mass:F2} × 9.8 = ?? Н\n" +
$"Прискорення: 9.8 м/с²";
}
AirTrailController trail = GetComponentInChildren<AirTrailController>();
if (trail != null)
{
trail.Deactivate();
}
Invoke("ClearText", 15f);
}
}
void ClearText()
{
if (infoText != null)
infoText.text = "";
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b86a5bfdc1f551f45939ce4249726c51
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlanetSpin : MonoBehaviour
{
[Header("Ïàðàìåòðè îáåðòàííÿ")]
[Header("Íàõèë îñ³")]
[Range(0f, 100f)]
[SerializeField] private float axialTilt = 0.5f;
[Header("Øâèäê³ñòü îáåðòàííÿ íàâêîëî îñ³")]
[Range(0f, 180f)]
[SerializeField] private float rotationSpeed = 10f;
public float RotationSpeed => rotationSpeed;
void Start()
{
transform.localRotation = Quaternion.Euler(0f, 0f, axialTilt);
}
public void SetRotationSpeed(float value)
{
rotationSpeed = value;
}
void Update()
{
float rotationThisFrame = rotationSpeed * Time.deltaTime;
transform.Rotate(Vector3.up, rotationThisFrame, Space.Self);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1f369feea756f9f4d9b6e1c778bd9a8e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,157 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using System;
public class SecretInfoManager : MonoBehaviour
{
[Header("Settings")]
[SerializeField] private string targetTag = "Target";
[SerializeField] private Canvas secretCanvas;
[SerializeField] private TextMeshProUGUI secretInfoText;
[SerializeField] private bool deleteZonesOnCompletion = true;
[SerializeField] private float deleteDelay = 0.5f;
private int _totalTargetObjects;
private HashSet<GameObject> _collectedObjects = new HashSet<GameObject>();
private List<SecretInfoZone> _allZones = new List<SecretInfoZone>();
public event Action<int, int> OnProgressChanged;
public int CollectedCount => _collectedObjects.Count;
public int TotalCount => _totalTargetObjects;
private float _showDuration = 40f;
public enum LocationType
{
Earth,
Moon
}
[SerializeField] private LocationType locationType;
void Start()
{
//_totalTargetObjects = GameObject.FindGameObjectsWithTag(targetTag).Length;
_totalTargetObjects = 9;
if (secretCanvas != null)
{
secretCanvas.gameObject.SetActive(false);
}
_allZones.AddRange(FindObjectsOfType<SecretInfoZone>());
UpdateProgressText();
}
public void ObjectEntered(GameObject obj)
{
if (!obj.CompareTag(targetTag)) return;
if (_collectedObjects.Add(obj))
{
UpdateProgressText();
CheckCompletion();
}
}
public void ObjectExited(GameObject obj)
{
if (!obj.CompareTag(targetTag))
return;
if (_collectedObjects.Remove(obj))
{
UpdateProgressText();
}
}
private void UpdateProgressText()
{
int collected = _collectedObjects.Count;
OnProgressChanged?.Invoke(collected, _totalTargetObjects);
}
private void CheckCompletion()
{
if (_collectedObjects.Count >= _totalTargetObjects)
{
if (secretCanvas != null)
{
secretCanvas.gameObject.SetActive(true);
StartCoroutine(HideCanvasAfterTime());
if (secretInfoText != null)
{
secretInfoText.text = GetSecretText();
}
}
if (deleteZonesOnCompletion)
{
StartCoroutine(DeleteAllZonesDelayed());
}
}
}
private IEnumerator DeleteAllZonesDelayed()
{
yield return new WaitForSeconds(deleteDelay);
foreach (SecretInfoZone zone in _allZones)
{
if (zone != null)
{
Destroy(zone.gameObject);
}
}
_allZones.Clear();
}
private IEnumerator HideCanvasAfterTime()
{
yield return new WaitForSeconds(_showDuration);
if (secretCanvas != null)
{
secretCanvas.gameObject.SetActive(false);
}
}
private string GetSecretText()
{
switch (locationType)
{
case LocationType.Moon:
return
"<b>ЦІКАВИЙ ФАКТ!</b>\n\n" +
"Гравітаційне прискорення на Місяці змінюється залежно від місця!\n\n" +
"<b>Над темними рівнинами:</b> 1.62 м/с²\n" +
"<b>Над гірськими масивами:</b> 1.63 м/с²\n\n" +
"Це відбувається через <b>маскони</b> - масивні концентрації густих порід під поверхнею. " +
"Вони як невидимі гори під землею, які посилюють гравітацію!\n\n" +
"<b>Ще цікавіше:</b>\n" +
"Центр мас Місяця зміщений на 2 км убік Землі - тому один бік важчий!\n\n";
case LocationType.Earth:
default:
return
"<b>ЦІКАВИЙ ФАКТ!</b>\n\n" +
"Галілео Галілей вимірював час за допомогою свого власного пульсу. " +
"Точних годинників ще не існувало, тому він використовував серцебиття " +
"для вимірювання часу падіння об'єктів.\n\n" +
"<b>Але найдивовижніше:</b>\n" +
"1642 рік - Галілей помирає.\n" +
"1642 рік - Ньютон народжується.\n\n" +
"Того самого року всесвіт передав факел знань від одного генія до іншого. " +
"Галілей почав розуміти гравітацію, а Ньютон завершив цю роботу математикою.\n\n";
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9d01549ca6e5d8b40a779293a2ebbb83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class SecretInfoZone : MonoBehaviour
{
[SerializeField] private TextMeshProUGUI _localProgressText;
private SecretInfoManager _manager;
void Start()
{
_manager = FindObjectOfType<SecretInfoManager>();
if (_manager == null)
{
return;
}
if (_localProgressText != null)
{
_manager.OnProgressChanged += UpdateLocalText;
UpdateLocalText(_manager.CollectedCount, _manager.TotalCount);
}
}
void OnDestroy()
{
if (_manager != null && _localProgressText != null)
{
_manager.OnProgressChanged -= UpdateLocalText;
}
}
void OnTriggerEnter(Collider other)
{
_manager?.ObjectEntered(other.gameObject);
}
void OnTriggerExit(Collider other)
{
_manager?.ObjectExited(other.gameObject);
}
private void UpdateLocalText(int collected, int total)
{
if (_localProgressText != null)
{
_localProgressText.text = $"{collected}/{total}";
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 77af6cb533a28c743a812d9afa6c00bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SolarCursor : MonoBehaviour
{
[SerializeField] private Texture2D cursorTexture;
void Start()
{
Vector2 hotspot = new Vector2(0, 31);
Cursor.SetCursor(cursorTexture, hotspot, CursorMode.Auto);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f09bdc61ab395549a25cc87eee879e1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,54 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SolarSystem : MonoBehaviour
{
[SerializeField] private float G = 100f;
private GameObject[] celestials;
void Start()
{
celestials = GameObject.FindGameObjectsWithTag("Celestial");
InitialVelocity();
}
private void FixedUpdate()
{
Gravity();
}
void Gravity()
{
foreach (GameObject a in celestials)
{
foreach (GameObject b in celestials)
{
if (!a.Equals(b))
{
float m1 = a.GetComponent<Rigidbody>().mass;
float m2 = b.GetComponent<Rigidbody>().mass;
float r = Vector3.Distance(a.transform.position, b.transform.position);
a.GetComponent<Rigidbody>().AddForce(
(b.transform.position - a.transform.position).normalized *
(G * (m1 * m2) / (r * r))
);
}
}
}
}
void InitialVelocity()
{
foreach (GameObject a in celestials)
{
foreach (GameObject b in celestials)
{
if (!a.Equals(b))
{
float m2 = b.GetComponent<Rigidbody>().mass;
float r = Vector3.Distance(a.transform.position, b.transform.position);
a.transform.LookAt(b.transform);
a.GetComponent<Rigidbody>().velocity +=
a.transform.right * Mathf.Sqrt((G * m2) / r);
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5b225d72a40ccca47b90fa93727bf38b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 86aaf4695bcdd4540a1de845fbe761a7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d156cf8c15007d34897098a176a47aa4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,42 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallHitParticles : MonoBehaviour
{
[SerializeField] private GameObject hitParticlesPrefab;
[SerializeField] private float minHitSpeed = 2f;
[SerializeField] private float destroyDelay = 2f;
private Rigidbody _rb;
private bool _hasHit = false;
private void Start()
{
_rb = GetComponent<Rigidbody>();
}
private void OnCollisionEnter(Collision collision)
{
if (_hasHit)
return;
if (collision.gameObject.CompareTag("Wall") == false)
return;
if (_rb.velocity.magnitude < minHitSpeed)
return;
_hasHit = true;
Vector3 hitPoint = collision.contacts[0].point;
Quaternion hitRotation =
Quaternion.LookRotation(collision.contacts[0].normal);
GameObject particles =
Instantiate(hitParticlesPrefab, hitPoint, hitRotation);
Destroy(particles, destroyDelay);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4102c64b1c693dc4f8d3104f2f9c5b9c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Wind : MonoBehaviour
{
[Header("Íàëàøòóâàííÿ â³òðó")]
[SerializeField] private WindZone windZone;
[Header("Ðåæèì ñåðåäîâèùà")]
[Space(5)]
[Header("Áåç â³òðó. Ïðåäìåò ïàäຠÿê ó âàêóóì³")]
[SerializeField] private bool noWind = false;
[Header("Ñëàáêèé â³òåð. ª îï³ð ïîâ³òðÿ + ñëàáêèé â³òåð âá³ê")]
[SerializeField] private bool weakWind = true;
[Header("Ñèëüíèé â³òåð. ª îï³ð ïîâ³òðÿ + ñèëüíèé â³òåð âá³ê")]
[SerializeField] private bool strongWind = false;
[Header("Íàëàøòóâàííÿ îïîðó ïîâ³òðÿ")]
[SerializeField] private float airDensity = 1.225f;
[Header("Ñèëà â³òðó âá³ê")]
[SerializeField] private float weakWindForce = 0.5f;
[SerializeField] private float strongWindForce = 2f;
private List<Rigidbody> _affectedBodies = new List<Rigidbody>();
private Dictionary<Rigidbody, ObjectAirProperties> _objectProperties = new Dictionary<Rigidbody, ObjectAirProperties>();
private void Start()
{
if (windZone == null) windZone = GetComponent<WindZone>();
UpdateWindZone();
}
private void OnValidate()
{
UpdateWindZone();
}
private void UpdateWindZone()
{
if (windZone == null) return;
if (noWind)
{
windZone.windMain = 0f;
}
else if (weakWind)
{
windZone.windMain = 2f;
windZone.windTurbulence = 0.1f;
}
else if (strongWind)
{
windZone.windMain = 8f;
windZone.windTurbulence = 0.5f;
}
}
private void OnTriggerEnter(Collider other)
{
Rigidbody rb = other.attachedRigidbody;
if (rb != null && !_affectedBodies.Contains(rb))
{
_affectedBodies.Add(rb);
ObjectAirProperties props = rb.GetComponent<ObjectAirProperties>();
if (props != null)
{
_objectProperties[rb] = props;
}
}
}
private void OnTriggerExit(Collider other)
{
Rigidbody rb = other.attachedRigidbody;
if (rb != null)
{
_affectedBodies.Remove(rb);
_objectProperties.Remove(rb);
}
}
private void FixedUpdate()
{
foreach (Rigidbody rb in _affectedBodies)
{
if (rb == null) continue;
if (!noWind)
{
ApplyAirResistance(rb);
if (weakWind || strongWind)
{
ApplyWindForce(rb);
}
}
}
}
private void ApplyAirResistance(Rigidbody rb)
{
if (rb.velocity.magnitude < 0.01f) return;
float crossSectionArea = 0.05f;
float dragCoefficient = 0.47f;
if (_objectProperties.ContainsKey(rb))
{
crossSectionArea = _objectProperties[rb].crossSectionArea;
dragCoefficient = _objectProperties[rb].dragCoefficient;
}
float speed = rb.velocity.magnitude;
float dragMagnitude = 0.5f * airDensity * speed * speed * dragCoefficient * crossSectionArea;
Vector3 dragForce = -rb.velocity.normalized * dragMagnitude;
rb.AddForce(dragForce, ForceMode.Force);
}
private void ApplyWindForce(Rigidbody rb)
{
float force = 0f;
if (weakWind)
force = weakWindForce;
else if (strongWind)
force = strongWindForce;
else
return;
Vector3 windDirection = transform.forward;
rb.AddForce(windDirection * force, ForceMode.Force);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1e91a8ca522aef540a791f9aa072455d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,180 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZodiacCameraController : MonoBehaviour
{
[SerializeField] private Transform zodiacRoot;
[SerializeField] private Camera zodiacCamera;
private int _currentIndex = 0;
private Dictionary<string, CameraPreset> _presets;
private struct CameraPreset
{
public Vector3 localPosition;
public Vector3 localRotation;
public CameraPreset(Vector3 pos, Vector3 rot)
{
localPosition = pos;
localRotation = rot;
}
}
void Awake()
{
_presets = new Dictionary<string, CameraPreset>
{
{ "Zodiac_Aries",
new CameraPreset(
new Vector3(52670f, 0f, 2644f),
new Vector3(0f, 82.342f, 0f))
},
{ "Zodiac_Taurus",
new CameraPreset(
new Vector3(29399f, 17419f, 26891f),
new Vector3(-1.675f, 69.34f, 0.769f))
},
{ "Zodiac_Gemini",
new CameraPreset(
new Vector3(27079f, 23051f, 31496f),
new Vector3(-2.952f, 20.843f, 1.051f)
)
},
{ "Zodiac_Cancer",
new CameraPreset(
new Vector3(5146f, 26343f, 37622f),
new Vector3(-18.238f, -25.072f, 15.872f))
},
{ "Zodiac_Leo",
new CameraPreset(
new Vector3(-24035f, 18632f, 24187f),
new Vector3(-11.603f, -31.992f, 4.569f)
)
},
{ "Zodiac_Virgo",
new CameraPreset(
new Vector3(-66493f, 26979f, -12167f),
new Vector3(-3.051f, -70.52f, 0.831f)
)
},
{ "Zodiac_Libra",
new CameraPreset(
new Vector3(-47207f, 2331f, -17070f),
new Vector3(5.864f, -45.753f, -3.965f))
},
{ "Zodiac_Scorpius",
new CameraPreset(
new Vector3(23243f, -3793f, -41775f),
new Vector3(-3.387f, -108.118f, -1.408f))
},
{ "Zodiac_Ophiuchus",
new CameraPreset(
new Vector3(-5486f, -72738f, -60897f),
new Vector3(-19.647f, 0.134f, 15.524f))
},
{ "Zodiac_Sagittarius",
new CameraPreset(
new Vector3(-22611f, -22913f, -34762f),
new Vector3(-0.858f, -163.7f, 0.486f))
},
{ "Zodiac_Capricornus",
new CameraPreset(
new Vector3(-9422f, -33410f, -64497f),
new Vector3(20.279f, 160.564f, 2f))
},
{ "Zodiac_Aquarius",
new CameraPreset(
new Vector3(23361f, -23299f, -35603f),
new Vector3(-2.652f, 146.782f, 0f))
},
{ "Zodiac_Pisces",
new CameraPreset(
new Vector3(33456f, -10168f, -23088f),
new Vector3(-9.924f, 109.295f, 3.294f))
},
};
}
void Start()
{
zodiacCamera.enabled = true;
if (zodiacRoot.childCount > 0)
FocusCurrent();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.RightArrow))
Next();
if (Input.GetKeyDown(KeyCode.LeftArrow))
Previous();
}
void Next()
{
_currentIndex++;
if (_currentIndex >= zodiacRoot.childCount)
_currentIndex = 0;
FocusCurrent();
}
void Previous()
{
_currentIndex--;
if (_currentIndex < 0)
_currentIndex = zodiacRoot.childCount - 1;
FocusCurrent();
}
void FocusCurrent()
{
Transform constellation = zodiacRoot.GetChild(_currentIndex);
if (_presets.ContainsKey(constellation.name))
{
CameraPreset preset = _presets[constellation.name];
zodiacCamera.transform.SetParent(null);
zodiacCamera.transform.position = preset.localPosition;
zodiacCamera.transform.rotation = Quaternion.Euler(preset.localRotation);
}
else
{
ApplyFallback(constellation);
}
}
void ApplyFallback(Transform constellation)
{
Bounds bounds = CalculateBounds(constellation);
Vector3 center = bounds.center;
Vector3 dir = new Vector3(-1f, 0f, 0f).normalized;
float size = Mathf.Max(bounds.size.x, bounds.size.y);
float distance = Mathf.Max(size * 1.6f, 1600f);
zodiacCamera.transform.SetParent(null);
zodiacCamera.transform.position = center + dir * distance;
zodiacCamera.transform.LookAt(center, Vector3.up);
}
Bounds CalculateBounds(Transform root)
{
Renderer[] renderers = root.GetComponentsInChildren<Renderer>();
Bounds bounds = renderers[0].bounds;
for (int i = 1; i < renderers.Length; i++)
bounds.Encapsulate(renderers[i].bounds);
return bounds;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 99b8956777a4ca242a475f8f4d354d12
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: