Files

148 lines
7.1 KiB
C#
Raw Permalink Normal View History

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace Ironspore
{
public static class WorldFactory
{
static readonly Dictionary<string, Material> materials = new Dictionary<string, Material>();
public enum Surface { Painted, Concrete, BareMetal }
public static Material Material(Color color, bool glow = false, Surface surface = Surface.Painted)
{
string key = ColorUtility.ToHtmlStringRGB(color) + (glow ? "g" : "") + (int)surface;
if (materials.TryGetValue(key, out var cached) && cached)
return cached;
var mat = new Material(Shader.Find("Standard"));
mat.color = color;
mat.SetFloat("_Metallic", surface == Surface.BareMetal ? .78f : surface == Surface.Concrete ? 0 : .04f);
mat.SetFloat("_Glossiness", surface == Surface.Concrete ? .15f : surface == Surface.BareMetal ? .48f : .32f);
mat.enableInstancing = true;
if (glow)
{
mat.EnableKeyword("_EMISSION");
mat.SetColor("_EmissionColor", color * 1.25f);
}
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;
var renderer = obj.GetComponent<Renderer>();
var surface = name == "Ground" || name == "AccessRamp" ? Surface.Concrete : name == "ContainerRib" || name == "CanopyRail" ? Surface.BareMetal : Surface.Painted;
renderer.sharedMaterial = Material(color, glow, surface);
bool detail = name == "FloorSeam" || name == "AmberStripe" || name == "CrateLatch" || name == "RelayScreen" || name == "LandingLight" || name == "CanopyIndicator" || name.EndsWith("WorkFixture");
renderer.shadowCastingMode = detail || name == "EnemyBolt" ? ShadowCastingMode.Off : ShadowCastingMode.On;
renderer.receiveShadows = !glow;
if (name == "EnemyBolt") obj.layer = 10;
if (!collision)
Object.Destroy(obj.GetComponent<Collider>());
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<Transform>())
child.gameObject.layer = 8;
foreach (var renderer in root.GetComponentsInChildren<Renderer>())
{
renderer.shadowCastingMode = ShadowCastingMode.Off;
renderer.lightProbeUsage = LightProbeUsage.Off;
renderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
}
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;
obj.layer = 11;
var label = obj.AddComponent<TextMesh>();
label.fontSize = 40;
label.characterSize = .09f;
label.anchor = TextAnchor.MiddleCenter;
label.color = color;
var renderer = obj.GetComponent<Renderer>();
renderer.shadowCastingMode = ShadowCastingMode.Off;
renderer.receiveShadows = false;
renderer.lightProbeUsage = LightProbeUsage.Off;
renderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
obj.AddComponent<LocalizedWorldLabel>().Initialize(key);
obj.AddComponent<FaceCamera>();
}
public static void Tracer(Vector3 from, Vector3 to, Color color)
{
var obj = new GameObject("ShotTrace");
var line = obj.AddComponent<LineRenderer>();
obj.layer = 11;
line.shadowCastingMode = ShadowCastingMode.Off;
line.receiveShadows = false;
line.lightProbeUsage = LightProbeUsage.Off;
line.reflectionProbeUsage = ReflectionProbeUsage.Off;
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<Camera>();
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<AudioListener>();
if (camera)
AudioSource.PlayClipAtPoint(clip, camera.transform.position, volume);
Object.Destroy(clip, length + 1);
}
}
}