Initial commit

This commit is contained in:
2026-02-18 00:08:49 +02:00
commit 5105b6b060
1270 changed files with 513010 additions and 0 deletions

View File

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

View File

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

View File

@@ -0,0 +1,172 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AnimalChase : MonoBehaviour
{ public enum AnimalType
{
Cat,
Dog
}
public AnimalType animalType;
public AnimalChase otherAnimal;
public PlayZone zone;
public float walkSpeed = 2f;
public float runSpeed = 4f;
public float catchDistance = 1.5f;
public float restTime = 1f;
private CharacterController _controller;
private Animator _animator;
private bool _isChasing;
private bool _isResting;
private bool _isRunningAway;
private Vector3 _targetPoint;
private float _gravity = -9.8f;
private float _verticalVelocity;
private void Awake()
{
_controller = GetComponent<CharacterController>();
_animator = GetComponent<Animator>();
}
private void Start()
{
if (animalType == AnimalType.Dog)
StartChasing();
}
private void Update()
{
if (zone == null || otherAnimal == null)
return;
ApplyGravity();
if (_isResting)
{
UpdateAnimator(0f, 0f);
return;
}
if (_isChasing)
{
ChaseTarget();
}
else if (_isRunningAway)
{
RunToPoint();
}
else
{
UpdateAnimator(0f, 0f);
}
}
private void ChaseTarget()
{
MoveTo(otherAnimal.transform.position, runSpeed);
float dist = Vector3.Distance(transform.position, otherAnimal.transform.position);
if (dist <= catchDistance)
{
StartCoroutine(RestAndSwitch());
}
}
private void RunToPoint()
{
MoveTo(_targetPoint, walkSpeed);
if (Vector3.Distance(transform.position, _targetPoint) < 0.5f)
{
_isRunningAway = false;
}
}
private void MoveTo(Vector3 worldTarget, float speed)
{
worldTarget = zone.ClampToZone(worldTarget);
Vector3 dir = worldTarget - transform.position;
dir.y = 0f;
float distance = dir.magnitude;
if (distance < 0.1f)
{
UpdateAnimator(0f, 0f);
return;
}
dir.Normalize();
Vector3 move = dir * speed;
move.y = _verticalVelocity;
_controller.Move(move * Time.deltaTime);
transform.rotation = Quaternion.LookRotation(dir);
if (speed >= runSpeed * 0.9f)
{
UpdateAnimator(1f, 1f);
}
else
{
UpdateAnimator(1f, 0f);
}
}
private IEnumerator RestAndSwitch()
{
_isChasing = false;
_isResting = true;
UpdateAnimator(0f, 0f);
yield return new WaitForSeconds(restTime);
_isResting = false;
_targetPoint = zone.GetRandomPoint();
_isRunningAway = true;
otherAnimal.StartChasing();
}
public void StartChasing()
{
_isChasing = true;
_isRunningAway = false;
_isResting = false;
}
private void UpdateAnimator(float vert, float state)
{
_animator.SetFloat("Vert", vert);
_animator.SetFloat("State", state);
}
private void ApplyGravity()
{
if (_controller.isGrounded)
{
_verticalVelocity = -1f;
}
else
{
_verticalVelocity += _gravity * Time.deltaTime;
}
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,19 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BillboardToCamera : MonoBehaviour
{
private Transform _camera;
void Start()
{
_camera = Camera.main.transform;
}
void LateUpdate()
{
if (_camera == null) return;
transform.LookAt(transform.position + _camera.forward);
}
}

View File

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

137
Assets/Scripts/Calendar.cs Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CanvasFollowPlanet : MonoBehaviour
{
[SerializeField] private Transform planet;
[SerializeField] private Vector3 worldOffset = new Vector3(0, 5, 0);
[SerializeField] private Camera mainCamera;
void Start()
{
if (mainCamera == null)
mainCamera = Camera.main;
}
void LateUpdate()
{
if (mainCamera == null || planet == null) return;
transform.position = planet.position + worldOffset;
Vector3 lookDirection = mainCamera.transform.position - transform.position;
transform.rotation = Quaternion.LookRotation(-lookDirection, Vector3.up);
}
}

View File

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

168
Assets/Scripts/CarPatrol.cs Normal file
View File

@@ -0,0 +1,168 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class CarPatrol : MonoBehaviour
{
[Header("Waypoints")]
[SerializeField] private Transform[] waypoints;
[Header("Movement")]
[SerializeField] private float patrolSpeed = 5f;
[SerializeField] private float chaseSpeed = 12f;
[SerializeField] private float acceleration = 3f;
[SerializeField] private float rotationSpeed = 6f;
[Header("Detection")]
[SerializeField] private float detectionDistance = 20f;
[Header("Siren Reference")]
[SerializeField] private PoliceSiren siren;
private Transform _player;
private int _currentWaypointIndex;
private float _currentSpeed;
private bool _isChasing;
void Start()
{
_player = GameObject.FindGameObjectWithTag("Player")?.transform;
_currentSpeed = patrolSpeed;
if (siren != null)
siren.isSirenOn = false;
}
void Update()
{
if (_player == null || waypoints.Length == 0) return;
DetectPlayer();
if (_isChasing)
ChasePlayer();
else
Patrol();
}
private void Patrol()
{
_currentSpeed = patrolSpeed;
Vector3 target = waypoints[_currentWaypointIndex].position;
MoveTowards(target);
RotateTowards(target);
if (Vector3.Distance(transform.position, target) < 0.5f)
{
_currentWaypointIndex++;
if (_currentWaypointIndex >= waypoints.Length)
_currentWaypointIndex = 0;
}
}
private void ChasePlayer()
{
_currentSpeed = Mathf.MoveTowards(
_currentSpeed,
chaseSpeed,
acceleration * Time.deltaTime
);
MoveTowards(_player.position);
RotateTowards(_player.position);
}
private void DetectPlayer()
{
if (_player == null) return;
Vector3 toPlayer = _player.position - transform.position;
float distance = toPlayer.magnitude;
if (distance > detectionDistance)
{
StopChase();
return;
}
Vector3 direction = toPlayer.normalized;
float dot = Vector3.Dot(transform.forward, direction);
if (dot < 0.5f)
{
StopChase();
return;
}
float lateralDistance = Vector3.Cross(transform.forward, toPlayer).magnitude;
if (lateralDistance > 2f)
{
StopChase();
return;
}
StartChase();
}
private void StartChase()
{
if (_isChasing) return;
_isChasing = true;
if (siren != null)
siren.isSirenOn = true;
}
private void StopChase()
{
if (!_isChasing) return;
_isChasing = false;
_currentSpeed = patrolSpeed;
if (siren != null)
siren.isSirenOn = false;
}
private void MoveTowards(Vector3 target)
{
Vector3 targetPos = new Vector3(target.x, transform.position.y, target.z);
Vector3 direction = (targetPos - transform.position).normalized;
transform.position += direction * _currentSpeed * Time.deltaTime;
}
private void RotateTowards(Vector3 target)
{
Vector3 direction = new Vector3(
target.x - transform.position.x,
0f,
target.z - transform.position.z
);
if (direction == Vector3.zero) return;
Quaternion targetRotation = Quaternion.LookRotation(direction);
transform.rotation = Quaternion.Slerp(
transform.rotation,
targetRotation,
rotationSpeed * Time.deltaTime
);
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Player"))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
}

View File

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

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarouselRotate : MonoBehaviour
{
[SerializeField] private Transform swing;
[SerializeField] private float rotationSpeed = 60f;
[SerializeField] private Vector3 rotationAxis = Vector3.up;
private bool _isActive;
private void Reset()
{
swing = transform.parent;
}
private void Update()
{
if (!_isActive || swing == null) return;
swing.Rotate(rotationAxis.normalized * rotationSpeed * Time.deltaTime, Space.Self);
}
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
_isActive = true;
}
private void OnTriggerExit(Collider other)
{
if (!other.CompareTag("Player")) return;
_isActive = false;
}
}

View File

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

View File

@@ -0,0 +1,141 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CelestialCalendarController : MonoBehaviour
{
[System.Serializable]
public class PlanetCalendar
{
public GameObject planet;
public GameObject calendar;
public GameObject monthText;
public GameObject daysGrid;
public GameObject infoText;
}
[SerializeField] private List<PlanetCalendar> planetCalendars;
private GameObject _activeCalendar;
private PlanetCalendar _activeItem;
private Camera _activeCamera;
void Start()
{
foreach (var item in planetCalendars)
{
if (item.calendar != null)
item.calendar.SetActive(false);
if (item.infoText != null)
item.infoText.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.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.DownArrow))
{
ToggleInfoMode();
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);
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(PlanetCalendar item)
{
if (item.calendar == null) return;
if (_activeCalendar == item.calendar)
{
HideActive();
return;
}
HideActive();
item.calendar.SetActive(true);
if (item.monthText != null) item.monthText.SetActive(true);
if (item.daysGrid != null) item.daysGrid.SetActive(true);
if (item.infoText != null) item.infoText.SetActive(false);
_activeCalendar = item.calendar;
_activeItem = item;
}
void ToggleInfoMode()
{
if (_activeItem == null) return;
bool infoActive = _activeItem.infoText != null && _activeItem.infoText.activeSelf;
if (_activeItem.monthText != null) _activeItem.monthText.SetActive(infoActive);
if (_activeItem.daysGrid != null) _activeItem.daysGrid.SetActive(infoActive);
if (_activeItem.infoText != null) _activeItem.infoText.SetActive(!infoActive);
}
void HideActive()
{
if (_activeCalendar != null)
{
if (_activeItem != null)
{
if (_activeItem.monthText != null) _activeItem.monthText.SetActive(true);
if (_activeItem.daysGrid != null) _activeItem.daysGrid.SetActive(true);
if (_activeItem.infoText != null) _activeItem.infoText.SetActive(false);
}
_activeCalendar.SetActive(false);
_activeCalendar = null;
_activeItem = null;
}
}
}

View File

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

View File

@@ -0,0 +1,242 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class ChildAnimController : MonoBehaviour
{
[Header("Animations")]
[SerializeField] private string idleAnimation1 = "idle_m_2_220f";
[SerializeField] private string idleAnimation2 = "idle_selfcheck_1_300f";
[SerializeField] private string walkAnimation = "locom_m_basicWalk_30f";
[SerializeField] private string talkingAnimation = "idle_phoneTalking_180f";
[Header("Movement Points")]
[SerializeField] private Transform targetPoint1;
[SerializeField] private Transform targetPoint2;
[Header("Light Check")]
[SerializeField] private LightManager lightManager;
[SerializeField] private int requiredLights = 9;
[SerializeField] private string successMessage = "×óäîâî! Ïðåçåíòóé ïåðåä êëàñîì ñâîþ äóìêó!";
[SerializeField] private string failMessage = "Òè ùå íå çàâåðøèâ çàâäàííÿ, ñïðîáóé ùå!";
[Header("Movement Settings")]
[SerializeField] private float walkSpeed = 1f;
[SerializeField] private float waitTime = 3f;
[SerializeField] private float rotationSpeed = 5f;
[SerializeField] private float gravity = 9.81f;
[SerializeField] private float stopDistance = 0.25f;
[Header("Dialogue Settings")]
[SerializeField] private float talkDuration = 7f;
[SerializeField] private float interactionCooldown = 10f;
[SerializeField] private float textHeight = 1f;
[SerializeField] private GameObject existingCanvas;
[SerializeField] private TextMeshProUGUI existingTextMesh;
private Animator _animator;
private CharacterController _characterController;
private bool _isTalking;
private bool _canInteract = true;
private float _verticalVelocity;
private Transform _player;
private Coroutine _walkRoutine;
private void Start()
{
_animator = GetComponent<Animator>();
_characterController = GetComponent<CharacterController>();
if (_characterController == null)
{
_characterController = gameObject.AddComponent<CharacterController>();
_characterController.height = 1f;
_characterController.radius = 0.3f;
_characterController.center = new Vector3(0f, 0.5f, 0f);
}
if (existingCanvas != null)
{
existingCanvas.transform.SetParent(transform);
existingCanvas.transform.localPosition = new Vector3(0f, textHeight, 0f);
existingCanvas.SetActive(false);
}
_walkRoutine = StartCoroutine(WalkRoutine());
}
private void Update()
{
if (existingCanvas != null && existingCanvas.activeSelf)
{
Camera cam = Camera.main;
if (cam != null)
{
Vector3 dir = existingCanvas.transform.position - cam.transform.position;
if (dir != Vector3.zero)
existingCanvas.transform.rotation = Quaternion.LookRotation(dir);
}
}
}
private IEnumerator WalkRoutine()
{
while (true)
{
if (_isTalking)
{
yield return null;
continue;
}
PlayAnimation(idleAnimation1);
yield return new WaitForSeconds(waitTime);
if (targetPoint1 != null)
{
yield return WalkToPoint(targetPoint1.position);
yield return TurnToFaceDirection(targetPoint2 != null ? targetPoint2.position : transform.forward);
}
if (_isTalking) continue;
PlayAnimation(idleAnimation2);
yield return new WaitForSeconds(waitTime);
if (targetPoint2 != null)
{
yield return WalkToPoint(targetPoint2.position);
yield return TurnToFaceDirection(targetPoint1 != null ? targetPoint1.position : transform.forward);
}
}
}
private IEnumerator WalkToPoint(Vector3 targetPosition)
{
PlayAnimation(walkAnimation);
while (true)
{
if (_isTalking) yield break;
Vector3 fromXZ = new Vector3(transform.position.x, 0f, transform.position.z);
Vector3 toXZ = new Vector3(targetPosition.x, 0f, targetPosition.z);
float dist = Vector3.Distance(fromXZ, toXZ);
if (dist <= stopDistance)
{
_verticalVelocity = -0.5f;
yield break;
}
Vector3 dir = (toXZ - fromXZ).normalized;
if (dir != Vector3.zero)
{
Quaternion look = Quaternion.LookRotation(dir);
transform.rotation = Quaternion.Slerp(transform.rotation, look, rotationSpeed * Time.deltaTime);
}
if (_characterController.isGrounded)
_verticalVelocity = -0.5f;
else
_verticalVelocity -= gravity * Time.deltaTime;
Vector3 move = dir * walkSpeed;
move.y = _verticalVelocity;
_characterController.Move(move * Time.deltaTime);
yield return null;
}
}
private IEnumerator TurnToFaceDirection(Vector3 targetPosition)
{
Vector3 dir = targetPosition - transform.position;
dir.y = 0f;
if (dir == Vector3.zero) yield break;
Quaternion targetRot = Quaternion.LookRotation(dir.normalized);
while (Quaternion.Angle(transform.rotation, targetRot) > 1f)
{
if (_isTalking) yield break;
transform.rotation = Quaternion.Slerp(transform.rotation, targetRot, rotationSpeed * Time.deltaTime);
yield return null;
}
}
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
if (!_canInteract) return;
if (_isTalking) return;
_player = other.transform;
StartCoroutine(TalkToPlayer());
}
private IEnumerator TalkToPlayer()
{
_isTalking = true;
_canInteract = false;
if (_walkRoutine != null)
StopCoroutine(_walkRoutine);
if (_player != null)
{
Vector3 dir = _player.position - transform.position;
dir.y = 0f;
if (dir != Vector3.zero)
transform.rotation = Quaternion.LookRotation(dir.normalized);
}
PlayAnimation(talkingAnimation);
if (existingTextMesh != null)
{
if (lightManager != null && lightManager.CurrentLights >= requiredLights)
existingTextMesh.text = successMessage;
else
existingTextMesh.text = failMessage;
}
if (existingCanvas != null)
existingCanvas.SetActive(true);
yield return new WaitForSeconds(talkDuration);
EndTalk();
}
private void EndTalk()
{
if (existingCanvas != null)
existingCanvas.SetActive(false);
_isTalking = false;
StartCoroutine(CooldownRoutine());
_walkRoutine = StartCoroutine(WalkRoutine());
}
private IEnumerator CooldownRoutine()
{
yield return new WaitForSeconds(interactionCooldown);
_canInteract = true;
}
private void PlayAnimation(string animationName)
{
if (_animator == null) return;
if (string.IsNullOrEmpty(animationName)) return;
_animator.CrossFade(animationName, 0.2f);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,50 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CustomCursor : MonoBehaviour
{
[SerializeField] private Texture2D cursorTexture;
[SerializeField] private Vector2 hotspot = Vector2.zero;
[SerializeField] private CursorMode cursorMode = CursorMode.Auto;
[SerializeField] private LightManager lightManager;
private bool _isCustomCursorActive = false;
void Update()
{
if (lightManager != null)
{
GameObject lightPanel = lightManager.GetLightPanel();
if (lightPanel != null && lightPanel.activeSelf && !_isCustomCursorActive)
{
SetCustomCursor();
}
else if ((lightPanel == null || !lightPanel.activeSelf) && _isCustomCursorActive)
{
SetDefaultCursor();
}
}
}
private void SetCustomCursor()
{
if (cursorTexture != null)
{
Cursor.SetCursor(cursorTexture, hotspot, cursorMode);
_isCustomCursorActive = true;
}
}
private void SetDefaultCursor()
{
Cursor.SetCursor(null, Vector2.zero, CursorMode.Auto);
_isCustomCursorActive = false;
}
void OnDestroy()
{
SetDefaultCursor();
}
}

View File

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

View File

@@ -0,0 +1,111 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class ElectricGenerator : MonoBehaviour
{
[SerializeField] private GameObject canvasObject;
[SerializeField] private TextMeshProUGUI messageText;
[Header("Optional")]
[SerializeField] private string lampTag = "LampLight";
[SerializeField] private string lockChildName = "Lock";
private string[] _randomMessages =
{
"Õìì... ö³êàâî äëÿ ÷îãî öåé çàìîê...",
"Õìì... ñõîæå ùîñü çàãóáèëîñÿ...",
"Òóò òî÷íî ùîñü íå âèñòà÷àº..."
};
private List<GameObject> _lamps = new List<GameObject>();
private bool _activated;
private void Start()
{
if (canvasObject != null) canvasObject.SetActive(false);
_lamps = FindSceneObjectsWithTagIncludingInactive(lampTag);
for (int i = 0; i < _lamps.Count; i++)
{
if (_lamps[i] != null)
_lamps[i].SetActive(false);
}
}
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
if (!KeyPickup.HasKey)
{
ShowRandomMessage();
return;
}
if (_activated) return;
ActivateLights();
}
private void OnTriggerExit(Collider other)
{
if (!other.CompareTag("Player")) return;
if (canvasObject != null) canvasObject.SetActive(false);
}
private void ShowRandomMessage()
{
if (canvasObject != null) canvasObject.SetActive(true);
int index = Random.Range(0, _randomMessages.Length);
if (messageText != null) messageText.text = _randomMessages[index];
}
private void ActivateLights()
{
if (canvasObject != null) canvasObject.SetActive(false);
if (_lamps == null || _lamps.Count == 0)
_lamps = FindSceneObjectsWithTagIncludingInactive(lampTag);
int activatedCount = 0;
for (int i = 0; i < _lamps.Count; i++)
{
GameObject lamp = _lamps[i];
if (lamp == null) continue;
lamp.SetActive(true);
activatedCount++;
}
Transform lockTr = transform.Find(lockChildName);
if (lockTr != null)
Destroy(lockTr.gameObject);
_activated = true;
}
private List<GameObject> FindSceneObjectsWithTagIncludingInactive(string tag)
{
var result = new List<GameObject>();
GameObject[] all = Resources.FindObjectsOfTypeAll<GameObject>();
for (int i = 0; i < all.Length; i++)
{
GameObject go = all[i];
if (go == null) continue;
if (!go.scene.IsValid() || !go.scene.isLoaded) continue;
if (go.hideFlags != HideFlags.None) continue;
if (go.CompareTag(tag))
result.Add(go);
}
return result;
}
}

View File

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

View File

@@ -0,0 +1,73 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GirlExercise : MonoBehaviour
{
[Header("Àí³ìàö³¿")]
[SerializeField] private string idleAnimation = "idle_selfcheck_1_300f";
[SerializeField] private string exerciseAnimation = "exercise_warmingUp_170f";
private Animator animator;
private AnimationClip[] animationClips;
private float currentAnimationLength;
private float animationTimer;
private bool isPlaying = false;
void Start()
{
animator = GetComponent<Animator>();
if (animator != null)
{
animationClips = animator.runtimeAnimatorController.animationClips;
PlayRandomAnimation();
}
}
void Update()
{
if (isPlaying)
{
animationTimer += Time.deltaTime;
if (animationTimer >= currentAnimationLength)
{
PlayRandomAnimation();
}
}
}
private void PlayRandomAnimation()
{
string selectedAnimation;
if (Random.value > 0.5f)
{
selectedAnimation = idleAnimation;
}
else
{
selectedAnimation = exerciseAnimation;
}
animator.Play(selectedAnimation);
currentAnimationLength = GetAnimationLength(selectedAnimation);
animationTimer = 0f;
isPlaying = true;
}
private float GetAnimationLength(string animationName)
{
foreach (AnimationClip clip in animationClips)
{
if (clip.name == animationName)
{
return clip.length;
}
}
return 5f;
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,31 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KeyPickup : MonoBehaviour
{
public static bool HasKey = false;
[SerializeField] private GameObject pickupEffect;
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
HasKey = true;
if (pickupEffect != null)
{
GameObject effect = Instantiate(
pickupEffect,
transform.position,
Quaternion.identity
);
Destroy(effect, 3f);
}
Destroy(gameObject);
}
}

View File

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

View File

@@ -0,0 +1,146 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class LightManager : MonoBehaviour
{
[SerializeField] private GameObject lightPanel;
public int maxLights = 15;
[SerializeField] private float maxDistance = 200f;
private int _currentLights = 0;
public int CurrentLights => _currentLights;
private Color _selectedColor;
private GameObject _previewObject;
private List<GameObject> _placedLights = new List<GameObject>();
public GameObject GetLightPanel() => lightPanel;
void Start()
{
lightPanel.SetActive(false);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
lightPanel.SetActive(!lightPanel.activeSelf);
if (!lightPanel.activeSelf)
CancelPreview();
}
if (_previewObject != null)
{
UpdatePreviewPosition();
if (Input.GetMouseButtonDown(0))
PlaceLight();
if (Input.GetMouseButtonDown(1))
CancelPreview();
}
else
{
if (Input.GetMouseButtonDown(1))
TryRemoveLight();
}
}
public void SetWhite() => CreatePreview(Color.white);
public void SetRed() => CreatePreview(Color.red);
public void SetBlue() => CreatePreview(Color.blue);
public void SetGreen() => CreatePreview(Color.green);
private void CreatePreview(Color color)
{
if (_currentLights >= maxLights) return;
CancelPreview();
_selectedColor = color;
_previewObject = new GameObject("Preview Light");
Light l = _previewObject.AddComponent<Light>();
l.type = LightType.Point;
l.range = 8f;
l.intensity = 3f;
l.color = _selectedColor;
}
private void CancelPreview()
{
if (_previewObject != null)
{
Destroy(_previewObject);
_previewObject = null;
}
}
private void UpdatePreviewPosition()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out RaycastHit hit, maxDistance))
{
_previewObject.transform.position = hit.point + hit.normal * 0.1f;
}
}
private void PlaceLight()
{
if (_currentLights >= maxLights) return;
GameObject lightGO = new GameObject("New Light");
lightGO.transform.position = _previewObject.transform.position;
Light l = lightGO.AddComponent<Light>();
l.type = LightType.Point;
l.range = 8f;
l.intensity = 5f;
l.color = _selectedColor;
SphereCollider col = lightGO.AddComponent<SphereCollider>();
col.radius = 0.5f;
_placedLights.Add(lightGO);
_currentLights++;
}
private void TryRemoveLight()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (!Physics.Raycast(ray, out RaycastHit hit, maxDistance))
return;
GameObject hitObject = hit.collider.gameObject;
if (_placedLights.Contains(hitObject))
{
RemoveLight(hitObject);
return;
}
float removeRadius = 1f;
Collider[] nearby = Physics.OverlapSphere(hit.point, removeRadius);
foreach (Collider col in nearby)
{
if (_placedLights.Contains(col.gameObject))
{
RemoveLight(col.gameObject);
return;
}
}
}
private void RemoveLight(GameObject lightObject)
{
_placedLights.Remove(lightObject);
Destroy(lightObject);
_currentLights--;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,131 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class PlanetInfoDisplay : MonoBehaviour
{
[SerializeField] private PlanetType planetType;
[SerializeField] private PlanetSpin planetSpin;
[SerializeField] private TextMeshProUGUI infoText;
[SerializeField] private float startDistanceUnity;
private Dictionary<PlanetType, float> _realDistances = new Dictionary<PlanetType, float>()
{
{ PlanetType.Mercury, 57.9f },
{ PlanetType.Venus, 108.2f },
{ PlanetType.Earth, 149.6f },
{ PlanetType.Mars, 227.9f },
{ PlanetType.Jupiter, 778.5f },
{ PlanetType.Saturn, 1432f },
{ PlanetType.Uranus, 2867f },
{ PlanetType.Neptune, 4515f },
{ PlanetType.Pluto, 5906f }
};
private Dictionary<PlanetType, float> _realRotationSpeeds = new Dictionary<PlanetType, float>()
{
{ PlanetType.Mercury, 10.83f },
{ PlanetType.Venus, 6.52f },
{ PlanetType.Earth, 1674f },
{ PlanetType.Mars, 868f },
{ PlanetType.Jupiter, 45583f },
{ PlanetType.Saturn, 36840f },
{ PlanetType.Uranus, 14794f },
{ PlanetType.Neptune, 9719f },
{ PlanetType.Pluto, 813f }
};
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 }
};
private Dictionary<PlanetType, float> _orbitalSpeeds = new Dictionary<PlanetType, float>()
{
{ PlanetType.Mercury, 47.4f },
{ PlanetType.Venus, 35.0f },
{ PlanetType.Earth, 29.8f },
{ PlanetType.Mars, 24.1f },
{ PlanetType.Jupiter, 13.1f },
{ PlanetType.Saturn, 9.7f },
{ PlanetType.Uranus, 6.8f },
{ PlanetType.Neptune, 5.4f },
{ PlanetType.Pluto, 4.7f }
};
private Dictionary<PlanetType, Vector2> _temperatures = new Dictionary<PlanetType, Vector2>()
{
{ PlanetType.Mercury, new Vector2(-180f, 430f) },
{ PlanetType.Venus, new Vector2(437f, 497f) },
{ PlanetType.Earth, new Vector2(-88f, 58f) },
{ PlanetType.Mars, new Vector2(-125f, 20f) },
{ PlanetType.Jupiter, new Vector2(-145f, -108f) },
{ PlanetType.Saturn, new Vector2(-178f, -130f) },
{ PlanetType.Uranus, new Vector2(-224f, -197f) },
{ PlanetType.Neptune, new Vector2(-218f, -200f) },
{ PlanetType.Pluto, new Vector2(-240f, -218f) }
};
private Dictionary<PlanetType, string> _planetTypes = new Dictionary<PlanetType, string>()
{
{ PlanetType.Mercury, "Êàì'ÿíèñòà" },
{ PlanetType.Venus, "Êàì'ÿíèñòà" },
{ PlanetType.Earth, "Êàì'ÿíèñòà" },
{ PlanetType.Mars, "Êàì'ÿíèñòà" },
{ PlanetType.Jupiter, "Ãàçîâèé ã³ãàíò" },
{ PlanetType.Saturn, "Ãàçîâèé ã³ãàíò" },
{ PlanetType.Uranus, "Êðèæàíèé ã³ãàíò" },
{ PlanetType.Neptune, "Êðèæàíèé ã³ãàíò" },
{ PlanetType.Pluto, "Êàðëèêîâà" }
};
void Update()
{
if (infoText == null) return;
UpdateInfo();
}
void UpdateInfo()
{
float currentX = Mathf.Abs(transform.position.x);
float distanceKm = 0f;
if (startDistanceUnity > 0.001f)
{
float ratio = currentX / startDistanceUnity;
distanceKm = ratio * _realDistances[planetType];
}
float currentRotationSpeed = 0f;
if (planetSpin != null)
{
float baseSpeed = Mathf.Abs(_baseRotationSpeeds[planetType]);
float currentSpeed = Mathf.Abs(planetSpin.RotationSpeed);
if (baseSpeed > 0.0001f)
{
float speedRatio = currentSpeed / baseSpeed;
currentRotationSpeed = _realRotationSpeeds[planetType] * speedRatio;
}
}
float orbitalSpeed = _orbitalSpeeds[planetType];
Vector2 temp = _temperatures[planetType];
string type = _planetTypes[planetType];
infoText.text =
"Òèï ïëàíåòè: " + type + "\n" +
"³äñòàíü â³ä Ñîíöÿ: " + distanceKm.ToString("F1") + " ìëí êì\n" +
"Øâèäê³ñòü îáåðòàííÿ íàâêîëî ñâ îñ³: " + currentRotationSpeed.ToString("F0") + " êì/ãîä\n" +
"Øâèäê³ñòü ðóõó ïî îðá³ò³ íàâêîëî Ñîíöÿ: " + orbitalSpeed.ToString("F1") + " êì/ñ\n" +
"Òåìïåðàòóðà ïîâåðõí³: â³ä "+"\n" + temp.x.ToString("F0") + "°C äî " + temp.y.ToString("F0") + "°C";
}
}

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayZone : MonoBehaviour
{
private BoxCollider _box;
private void Awake()
{
_box = GetComponent<BoxCollider>();
}
public Vector3 ClampToZone(Vector3 position)
{
Vector3 localPos = transform.InverseTransformPoint(position);
Vector3 halfSize = _box.size / 2f;
localPos.x = Mathf.Clamp(localPos.x, -halfSize.x, halfSize.x);
localPos.z = Mathf.Clamp(localPos.z, -halfSize.z, halfSize.z);
return transform.TransformPoint(localPos);
}
public Vector3 GetRandomPoint()
{
Vector3 halfSize = _box.size / 2f;
float randomX = Random.Range(-halfSize.x, halfSize.x);
float randomZ = Random.Range(-halfSize.z, halfSize.z);
Vector3 localPoint = new Vector3(randomX, 0f, randomZ);
return transform.TransformPoint(localPoint);
}
}

