using System.Collections.Generic; using UnityEngine; namespace Ironspore { public static class WorldFactory { static readonly Dictionary materials = new Dictionary(); public static Material Material(Color color, bool glow = false) { string key = ColorUtility.ToHtmlStringRGB(color) + (glow ? "g" : ""); if (materials.TryGetValue(key, out var cached) && cached) return cached; var mat = new Material(Shader.Find("Standard")); mat.color = color; mat.SetFloat("_Metallic", .3f); mat.SetFloat("_Glossiness", .35f); if (glow) { mat.EnableKeyword("_EMISSION"); mat.SetColor("_EmissionColor", color * 1.8f); } materials[key] = mat; return mat; } public static GameObject Box(string name, Vector3 position, Vector3 scale, Color color, Transform parent, bool collision = true, bool glow = false) { return Primitive(PrimitiveType.Cube, name, position, scale, color, parent, collision, glow); } public static GameObject Cylinder(string name, Vector3 position, Vector3 scale, Color color, Transform parent, bool collision = true) { return Primitive(PrimitiveType.Cylinder, name, position, scale, color, parent, collision, false); } public static GameObject Primitive(PrimitiveType type, string name, Vector3 position, Vector3 scale, Color color, Transform parent, bool collision, bool glow) { var obj = GameObject.CreatePrimitive(type); obj.name = name; obj.transform.SetParent(parent); obj.transform.position = position; obj.transform.localScale = scale; obj.GetComponent().sharedMaterial = Material(color, glow); if (!collision) Object.Destroy(obj.GetComponent()); return obj; } public static GameObject Cockpit(Transform camera) { var root = new GameObject("CockpitFrame"); root.transform.SetParent(camera, false); foreach (int side in new[] { -1, 1 }) { var frame = Box("CanopyRail", Vector3.zero, new Vector3(.045f, .8f, .06f), new Color(.08f, .16f, .19f), root.transform, false); frame.transform.localPosition = new Vector3(side * .48f, -.05f, .7f); frame.transform.localRotation = Quaternion.Euler(0, 0, side * -12); var indicator = Box("CanopyIndicator", Vector3.zero, new Vector3(.018f, .27f, .065f), new Color(.05f, .9f, .75f), root.transform, false, true); indicator.transform.localPosition = new Vector3(side * .48f, -.15f, .66f); } var dashboard = Box("Dashboard", Vector3.zero, new Vector3(1.3f, .14f, .2f), new Color(.07f, .13f, .16f), root.transform, false); dashboard.transform.localPosition = new Vector3(0, -.42f, .75f); foreach (var child in root.GetComponentsInChildren()) child.gameObject.layer = 8; root.SetActive(false); return root; } public static void Label(string key, Vector3 position, Color color, Transform parent) { var obj = new GameObject("Sign"); obj.transform.SetParent(parent); obj.transform.position = position; var label = obj.AddComponent(); label.fontSize = 40; label.characterSize = .09f; label.anchor = TextAnchor.MiddleCenter; label.color = color; obj.AddComponent().Initialize(key); obj.AddComponent(); } public static void Tracer(Vector3 from, Vector3 to, Color color) { var obj = new GameObject("ShotTrace"); var line = obj.AddComponent(); line.positionCount = 2; line.SetPosition(0, from); line.SetPosition(1, to); line.startWidth = .045f; line.endWidth = .015f; line.sharedMaterial = Material(color, true); Object.Destroy(obj, .07f); } } public sealed class FaceCamera : MonoBehaviour { void LateUpdate() { var c = Camera.main; if (!c) c = Object.FindAnyObjectByType(); if (c) transform.rotation = c.transform.rotation; } } public static class GameAudio { public static void Cue(float frequency, float length, float volume = .12f) { int count = (int)(22050 * length); var data = new float[count]; for (int i = 0; i < count; i++) { float t = i / 22050f; data[i] = Mathf.Sin(t * frequency * Mathf.PI * 2) * Mathf.Exp(-t / length * 6); } var clip = AudioClip.Create("SynthCue", count, 1, 22050, false); clip.SetData(data, 0); var camera = Object.FindAnyObjectByType(); if (camera) AudioSource.PlayClipAtPoint(clip, camera.transform.position, volume); Object.Destroy(clip, length + 1); } } }