Files
ScienceLab.AtmosphericPressure/Assets/Scripts/ThermosphereEffects.cs
2026-05-29 18:21:53 +03:00

242 lines
7.1 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThermosphereEffects : MonoBehaviour
{
[Header("ÌÊÑ")]
public GameObject issPrefab;
public float issOrbitRadius = 32f;
public float issOrbitSpeed = 20f;
public int issCount = 6;
public StratosphereDeath stratosphereDeath;
[Header("Ïîëÿðíå ñÿéâî")]
public GameObject auroraPrefab;
public float auroraRadius = 9.2f;
[Header("Âèáóõ ïðè ïàä³íí³")]
public GameObject explosionPrefab;
[Range(0f, 1f)]
public float thermosphereLevel = 1f;
private float previousLevel = 1f;
private class SatelliteData
{
public Transform transform;
public Vector3 orbitAxis;
public float orbitAngle;
public float orbitSpeed;
public bool isFalling;
}
private List<SatelliteData> satellites = new List<SatelliteData>();
private GameObject auroraNorth;
private GameObject auroraSouth;
void Awake()
{
enabled = false;
}
void SpawnISS()
{
if (issPrefab == null) return;
for (int i = 0; i < issCount; i++)
{
Vector3 axis = Random.onUnitSphere;
float angle = Random.Range(0f, 360f);
GameObject sat = Instantiate(issPrefab, this.transform);
sat.name = "Satellite_" + i;
sat.transform.localScale = Vector3.one * 0.002f;
Vector3 perpendicular = Vector3.Cross(axis, Vector3.up).normalized;
if (perpendicular.magnitude < 0.01f)
perpendicular = Vector3.Cross(axis, Vector3.right).normalized;
Quaternion rot = Quaternion.AngleAxis(angle, axis);
sat.transform.position = this.transform.position + rot * perpendicular * issOrbitRadius;
satellites.Add(new SatelliteData
{
transform = sat.transform,
orbitAxis = axis,
orbitAngle = angle,
orbitSpeed = Random.Range(15f, 25f),
isFalling = false
});
StartCoroutine(RotateSolarPanels(sat));
}
}
IEnumerator RotateSolarPanels(GameObject sat)
{
while (sat != null)
{
Transform panel1 = sat.transform.Find("solar_plane");
Transform panel2 = sat.transform.Find("solar_plane1");
if (panel1 != null) panel1.Rotate(Vector3.right * 10f * Time.deltaTime);
if (panel2 != null) panel2.Rotate(Vector3.right * 10f * Time.deltaTime);
yield return null;
}
}
void SpawnAurora()
{
if (auroraPrefab == null) return;
Vector3 center = this.transform.position;
auroraNorth = Instantiate(auroraPrefab, this.transform);
auroraNorth.name = "AuroraNorth";
auroraNorth.transform.position = center + Vector3.up * auroraRadius * 0.8f;
auroraNorth.transform.rotation = Quaternion.identity;
auroraNorth.transform.localScale = Vector3.one * 0.5f;
auroraSouth = Instantiate(auroraPrefab, this.transform);
auroraSouth.name = "AuroraSouth";
auroraSouth.transform.position = center + Vector3.down * auroraRadius * 0.8f;
auroraSouth.transform.rotation = Quaternion.Euler(180f, 0f, 0f);
auroraSouth.transform.localScale = Vector3.one * 0.5f;
}
public void InitState()
{
foreach (SatelliteData sat in satellites)
if (sat.transform != null) Destroy(sat.transform.gameObject);
satellites.Clear();
if (auroraNorth != null) Destroy(auroraNorth);
if (auroraSouth != null) Destroy(auroraSouth);
auroraNorth = null;
auroraSouth = null;
thermosphereLevel = 1f;
previousLevel = 1f;
}
public void InitStateAndSpawn()
{
InitState();
if (gameObject.activeInHierarchy)
StartCoroutine(SpawnDelayed());
}
IEnumerator SpawnDelayed()
{
yield return null;
SpawnISS();
SpawnAurora();
}
public void DropAllSatellites()
{
foreach (SatelliteData sat in satellites)
{
if (sat.transform != null && !sat.isFalling)
{
sat.isFalling = true;
StartCoroutine(SatelliteFall(sat));
}
}
}
void Update()
{
if (!Application.isPlaying) return;
if (thermosphereLevel >= 1f && previousLevel < 1f)
InitStateAndSpawn();
previousLevel = thermosphereLevel;
UpdateSatellites();
UpdateAurora();
}
void UpdateSatellites()
{
bool shouldFall = thermosphereLevel <= 0.3f;
bool shouldDrift = thermosphereLevel <= 0.5f && thermosphereLevel > 0.3f;
if (shouldFall && stratosphereDeath != null)
stratosphereDeath.TriggerPlanesDown();
foreach (SatelliteData sat in satellites)
{
if (sat.transform == null || sat.isFalling) continue;
sat.orbitAngle += sat.orbitSpeed * Time.deltaTime;
if (shouldDrift)
sat.orbitAngle += Random.Range(-2f, 2f) * Time.deltaTime;
Vector3 perpendicular = Vector3.Cross(sat.orbitAxis, Vector3.up).normalized;
if (perpendicular.magnitude < 0.01f)
perpendicular = Vector3.Cross(sat.orbitAxis, Vector3.right).normalized;
Quaternion rot = Quaternion.AngleAxis(sat.orbitAngle, sat.orbitAxis);
Vector3 newPos = this.transform.position + rot * perpendicular * issOrbitRadius;
Vector3 direction = (newPos - sat.transform.position).normalized;
sat.transform.position = newPos;
if (direction != Vector3.zero)
sat.transform.rotation = Quaternion.LookRotation(direction, sat.transform.position - this.transform.position);
if (shouldFall)
{
sat.isFalling = true;
StartCoroutine(SatelliteFall(sat));
}
}
}
IEnumerator SatelliteFall(SatelliteData sat)
{
float elapsed = 0f;
float fallSpeed = 3f;
while (elapsed < 5f && sat.transform != null)
{
Vector3 fallDir = (this.transform.position - sat.transform.position).normalized;
sat.transform.position += fallDir * fallSpeed * Time.deltaTime;
sat.transform.Rotate(Random.insideUnitSphere * 40f * Time.deltaTime);
fallSpeed += 2f * Time.deltaTime;
elapsed += Time.deltaTime;
yield return null;
}
if (sat.transform != null)
{
if (explosionPrefab != null)
{
GameObject exp = Instantiate(explosionPrefab, sat.transform.position, Quaternion.identity);
exp.transform.localScale = Vector3.one * 0.4f;
Destroy(exp, 4f);
}
Destroy(sat.transform.gameObject);
}
}
void UpdateAurora()
{
bool auroraActive = thermosphereLevel > 0.3f;
if (auroraNorth != null) auroraNorth.SetActive(auroraActive);
if (auroraSouth != null) auroraSouth.SetActive(auroraActive);
}
public void SetThermosphereLevel(float level)
{
thermosphereLevel = level;
}
}