View File

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

View File

@@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerKick : MonoBehaviour
{
[SerializeField] private float kickForce = 8f;
private void OnControllerColliderHit(ControllerColliderHit hit)
{
if (hit.collider.CompareTag("Ball"))
{
Rigidbody rb = hit.collider.GetComponent<Rigidbody>();
if (rb != null)
{
Vector3 direction = hit.moveDirection;
direction.y = 0.3f;
rb.AddForce(direction * kickForce, ForceMode.Impulse);
}
}
}
}

View File

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

View File

@@ -0,0 +1,18 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PoliceIdle : MonoBehaviour
{
private Animator animator;
void Start()
{
animator = GetComponent<Animator>();
if (animator != null)
{
animator.Play("idle_selfcheck_1_300f");
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

20
Assets/Scripts/Swing.cs Normal file
View File

@@ -0,0 +1,20 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Swing : MonoBehaviour
{
private Rigidbody _rb;
[SerializeField] private float torque = 30f;
void Awake()
{
_rb = GetComponent<Rigidbody>();
}
void Start()
{
_rb.WakeUp();
_rb.AddTorque(transform.right * torque, ForceMode.Impulse);
}
}

View File

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

View File

@@ -0,0 +1,36 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwingRotate : MonoBehaviour
{
[SerializeField] private Vector3 rotationAxis = Vector3.up;
[SerializeField] private float rotationSpeed = 60f;
private bool isActive = false;
void Update()
{
if (isActive)
{
transform.Rotate(rotationAxis * rotationSpeed * Time.deltaTime, Space.Self);
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
isActive = false;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
isActive = true;
}
}
}

View File

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

View File

@@ -0,0 +1,58 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SwingSmoothRotate : MonoBehaviour
{
[SerializeField] private Transform swing;
[SerializeField] private float leftAngle = -2.457f;
[SerializeField] private float rightAngle = 21f;
[SerializeField] private float rotateSpeed = 60f;
private float targetAngleX;
private bool rotate = false;
private void Update()
{
if (!rotate) return;
Vector3 current = swing.localEulerAngles;
float currentX = NormalizeAngle(current.x);
float newX = Mathf.MoveTowards(
currentX,
targetAngleX,
rotateSpeed * Time.deltaTime
);
swing.localEulerAngles = new Vector3(newX, current.y, current.z);
if (Mathf.Abs(newX - targetAngleX) < 0.1f)
{
rotate = false;
}
}
private void OnTriggerEnter(Collider other)
{
if (!other.CompareTag("Player")) return;
if (gameObject.name.Contains("Left"))
{
targetAngleX = leftAngle;
rotate = true;
}
else if (gameObject.name.Contains("Right"))
{
targetAngleX = rightAngle;
rotate = true;
}
}
private float NormalizeAngle(float angle)
{
if (angle > 180f) angle -= 360f;
return angle;
}
}

View File

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

View File

@@ -0,0 +1,185 @@
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()
{
if (zodiacRoot == null || zodiacRoot.childCount == 0) return;
if (_currentIndex < 0 || _currentIndex >= zodiacRoot.childCount)
_currentIndex = 0;
Transform constellation = zodiacRoot.GetChild(_currentIndex);
if (_presets.ContainsKey(constellation.name))
{
CameraPreset preset = _presets[constellation.name];
zodiacCamera.transform.SetParent(null);
zodiacCamera.transform.position = preset.localPosition;
zodiacCamera.transform.rotation = Quaternion.Euler(preset.localRotation);
}
else
{
ApplyFallback(constellation);
}
}
void ApplyFallback(Transform constellation)
{
Bounds bounds = CalculateBounds(constellation);
Vector3 center = bounds.center;
Vector3 dir = new Vector3(-1f, 0f, 0f).normalized;
float size = Mathf.Max(bounds.size.x, bounds.size.y);
float distance = Mathf.Max(size * 1.6f, 1600f);
zodiacCamera.transform.SetParent(null);
zodiacCamera.transform.position = center + dir * distance;
zodiacCamera.transform.LookAt(center, Vector3.up);
}
Bounds CalculateBounds(Transform root)
{
Renderer[] renderers = root.GetComponentsInChildren<Renderer>();
Bounds bounds = renderers[0].bounds;
for (int i = 1; i < renderers.Length; i++)
bounds.Encapsulate(renderers[i].bounds);
return bounds;
}
}

View File

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