242 lines
7.1 KiB
C#
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;
|
|
}
|
|
}
|