diff --git a/Assets/Scripts/Editor/ShipModPreview.cs b/Assets/Scripts/Editor/ShipModPreview.cs index 677253561..9ed4fcec4 100644 --- a/Assets/Scripts/Editor/ShipModPreview.cs +++ b/Assets/Scripts/Editor/ShipModPreview.cs @@ -51,9 +51,9 @@ public static class ShipModPreview // Instantiate clones the assembled root, and Unity must remap every array reference into the clone. var clone = UnityEngine.Object.Instantiate(ship.gameObject).GetComponent(); - try { CheckShip(clone, plan, "clone"); } + try { CheckShip(clone, plan, "clone"); CheckExhaust(clone); } finally { UnityEngine.Object.DestroyImmediate(clone.gameObject); } - Debug.Log($"SHIP_MOD_ASSEMBLY_SMOKE thrusters={plan.Thrusters.Length} " + + Debug.Log($"SHIP_MOD_ASSEMBLY_SMOKE thrusters={plan.Thrusters.Length} exhaust=ok collider=hidden " + $"weapons={plan.Weapons.Length} radiators={plan.Radiators.Length}"); } @@ -79,6 +79,42 @@ public static class ShipModPreview node.FiringPoint.All(Inside)).All(ok => ok), "weapon hardpoints with their muzzles in order"); } + // Exhaust from each hidden emitter, wired as ShipInstance wires it, from a particle system left at Unity's defaults + // (Use Mesh Colors on). The emitter's invisible material has alpha 0, so mesh colours would make every particle + // transparent; the wiring must turn them off. + private static void CheckExhaust(ShipInstance ship) + { + const int count = 200; + foreach (var hardpoint in ship.ThrusterHardpoints) + { + var exhaust = new GameObject("Smoke Exhaust").AddComponent(); + try + { + exhaust.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear); + var main = exhaust.main; + main.playOnAwake = false; + main.startSpeed = 0; + main.startLifetime = 10; + main.maxParticles = count * 2; + var emission = exhaust.emission; + emission.enabled = false; + var shape = exhaust.shape; + shape.enabled = true; + shape.shapeType = ParticleSystemShapeType.MeshRenderer; + if (!shape.useMeshColors) throw new InvalidOperationException("Unity's default Use Mesh Colors is off; the exhaust check proves nothing."); + ThrusterHardpoint.WireExhaust(exhaust, hardpoint); + exhaust.Emit(count); + if (exhaust.particleCount != count) + throw new InvalidOperationException($"clone: exhaust from {hardpoint.name} emitted {exhaust.particleCount} of {count} particles."); + var alive = new ParticleSystem.Particle[count]; + exhaust.GetParticles(alive); + if (alive.Any(particle => particle.GetCurrentColor(exhaust).a == 0)) + throw new InvalidOperationException($"clone: exhaust from {hardpoint.name} has transparent particles."); + } + finally { UnityEngine.Object.DestroyImmediate(exhaust.gameObject); } + } + } + [MenuItem("Aetheria/Preview Mod Ship Package")] private static async void Open() { diff --git a/Assets/Scripts/Gameplay/ShipInstance.cs b/Assets/Scripts/Gameplay/ShipInstance.cs index 8a0b22b6e..8b2540974 100644 --- a/Assets/Scripts/Gameplay/ShipInstance.cs +++ b/Assets/Scripts/Gameplay/ShipInstance.cs @@ -65,10 +65,9 @@ public class ShipInstance : EntityInstance { var effectData = (ThrusterData) thruster.Data; var particles = Instantiate(EngineAssets.Load(effectData.ParticlesPrefab), transform, false); - var particlesShape = particles.shape; var thrusterHardpoint = ThrusterHardpoints .FirstOrDefault(t => t.name == ship.Hardpoints[thruster.Item.Position.x, thruster.Item.Position.y].Transform); - particlesShape.meshRenderer = thrusterHardpoint?.Emitter; + ThrusterHardpoint.WireExhaust(particles, thrusterHardpoint); // if (!string.IsNullOrEmpty(thruster.Item.Data.SoundEffectTrigger) && thrusterHardpoint != null) // { // AkSoundEngine.RegisterGameObj(thrusterHardpoint.gameObject); diff --git a/Assets/Scripts/Gameplay/ThrusterHardpoint.cs b/Assets/Scripts/Gameplay/ThrusterHardpoint.cs index d3c3dbb98..b0b1d0f26 100644 --- a/Assets/Scripts/Gameplay/ThrusterHardpoint.cs +++ b/Assets/Scripts/Gameplay/ThrusterHardpoint.cs @@ -1,8 +1,16 @@ -using System.Collections; -using System.Collections.Generic; -using UnityEngine; +using UnityEngine; public class ThrusterHardpoint : MonoBehaviour { public MeshRenderer Emitter; + + // Points an exhaust's shape at a hardpoint's emitter, or at nothing when the ship has no such hardpoint. The emitter + // carries the invisible material (alpha 0), so the particles never take their colour from its mesh: with Use Mesh + // Colors on, Unity's default, they would all be born transparent. + public static void WireExhaust(ParticleSystem exhaust, ThrusterHardpoint hardpoint) + { + var shape = exhaust.shape; + shape.useMeshColors = false; + shape.meshRenderer = hardpoint != null ? hardpoint.Emitter : null; + } }