180 lines
5.6 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|