Initial commit
This commit is contained in:
39
Assets/Materials/Scripts/AirTrailController.cs
Normal file
39
Assets/Materials/Scripts/AirTrailController.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/Materials/Scripts/AirTrailController.cs.meta
Normal file
11
Assets/Materials/Scripts/AirTrailController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4fc423f8b56a3c49b0465f34ef591fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
36
Assets/Materials/Scripts/Billboard.cs
Normal file
36
Assets/Materials/Scripts/Billboard.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/Billboard.cs.meta
Normal file
11
Assets/Materials/Scripts/Billboard.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c82cf7b3ebf181e4599af2d56540458b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
137
Assets/Materials/Scripts/Calendar.cs
Normal file
137
Assets/Materials/Scripts/Calendar.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/Calendar.cs.meta
Normal file
11
Assets/Materials/Scripts/Calendar.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0280349c718ed9246a7ea331113f1dc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
156
Assets/Materials/Scripts/CalendarManager.cs
Normal file
156
Assets/Materials/Scripts/CalendarManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/CalendarManager.cs.meta
Normal file
11
Assets/Materials/Scripts/CalendarManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 417b78b32d1a42443891caffbd20b9bf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
241
Assets/Materials/Scripts/CameraController.cs
Normal file
241
Assets/Materials/Scripts/CameraController.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/CameraController.cs.meta
Normal file
11
Assets/Materials/Scripts/CameraController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09215415902ffb443a9218882c828949
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
45
Assets/Materials/Scripts/CameraManager.cs
Normal file
45
Assets/Materials/Scripts/CameraManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/CameraManager.cs.meta
Normal file
11
Assets/Materials/Scripts/CameraManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18092287e6b14e74ea4080a9936907b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
116
Assets/Materials/Scripts/CelestialCalendarController.cs
Normal file
116
Assets/Materials/Scripts/CelestialCalendarController.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/CelestialCalendarController.cs.meta
Normal file
11
Assets/Materials/Scripts/CelestialCalendarController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8a2451b673893c4da97804e208be5a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
196
Assets/Materials/Scripts/Constellation.cs
Normal file
196
Assets/Materials/Scripts/Constellation.cs
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
11
Assets/Materials/Scripts/Constellation.cs.meta
Normal file
11
Assets/Materials/Scripts/Constellation.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88f4e4721ea8d144cac21d732d053f30
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Materials/Scripts/ConstellationManager.cs
Normal file
8
Assets/Materials/Scripts/ConstellationManager.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class ConstellationManager : MonoBehaviour
|
||||
{
|
||||
|
||||
}
|
||||
11
Assets/Materials/Scripts/ConstellationManager.cs.meta
Normal file
11
Assets/Materials/Scripts/ConstellationManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8357f6bd3c528a4479c2717bd97bf93f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
156
Assets/Materials/Scripts/CustomCursor.cs
Normal file
156
Assets/Materials/Scripts/CustomCursor.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/CustomCursor.cs.meta
Normal file
11
Assets/Materials/Scripts/CustomCursor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d42e0f8a5176e34e8c5a5ec7717d56e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
88
Assets/Materials/Scripts/HeroCameraController.cs
Normal file
88
Assets/Materials/Scripts/HeroCameraController.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/Materials/Scripts/HeroCameraController.cs.meta
Normal file
11
Assets/Materials/Scripts/HeroCameraController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7670a57d9592c0e4d9cb3fa85786b01a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
72
Assets/Materials/Scripts/HeroController.cs
Normal file
72
Assets/Materials/Scripts/HeroController.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/HeroController.cs.meta
Normal file
11
Assets/Materials/Scripts/HeroController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28e7b6caa53e8b34eaed9f45728ba640
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
161
Assets/Materials/Scripts/MarsmoonsOrbit.cs
Normal file
161
Assets/Materials/Scripts/MarsmoonsOrbit.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MarsmoonsOrbit.cs.meta
Normal file
11
Assets/Materials/Scripts/MarsmoonsOrbit.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88294a843778ac649973a306a1c356d4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
35
Assets/Materials/Scripts/MassInspectorController.cs
Normal file
35
Assets/Materials/Scripts/MassInspectorController.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MassInspectorController.cs.meta
Normal file
11
Assets/Materials/Scripts/MassInspectorController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e883c09c525351e49a1618558df234e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
18
Assets/Materials/Scripts/MassSliderController.cs
Normal file
18
Assets/Materials/Scripts/MassSliderController.cs
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MassSliderController.cs.meta
Normal file
11
Assets/Materials/Scripts/MassSliderController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88bd81e4a6167454ba115b8ba06aa071
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
19
Assets/Materials/Scripts/MoonGravity.cs
Normal file
19
Assets/Materials/Scripts/MoonGravity.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonGravity.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonGravity.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8d410bad46ab98044b782c737e5b183a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
41
Assets/Materials/Scripts/MoonGravityForce.cs
Normal file
41
Assets/Materials/Scripts/MoonGravityForce.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/Materials/Scripts/MoonGravityForce.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonGravityForce.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1219dc08a36c7914c94a80ac0d2be6b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
88
Assets/Materials/Scripts/MoonObjectInfo.cs
Normal file
88
Assets/Materials/Scripts/MoonObjectInfo.cs
Normal 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 = "";
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonObjectInfo.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonObjectInfo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e37c77ea429da2c48b3bb501598e8101
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
216
Assets/Materials/Scripts/MoonOrbitJupiter.cs
Normal file
216
Assets/Materials/Scripts/MoonOrbitJupiter.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonOrbitJupiter.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonOrbitJupiter.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7d9f13d9ad753643b82e5a6011ab53d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
164
Assets/Materials/Scripts/MoonOrbitNeptune.cs
Normal file
164
Assets/Materials/Scripts/MoonOrbitNeptune.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonOrbitNeptune.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonOrbitNeptune.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 14332449173ef1340b37742922c8ca0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
164
Assets/Materials/Scripts/MoonOrbitPluto.cs
Normal file
164
Assets/Materials/Scripts/MoonOrbitPluto.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonOrbitPluto.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonOrbitPluto.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9f8500565a110f4b94b56329e24c0cc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
204
Assets/Materials/Scripts/MoonOrbitSaturn.cs
Normal file
204
Assets/Materials/Scripts/MoonOrbitSaturn.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonOrbitSaturn.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonOrbitSaturn.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99fc8b42758bbdb4384937e769a73dce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
230
Assets/Materials/Scripts/MoonOrbitUranus.cs
Normal file
230
Assets/Materials/Scripts/MoonOrbitUranus.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/MoonOrbitUranus.cs.meta
Normal file
11
Assets/Materials/Scripts/MoonOrbitUranus.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5fa6b567046ab6a478f19625610abf20
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
90
Assets/Materials/Scripts/ObjectAirProperties.cs
Normal file
90
Assets/Materials/Scripts/ObjectAirProperties.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/ObjectAirProperties.cs.meta
Normal file
11
Assets/Materials/Scripts/ObjectAirProperties.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f9961d795d590eb4c816e070425a736b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
87
Assets/Materials/Scripts/ObjectPhysicsInfo.cs
Normal file
87
Assets/Materials/Scripts/ObjectPhysicsInfo.cs
Normal 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 = "";
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/ObjectPhysicsInfo.cs.meta
Normal file
11
Assets/Materials/Scripts/ObjectPhysicsInfo.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b86a5bfdc1f551f45939ce4249726c51
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
37
Assets/Materials/Scripts/PlanetSpin.cs
Normal file
37
Assets/Materials/Scripts/PlanetSpin.cs
Normal 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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
11
Assets/Materials/Scripts/PlanetSpin.cs.meta
Normal file
11
Assets/Materials/Scripts/PlanetSpin.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f369feea756f9f4d9b6e1c778bd9a8e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
157
Assets/Materials/Scripts/SecretInfoManager.cs
Normal file
157
Assets/Materials/Scripts/SecretInfoManager.cs
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/SecretInfoManager.cs.meta
Normal file
11
Assets/Materials/Scripts/SecretInfoManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9d01549ca6e5d8b40a779293a2ebbb83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
53
Assets/Materials/Scripts/SecretInfoZone.cs
Normal file
53
Assets/Materials/Scripts/SecretInfoZone.cs
Normal 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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/SecretInfoZone.cs.meta
Normal file
11
Assets/Materials/Scripts/SecretInfoZone.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77af6cb533a28c743a812d9afa6c00bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/Materials/Scripts/SolarCursor.cs
Normal file
14
Assets/Materials/Scripts/SolarCursor.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/SolarCursor.cs.meta
Normal file
11
Assets/Materials/Scripts/SolarCursor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f09bdc61ab395549a25cc87eee879e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
54
Assets/Materials/Scripts/SolarSystem.cs
Normal file
54
Assets/Materials/Scripts/SolarSystem.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/SolarSystem.cs.meta
Normal file
11
Assets/Materials/Scripts/SolarSystem.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5b225d72a40ccca47b90fa93727bf38b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Materials/Scripts/Stars.meta
Normal file
8
Assets/Materials/Scripts/Stars.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86aaf4695bcdd4540a1de845fbe761a7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
1224
Assets/Materials/Scripts/Stars/ZodiacConstellations.cs
Normal file
1224
Assets/Materials/Scripts/Stars/ZodiacConstellations.cs
Normal file
File diff suppressed because it is too large
Load Diff
11
Assets/Materials/Scripts/Stars/ZodiacConstellations.cs.meta
Normal file
11
Assets/Materials/Scripts/Stars/ZodiacConstellations.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d156cf8c15007d34897098a176a47aa4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
Assets/Materials/Scripts/WallHitParticles.cs
Normal file
42
Assets/Materials/Scripts/WallHitParticles.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/WallHitParticles.cs.meta
Normal file
11
Assets/Materials/Scripts/WallHitParticles.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4102c64b1c693dc4f8d3104f2f9c5b9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
137
Assets/Materials/Scripts/Wind.cs
Normal file
137
Assets/Materials/Scripts/Wind.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
11
Assets/Materials/Scripts/Wind.cs.meta
Normal file
11
Assets/Materials/Scripts/Wind.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e91a8ca522aef540a791f9aa072455d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
180
Assets/Materials/Scripts/ZodiacCameraController.cs
Normal file
180
Assets/Materials/Scripts/ZodiacCameraController.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
11
Assets/Materials/Scripts/ZodiacCameraController.cs.meta
Normal file
11
Assets/Materials/Scripts/ZodiacCameraController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99b8956777a4ca242a475f8f4d354d12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user