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

180 lines
5.6 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class StratosphereEffects : MonoBehaviour
{
[Header("˳òàêè")]
public GameObject planePrefab;
public int planeCount = 15;
public float planeOrbitRadius = 8.0f;
public float planeMinSpeed = 15f;
public float planeMaxSpeed = 25f;
public float planeScale = 0.003f;
[Header("Ïåðëàìóòðîâ³ õìàðè")]
public Material pearlCloudMaterial;
public int pearlCloudGroupCount = 10;
public float pearlCloudRadius = 8.3f;
[Header("UV ïðîìåí³")]
public GameObject godRayPrefab;
public int rayCount = 5;
public float rayDistance = 12f;
public Transform sunTransform;
private List<PlaneData> planes = new List<PlaneData>();
private List<ParticleSystem> pearlClouds = new List<ParticleSystem>();
private class PlaneData
{
public Transform transform;
public Vector3 orbitAxis;
public float orbitSpeed;
public float orbitAngle;
}
void Start()
{
SpawnPlanes();
SpawnPearlClouds();
SpawnGodRays();
}
public void SpawnPlanes()
{
if (planePrefab == null) return;
for (int i = 0; i < planeCount; i++)
{
GameObject plane = Instantiate(planePrefab, this.transform);
plane.name = "Plane_" + i;
plane.transform.localScale = Vector3.one * planeScale;
Vector3 axis = Random.onUnitSphere;
float angle = Random.Range(0f, 360f);
Vector3 startPos = GetOrbitPosition(axis, angle);
plane.transform.position = startPos;
planes.Add(new PlaneData
{
transform = plane.transform,
orbitAxis = axis,
orbitSpeed = Random.Range(planeMinSpeed, planeMaxSpeed),
orbitAngle = angle
});
}
}
public void SpawnPearlClouds()
{
for (int i = 0; i < pearlCloudGroupCount; i++)
{
Vector3 groupCenter = this.transform.position + Random.onUnitSphere * pearlCloudRadius;
GameObject obj = new GameObject("PearlCloud_" + i);
obj.transform.parent = this.transform;
obj.transform.position = groupCenter;
ParticleSystem ps = obj.AddComponent<ParticleSystem>();
var main = ps.main;
main.loop = false;
main.playOnAwake = true;
main.maxParticles = 12;
main.startLifetime = 999f;
main.startSpeed = 0f;
main.startSize = new ParticleSystem.MinMaxCurve(0.4f, 0.9f);
main.startColor = new ParticleSystem.MinMaxGradient(
new Color(1f, 0.6f, 0.85f, 0.6f),
new Color(0.85f, 0.5f, 0.9f, 0.45f)
);
main.simulationSpace = ParticleSystemSimulationSpace.Local;
var emission = ps.emission;
emission.rateOverTime = 0f;
emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0f, 12) });
var shape = ps.shape;
shape.enabled = true;
shape.shapeType = ParticleSystemShapeType.Sphere;
shape.radius = 0.5f;
shape.radiusThickness = 1f;
var renderer = ps.GetComponent<ParticleSystemRenderer>();
renderer.renderMode = ParticleSystemRenderMode.Billboard;
renderer.sortingFudge = -8f;
if (pearlCloudMaterial != null)
renderer.material = pearlCloudMaterial;
ps.Play();
pearlClouds.Add(ps);
}
}
void SpawnGodRays()
{
if (godRayPrefab == null) return;
for (int i = 0; i < rayCount; i++)
{
float spreadX = Random.Range(-2f, 2f);
float spreadY = Random.Range(-2f, 2f);
Vector3 spawnPos = this.transform.position
+ new Vector3(0.19f, -0.21f, -0.51f) * rayDistance
+ Vector3.up * spreadY
+ Vector3.right * spreadX;
GameObject ray = Instantiate(godRayPrefab, this.transform);
ray.name = "GodRay_" + i;
ray.transform.position = spawnPos;
ray.transform.rotation = Quaternion.Euler(90f, 0f, 189f);
ray.transform.localScale = new Vector3(0.3f, 0.3f, 1f);
}
}
Vector3 GetOrbitPosition(Vector3 axis, float angle)
{
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);
return this.transform.position + rot * perpendicular * planeOrbitRadius;
}
void Awake()
{
enabled = false;
}
void Update()
{
if (!Application.isPlaying) return;
foreach (PlaneData p in planes)
{
if (p.transform == null) continue;
p.orbitAngle += p.orbitSpeed * Time.deltaTime;
Vector3 newPos = GetOrbitPosition(p.orbitAxis, p.orbitAngle);
Vector3 direction = (newPos - p.transform.position).normalized;
p.transform.position = newPos;
if (direction != Vector3.zero)
p.transform.rotation = Quaternion.LookRotation(direction, p.transform.position - this.transform.position);
}
Quaternion pearlRotation = Quaternion.AngleAxis(2f * Time.deltaTime, Vector3.up);
foreach (ParticleSystem ps in pearlClouds)
{
if (ps == null) continue;
ps.transform.position = this.transform.position + pearlRotation * (ps.transform.position - this.transform.position);
}
}
}